@soederpop/luca 0.0.6 → 0.0.8
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/CLAUDE.md +10 -1
- package/RUNME.md +56 -0
- package/bun.lock +1 -1
- package/commands/build-bootstrap.ts +78 -0
- package/commands/build-scaffolds.ts +24 -2
- package/commands/try-all-challenges.ts +543 -0
- package/commands/try-challenge.ts +100 -0
- package/docs/README.md +52 -80
- package/docs/TABLE-OF-CONTENTS.md +82 -51
- package/docs/apis/clients/elevenlabs.md +232 -8
- package/docs/apis/clients/graph.md +59 -8
- package/docs/apis/clients/openai.md +362 -2
- package/docs/apis/clients/rest.md +122 -2
- package/docs/apis/clients/websocket.md +71 -17
- package/docs/apis/features/agi/assistant.md +9 -3
- package/docs/apis/features/agi/assistants-manager.md +2 -2
- package/docs/apis/features/agi/claude-code.md +153 -14
- package/docs/apis/features/agi/conversation-history.md +15 -3
- package/docs/apis/features/agi/conversation.md +133 -20
- package/docs/apis/features/agi/openai-codex.md +90 -12
- package/docs/apis/features/agi/skills-library.md +23 -5
- package/docs/apis/features/node/container-link.md +59 -0
- package/docs/apis/features/node/content-db.md +1 -1
- package/docs/apis/features/node/disk-cache.md +1 -1
- package/docs/apis/features/node/dns.md +1 -0
- package/docs/apis/features/node/docker.md +2 -1
- package/docs/apis/features/node/esbuild.md +4 -3
- package/docs/apis/features/node/file-manager.md +13 -4
- package/docs/apis/features/node/fs.md +726 -171
- package/docs/apis/features/node/git.md +1 -0
- package/docs/apis/features/node/google-auth.md +23 -4
- package/docs/apis/features/node/google-calendar.md +14 -2
- package/docs/apis/features/node/google-docs.md +15 -2
- package/docs/apis/features/node/google-drive.md +21 -3
- package/docs/apis/features/node/google-sheets.md +14 -2
- package/docs/apis/features/node/grep.md +2 -0
- package/docs/apis/features/node/helpers.md +29 -0
- package/docs/apis/features/node/ink.md +2 -2
- package/docs/apis/features/node/networking.md +39 -4
- package/docs/apis/features/node/os.md +28 -0
- package/docs/apis/features/node/postgres.md +26 -4
- package/docs/apis/features/node/proc.md +37 -28
- package/docs/apis/features/node/process-manager.md +33 -5
- package/docs/apis/features/node/repl.md +1 -1
- package/docs/apis/features/node/runpod.md +1 -0
- package/docs/apis/features/node/secure-shell.md +7 -0
- package/docs/apis/features/node/semantic-search.md +12 -5
- package/docs/apis/features/node/sqlite.md +26 -4
- package/docs/apis/features/node/telegram.md +30 -5
- package/docs/apis/features/node/tts.md +17 -2
- package/docs/apis/features/node/ui.md +1 -1
- package/docs/apis/features/node/vault.md +4 -9
- package/docs/apis/features/node/vm.md +3 -12
- package/docs/apis/features/node/window-manager.md +128 -20
- package/docs/apis/features/web/asset-loader.md +13 -1
- package/docs/apis/features/web/container-link.md +59 -0
- package/docs/apis/features/web/esbuild.md +4 -3
- package/docs/apis/features/web/helpers.md +29 -0
- package/docs/apis/features/web/network.md +16 -2
- package/docs/apis/features/web/speech.md +16 -2
- package/docs/apis/features/web/vault.md +4 -9
- package/docs/apis/features/web/vm.md +3 -12
- package/docs/apis/features/web/voice.md +18 -1
- package/docs/apis/servers/express.md +18 -2
- package/docs/apis/servers/mcp.md +29 -4
- package/docs/apis/servers/websocket.md +34 -6
- package/docs/bootstrap/CLAUDE.md +100 -0
- package/docs/bootstrap/SKILL.md +222 -0
- package/docs/bootstrap/templates/about-command.ts +41 -0
- package/docs/bootstrap/templates/docs-models.ts +22 -0
- package/docs/bootstrap/templates/docs-readme.md +43 -0
- package/docs/bootstrap/templates/example-feature.ts +53 -0
- package/docs/bootstrap/templates/health-endpoint.ts +15 -0
- package/docs/bootstrap/templates/luca-cli.ts +25 -0
- package/docs/bootstrap/templates/runme.md +54 -0
- package/docs/challenges/caching-proxy.md +16 -0
- package/docs/challenges/content-db-round-trip.md +14 -0
- package/docs/challenges/custom-command.md +9 -0
- package/docs/challenges/file-watcher-pipeline.md +11 -0
- package/docs/challenges/grep-audit-report.md +15 -0
- package/docs/challenges/multi-feature-dashboard.md +14 -0
- package/docs/challenges/process-orchestrator.md +17 -0
- package/docs/challenges/rest-api-server-with-client.md +12 -0
- package/docs/challenges/script-runner-with-vm.md +11 -0
- package/docs/challenges/simple-rest-api.md +15 -0
- package/docs/challenges/websocket-serve-and-client.md +11 -0
- package/docs/challenges/yaml-config-system.md +14 -0
- package/docs/command-system-overhaul.md +94 -0
- package/docs/examples/assistant/CORE.md +18 -0
- package/docs/examples/assistant/hooks.ts +3 -0
- package/docs/examples/assistant/tools.ts +10 -0
- package/docs/examples/window-manager-layouts.md +180 -0
- package/docs/in-memory-fs.md +4 -0
- package/docs/models.ts +13 -10
- package/docs/philosophy.md +4 -3
- package/docs/reports/console-hmr-design.md +170 -0
- package/docs/reports/helper-semantic-search.md +72 -0
- package/docs/scaffolds/client.md +29 -20
- package/docs/scaffolds/command.md +64 -50
- package/docs/scaffolds/endpoint.md +31 -36
- package/docs/scaffolds/feature.md +28 -18
- package/docs/scaffolds/selector.md +91 -0
- package/docs/scaffolds/server.md +18 -9
- package/docs/selectors.md +115 -0
- package/docs/sessions/custom-command/attempt-log-2.md +195 -0
- package/docs/sessions/file-watcher-pipeline/attempt-log-1.md +728 -0
- package/docs/sessions/file-watcher-pipeline/attempt-log-2.md +555 -0
- package/docs/sessions/grep-audit-report/attempt-log-1.md +289 -0
- package/docs/sessions/multi-feature-dashboard/attempt-log-2.md +679 -0
- package/docs/sessions/rest-api-server-with-client/attempt-log-1.md +1 -0
- package/docs/sessions/rest-api-server-with-client/attempt-log-3.md +920 -0
- package/docs/sessions/simple-rest-api/attempt-log-1.md +593 -0
- package/docs/sessions/websocket-serve-and-client/attempt-log-2.md +995 -0
- package/docs/tutorials/00-bootstrap.md +148 -0
- package/docs/tutorials/07-endpoints.md +7 -7
- package/docs/tutorials/08-commands.md +153 -72
- package/luca.cli.ts +3 -0
- package/package.json +6 -5
- package/public/index.html +1430 -0
- package/scripts/examples/using-ollama.ts +2 -1
- package/scripts/update-introspection-data.ts +2 -2
- package/src/agi/endpoints/experts.ts +1 -1
- package/src/agi/features/assistant.ts +7 -0
- package/src/agi/features/assistants-manager.ts +5 -5
- package/src/agi/features/claude-code.ts +263 -3
- package/src/agi/features/conversation-history.ts +7 -1
- package/src/agi/features/conversation.ts +26 -3
- package/src/agi/features/openai-codex.ts +26 -2
- package/src/agi/features/openapi.ts +6 -1
- package/src/agi/features/skills-library.ts +9 -1
- package/src/bootstrap/generated.ts +595 -0
- package/src/cli/cli.ts +64 -21
- package/src/client.ts +23 -357
- package/src/clients/civitai/index.ts +1 -1
- package/src/clients/client-template.ts +1 -1
- package/src/clients/comfyui/index.ts +13 -2
- package/src/clients/elevenlabs/index.ts +2 -1
- package/src/clients/graph.ts +87 -0
- package/src/clients/openai/index.ts +10 -1
- package/src/clients/rest.ts +207 -0
- package/src/clients/websocket.ts +176 -0
- package/src/command.ts +281 -34
- package/src/commands/bootstrap.ts +185 -0
- package/src/commands/chat.ts +5 -4
- package/src/commands/describe.ts +341 -4
- package/src/commands/help.ts +35 -9
- package/src/commands/index.ts +3 -0
- package/src/commands/introspect.ts +92 -2
- package/src/commands/prompt.ts +5 -6
- package/src/commands/run.ts +75 -10
- package/src/commands/save-api-docs.ts +49 -0
- package/src/commands/scaffold.ts +169 -23
- package/src/commands/select.ts +94 -0
- package/src/commands/serve.ts +10 -1
- package/src/container.ts +15 -0
- package/src/endpoint.ts +19 -0
- package/src/graft.ts +181 -0
- package/src/introspection/generated.agi.ts +12458 -8968
- package/src/introspection/generated.node.ts +10573 -7145
- package/src/introspection/generated.web.ts +1 -1
- package/src/introspection/index.ts +26 -0
- package/src/node/container.ts +6 -7
- package/src/node/features/content-db.ts +49 -2
- package/src/node/features/disk-cache.ts +16 -9
- package/src/node/features/dns.ts +16 -3
- package/src/node/features/docker.ts +16 -4
- package/src/node/features/esbuild.ts +22 -2
- package/src/node/features/file-manager.ts +184 -29
- package/src/node/features/fs.ts +704 -248
- package/src/node/features/git.ts +21 -8
- package/src/node/features/grep.ts +23 -3
- package/src/node/features/helpers.ts +372 -43
- package/src/node/features/networking.ts +39 -4
- package/src/node/features/opener.ts +28 -15
- package/src/node/features/os.ts +76 -0
- package/src/node/features/port-exposer.ts +11 -1
- package/src/node/features/postgres.ts +17 -1
- package/src/node/features/proc.ts +4 -1
- package/src/node/features/python.ts +63 -14
- package/src/node/features/repl.ts +11 -7
- package/src/node/features/runpod.ts +16 -3
- package/src/node/features/secure-shell.ts +27 -2
- package/src/node/features/semantic-search.ts +12 -1
- package/src/node/features/ui.ts +5 -69
- package/src/node/features/vm.ts +17 -0
- package/src/node/features/window-manager.ts +68 -20
- package/src/node.ts +5 -0
- package/src/scaffolds/generated.ts +492 -290
- package/src/scaffolds/template.ts +9 -0
- package/src/schemas/base.ts +46 -5
- package/src/selector.ts +282 -0
- package/src/server.ts +11 -0
- package/src/servers/express.ts +27 -12
- package/src/servers/socket.ts +45 -11
- package/src/web/clients/socket.ts +4 -1
- package/src/web/container.ts +2 -1
- package/src/web/features/network.ts +7 -1
- package/src/web/features/voice-recognition.ts +16 -1
- package/test/clients-servers.test.ts +2 -1
- package/test/command.test.ts +267 -0
- package/test/vm-context.test.ts +146 -0
- package/test-integration/assistants-manager.test.ts +10 -20
- package/docs/apis/features/node/launcher-app-command-listener.md +0 -145
- package/docs/examples/launcher-app-command-listener.md +0 -120
- package/docs/tasks/web-container-helper-discovery.md +0 -71
- package/docs/todos.md +0 -1
- package/scripts/test-command-listener.ts +0 -123
- package/src/node/features/launcher-app-command-listener.ts +0 -389
package/src/node/features/ui.ts
CHANGED
|
@@ -48,75 +48,11 @@ type ColoredPrintFunction = PrintFunction & {
|
|
|
48
48
|
|
|
49
49
|
/**
|
|
50
50
|
* UI Feature - Interactive Terminal User Interface Builder
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
* **Core Capabilities:**
|
|
57
|
-
* - Rich color management using chalk library
|
|
58
|
-
* - ASCII art generation with multiple fonts
|
|
59
|
-
* - Interactive prompts and wizards
|
|
60
|
-
* - Automatic color assignment for consistent theming
|
|
61
|
-
* - Text padding and formatting utilities
|
|
62
|
-
* - Gradient text effects (horizontal and vertical)
|
|
63
|
-
* - Banner creation with styled ASCII art
|
|
64
|
-
*
|
|
65
|
-
* **Color System:**
|
|
66
|
-
* - Full chalk API access for complex styling
|
|
67
|
-
* - Automatic color assignment with palette cycling
|
|
68
|
-
* - Consistent color mapping for named entities
|
|
69
|
-
* - Support for hex colors and gradients
|
|
70
|
-
*
|
|
71
|
-
* **ASCII Art Features:**
|
|
72
|
-
* - Multiple font options via figlet
|
|
73
|
-
* - Automatic font discovery and caching
|
|
74
|
-
* - Banner creation with color gradients
|
|
75
|
-
* - Text styling and effects
|
|
76
|
-
*
|
|
77
|
-
* **Interactive Elements:**
|
|
78
|
-
* - Wizard creation with inquirer integration
|
|
79
|
-
* - External editor integration
|
|
80
|
-
* - User input validation and processing
|
|
81
|
-
*
|
|
82
|
-
* **Usage Examples:**
|
|
83
|
-
*
|
|
84
|
-
* **Basic Colors:**
|
|
85
|
-
* ```typescript
|
|
86
|
-
* const ui = container.feature('ui');
|
|
87
|
-
*
|
|
88
|
-
* // Direct color usage
|
|
89
|
-
* ui.print.red('Error message');
|
|
90
|
-
* ui.print.green('Success!');
|
|
91
|
-
*
|
|
92
|
-
* // Complex styling
|
|
93
|
-
* console.log(ui.colors.blue.bold.underline('Important text'));
|
|
94
|
-
* ```
|
|
95
|
-
*
|
|
96
|
-
* **ASCII Art Banners:**
|
|
97
|
-
* ```typescript
|
|
98
|
-
* const banner = ui.banner('MyApp', {
|
|
99
|
-
* font: 'Big',
|
|
100
|
-
* colors: ['red', 'white', 'blue']
|
|
101
|
-
* });
|
|
102
|
-
* console.log(banner);
|
|
103
|
-
* ```
|
|
104
|
-
*
|
|
105
|
-
* **Interactive Wizards:**
|
|
106
|
-
* ```typescript
|
|
107
|
-
* const answers = await ui.wizard([
|
|
108
|
-
* { type: 'input', name: 'name', message: 'Your name?' },
|
|
109
|
-
* { type: 'confirm', name: 'continue', message: 'Continue?' }
|
|
110
|
-
* ]);
|
|
111
|
-
* ```
|
|
112
|
-
*
|
|
113
|
-
* **Automatic Color Assignment:**
|
|
114
|
-
* ```typescript
|
|
115
|
-
* const userColor = ui.assignColor('john');
|
|
116
|
-
* const adminColor = ui.assignColor('admin');
|
|
117
|
-
* console.log(userColor('John\'s message'));
|
|
118
|
-
* console.log(adminColor('Admin notice'));
|
|
119
|
-
* ```
|
|
51
|
+
*
|
|
52
|
+
* Unified interface for building professional CLI experiences using chalk (colors/styles),
|
|
53
|
+
* figlet (ASCII art), and inquirer (interactive prompts). Provides rich color management,
|
|
54
|
+
* automatic color assignment, text gradients, banner generation, padding utilities,
|
|
55
|
+
* markdown rendering, and interactive wizards.
|
|
120
56
|
*/
|
|
121
57
|
export class UI<T extends UIState = UIState> extends Feature<T> {
|
|
122
58
|
static { Feature.register(this, 'ui') }
|
package/src/node/features/vm.ts
CHANGED
|
@@ -155,6 +155,15 @@ export class VM<
|
|
|
155
155
|
createContext(ctx: any = {}) {
|
|
156
156
|
if (this.isContext(ctx)) return ctx
|
|
157
157
|
return vm.createContext({
|
|
158
|
+
console,
|
|
159
|
+
setTimeout,
|
|
160
|
+
setInterval,
|
|
161
|
+
clearTimeout,
|
|
162
|
+
clearInterval,
|
|
163
|
+
process,
|
|
164
|
+
Buffer,
|
|
165
|
+
URL,
|
|
166
|
+
URLSearchParams,
|
|
158
167
|
...this.container.context,
|
|
159
168
|
...ctx
|
|
160
169
|
})
|
|
@@ -340,6 +349,14 @@ export class VM<
|
|
|
340
349
|
exports: {},
|
|
341
350
|
module: { exports: {} },
|
|
342
351
|
console,
|
|
352
|
+
setTimeout,
|
|
353
|
+
setInterval,
|
|
354
|
+
clearTimeout,
|
|
355
|
+
clearInterval,
|
|
356
|
+
process,
|
|
357
|
+
Buffer,
|
|
358
|
+
URL,
|
|
359
|
+
URLSearchParams,
|
|
343
360
|
...ctx,
|
|
344
361
|
})
|
|
345
362
|
|
|
@@ -72,15 +72,20 @@ export const WindowManagerEventsSchema = FeatureEventsSchema.extend({
|
|
|
72
72
|
|
|
73
73
|
// --- Types ---
|
|
74
74
|
|
|
75
|
+
/** A dimension value — either absolute points or a percentage string like `"50%"`. */
|
|
76
|
+
export type DimensionValue = number | `${number}%`
|
|
77
|
+
|
|
75
78
|
/**
|
|
76
79
|
* Options for spawning a new native browser window.
|
|
80
|
+
* Dimensions and positions accept absolute points or percentage strings (e.g. `"50%"`)
|
|
81
|
+
* resolved against the primary display.
|
|
77
82
|
*/
|
|
78
83
|
export interface SpawnOptions {
|
|
79
84
|
url?: string
|
|
80
|
-
width?:
|
|
81
|
-
height?:
|
|
82
|
-
x?:
|
|
83
|
-
y?:
|
|
85
|
+
width?: DimensionValue
|
|
86
|
+
height?: DimensionValue
|
|
87
|
+
x?: DimensionValue
|
|
88
|
+
y?: DimensionValue
|
|
84
89
|
alwaysOnTop?: boolean
|
|
85
90
|
window?: {
|
|
86
91
|
decorations?: 'normal' | 'hiddenTitleBar' | 'none'
|
|
@@ -94,6 +99,8 @@ export interface SpawnOptions {
|
|
|
94
99
|
|
|
95
100
|
/**
|
|
96
101
|
* Options for spawning a native terminal window.
|
|
102
|
+
* Dimensions and positions accept absolute points or percentage strings (e.g. `"50%"`)
|
|
103
|
+
* resolved against the primary display.
|
|
97
104
|
*/
|
|
98
105
|
export interface SpawnTTYOptions {
|
|
99
106
|
/** Executable name or path (required). */
|
|
@@ -111,13 +118,13 @@ export interface SpawnTTYOptions {
|
|
|
111
118
|
/** Window title. */
|
|
112
119
|
title?: string
|
|
113
120
|
/** Window width in points. */
|
|
114
|
-
width?:
|
|
121
|
+
width?: DimensionValue
|
|
115
122
|
/** Window height in points. */
|
|
116
|
-
height?:
|
|
123
|
+
height?: DimensionValue
|
|
117
124
|
/** Window x position. */
|
|
118
|
-
x?:
|
|
125
|
+
x?: DimensionValue
|
|
119
126
|
/** Window y position. */
|
|
120
|
-
y?:
|
|
127
|
+
y?: DimensionValue
|
|
121
128
|
/** Chrome options (decorations, alwaysOnTop, etc.) */
|
|
122
129
|
window?: SpawnOptions['window']
|
|
123
130
|
}
|
|
@@ -366,10 +373,7 @@ export class WindowManager extends Feature<WindowManagerState, WindowManagerOpti
|
|
|
366
373
|
}
|
|
367
374
|
|
|
368
375
|
private getBridgeListener(): any | undefined {
|
|
369
|
-
|
|
370
|
-
if (!listener || listener === this) return undefined
|
|
371
|
-
if (typeof listener.send !== 'function') return undefined
|
|
372
|
-
return listener
|
|
376
|
+
return undefined
|
|
373
377
|
}
|
|
374
378
|
|
|
375
379
|
/** Default state: not listening, no client connected, zero windows tracked. */
|
|
@@ -440,13 +444,15 @@ export class WindowManager extends Feature<WindowManagerState, WindowManagerOpti
|
|
|
440
444
|
this.handleClientConnect(socket)
|
|
441
445
|
})
|
|
442
446
|
|
|
447
|
+
// Set immediately to prevent parallel calls from creating duplicate servers
|
|
448
|
+
this._server = server
|
|
449
|
+
|
|
443
450
|
server.on('error', (err) => {
|
|
444
451
|
this.setState({ lastError: err.message })
|
|
445
452
|
})
|
|
446
453
|
|
|
447
454
|
const finalPath = socketPath
|
|
448
455
|
server.listen(finalPath, () => {
|
|
449
|
-
this._server = server
|
|
450
456
|
this.setState({ listening: true, socketPath: finalPath })
|
|
451
457
|
this.emit('listening')
|
|
452
458
|
})
|
|
@@ -502,7 +508,8 @@ export class WindowManager extends Feature<WindowManagerState, WindowManagerOpti
|
|
|
502
508
|
* @returns A WindowHandle for the spawned window (with `.result` containing the ack data)
|
|
503
509
|
*/
|
|
504
510
|
async spawn(opts: SpawnOptions = {}): Promise<WindowHandle> {
|
|
505
|
-
const
|
|
511
|
+
const resolved = this.resolveDimensions(opts)
|
|
512
|
+
const { window: windowChrome, ...flat } = resolved
|
|
506
513
|
|
|
507
514
|
let ackResult: WindowAckResult
|
|
508
515
|
if (windowChrome) {
|
|
@@ -533,7 +540,8 @@ export class WindowManager extends Feature<WindowManagerState, WindowManagerOpti
|
|
|
533
540
|
* @returns A WindowHandle for the spawned terminal (with `.result` containing the ack data)
|
|
534
541
|
*/
|
|
535
542
|
async spawnTTY(opts: SpawnTTYOptions): Promise<WindowHandle> {
|
|
536
|
-
const
|
|
543
|
+
const resolved = this.resolveDimensions(opts)
|
|
544
|
+
const { window: windowChrome, ...flat } = resolved
|
|
537
545
|
|
|
538
546
|
let ackResult: WindowAckResult
|
|
539
547
|
if (windowChrome) {
|
|
@@ -668,16 +676,17 @@ export class WindowManager extends Feature<WindowManagerState, WindowManagerOpti
|
|
|
668
676
|
* ```
|
|
669
677
|
*/
|
|
670
678
|
async spawnLayout(config: LayoutEntry[]): Promise<WindowHandle[]> {
|
|
671
|
-
const
|
|
679
|
+
const handles: WindowHandle[] = []
|
|
680
|
+
for (const entry of config) {
|
|
672
681
|
if (entry.type === 'tty' || ('command' in entry && !entry.type)) {
|
|
673
682
|
const { type, ...opts } = entry as { type?: string } & SpawnTTYOptions
|
|
674
|
-
|
|
683
|
+
handles.push(await this.spawnTTY(opts))
|
|
675
684
|
} else {
|
|
676
685
|
const { type, ...opts } = entry as { type?: string } & SpawnOptions
|
|
677
|
-
|
|
686
|
+
handles.push(await this.spawn(opts))
|
|
678
687
|
}
|
|
679
|
-
}
|
|
680
|
-
return
|
|
688
|
+
}
|
|
689
|
+
return handles
|
|
681
690
|
}
|
|
682
691
|
|
|
683
692
|
/**
|
|
@@ -718,6 +727,45 @@ export class WindowManager extends Feature<WindowManagerState, WindowManagerOpti
|
|
|
718
727
|
|
|
719
728
|
// --- Private internals ---
|
|
720
729
|
|
|
730
|
+
private _displayCache: { width: number; height: number } | null = null
|
|
731
|
+
|
|
732
|
+
/**
|
|
733
|
+
* Get the primary display resolution, cached for the lifetime of the feature.
|
|
734
|
+
*/
|
|
735
|
+
private getPrimaryDisplay(): { width: number; height: number } {
|
|
736
|
+
if (this._displayCache) return this._displayCache
|
|
737
|
+
const osFeature = this.container.feature('os')
|
|
738
|
+
const displays = osFeature.getDisplayInfo()
|
|
739
|
+
const primary = displays.find(d => d.main) ?? displays[0]
|
|
740
|
+
if (!primary) throw new Error('No displays found')
|
|
741
|
+
this._displayCache = { width: primary.resolution.width, height: primary.resolution.height }
|
|
742
|
+
return this._displayCache
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
/**
|
|
746
|
+
* Resolve percentage-based dimension values to absolute points using the primary display.
|
|
747
|
+
* Passes through absolute numbers unchanged. Only fetches display info if percentages are present.
|
|
748
|
+
*/
|
|
749
|
+
private resolveDimensions<T extends Record<string, any>>(opts: T): T {
|
|
750
|
+
const keys = ['width', 'height', 'x', 'y'] as const
|
|
751
|
+
const hasPercentage = keys.some(k => typeof opts[k] === 'string' && (opts[k] as string).endsWith('%'))
|
|
752
|
+
if (!hasPercentage) return opts
|
|
753
|
+
|
|
754
|
+
const display = this.getPrimaryDisplay()
|
|
755
|
+
const resolved = { ...opts }
|
|
756
|
+
|
|
757
|
+
for (const key of keys) {
|
|
758
|
+
const val = opts[key]
|
|
759
|
+
if (typeof val === 'string' && val.endsWith('%')) {
|
|
760
|
+
const pct = parseFloat(val) / 100
|
|
761
|
+
const ref = (key === 'width' || key === 'x') ? display.width : display.height
|
|
762
|
+
;(resolved as any)[key] = Math.round(pct * ref)
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
return resolved
|
|
767
|
+
}
|
|
768
|
+
|
|
721
769
|
/**
|
|
722
770
|
* Handle a new client connection from the native app.
|
|
723
771
|
* Sets up NDJSON buffering and event forwarding.
|
package/src/node.ts
CHANGED
|
@@ -42,8 +42,12 @@ export { Registry } from './registry'
|
|
|
42
42
|
|
|
43
43
|
// Helper subclasses & registries
|
|
44
44
|
export { Client, ClientsRegistry } from './client'
|
|
45
|
+
export { RestClient } from './clients/rest'
|
|
46
|
+
export { GraphClient } from './clients/graph'
|
|
47
|
+
export { WebSocketClient } from './clients/websocket'
|
|
45
48
|
export { Command, CommandsRegistry, commands } from './command'
|
|
46
49
|
export { Endpoint, EndpointsRegistry, endpoints } from './endpoint'
|
|
50
|
+
export { Selector, SelectorsRegistry, selectors } from './selector'
|
|
47
51
|
export { Server, ServersRegistry } from './server'
|
|
48
52
|
export { FeaturesRegistry } from './feature'
|
|
49
53
|
|
|
@@ -56,6 +60,7 @@ export type { ContainerContext, ContainerArgv, Plugin, Extension } from './conta
|
|
|
56
60
|
export type { AvailableClients } from './client'
|
|
57
61
|
export type { AvailableCommands, CommandHandler } from './command'
|
|
58
62
|
export type { AvailableEndpoints, EndpointContext } from './endpoint'
|
|
63
|
+
export type { AvailableSelectors, SelectorsInterface, SelectorRunResult, SimpleSelector } from './selector'
|
|
59
64
|
export type { AvailableFeatures, FeatureOptions, FeatureState } from './feature'
|
|
60
65
|
export type { NodeContainer, NodeFeatures } from './node/container'
|
|
61
66
|
export type { AvailableServers, StartOptions, ServersInterface } from './server'
|