s3db.js 19.3.25 → 19.4.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.
Files changed (39) hide show
  1. package/dist/cli/components/index.js +12 -0
  2. package/dist/cli/components/spinner.js +153 -0
  3. package/dist/cli/components/table.js +157 -0
  4. package/dist/cli/components/ui.js +99 -0
  5. package/dist/cli/index.js +1284 -1113
  6. package/dist/s3db-lite.cjs +2 -2
  7. package/dist/s3db-lite.es.js +2 -2
  8. package/dist/s3db.cjs +2 -2
  9. package/dist/s3db.es.js +2 -2
  10. package/dist/types/cli/components/index.d.ts +9 -0
  11. package/dist/types/cli/components/spinner.d.ts +47 -0
  12. package/dist/types/cli/components/table.d.ts +38 -0
  13. package/dist/types/cli/components/ui.d.ts +73 -0
  14. package/dist/types/cli/index.d.ts +1 -1
  15. package/dist/types/types/cli.types.d.ts +6 -25
  16. package/mcp/search/hybrid-search.ts +17 -210
  17. package/mcp/search/index.ts +1 -9
  18. package/mcp/search/types.ts +4 -24
  19. package/mcp/tools/docs-search.ts +226 -164
  20. package/package.json +5 -11
  21. package/src/cli/components/index.ts +35 -0
  22. package/src/cli/components/spinner.ts +185 -0
  23. package/src/cli/components/table.ts +227 -0
  24. package/src/cli/components/ui.ts +114 -0
  25. package/src/cli/index.ts +1371 -1232
  26. package/src/types/cli.types.ts +7 -27
  27. package/mcp/search/embeddings-loader.d.ts +0 -69
  28. package/mcp/search/embeddings-loader.js +0 -205
  29. package/mcp/search/embeddings-loader.ts +0 -285
  30. package/mcp/search/hybrid-search.d.ts +0 -74
  31. package/mcp/search/hybrid-search.js +0 -300
  32. package/mcp/search/index.d.ts +0 -7
  33. package/mcp/search/index.js +0 -7
  34. package/mcp/search/math.d.ts +0 -50
  35. package/mcp/search/math.js +0 -113
  36. package/mcp/search/types.d.ts +0 -53
  37. package/mcp/search/types.js +0 -5
  38. package/mcp/tools/docs-search.d.ts +0 -90
  39. package/mcp/tools/docs-search.js +0 -274
@@ -0,0 +1,12 @@
1
+ /**
2
+ * S3DB CLI Components
3
+ *
4
+ * Re-exports all CLI UI components using tuiuiu.js
5
+ */
6
+ // UI utilities and styles
7
+ export { styles, c, tpl, red, green, yellow, cyan, gray, bold, dim, print, printError, printSuccess, printWarning, printInfo, printHeader, printSection, printKeyValue, printMuted, printTip, } from './ui.js';
8
+ // Table component
9
+ export { Table, renderTable, printTable } from './table.js';
10
+ // Spinner component
11
+ export { Spinner, createSpinner, spinner } from './spinner.js';
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,153 @@
1
+ /**
2
+ * S3DB CLI Spinner Component
3
+ *
4
+ * Simple animated spinner for CLI operations using tuiuiu spinner styles
5
+ */
6
+ import { cyan, green, red, yellow } from 'tuiuiu.js/colors';
7
+ const SPINNERS = {
8
+ dots: {
9
+ frames: ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'],
10
+ interval: 80,
11
+ },
12
+ line: {
13
+ frames: ['-', '\\', '|', '/'],
14
+ interval: 130,
15
+ },
16
+ arc: {
17
+ frames: ['◜', '◠', '◝', '◞', '◡', '◟'],
18
+ interval: 100,
19
+ },
20
+ circle: {
21
+ frames: ['◐', '◓', '◑', '◒'],
22
+ interval: 50,
23
+ },
24
+ bouncingBar: {
25
+ frames: [
26
+ '[ ]', '[= ]', '[== ]', '[=== ]', '[ ===]',
27
+ '[ ==]', '[ =]', '[ ]', '[ =]', '[ ==]',
28
+ '[ ===]', '[====]', '[=== ]', '[== ]', '[= ]',
29
+ ],
30
+ interval: 80,
31
+ },
32
+ aesthetic: {
33
+ frames: ['▰▱▱▱▱▱▱', '▰▰▱▱▱▱▱', '▰▰▰▱▱▱▱', '▰▰▰▰▱▱▱', '▰▰▰▰▰▱▱', '▰▰▰▰▰▰▱', '▰▰▰▰▰▰▰', '▰▱▱▱▱▱▱'],
34
+ interval: 80,
35
+ },
36
+ arrow: {
37
+ frames: ['▹▹▹▹▹', '▸▹▹▹▹', '▹▸▹▹▹', '▹▹▸▹▹', '▹▹▹▸▹', '▹▹▹▹▸'],
38
+ interval: 120,
39
+ },
40
+ };
41
+ /**
42
+ * CLI Spinner class for showing loading states
43
+ */
44
+ export class Spinner {
45
+ _text;
46
+ style;
47
+ color;
48
+ frameIndex = 0;
49
+ timer = null;
50
+ stream;
51
+ isRunning = false;
52
+ constructor(options = {}) {
53
+ if (typeof options === 'string') {
54
+ options = { text: options };
55
+ }
56
+ this._text = options.text || 'Loading...';
57
+ this.style = options.style || 'dots';
58
+ this.color = options.color || cyan;
59
+ this.stream = process.stderr;
60
+ }
61
+ get text() {
62
+ return this._text;
63
+ }
64
+ set text(value) {
65
+ this._text = value;
66
+ if (this.isRunning) {
67
+ this.render();
68
+ }
69
+ }
70
+ get config() {
71
+ return SPINNERS[this.style];
72
+ }
73
+ get frame() {
74
+ return this.config.frames[this.frameIndex] ?? this.config.frames[0];
75
+ }
76
+ get isTTY() {
77
+ return this.stream.isTTY === true;
78
+ }
79
+ clearLine() {
80
+ if (this.isTTY) {
81
+ this.stream.clearLine(0);
82
+ this.stream.cursorTo(0);
83
+ }
84
+ }
85
+ render() {
86
+ if (!this.isTTY)
87
+ return;
88
+ const frame = this.color(this.frame);
89
+ this.clearLine();
90
+ this.stream.write(`${frame} ${this._text}`);
91
+ }
92
+ start(text) {
93
+ if (text)
94
+ this._text = text;
95
+ if (this.isRunning)
96
+ return this;
97
+ this.isRunning = true;
98
+ if (this.isTTY) {
99
+ this.render();
100
+ this.timer = setInterval(() => {
101
+ this.frameIndex = (this.frameIndex + 1) % this.config.frames.length;
102
+ this.render();
103
+ }, this.config.interval);
104
+ }
105
+ return this;
106
+ }
107
+ stop() {
108
+ if (this.timer) {
109
+ clearInterval(this.timer);
110
+ this.timer = null;
111
+ }
112
+ this.isRunning = false;
113
+ this.clearLine();
114
+ return this;
115
+ }
116
+ succeed(text) {
117
+ this.stop();
118
+ const message = text || this._text;
119
+ console.log(`${green('✓')} ${message}`);
120
+ return this;
121
+ }
122
+ fail(text) {
123
+ this.stop();
124
+ const message = text || this._text;
125
+ console.error(`${red('✗')} ${message}`);
126
+ return this;
127
+ }
128
+ warn(text) {
129
+ this.stop();
130
+ const message = text || this._text;
131
+ console.log(`${yellow('⚠')} ${message}`);
132
+ return this;
133
+ }
134
+ info(text) {
135
+ this.stop();
136
+ const message = text || this._text;
137
+ console.log(`${cyan('ℹ')} ${message}`);
138
+ return this;
139
+ }
140
+ }
141
+ /**
142
+ * Create a new spinner instance
143
+ */
144
+ export function createSpinner(options) {
145
+ return new Spinner(options);
146
+ }
147
+ /**
148
+ * Convenience function to create and start a spinner
149
+ */
150
+ export function spinner(text) {
151
+ return new Spinner({ text }).start();
152
+ }
153
+ //# sourceMappingURL=spinner.js.map
@@ -0,0 +1,157 @@
1
+ /**
2
+ * S3DB CLI Table Component
3
+ *
4
+ * String-based table renderer for CLI output using tuiuiu border styles
5
+ */
6
+ import { cyan, gray, bold } from 'tuiuiu.js/colors';
7
+ const BORDERS = {
8
+ single: {
9
+ topLeft: '┌', topRight: '┐', bottomLeft: '└', bottomRight: '┘',
10
+ horizontal: '─', vertical: '│',
11
+ topMid: '┬', bottomMid: '┴', leftMid: '├', rightMid: '┤', midMid: '┼',
12
+ },
13
+ double: {
14
+ topLeft: '╔', topRight: '╗', bottomLeft: '╚', bottomRight: '╝',
15
+ horizontal: '═', vertical: '║',
16
+ topMid: '╦', bottomMid: '╩', leftMid: '╠', rightMid: '╣', midMid: '╬',
17
+ },
18
+ round: {
19
+ topLeft: '╭', topRight: '╮', bottomLeft: '╰', bottomRight: '╯',
20
+ horizontal: '─', vertical: '│',
21
+ topMid: '┬', bottomMid: '┴', leftMid: '├', rightMid: '┤', midMid: '┼',
22
+ },
23
+ bold: {
24
+ topLeft: '┏', topRight: '┓', bottomLeft: '┗', bottomRight: '┛',
25
+ horizontal: '━', vertical: '┃',
26
+ topMid: '┳', bottomMid: '┻', leftMid: '┣', rightMid: '┫', midMid: '╋',
27
+ },
28
+ ascii: {
29
+ topLeft: '+', topRight: '+', bottomLeft: '+', bottomRight: '+',
30
+ horizontal: '-', vertical: '|',
31
+ topMid: '+', bottomMid: '+', leftMid: '+', rightMid: '+', midMid: '+',
32
+ },
33
+ none: {
34
+ topLeft: '', topRight: '', bottomLeft: '', bottomRight: '',
35
+ horizontal: '', vertical: '',
36
+ topMid: '', bottomMid: '', leftMid: '', rightMid: '', midMid: '',
37
+ },
38
+ };
39
+ /**
40
+ * Calculate column widths based on content
41
+ */
42
+ function calculateWidths(head, rows, maxWidth) {
43
+ const widths = head.map(h => String(h).length);
44
+ for (const row of rows) {
45
+ for (let i = 0; i < row.length; i++) {
46
+ const cellWidth = String(row[i] ?? '').length;
47
+ widths[i] = Math.max(widths[i] || 0, cellWidth);
48
+ }
49
+ }
50
+ if (maxWidth) {
51
+ return widths.map(w => Math.min(w, maxWidth));
52
+ }
53
+ return widths;
54
+ }
55
+ /**
56
+ * Pad a string to a specific width
57
+ */
58
+ function pad(str, width) {
59
+ const s = String(str);
60
+ if (s.length >= width)
61
+ return s.slice(0, width);
62
+ return s + ' '.repeat(width - s.length);
63
+ }
64
+ /**
65
+ * Create a horizontal line
66
+ */
67
+ function horizontalLine(widths, borders, left, mid, right, padding, borderColor) {
68
+ if (!left)
69
+ return '';
70
+ const parts = widths.map(w => borders.horizontal.repeat(w + padding * 2));
71
+ return borderColor(left + parts.join(mid) + right);
72
+ }
73
+ /**
74
+ * Create a data row
75
+ */
76
+ function dataRow(cells, widths, borders, padding, borderColor, cellFormatter) {
77
+ const paddingStr = ' '.repeat(padding);
78
+ const formattedCells = cells.map((cell, i) => {
79
+ const value = cell ?? '';
80
+ const padded = pad(String(value), widths[i] || 0);
81
+ return cellFormatter ? cellFormatter(padded, i) : padded;
82
+ });
83
+ if (borders.vertical) {
84
+ return borderColor(borders.vertical) +
85
+ formattedCells.map(c => paddingStr + c + paddingStr).join(borderColor(borders.vertical)) +
86
+ borderColor(borders.vertical);
87
+ }
88
+ return formattedCells.join(' ');
89
+ }
90
+ /**
91
+ * Render a table to string
92
+ */
93
+ export function renderTable(options) {
94
+ const { head, rows, borderStyle = 'single', headerColor = cyan, borderColor = gray, padding = 1, maxColWidth = 50, } = options;
95
+ const borders = BORDERS[borderStyle];
96
+ const widths = calculateWidths(head, rows, maxColWidth);
97
+ const lines = [];
98
+ // Top border
99
+ const topLine = horizontalLine(widths, borders, borders.topLeft, borders.topMid, borders.topRight, padding, borderColor);
100
+ if (topLine)
101
+ lines.push(topLine);
102
+ // Header row
103
+ const headerRow = dataRow(head, widths, borders, padding, borderColor, (cell) => bold(headerColor(cell)));
104
+ lines.push(headerRow);
105
+ // Header separator
106
+ const sepLine = horizontalLine(widths, borders, borders.leftMid, borders.midMid, borders.rightMid, padding, borderColor);
107
+ if (sepLine)
108
+ lines.push(sepLine);
109
+ // Data rows
110
+ for (const row of rows) {
111
+ lines.push(dataRow(row, widths, borders, padding, borderColor));
112
+ }
113
+ // Bottom border
114
+ const bottomLine = horizontalLine(widths, borders, borders.bottomLeft, borders.bottomMid, borders.bottomRight, padding, borderColor);
115
+ if (bottomLine)
116
+ lines.push(bottomLine);
117
+ return lines.join('\n');
118
+ }
119
+ /**
120
+ * Print a table directly to console
121
+ */
122
+ export function printTable(options) {
123
+ console.log(renderTable(options));
124
+ }
125
+ /**
126
+ * Create a table instance for building incrementally
127
+ */
128
+ export class Table {
129
+ head = [];
130
+ rows = [];
131
+ options;
132
+ constructor(options = {}) {
133
+ this.options = options;
134
+ if (options.head) {
135
+ this.head = options.head;
136
+ }
137
+ }
138
+ setHead(head) {
139
+ this.head = head;
140
+ return this;
141
+ }
142
+ push(row) {
143
+ this.rows.push(row);
144
+ return this;
145
+ }
146
+ toString() {
147
+ return renderTable({
148
+ head: this.head,
149
+ rows: this.rows,
150
+ ...this.options,
151
+ });
152
+ }
153
+ print() {
154
+ console.log(this.toString());
155
+ }
156
+ }
157
+ //# sourceMappingURL=table.js.map
@@ -0,0 +1,99 @@
1
+ /**
2
+ * S3DB CLI UI Components
3
+ *
4
+ * Uses tuiuiu.js for colors and styling
5
+ */
6
+ import { c, tpl, compose, red, green, yellow, cyan, gray, bold, dim } from 'tuiuiu.js/colors';
7
+ /**
8
+ * Pre-composed styles for consistent CLI output
9
+ */
10
+ export const styles = {
11
+ // Status colors
12
+ error: compose(red, bold),
13
+ success: compose(green),
14
+ warning: compose(yellow),
15
+ info: compose(cyan),
16
+ muted: compose(gray, dim),
17
+ // Semantic styles
18
+ title: compose(cyan, bold),
19
+ label: compose(cyan),
20
+ value: (v) => String(v),
21
+ highlight: compose(bold),
22
+ // Icons with colors
23
+ checkmark: () => green('✓'),
24
+ cross: () => red('✗'),
25
+ arrow: () => cyan('→'),
26
+ bullet: () => gray('•'),
27
+ };
28
+ /**
29
+ * Chainable color API (re-export from tuiuiu)
30
+ */
31
+ export { c, tpl };
32
+ /**
33
+ * Simple functions for common cases
34
+ */
35
+ export { red, green, yellow, cyan, gray, bold, dim };
36
+ /**
37
+ * Print a styled message
38
+ */
39
+ export function print(message) {
40
+ console.log(message);
41
+ }
42
+ /**
43
+ * Print an error message
44
+ */
45
+ export function printError(message) {
46
+ console.error(styles.error(`Error: ${message}`));
47
+ }
48
+ /**
49
+ * Print a success message
50
+ */
51
+ export function printSuccess(message) {
52
+ console.log(styles.success(`${styles.checkmark()} ${message}`));
53
+ }
54
+ /**
55
+ * Print a warning message
56
+ */
57
+ export function printWarning(message) {
58
+ console.log(styles.warning(`⚠️ ${message}`));
59
+ }
60
+ /**
61
+ * Print an info message
62
+ */
63
+ export function printInfo(message) {
64
+ console.log(styles.info(`ℹ️ ${message}`));
65
+ }
66
+ /**
67
+ * Print a header/title
68
+ */
69
+ export function printHeader(title) {
70
+ console.log(styles.title(`\n${title}\n`));
71
+ }
72
+ /**
73
+ * Print a section header
74
+ */
75
+ export function printSection(title) {
76
+ console.log(bold(title));
77
+ }
78
+ /**
79
+ * Print a key-value pair
80
+ */
81
+ export function printKeyValue(key, value) {
82
+ const displayValue = typeof value === 'boolean'
83
+ ? (value ? green('✓') : red('✗'))
84
+ : String(value);
85
+ console.log(` ${key}: ${displayValue}`);
86
+ }
87
+ /**
88
+ * Print a muted/gray message
89
+ */
90
+ export function printMuted(message) {
91
+ console.log(styles.muted(message));
92
+ }
93
+ /**
94
+ * Print a tip/hint
95
+ */
96
+ export function printTip(message) {
97
+ console.log(styles.muted(`💡 ${message}`));
98
+ }
99
+ //# sourceMappingURL=ui.js.map