@portel/photon-core 1.4.0 → 2.1.0
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/README.md +123 -0
- package/dist/auto-ui.d.ts +103 -0
- package/dist/auto-ui.d.ts.map +1 -0
- package/dist/auto-ui.js +275 -0
- package/dist/auto-ui.js.map +1 -0
- package/dist/base.d.ts +9 -2
- package/dist/base.d.ts.map +1 -1
- package/dist/base.js +23 -10
- package/dist/base.js.map +1 -1
- package/dist/cli-ui-renderer.d.ts +31 -0
- package/dist/cli-ui-renderer.d.ts.map +1 -0
- package/dist/cli-ui-renderer.js +224 -0
- package/dist/cli-ui-renderer.js.map +1 -0
- package/dist/dependency-manager.d.ts.map +1 -1
- package/dist/dependency-manager.js +0 -1
- package/dist/dependency-manager.js.map +1 -1
- package/dist/design-system/index.d.ts +21 -0
- package/dist/design-system/index.d.ts.map +1 -0
- package/dist/design-system/index.js +27 -0
- package/dist/design-system/index.js.map +1 -0
- package/dist/design-system/tokens.d.ts +149 -0
- package/dist/design-system/tokens.d.ts.map +1 -0
- package/dist/design-system/tokens.js +413 -0
- package/dist/design-system/tokens.js.map +1 -0
- package/dist/design-system/transaction-ui.d.ts +70 -0
- package/dist/design-system/transaction-ui.d.ts.map +1 -0
- package/dist/design-system/transaction-ui.js +982 -0
- package/dist/design-system/transaction-ui.js.map +1 -0
- package/dist/generator.d.ts +58 -8
- package/dist/generator.d.ts.map +1 -1
- package/dist/generator.js +9 -4
- package/dist/generator.js.map +1 -1
- package/dist/index.d.ts +10 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +48 -44
- package/dist/index.js.map +1 -1
- package/dist/io.d.ts +395 -0
- package/dist/io.d.ts.map +1 -0
- package/dist/io.js +304 -0
- package/dist/io.js.map +1 -0
- package/dist/path-resolver.d.ts.map +1 -1
- package/dist/path-resolver.js +2 -1
- package/dist/path-resolver.js.map +1 -1
- package/dist/rendering/components.d.ts +29 -0
- package/dist/rendering/components.d.ts.map +1 -0
- package/dist/rendering/components.js +773 -0
- package/dist/rendering/components.js.map +1 -0
- package/dist/rendering/field-analyzer.d.ts +48 -0
- package/dist/rendering/field-analyzer.d.ts.map +1 -0
- package/dist/rendering/field-analyzer.js +270 -0
- package/dist/rendering/field-analyzer.js.map +1 -0
- package/dist/rendering/field-renderers.d.ts +64 -0
- package/dist/rendering/field-renderers.d.ts.map +1 -0
- package/dist/rendering/field-renderers.js +317 -0
- package/dist/rendering/field-renderers.js.map +1 -0
- package/dist/rendering/index.d.ts +28 -0
- package/dist/rendering/index.d.ts.map +1 -0
- package/dist/rendering/index.js +60 -0
- package/dist/rendering/index.js.map +1 -0
- package/dist/rendering/layout-selector.d.ts +48 -0
- package/dist/rendering/layout-selector.d.ts.map +1 -0
- package/dist/rendering/layout-selector.js +347 -0
- package/dist/rendering/layout-selector.js.map +1 -0
- package/dist/rendering/template-engine.d.ts +41 -0
- package/dist/rendering/template-engine.d.ts.map +1 -0
- package/dist/rendering/template-engine.js +236 -0
- package/dist/rendering/template-engine.js.map +1 -0
- package/dist/schema-extractor.d.ts +30 -0
- package/dist/schema-extractor.d.ts.map +1 -1
- package/dist/schema-extractor.js +205 -12
- package/dist/schema-extractor.js.map +1 -1
- package/dist/stateful.d.ts +63 -0
- package/dist/stateful.d.ts.map +1 -1
- package/dist/stateful.js +222 -0
- package/dist/stateful.js.map +1 -1
- package/dist/types.d.ts +9 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/ucp/ap2/handlers.d.ts +242 -0
- package/dist/ucp/ap2/handlers.d.ts.map +1 -0
- package/dist/ucp/ap2/handlers.js +482 -0
- package/dist/ucp/ap2/handlers.js.map +1 -0
- package/dist/ucp/ap2/mandates.d.ts +95 -0
- package/dist/ucp/ap2/mandates.d.ts.map +1 -0
- package/dist/ucp/ap2/mandates.js +234 -0
- package/dist/ucp/ap2/mandates.js.map +1 -0
- package/dist/ucp/ap2/types.d.ts +305 -0
- package/dist/ucp/ap2/types.d.ts.map +1 -0
- package/dist/ucp/ap2/types.js +8 -0
- package/dist/ucp/ap2/types.js.map +1 -0
- package/dist/ucp/capabilities/checkout.d.ts +118 -0
- package/dist/ucp/capabilities/checkout.d.ts.map +1 -0
- package/dist/ucp/capabilities/checkout.js +344 -0
- package/dist/ucp/capabilities/checkout.js.map +1 -0
- package/dist/ucp/capabilities/identity.d.ts +130 -0
- package/dist/ucp/capabilities/identity.d.ts.map +1 -0
- package/dist/ucp/capabilities/identity.js +290 -0
- package/dist/ucp/capabilities/identity.js.map +1 -0
- package/dist/ucp/capabilities/order.d.ts +142 -0
- package/dist/ucp/capabilities/order.d.ts.map +1 -0
- package/dist/ucp/capabilities/order.js +383 -0
- package/dist/ucp/capabilities/order.js.map +1 -0
- package/dist/ucp/index.d.ts +18 -0
- package/dist/ucp/index.d.ts.map +1 -0
- package/dist/ucp/index.js +19 -0
- package/dist/ucp/index.js.map +1 -0
- package/dist/ucp/manifest.d.ts +62 -0
- package/dist/ucp/manifest.d.ts.map +1 -0
- package/dist/ucp/manifest.js +180 -0
- package/dist/ucp/manifest.js.map +1 -0
- package/dist/ucp/types.d.ts +327 -0
- package/dist/ucp/types.d.ts.map +1 -0
- package/dist/ucp/types.js +8 -0
- package/dist/ucp/types.js.map +1 -0
- package/package.json +3 -4
- package/src/auto-ui.ts +413 -0
- package/src/base.ts +22 -9
- package/src/cli-ui-renderer.ts +264 -0
- package/src/dependency-manager.ts +0 -1
- package/src/design-system/index.ts +30 -0
- package/src/design-system/tokens.ts +451 -0
- package/src/design-system/transaction-ui.ts +1038 -0
- package/src/generator.ts +68 -8
- package/src/index.ts +159 -101
- package/src/io.ts +493 -0
- package/src/path-resolver.ts +2 -1
- package/src/rendering/components.ts +785 -0
- package/src/rendering/field-analyzer.ts +299 -0
- package/src/rendering/field-renderers.ts +356 -0
- package/src/rendering/index.ts +63 -0
- package/src/rendering/layout-selector.ts +390 -0
- package/src/rendering/template-engine.ts +254 -0
- package/src/schema-extractor.ts +225 -12
- package/src/stateful.ts +301 -0
- package/src/types.ts +10 -1
- package/src/ucp/ap2/handlers.ts +779 -0
- package/src/ucp/ap2/mandates.ts +354 -0
- package/src/ucp/ap2/types.ts +441 -0
- package/src/ucp/capabilities/checkout.ts +497 -0
- package/src/ucp/capabilities/identity.ts +425 -0
- package/src/ucp/capabilities/order.ts +549 -0
- package/src/ucp/index.ts +27 -0
- package/src/ucp/manifest.ts +257 -0
- package/src/ucp/types.ts +454 -0
- package/dist/cli-formatter.d.ts +0 -92
- package/dist/cli-formatter.d.ts.map +0 -1
- package/dist/cli-formatter.js +0 -486
- package/dist/cli-formatter.js.map +0 -1
- package/dist/elicit.d.ts +0 -93
- package/dist/elicit.d.ts.map +0 -1
- package/dist/elicit.js +0 -373
- package/dist/elicit.js.map +0 -1
- package/dist/mcp-client.d.ts +0 -218
- package/dist/mcp-client.d.ts.map +0 -1
- package/dist/mcp-client.js +0 -424
- package/dist/mcp-client.js.map +0 -1
- package/dist/mcp-sdk-transport.d.ts +0 -88
- package/dist/mcp-sdk-transport.d.ts.map +0 -1
- package/dist/mcp-sdk-transport.js +0 -360
- package/dist/mcp-sdk-transport.js.map +0 -1
- package/dist/photon-config.d.ts +0 -86
- package/dist/photon-config.d.ts.map +0 -1
- package/dist/photon-config.js +0 -156
- package/dist/photon-config.js.map +0 -1
- package/src/cli-formatter.ts +0 -579
- package/src/elicit.ts +0 -438
- package/src/mcp-client.ts +0 -561
- package/src/mcp-sdk-transport.ts +0 -449
- package/src/photon-config.ts +0 -201
package/README.md
CHANGED
|
@@ -326,6 +326,129 @@ interface ExtractedSchema {
|
|
|
326
326
|
|
|
327
327
|
---
|
|
328
328
|
|
|
329
|
+
### Generator Support (Ask/Emit Pattern)
|
|
330
|
+
|
|
331
|
+
Photon methods can be async generators that yield interactive prompts and progress updates:
|
|
332
|
+
|
|
333
|
+
```typescript
|
|
334
|
+
import { PhotonMCP } from '@portel/photon-core';
|
|
335
|
+
|
|
336
|
+
export default class DeployTool extends PhotonMCP {
|
|
337
|
+
/**
|
|
338
|
+
* Deploy with confirmation and progress
|
|
339
|
+
*/
|
|
340
|
+
async *deploy(params: { env: string }) {
|
|
341
|
+
// Ask for confirmation
|
|
342
|
+
const confirmed = yield { ask: 'confirm', message: `Deploy to ${params.env}?` };
|
|
343
|
+
if (!confirmed) return { status: 'cancelled' };
|
|
344
|
+
|
|
345
|
+
// Show progress
|
|
346
|
+
yield { emit: 'progress', value: 0.3, message: 'Building...' };
|
|
347
|
+
await this.build();
|
|
348
|
+
|
|
349
|
+
yield { emit: 'progress', value: 0.7, message: 'Deploying...' };
|
|
350
|
+
const result = await this.push(params.env);
|
|
351
|
+
|
|
352
|
+
yield { emit: 'progress', value: 1.0, message: 'Done!' };
|
|
353
|
+
return result;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
**Ask yields** (input from user):
|
|
359
|
+
- `{ ask: 'text', message: string }` - Text input
|
|
360
|
+
- `{ ask: 'confirm', message: string }` - Yes/no confirmation
|
|
361
|
+
- `{ ask: 'select', message: string, options: string[] }` - Selection
|
|
362
|
+
- `{ ask: 'number', message: string }` - Number input
|
|
363
|
+
- `{ ask: 'password', message: string }` - Hidden input
|
|
364
|
+
|
|
365
|
+
**Emit yields** (output to user):
|
|
366
|
+
- `{ emit: 'progress', value: number, message?: string }` - Progress bar (0-1)
|
|
367
|
+
- `{ emit: 'status', message: string }` - Status update
|
|
368
|
+
- `{ emit: 'log', level: 'info'|'warn'|'error', message: string }` - Log message
|
|
369
|
+
- `{ emit: 'stream', data: string }` - Streaming output
|
|
370
|
+
|
|
371
|
+
---
|
|
372
|
+
|
|
373
|
+
### Stateful Workflows (Checkpoint Pattern)
|
|
374
|
+
|
|
375
|
+
For long-running workflows that need to survive interruptions, use checkpoint yields:
|
|
376
|
+
|
|
377
|
+
```typescript
|
|
378
|
+
export default class ReportGenerator extends PhotonMCP {
|
|
379
|
+
/**
|
|
380
|
+
* Generate weekly report with checkpoints for resume
|
|
381
|
+
*/
|
|
382
|
+
async *generate(params: { week: number }) {
|
|
383
|
+
// Step 1: Collect data
|
|
384
|
+
const commits = await this.github.list_commits({ since: params.week });
|
|
385
|
+
yield { checkpoint: true, state: { step: 1, commits } };
|
|
386
|
+
|
|
387
|
+
// Step 2: Analyze
|
|
388
|
+
const analysis = await this.analyze(commits);
|
|
389
|
+
yield { checkpoint: true, state: { step: 2, commits, analysis } };
|
|
390
|
+
|
|
391
|
+
// Step 3: Generate report
|
|
392
|
+
const report = await this.format(analysis);
|
|
393
|
+
yield { checkpoint: true, state: { step: 3, report } };
|
|
394
|
+
|
|
395
|
+
return report;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
**Key concepts:**
|
|
401
|
+
- **Checkpoint** - marks a safe resume point with accumulated state
|
|
402
|
+
- **State** - preserved data to restore on resume
|
|
403
|
+
- **Idempotency** - place checkpoint AFTER side effects to avoid repeating them
|
|
404
|
+
|
|
405
|
+
**Using the stateful executor:**
|
|
406
|
+
|
|
407
|
+
```typescript
|
|
408
|
+
import { maybeStatefulExecute } from '@portel/photon-core';
|
|
409
|
+
|
|
410
|
+
// Execute with implicit checkpoint detection
|
|
411
|
+
const result = await maybeStatefulExecute(
|
|
412
|
+
() => instance.generate({ week: 52 }),
|
|
413
|
+
{
|
|
414
|
+
photon: 'report-generator',
|
|
415
|
+
tool: 'generate',
|
|
416
|
+
params: { week: 52 },
|
|
417
|
+
inputProvider: async (ask) => { /* handle asks */ },
|
|
418
|
+
outputHandler: (emit) => { /* handle emits */ },
|
|
419
|
+
}
|
|
420
|
+
);
|
|
421
|
+
|
|
422
|
+
// If workflow used checkpoints, result includes runId
|
|
423
|
+
if (result.isStateful) {
|
|
424
|
+
console.log(`Run ID: ${result.runId}`);
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
// Resume an interrupted workflow
|
|
428
|
+
const resumed = await maybeStatefulExecute(
|
|
429
|
+
() => instance.generate({ week: 52 }),
|
|
430
|
+
{
|
|
431
|
+
photon: 'report-generator',
|
|
432
|
+
tool: 'generate',
|
|
433
|
+
params: { week: 52 },
|
|
434
|
+
resumeRunId: 'run_abc123_xyz', // Resume from this run
|
|
435
|
+
inputProvider,
|
|
436
|
+
outputHandler,
|
|
437
|
+
}
|
|
438
|
+
);
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
**JSONL persistence:** Workflows are persisted to `~/.photon/runs/{runId}.jsonl`:
|
|
442
|
+
|
|
443
|
+
```jsonl
|
|
444
|
+
{"t":"start","tool":"generate","params":{"week":52},"ts":1704067200}
|
|
445
|
+
{"t":"checkpoint","id":"cp_0","state":{"step":1,"commits":[...]},"ts":1704067205}
|
|
446
|
+
{"t":"checkpoint","id":"cp_1","state":{"step":2,"analysis":{...}},"ts":1704067210}
|
|
447
|
+
{"t":"return","value":{"report":"..."},"ts":1704067215}
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
---
|
|
451
|
+
|
|
329
452
|
## 🏗️ Building Custom Runtimes
|
|
330
453
|
|
|
331
454
|
Photon Core is designed to be the foundation for custom runtimes. Here are examples:
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-UI System
|
|
3
|
+
*
|
|
4
|
+
* Automatically generates UI components based on data introspection and JSDoc hints.
|
|
5
|
+
* This allows .photon.ts files to return raw data without worrying about presentation.
|
|
6
|
+
*
|
|
7
|
+
* Features:
|
|
8
|
+
* - Automatic format detection (primitive, list, table, tree)
|
|
9
|
+
* - JSDoc hint support (@format, @ui-component, @ui-layout)
|
|
10
|
+
* - Extensible component registry
|
|
11
|
+
* - Support for CLI, MCP, and Web UIs
|
|
12
|
+
*/
|
|
13
|
+
import { OutputFormat } from './types.js';
|
|
14
|
+
/**
|
|
15
|
+
* UI Component types that can be auto-generated
|
|
16
|
+
*/
|
|
17
|
+
export type UIComponentType = 'text' | 'number' | 'boolean' | 'list' | 'table' | 'tree' | 'card' | 'chart' | 'progress' | 'code' | 'markdown' | 'json' | 'form' | 'tabs' | 'accordion';
|
|
18
|
+
/**
|
|
19
|
+
* UI Layout types
|
|
20
|
+
*/
|
|
21
|
+
export type UILayout = 'single' | 'grid' | 'flex' | 'stack' | 'tabs';
|
|
22
|
+
/**
|
|
23
|
+
* UI Component descriptor
|
|
24
|
+
*/
|
|
25
|
+
export interface UIComponent {
|
|
26
|
+
type: UIComponentType;
|
|
27
|
+
data: any;
|
|
28
|
+
layout?: UILayout;
|
|
29
|
+
metadata?: {
|
|
30
|
+
title?: string;
|
|
31
|
+
description?: string;
|
|
32
|
+
format?: OutputFormat;
|
|
33
|
+
interactive?: boolean;
|
|
34
|
+
collapsible?: boolean;
|
|
35
|
+
searchable?: boolean;
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Auto-UI configuration from JSDoc hints
|
|
40
|
+
*/
|
|
41
|
+
export interface AutoUIConfig {
|
|
42
|
+
component?: UIComponentType;
|
|
43
|
+
layout?: UILayout;
|
|
44
|
+
format?: OutputFormat;
|
|
45
|
+
title?: string;
|
|
46
|
+
description?: string;
|
|
47
|
+
interactive?: boolean;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Extract Auto-UI hints from JSDoc
|
|
51
|
+
*
|
|
52
|
+
* Supports:
|
|
53
|
+
* - @format <type> - Data format
|
|
54
|
+
* - @ui-component <type> - Explicit UI component
|
|
55
|
+
* - @ui-layout <layout> - Layout style
|
|
56
|
+
* - @ui-title <title> - Display title
|
|
57
|
+
* - @ui-interactive - Enable interactivity
|
|
58
|
+
*/
|
|
59
|
+
export declare function extractUIHints(jsdoc?: string): AutoUIConfig;
|
|
60
|
+
/**
|
|
61
|
+
* Generate UI component from data and hints
|
|
62
|
+
*/
|
|
63
|
+
export declare function generateUIComponent(data: any, config?: AutoUIConfig): UIComponent;
|
|
64
|
+
/**
|
|
65
|
+
* Detect if data should be rendered as cards
|
|
66
|
+
* (Objects with multiple rich properties)
|
|
67
|
+
*/
|
|
68
|
+
export declare function shouldUseCards(data: any): boolean;
|
|
69
|
+
/**
|
|
70
|
+
* Detect if data should be rendered as chart
|
|
71
|
+
* (Numeric data with labels)
|
|
72
|
+
*/
|
|
73
|
+
export declare function shouldUseChart(data: any): boolean;
|
|
74
|
+
/**
|
|
75
|
+
* UI Component renderer interface
|
|
76
|
+
* (To be implemented by CLI, MCP, and Web UI)
|
|
77
|
+
*/
|
|
78
|
+
export interface UIRenderer {
|
|
79
|
+
renderText(value: string): void;
|
|
80
|
+
renderNumber(value: number): void;
|
|
81
|
+
renderBoolean(value: boolean): void;
|
|
82
|
+
renderList(items: any[]): void;
|
|
83
|
+
renderTable(data: any): void;
|
|
84
|
+
renderTree(data: any): void;
|
|
85
|
+
renderCard(data: any): void;
|
|
86
|
+
renderChart(data: any): void;
|
|
87
|
+
renderProgress(value: number, total?: number): void;
|
|
88
|
+
renderCode(code: string, language?: string): void;
|
|
89
|
+
renderMarkdown(content: string): void;
|
|
90
|
+
renderJson(data: any): void;
|
|
91
|
+
renderForm(fields: any): void;
|
|
92
|
+
renderTabs(tabs: any): void;
|
|
93
|
+
renderAccordion(items: any): void;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Render UI component using the appropriate renderer
|
|
97
|
+
*/
|
|
98
|
+
export declare function renderUIComponent(component: UIComponent, renderer: UIRenderer): void;
|
|
99
|
+
/**
|
|
100
|
+
* Enhanced component suggestions based on data patterns
|
|
101
|
+
*/
|
|
102
|
+
export declare function suggestComponents(data: any): UIComponentType[];
|
|
103
|
+
//# sourceMappingURL=auto-ui.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto-ui.d.ts","sourceRoot":"","sources":["../src/auto-ui.ts"],"names":[],"mappings":"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"}
|
package/dist/auto-ui.js
ADDED
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-UI System
|
|
3
|
+
*
|
|
4
|
+
* Automatically generates UI components based on data introspection and JSDoc hints.
|
|
5
|
+
* This allows .photon.ts files to return raw data without worrying about presentation.
|
|
6
|
+
*
|
|
7
|
+
* Features:
|
|
8
|
+
* - Automatic format detection (primitive, list, table, tree)
|
|
9
|
+
* - JSDoc hint support (@format, @ui-component, @ui-layout)
|
|
10
|
+
* - Extensible component registry
|
|
11
|
+
* - Support for CLI, MCP, and Web UIs
|
|
12
|
+
*/
|
|
13
|
+
import { detectFormat } from '@portel/cli';
|
|
14
|
+
/**
|
|
15
|
+
* Extract Auto-UI hints from JSDoc
|
|
16
|
+
*
|
|
17
|
+
* Supports:
|
|
18
|
+
* - @format <type> - Data format
|
|
19
|
+
* - @ui-component <type> - Explicit UI component
|
|
20
|
+
* - @ui-layout <layout> - Layout style
|
|
21
|
+
* - @ui-title <title> - Display title
|
|
22
|
+
* - @ui-interactive - Enable interactivity
|
|
23
|
+
*/
|
|
24
|
+
export function extractUIHints(jsdoc) {
|
|
25
|
+
if (!jsdoc)
|
|
26
|
+
return {};
|
|
27
|
+
const config = {};
|
|
28
|
+
// Extract @format
|
|
29
|
+
const formatMatch = jsdoc.match(/@format\s+([\w:-]+)/);
|
|
30
|
+
if (formatMatch) {
|
|
31
|
+
config.format = formatMatch[1];
|
|
32
|
+
}
|
|
33
|
+
// Extract @ui-component
|
|
34
|
+
const componentMatch = jsdoc.match(/@ui-component\s+(\w+)/);
|
|
35
|
+
if (componentMatch) {
|
|
36
|
+
config.component = componentMatch[1];
|
|
37
|
+
}
|
|
38
|
+
// Extract @ui-layout
|
|
39
|
+
const layoutMatch = jsdoc.match(/@ui-layout\s+(\w+)/);
|
|
40
|
+
if (layoutMatch) {
|
|
41
|
+
config.layout = layoutMatch[1];
|
|
42
|
+
}
|
|
43
|
+
// Extract @ui-title
|
|
44
|
+
const titleMatch = jsdoc.match(/@ui-title\s+(.+?)(?:\n|$)/);
|
|
45
|
+
if (titleMatch) {
|
|
46
|
+
config.title = titleMatch[1].trim();
|
|
47
|
+
}
|
|
48
|
+
// Check for @ui-interactive
|
|
49
|
+
if (jsdoc.includes('@ui-interactive')) {
|
|
50
|
+
config.interactive = true;
|
|
51
|
+
}
|
|
52
|
+
return config;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Generate UI component from data and hints
|
|
56
|
+
*/
|
|
57
|
+
export function generateUIComponent(data, config = {}) {
|
|
58
|
+
// Use explicit component type if provided
|
|
59
|
+
if (config.component) {
|
|
60
|
+
return {
|
|
61
|
+
type: config.component,
|
|
62
|
+
data,
|
|
63
|
+
layout: config.layout,
|
|
64
|
+
metadata: {
|
|
65
|
+
format: config.format,
|
|
66
|
+
title: config.title,
|
|
67
|
+
interactive: config.interactive,
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
// Auto-detect component from data structure
|
|
72
|
+
const format = config.format || detectFormat(data);
|
|
73
|
+
const component = formatToComponent(format, data);
|
|
74
|
+
return {
|
|
75
|
+
type: component,
|
|
76
|
+
data,
|
|
77
|
+
layout: config.layout || inferLayout(component, data),
|
|
78
|
+
metadata: {
|
|
79
|
+
format,
|
|
80
|
+
title: config.title,
|
|
81
|
+
interactive: config.interactive,
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Map output format to UI component type
|
|
87
|
+
*/
|
|
88
|
+
function formatToComponent(format, data) {
|
|
89
|
+
switch (format) {
|
|
90
|
+
case 'primitive':
|
|
91
|
+
if (typeof data === 'boolean')
|
|
92
|
+
return 'boolean';
|
|
93
|
+
if (typeof data === 'number')
|
|
94
|
+
return 'number';
|
|
95
|
+
return 'text';
|
|
96
|
+
case 'list':
|
|
97
|
+
return 'list';
|
|
98
|
+
case 'table':
|
|
99
|
+
return 'table';
|
|
100
|
+
case 'tree':
|
|
101
|
+
return 'tree';
|
|
102
|
+
case 'markdown':
|
|
103
|
+
return 'markdown';
|
|
104
|
+
case 'json':
|
|
105
|
+
return 'json';
|
|
106
|
+
case 'code':
|
|
107
|
+
return 'code';
|
|
108
|
+
case 'none':
|
|
109
|
+
return 'text';
|
|
110
|
+
default:
|
|
111
|
+
// Handle code:lang format
|
|
112
|
+
if (format.startsWith('code:')) {
|
|
113
|
+
return 'code';
|
|
114
|
+
}
|
|
115
|
+
return 'text';
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Infer optimal layout from component and data
|
|
120
|
+
*/
|
|
121
|
+
function inferLayout(component, data) {
|
|
122
|
+
switch (component) {
|
|
123
|
+
case 'table':
|
|
124
|
+
// Large tables work better in grid
|
|
125
|
+
if (Array.isArray(data) && data.length > 10) {
|
|
126
|
+
return 'grid';
|
|
127
|
+
}
|
|
128
|
+
return 'single';
|
|
129
|
+
case 'tree':
|
|
130
|
+
// Trees need vertical space
|
|
131
|
+
return 'stack';
|
|
132
|
+
case 'card':
|
|
133
|
+
// Multiple cards use grid
|
|
134
|
+
if (Array.isArray(data)) {
|
|
135
|
+
return 'grid';
|
|
136
|
+
}
|
|
137
|
+
return 'single';
|
|
138
|
+
case 'tabs':
|
|
139
|
+
return 'tabs';
|
|
140
|
+
default:
|
|
141
|
+
return 'single';
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Detect if data should be rendered as cards
|
|
146
|
+
* (Objects with multiple rich properties)
|
|
147
|
+
*/
|
|
148
|
+
export function shouldUseCards(data) {
|
|
149
|
+
if (!Array.isArray(data) || data.length === 0) {
|
|
150
|
+
return false;
|
|
151
|
+
}
|
|
152
|
+
const firstItem = data[0];
|
|
153
|
+
if (typeof firstItem !== 'object' || firstItem === null) {
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
// If objects have more than 5 properties or contain nested data, use cards
|
|
157
|
+
const keys = Object.keys(firstItem);
|
|
158
|
+
if (keys.length > 5) {
|
|
159
|
+
return true;
|
|
160
|
+
}
|
|
161
|
+
// Check for nested data
|
|
162
|
+
for (const value of Object.values(firstItem)) {
|
|
163
|
+
if (typeof value === 'object' && value !== null) {
|
|
164
|
+
return true;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return false;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Detect if data should be rendered as chart
|
|
171
|
+
* (Numeric data with labels)
|
|
172
|
+
*/
|
|
173
|
+
export function shouldUseChart(data) {
|
|
174
|
+
if (!Array.isArray(data) || data.length === 0) {
|
|
175
|
+
return false;
|
|
176
|
+
}
|
|
177
|
+
// Check if all items are objects with numeric values
|
|
178
|
+
return data.every((item) => {
|
|
179
|
+
if (typeof item !== 'object' || item === null) {
|
|
180
|
+
return false;
|
|
181
|
+
}
|
|
182
|
+
const values = Object.values(item);
|
|
183
|
+
return values.some((v) => typeof v === 'number');
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Render UI component using the appropriate renderer
|
|
188
|
+
*/
|
|
189
|
+
export function renderUIComponent(component, renderer) {
|
|
190
|
+
const { type, data, metadata } = component;
|
|
191
|
+
switch (type) {
|
|
192
|
+
case 'text':
|
|
193
|
+
renderer.renderText(String(data));
|
|
194
|
+
break;
|
|
195
|
+
case 'number':
|
|
196
|
+
renderer.renderNumber(Number(data));
|
|
197
|
+
break;
|
|
198
|
+
case 'boolean':
|
|
199
|
+
renderer.renderBoolean(Boolean(data));
|
|
200
|
+
break;
|
|
201
|
+
case 'list':
|
|
202
|
+
renderer.renderList(Array.isArray(data) ? data : [data]);
|
|
203
|
+
break;
|
|
204
|
+
case 'table':
|
|
205
|
+
renderer.renderTable(data);
|
|
206
|
+
break;
|
|
207
|
+
case 'tree':
|
|
208
|
+
renderer.renderTree(data);
|
|
209
|
+
break;
|
|
210
|
+
case 'card':
|
|
211
|
+
renderer.renderCard(data);
|
|
212
|
+
break;
|
|
213
|
+
case 'chart':
|
|
214
|
+
renderer.renderChart(data);
|
|
215
|
+
break;
|
|
216
|
+
case 'progress':
|
|
217
|
+
renderer.renderProgress(data.value, data.total);
|
|
218
|
+
break;
|
|
219
|
+
case 'code':
|
|
220
|
+
const lang = metadata?.format?.startsWith('code:')
|
|
221
|
+
? metadata.format.split(':')[1]
|
|
222
|
+
: undefined;
|
|
223
|
+
renderer.renderCode(String(data), lang);
|
|
224
|
+
break;
|
|
225
|
+
case 'markdown':
|
|
226
|
+
renderer.renderMarkdown(String(data));
|
|
227
|
+
break;
|
|
228
|
+
case 'json':
|
|
229
|
+
renderer.renderJson(data);
|
|
230
|
+
break;
|
|
231
|
+
case 'form':
|
|
232
|
+
renderer.renderForm(data);
|
|
233
|
+
break;
|
|
234
|
+
case 'tabs':
|
|
235
|
+
renderer.renderTabs(data);
|
|
236
|
+
break;
|
|
237
|
+
case 'accordion':
|
|
238
|
+
renderer.renderAccordion(data);
|
|
239
|
+
break;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Enhanced component suggestions based on data patterns
|
|
244
|
+
*/
|
|
245
|
+
export function suggestComponents(data) {
|
|
246
|
+
const suggestions = [];
|
|
247
|
+
// Always suggest the default component
|
|
248
|
+
const format = detectFormat(data);
|
|
249
|
+
suggestions.push(formatToComponent(format, data));
|
|
250
|
+
// Suggest alternatives based on data
|
|
251
|
+
if (Array.isArray(data) && data.length > 0) {
|
|
252
|
+
const firstItem = data[0];
|
|
253
|
+
if (typeof firstItem === 'object' && firstItem !== null) {
|
|
254
|
+
// Could be table, tree, or cards
|
|
255
|
+
suggestions.push('table', 'tree');
|
|
256
|
+
if (shouldUseCards(data)) {
|
|
257
|
+
suggestions.push('card');
|
|
258
|
+
}
|
|
259
|
+
if (shouldUseChart(data)) {
|
|
260
|
+
suggestions.push('chart');
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
if (typeof data === 'object' && data !== null && !Array.isArray(data)) {
|
|
265
|
+
// Could be card, tree, or form
|
|
266
|
+
suggestions.push('card', 'tree');
|
|
267
|
+
// If has many fields, suggest form
|
|
268
|
+
if (Object.keys(data).length > 3) {
|
|
269
|
+
suggestions.push('form');
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
// Remove duplicates
|
|
273
|
+
return Array.from(new Set(suggestions));
|
|
274
|
+
}
|
|
275
|
+
//# sourceMappingURL=auto-ui.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto-ui.js","sourceRoot":"","sources":["../src/auto-ui.ts"],"names":[],"mappings":"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"}
|
package/dist/base.d.ts
CHANGED
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
* }
|
|
39
39
|
* ```
|
|
40
40
|
*/
|
|
41
|
-
import { MCPClient, MCPClientFactory } from '
|
|
41
|
+
import { MCPClient, MCPClientFactory } from '@portel/mcp';
|
|
42
42
|
/**
|
|
43
43
|
* Simple base class for creating Photon MCPs
|
|
44
44
|
*
|
|
@@ -47,6 +47,11 @@ import { MCPClient, MCPClientFactory } from './mcp-client.js';
|
|
|
47
47
|
* - Return value = Tool result
|
|
48
48
|
*/
|
|
49
49
|
export declare class PhotonMCP {
|
|
50
|
+
/**
|
|
51
|
+
* Emit an event/progress update
|
|
52
|
+
* @param data Data to emit
|
|
53
|
+
*/
|
|
54
|
+
protected emit(data: any): void;
|
|
50
55
|
/**
|
|
51
56
|
* MCP client factory - injected by runtime
|
|
52
57
|
* @internal
|
|
@@ -70,7 +75,9 @@ export declare class PhotonMCP {
|
|
|
70
75
|
/**
|
|
71
76
|
* Execute a tool method
|
|
72
77
|
*/
|
|
73
|
-
executeTool(toolName: string, parameters: any
|
|
78
|
+
executeTool(toolName: string, parameters: any, options?: {
|
|
79
|
+
outputHandler?: (data: any) => void;
|
|
80
|
+
}): Promise<any>;
|
|
74
81
|
/**
|
|
75
82
|
* Optional lifecycle hooks
|
|
76
83
|
*/
|
package/dist/base.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../src/base.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAkB,MAAM,
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../src/base.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAkB,MAAM,aAAa,CAAC;AAG1E;;;;;;GAMG;AACH,qBAAa,SAAS;IACpB;;;OAGG;IACH,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,GAAG,IAAI;IAM/B;;;OAGG;IACH,SAAS,CAAC,WAAW,CAAC,EAAE,gBAAgB,CAAC;IAEzC;;;OAGG;IACH,OAAO,CAAC,WAAW,CAAsF;IAEzG;;;OAGG;IACH,MAAM,CAAC,UAAU,IAAI,MAAM;IAQ3B;;;OAGG;IACH,MAAM,CAAC,cAAc,IAAI,MAAM,EAAE;IA0BjC;;OAEG;IACG,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE;QAAE,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,CAAA;KAAE,GAAG,OAAO,CAAC,GAAG,CAAC;IAkBrH;;OAEG;IACG,YAAY,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC;IAC9B,UAAU,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC;IAElC;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACH,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;IAoBhF;;;;;OAKG;IACH,aAAa,CAAC,OAAO,EAAE,gBAAgB,GAAG,IAAI;IAM9C;;OAEG;IACH,YAAY,IAAI,OAAO;IAIvB;;;OAGG;IACG,cAAc,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;CAM1C"}
|
package/dist/base.js
CHANGED
|
@@ -38,7 +38,8 @@
|
|
|
38
38
|
* }
|
|
39
39
|
* ```
|
|
40
40
|
*/
|
|
41
|
-
import { createMCPProxy } from '
|
|
41
|
+
import { createMCPProxy } from '@portel/mcp';
|
|
42
|
+
import { executionContext } from '@portel/cli';
|
|
42
43
|
/**
|
|
43
44
|
* Simple base class for creating Photon MCPs
|
|
44
45
|
*
|
|
@@ -47,6 +48,16 @@ import { createMCPProxy } from './mcp-client.js';
|
|
|
47
48
|
* - Return value = Tool result
|
|
48
49
|
*/
|
|
49
50
|
export class PhotonMCP {
|
|
51
|
+
/**
|
|
52
|
+
* Emit an event/progress update
|
|
53
|
+
* @param data Data to emit
|
|
54
|
+
*/
|
|
55
|
+
emit(data) {
|
|
56
|
+
const store = executionContext.getStore();
|
|
57
|
+
if (store?.outputHandler) {
|
|
58
|
+
store.outputHandler(data);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
50
61
|
/**
|
|
51
62
|
* MCP client factory - injected by runtime
|
|
52
63
|
* @internal
|
|
@@ -96,19 +107,21 @@ export class PhotonMCP {
|
|
|
96
107
|
/**
|
|
97
108
|
* Execute a tool method
|
|
98
109
|
*/
|
|
99
|
-
async executeTool(toolName, parameters) {
|
|
110
|
+
async executeTool(toolName, parameters, options) {
|
|
100
111
|
const method = this[toolName];
|
|
101
112
|
if (!method || typeof method !== 'function') {
|
|
102
113
|
throw new Error(`Tool not found: ${toolName}`);
|
|
103
114
|
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
115
|
+
return executionContext.run({ outputHandler: options?.outputHandler }, async () => {
|
|
116
|
+
try {
|
|
117
|
+
const result = await method.call(this, parameters);
|
|
118
|
+
return result;
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
console.error(`Tool execution failed: ${toolName} - ${error.message}`);
|
|
122
|
+
throw error;
|
|
123
|
+
}
|
|
124
|
+
});
|
|
112
125
|
}
|
|
113
126
|
/**
|
|
114
127
|
* Get an MCP client for calling external MCP servers
|
package/dist/base.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.js","sourceRoot":"","sources":["../src/base.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH,OAAO,EAA+B,cAAc,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"base.js","sourceRoot":"","sources":["../src/base.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH,OAAO,EAA+B,cAAc,EAAE,MAAM,aAAa,CAAC;AAC1E,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE/C;;;;;;GAMG;AACH,MAAM,OAAO,SAAS;IACpB;;;OAGG;IACO,IAAI,CAAC,IAAS;QACtB,MAAM,KAAK,GAAG,gBAAgB,CAAC,QAAQ,EAAE,CAAC;QAC1C,IAAI,KAAK,EAAE,aAAa,EAAE,CAAC;YACzB,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC;IACD;;;OAGG;IACO,WAAW,CAAoB;IAEzC;;;OAGG;IACK,WAAW,GAA4E,IAAI,GAAG,EAAE,CAAC;IAEzG;;;OAGG;IACH,MAAM,CAAC,UAAU;QACf,OAAO,IAAI,CAAC,IAAI;aACb,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,iCAAiC;aACrD,OAAO,CAAC,UAAU,EAAE,KAAK,CAAC;aAC1B,WAAW,EAAE;aACb,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,sBAAsB;IAC9C,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,cAAc;QACnB,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;QACjC,MAAM,OAAO,GAAa,EAAE,CAAC;QAE7B,8CAA8C;QAC9C,IAAI,OAAO,GAAG,SAAS,CAAC;QACxB,OAAO,OAAO,IAAI,OAAO,KAAK,SAAS,CAAC,SAAS,EAAE,CAAC;YAClD,MAAM,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;gBACnD,2EAA2E;gBAC3E,IACE,IAAI,KAAK,aAAa;oBACtB,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;oBACrB,IAAI,KAAK,cAAc;oBACvB,IAAI,KAAK,YAAY;oBACrB,OAAQ,SAAiB,CAAC,IAAI,CAAC,KAAK,UAAU;oBAC9C,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EACvB,CAAC;oBACD,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACrB,CAAC;YACH,CAAC,CAAC,CAAC;YACH,OAAO,GAAG,MAAM,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;QAC3C,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,WAAW,CAAC,QAAgB,EAAE,UAAe,EAAE,OAAiD;QACpG,MAAM,MAAM,GAAI,IAAY,CAAC,QAAQ,CAAC,CAAC;QAEvC,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,UAAU,EAAE,CAAC;YAC5C,MAAM,IAAI,KAAK,CAAC,mBAAmB,QAAQ,EAAE,CAAC,CAAC;QACjD,CAAC;QAED,OAAO,gBAAgB,CAAC,GAAG,CAAC,EAAE,aAAa,EAAE,OAAO,EAAE,aAAa,EAAE,EAAE,KAAK,IAAI,EAAE;YAChF,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;gBACnD,OAAO,MAAM,CAAC;YAChB,CAAC;YAAC,OAAO,KAAU,EAAE,CAAC;gBACpB,OAAO,CAAC,KAAK,CAAC,0BAA0B,QAAQ,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;gBACvE,MAAM,KAAK,CAAC;YACd,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAQD;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACH,GAAG,CAAC,OAAe;QACjB,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CACb,8CAA8C,OAAO,2GAA2G,CACjK,CAAC;QACJ,CAAC;QAED,oCAAoC;QACpC,IAAI,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC3C,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,iCAAiC;QACjC,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACnD,MAAM,GAAG,cAAc,CAAC,SAAS,CAAC,CAAC;QACnC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACtC,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;;;;OAKG;IACH,aAAa,CAAC,OAAyB;QACrC,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC;QAC3B,4CAA4C;QAC5C,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;IAC3B,CAAC;IAED;;OAEG;IACH,YAAY;QACV,OAAO,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC;IAC5B,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,cAAc;QAClB,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACtB,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,OAAO,IAAI,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC;IACxC,CAAC;CACF"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI UI Renderer
|
|
3
|
+
*
|
|
4
|
+
* Implements UIRenderer interface for terminal output.
|
|
5
|
+
* Uses existing cli-formatter utilities.
|
|
6
|
+
*/
|
|
7
|
+
import { UIRenderer } from './auto-ui.js';
|
|
8
|
+
export declare class CLIUIRenderer implements UIRenderer {
|
|
9
|
+
renderText(value: string): void;
|
|
10
|
+
renderNumber(value: number): void;
|
|
11
|
+
renderBoolean(value: boolean): void;
|
|
12
|
+
renderList(items: any[]): void;
|
|
13
|
+
renderTable(data: any): void;
|
|
14
|
+
renderTree(data: any): void;
|
|
15
|
+
renderCard(data: any): void;
|
|
16
|
+
private renderSingleCard;
|
|
17
|
+
private formatCardValue;
|
|
18
|
+
renderChart(data: any): void;
|
|
19
|
+
renderProgress(value: number, total?: number): void;
|
|
20
|
+
renderCode(code: string, language?: string): void;
|
|
21
|
+
renderMarkdown(content: string): void;
|
|
22
|
+
renderJson(data: any): void;
|
|
23
|
+
renderForm(fields: any): void;
|
|
24
|
+
renderTabs(tabs: any): void;
|
|
25
|
+
renderAccordion(items: any): void;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Default CLI renderer instance
|
|
29
|
+
*/
|
|
30
|
+
export declare const cliRenderer: CLIUIRenderer;
|
|
31
|
+
//# sourceMappingURL=cli-ui-renderer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-ui-renderer.d.ts","sourceRoot":"","sources":["../src/cli-ui-renderer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAUH,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAI1C,qBAAa,aAAc,YAAW,UAAU;IAC9C,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAI/B,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAIjC,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAInC,UAAU,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,IAAI;IAI9B,WAAW,CAAC,IAAI,EAAE,GAAG,GAAG,IAAI;IAI5B,UAAU,CAAC,IAAI,EAAE,GAAG,GAAG,IAAI;IAI3B,UAAU,CAAC,IAAI,EAAE,GAAG,GAAG,IAAI;IAa3B,OAAO,CAAC,gBAAgB;IAkCxB,OAAO,CAAC,eAAe;IAUvB,WAAW,CAAC,IAAI,EAAE,GAAG,GAAG,IAAI;IA2B5B,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI;IASnD,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI;IAYjD,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAoDrC,UAAU,CAAC,IAAI,EAAE,GAAG,GAAG,IAAI;IAS3B,UAAU,CAAC,MAAM,EAAE,GAAG,GAAG,IAAI;IAK7B,UAAU,CAAC,IAAI,EAAE,GAAG,GAAG,IAAI;IAmB3B,eAAe,CAAC,KAAK,EAAE,GAAG,GAAG,IAAI;CAwBlC;AAED;;GAEG;AACH,eAAO,MAAM,WAAW,eAAsB,CAAC"}
|