tuimon 0.1.0 → 0.2.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 (111) hide show
  1. package/AI.md +191 -0
  2. package/README.md +223 -87
  3. package/dist/browser.d.ts.map +1 -1
  4. package/dist/browser.js +3 -0
  5. package/dist/browser.js.map +1 -1
  6. package/dist/cli.js +171 -3
  7. package/dist/cli.js.map +1 -1
  8. package/dist/config.d.ts +17 -0
  9. package/dist/config.d.ts.map +1 -0
  10. package/dist/config.js +106 -0
  11. package/dist/config.js.map +1 -0
  12. package/dist/fkeybar.d.ts.map +1 -1
  13. package/dist/fkeybar.js +13 -0
  14. package/dist/fkeybar.js.map +1 -1
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +148 -18
  17. package/dist/index.js.map +1 -1
  18. package/dist/layout/generator-css.d.ts +3 -0
  19. package/dist/layout/generator-css.d.ts.map +1 -0
  20. package/dist/layout/generator-css.js +202 -0
  21. package/dist/layout/generator-css.js.map +1 -0
  22. package/dist/layout/generator-js.d.ts +3 -0
  23. package/dist/layout/generator-js.d.ts.map +1 -0
  24. package/dist/layout/generator-js.js +353 -0
  25. package/dist/layout/generator-js.js.map +1 -0
  26. package/dist/layout/generator.d.ts +4 -0
  27. package/dist/layout/generator.d.ts.map +1 -0
  28. package/dist/layout/generator.js +124 -0
  29. package/dist/layout/generator.js.map +1 -0
  30. package/dist/layout/theme.d.ts +4 -0
  31. package/dist/layout/theme.d.ts.map +1 -0
  32. package/dist/layout/theme.js +28 -0
  33. package/dist/layout/theme.js.map +1 -0
  34. package/dist/layout/types.d.ts +68 -0
  35. package/dist/layout/types.d.ts.map +1 -0
  36. package/dist/layout/types.js +3 -0
  37. package/dist/layout/types.js.map +1 -0
  38. package/dist/quick/auto-layout.d.ts +5 -0
  39. package/dist/quick/auto-layout.d.ts.map +1 -0
  40. package/dist/quick/auto-layout.js +262 -0
  41. package/dist/quick/auto-layout.js.map +1 -0
  42. package/dist/quick/db/detect.d.ts +16 -0
  43. package/dist/quick/db/detect.d.ts.map +1 -0
  44. package/dist/quick/db/detect.js +131 -0
  45. package/dist/quick/db/detect.js.map +1 -0
  46. package/dist/quick/db/mongo.d.ts +10 -0
  47. package/dist/quick/db/mongo.d.ts.map +1 -0
  48. package/dist/quick/db/mongo.js +81 -0
  49. package/dist/quick/db/mongo.js.map +1 -0
  50. package/dist/quick/db/mysql.d.ts +8 -0
  51. package/dist/quick/db/mysql.d.ts.map +1 -0
  52. package/dist/quick/db/mysql.js +43 -0
  53. package/dist/quick/db/mysql.js.map +1 -0
  54. package/dist/quick/db/postgres.d.ts +8 -0
  55. package/dist/quick/db/postgres.d.ts.map +1 -0
  56. package/dist/quick/db/postgres.js +47 -0
  57. package/dist/quick/db/postgres.js.map +1 -0
  58. package/dist/quick/db/sqlite.d.ts +8 -0
  59. package/dist/quick/db/sqlite.d.ts.map +1 -0
  60. package/dist/quick/db/sqlite.js +43 -0
  61. package/dist/quick/db/sqlite.js.map +1 -0
  62. package/dist/quick/db-mode.d.ts +13 -0
  63. package/dist/quick/db-mode.d.ts.map +1 -0
  64. package/dist/quick/db-mode.js +159 -0
  65. package/dist/quick/db-mode.js.map +1 -0
  66. package/dist/quick/detect.d.ts +4 -0
  67. package/dist/quick/detect.d.ts.map +1 -0
  68. package/dist/quick/detect.js +76 -0
  69. package/dist/quick/detect.js.map +1 -0
  70. package/dist/quick/file-mode.d.ts +5 -0
  71. package/dist/quick/file-mode.d.ts.map +1 -0
  72. package/dist/quick/file-mode.js +158 -0
  73. package/dist/quick/file-mode.js.map +1 -0
  74. package/dist/quick/parsers/csv.d.ts +3 -0
  75. package/dist/quick/parsers/csv.d.ts.map +1 -0
  76. package/dist/quick/parsers/csv.js +145 -0
  77. package/dist/quick/parsers/csv.js.map +1 -0
  78. package/dist/quick/parsers/detect-meta.d.ts +7 -0
  79. package/dist/quick/parsers/detect-meta.d.ts.map +1 -0
  80. package/dist/quick/parsers/detect-meta.js +35 -0
  81. package/dist/quick/parsers/detect-meta.js.map +1 -0
  82. package/dist/quick/parsers/json.d.ts +3 -0
  83. package/dist/quick/parsers/json.d.ts.map +1 -0
  84. package/dist/quick/parsers/json.js +74 -0
  85. package/dist/quick/parsers/json.js.map +1 -0
  86. package/dist/quick/parsers/log.d.ts +3 -0
  87. package/dist/quick/parsers/log.d.ts.map +1 -0
  88. package/dist/quick/parsers/log.js +185 -0
  89. package/dist/quick/parsers/log.js.map +1 -0
  90. package/dist/quick/parsers/modsec.d.ts +3 -0
  91. package/dist/quick/parsers/modsec.d.ts.map +1 -0
  92. package/dist/quick/parsers/modsec.js +338 -0
  93. package/dist/quick/parsers/modsec.js.map +1 -0
  94. package/dist/quick/types.d.ts +90 -0
  95. package/dist/quick/types.d.ts.map +1 -0
  96. package/dist/quick/types.js +3 -0
  97. package/dist/quick/types.js.map +1 -0
  98. package/dist/quick/watch-mode.d.ts +3 -0
  99. package/dist/quick/watch-mode.d.ts.map +1 -0
  100. package/dist/quick/watch-mode.js +156 -0
  101. package/dist/quick/watch-mode.js.map +1 -0
  102. package/dist/server.js +2 -2
  103. package/dist/server.js.map +1 -1
  104. package/dist/types.d.ts +8 -1
  105. package/dist/types.d.ts.map +1 -1
  106. package/examples/demo.ts +134 -0
  107. package/examples/generate-access-log.ts +42 -0
  108. package/examples/screenshot-test.ts +105 -0
  109. package/examples/screenshot.png +0 -0
  110. package/frame-log.txt +830 -0
  111. package/package.json +10 -5
@@ -0,0 +1,338 @@
1
+ import { readFileSync } from 'node:fs';
2
+ const MAX_EVENTS = 10000;
3
+ const SECTION_RE = /^--([a-zA-Z0-9@._-]+)-([A-Z])--$/;
4
+ const RULE_ID_RE = /\[id "(\d+)"\]/g;
5
+ const RULE_TAG_RE = /\[tag "([^"]+)"\]/g;
6
+ const ACTION_RE = /Action: (\S+)/;
7
+ const ATTACK_CATEGORIES = {
8
+ '920': 'Protocol Violation',
9
+ '921': 'Protocol Attack',
10
+ '930': 'LFI (Local File Inclusion)',
11
+ '931': 'RFI (Remote File Inclusion)',
12
+ '932': 'RCE (Remote Code Execution)',
13
+ '933': 'PHP Injection',
14
+ '934': 'Node.js Injection',
15
+ '941': 'XSS (Cross-Site Scripting)',
16
+ '942': 'SQLi (SQL Injection)',
17
+ '943': 'Session Fixation',
18
+ '944': 'Java Attack',
19
+ '913': 'Scanner Detection',
20
+ };
21
+ export function parseModSecFile(filePath) {
22
+ const content = readFileSync(filePath, 'utf-8');
23
+ // Try JSON lines format first
24
+ const trimmed = content.trimStart();
25
+ if (trimmed.startsWith('{')) {
26
+ return parseJsonModSec(content);
27
+ }
28
+ return parseSerialAuditLog(content);
29
+ }
30
+ // ─── Serial audit log format ────────────────────────────────────────────────
31
+ function parseSerialAuditLog(content) {
32
+ const lines = content.split('\n');
33
+ const events = [];
34
+ const eventSections = new Map();
35
+ const eventOrder = [];
36
+ let currentId = null;
37
+ let currentSection = null;
38
+ let currentLines = [];
39
+ for (const line of lines) {
40
+ const m = SECTION_RE.exec(line);
41
+ if (m) {
42
+ // Flush previous section
43
+ if (currentId && currentSection) {
44
+ let sections = eventSections.get(currentId);
45
+ if (!sections) {
46
+ sections = {};
47
+ eventSections.set(currentId, sections);
48
+ eventOrder.push(currentId);
49
+ }
50
+ sections[currentSection] = currentLines;
51
+ }
52
+ currentId = m[1];
53
+ currentSection = m[2];
54
+ currentLines = [];
55
+ // Init entry if new
56
+ if (!eventSections.has(currentId)) {
57
+ eventSections.set(currentId, {});
58
+ eventOrder.push(currentId);
59
+ }
60
+ continue;
61
+ }
62
+ currentLines.push(line);
63
+ }
64
+ // Flush last section
65
+ if (currentId && currentSection) {
66
+ let sections = eventSections.get(currentId);
67
+ if (!sections) {
68
+ sections = {};
69
+ eventSections.set(currentId, sections);
70
+ eventOrder.push(currentId);
71
+ }
72
+ sections[currentSection] = currentLines;
73
+ }
74
+ // Deduplicate eventOrder
75
+ const seen = new Set();
76
+ const uniqueOrder = eventOrder.filter((id) => {
77
+ if (seen.has(id))
78
+ return false;
79
+ seen.add(id);
80
+ return true;
81
+ });
82
+ // Parse each event (cap at MAX_EVENTS)
83
+ for (const id of uniqueOrder.slice(0, MAX_EVENTS)) {
84
+ const sections = eventSections.get(id);
85
+ if (!sections)
86
+ continue;
87
+ const event = parseSections(id, sections);
88
+ if (event)
89
+ events.push(event);
90
+ }
91
+ return buildModSecData(events);
92
+ }
93
+ function parseSections(uniqueId, sections) {
94
+ // Section A: header
95
+ const aLines = sections['A'] ?? [];
96
+ const aLine = aLines.find((l) => l.trim().length > 0);
97
+ let timestamp = '';
98
+ let clientIp = '';
99
+ let clientPort;
100
+ let serverIp;
101
+ let serverPort;
102
+ if (aLine) {
103
+ // Format: [dd/Mon/yyyy:HH:mm:ss +ZZZZ] uniqueId sourceIp sourcePort destIp destPort
104
+ const aMatch = aLine.match(/\[([^\]]+)\]\s+\S+\s+(\S+)\s+(\d+)\s+(\S+)\s+(\d+)/);
105
+ if (aMatch) {
106
+ timestamp = aMatch[1];
107
+ clientIp = aMatch[2];
108
+ clientPort = parseInt(aMatch[3], 10);
109
+ serverIp = aMatch[4];
110
+ serverPort = parseInt(aMatch[5], 10);
111
+ }
112
+ else {
113
+ // v3 format or other variant — try simpler extraction
114
+ const simpleParts = aLine.trim().split(/\s+/);
115
+ // Look for timestamp in brackets
116
+ const tsMatch = aLine.match(/\[([^\]]+)\]/);
117
+ if (tsMatch)
118
+ timestamp = tsMatch[1];
119
+ // Look for IP-like strings
120
+ for (const part of simpleParts) {
121
+ if (/^\d+\.\d+\.\d+\.\d+$/.test(part) && !clientIp) {
122
+ clientIp = part;
123
+ }
124
+ }
125
+ }
126
+ }
127
+ // Section B: request line + headers
128
+ const bLines = sections['B'] ?? [];
129
+ let method = '';
130
+ let uri = '';
131
+ let protocol;
132
+ const requestLine = bLines.find((l) => l.trim().length > 0);
133
+ if (requestLine) {
134
+ const parts = requestLine.trim().split(/\s+/);
135
+ method = parts[0] ?? '';
136
+ uri = parts[1] ?? '';
137
+ protocol = parts[2];
138
+ }
139
+ // Section F: response status
140
+ const fLines = sections['F'] ?? [];
141
+ let httpCode = 0;
142
+ const statusLine = fLines.find((l) => l.trim().length > 0);
143
+ if (statusLine) {
144
+ const fMatch = statusLine.match(/\S+\s+(\d+)/);
145
+ if (fMatch) {
146
+ httpCode = parseInt(fMatch[1], 10);
147
+ }
148
+ }
149
+ // Section H: messages/trailer
150
+ const hLines = sections['H'] ?? [];
151
+ const hContent = hLines.join('\n');
152
+ const messages = parseHSection(hContent);
153
+ let action;
154
+ const actionMatch = ACTION_RE.exec(hContent);
155
+ if (actionMatch) {
156
+ action = actionMatch[1];
157
+ }
158
+ // Build raw from all sections
159
+ const rawParts = [];
160
+ for (const [key, val] of Object.entries(sections)) {
161
+ rawParts.push(`--${uniqueId}-${key}--`);
162
+ rawParts.push(...(val ?? []));
163
+ }
164
+ const raw = rawParts.join('\n');
165
+ const event = {
166
+ uniqueId,
167
+ timestamp,
168
+ clientIp,
169
+ method,
170
+ uri,
171
+ httpCode,
172
+ messages,
173
+ raw,
174
+ };
175
+ if (clientPort !== undefined)
176
+ event.clientPort = clientPort;
177
+ if (serverIp !== undefined)
178
+ event.serverIp = serverIp;
179
+ if (serverPort !== undefined)
180
+ event.serverPort = serverPort;
181
+ if (protocol !== undefined)
182
+ event.protocol = protocol;
183
+ if (action !== undefined)
184
+ event.action = action;
185
+ return event;
186
+ }
187
+ function parseHSection(content) {
188
+ // Find all rule IDs first, then match msgs/severities/tags at same positions
189
+ const ids = [];
190
+ let m;
191
+ const idRe = new RegExp(RULE_ID_RE.source, 'g');
192
+ while ((m = idRe.exec(content)) !== null) {
193
+ ids.push({ id: m[1], index: m.index });
194
+ }
195
+ if (ids.length === 0)
196
+ return [];
197
+ const messages = [];
198
+ for (let i = 0; i < ids.length; i++) {
199
+ const start = ids[i].index;
200
+ const end = i + 1 < ids.length ? ids[i + 1].index : content.length;
201
+ const segment = content.slice(start, end);
202
+ const msgMatch = /\[msg "([^"]+)"\]/.exec(segment);
203
+ const sevMatch = /\[severity "([^"]+)"\]/.exec(segment);
204
+ const tags = [];
205
+ const tagRe = new RegExp(RULE_TAG_RE.source, 'g');
206
+ let tagMatch;
207
+ while ((tagMatch = tagRe.exec(segment)) !== null) {
208
+ tags.push(tagMatch[1]);
209
+ }
210
+ const message = {
211
+ id: ids[i].id,
212
+ msg: msgMatch?.[1] ?? '',
213
+ severity: sevMatch?.[1] ?? '',
214
+ };
215
+ if (tags.length > 0)
216
+ message.tags = tags;
217
+ messages.push(message);
218
+ }
219
+ return messages;
220
+ }
221
+ // ─── JSON lines modsec format ───────────────────────────────────────────────
222
+ function parseJsonModSec(content) {
223
+ const lines = content.split('\n').filter((l) => l.trim());
224
+ const events = [];
225
+ for (const line of lines.slice(0, MAX_EVENTS)) {
226
+ let obj;
227
+ try {
228
+ obj = JSON.parse(line);
229
+ }
230
+ catch {
231
+ continue;
232
+ }
233
+ const tx = obj['transaction'];
234
+ if (!tx)
235
+ continue;
236
+ const request = tx['request'];
237
+ const response = tx['response'];
238
+ const rawMessages = tx['messages'];
239
+ const messages = (rawMessages ?? []).map((m) => {
240
+ const msg = {
241
+ id: String(m['id'] ?? ''),
242
+ msg: String(m['msg'] ?? m['message'] ?? ''),
243
+ severity: String(m['severity'] ?? ''),
244
+ };
245
+ if (Array.isArray(m['tags']))
246
+ msg.tags = m['tags'].map(String);
247
+ return msg;
248
+ });
249
+ const event = {
250
+ uniqueId: String(tx['unique_id'] ?? tx['id'] ?? ''),
251
+ timestamp: String(tx['timestamp'] ?? tx['time_stamp'] ?? ''),
252
+ clientIp: String(tx['client_ip'] ?? ''),
253
+ method: String(request?.['method'] ?? ''),
254
+ uri: String(request?.['uri'] ?? ''),
255
+ httpCode: typeof response?.['http_code'] === 'number' ? response['http_code'] : 0,
256
+ messages,
257
+ raw: line,
258
+ };
259
+ if (typeof tx['client_port'] === 'number')
260
+ event.clientPort = tx['client_port'];
261
+ if (typeof tx['server_ip'] === 'string')
262
+ event.serverIp = tx['server_ip'];
263
+ if (typeof tx['server_port'] === 'number')
264
+ event.serverPort = tx['server_port'];
265
+ if (typeof request?.['protocol'] === 'string')
266
+ event.protocol = request['protocol'];
267
+ if (typeof tx['action'] === 'string')
268
+ event.action = tx['action'];
269
+ events.push(event);
270
+ }
271
+ return buildModSecData(events);
272
+ }
273
+ // ─── Stats builder ──────────────────────────────────────────────────────────
274
+ function buildModSecData(events) {
275
+ const severityCounts = {};
276
+ const ruleCounts = {};
277
+ const ipCounts = {};
278
+ const attackCats = {};
279
+ let blockedRequests = 0;
280
+ let firstTimestamp;
281
+ let lastTimestamp;
282
+ for (const evt of events) {
283
+ // IP counts
284
+ if (evt.clientIp) {
285
+ ipCounts[evt.clientIp] = (ipCounts[evt.clientIp] ?? 0) + 1;
286
+ }
287
+ // Blocked?
288
+ if (evt.action === 'Intercepted' || evt.httpCode >= 400) {
289
+ blockedRequests++;
290
+ }
291
+ // Timestamps
292
+ if (evt.timestamp) {
293
+ if (!firstTimestamp)
294
+ firstTimestamp = evt.timestamp;
295
+ lastTimestamp = evt.timestamp;
296
+ }
297
+ // Messages
298
+ for (const msg of evt.messages) {
299
+ if (msg.severity) {
300
+ severityCounts[msg.severity] = (severityCounts[msg.severity] ?? 0) + 1;
301
+ }
302
+ if (msg.id) {
303
+ ruleCounts[msg.id] = (ruleCounts[msg.id] ?? 0) + 1;
304
+ // Attack category from first 3 digits of rule ID
305
+ const prefix = msg.id.slice(0, 3);
306
+ const category = ATTACK_CATEGORIES[prefix];
307
+ if (category) {
308
+ attackCats[category] = (attackCats[category] ?? 0) + 1;
309
+ }
310
+ }
311
+ }
312
+ }
313
+ const uniqueIPs = new Set(events.map((e) => e.clientIp).filter(Boolean)).size;
314
+ const stats = {
315
+ totalEvents: events.length,
316
+ blockedRequests,
317
+ uniqueIPs,
318
+ severityCounts,
319
+ topRules: topN(ruleCounts, 20),
320
+ topIPs: topN(ipCounts, 20),
321
+ attackCategories: attackCats,
322
+ };
323
+ if (firstTimestamp && lastTimestamp) {
324
+ stats.timeRange = { start: firstTimestamp, end: lastTimestamp };
325
+ }
326
+ return {
327
+ type: 'modsec',
328
+ events,
329
+ stats,
330
+ };
331
+ }
332
+ function topN(map, n) {
333
+ const sorted = Object.entries(map)
334
+ .sort((a, b) => b[1] - a[1])
335
+ .slice(0, n);
336
+ return Object.fromEntries(sorted);
337
+ }
338
+ //# sourceMappingURL=modsec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modsec.js","sourceRoot":"","sources":["../../../src/quick/parsers/modsec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,90 @@
1
+ export type InputType = 'json' | 'csv' | 'log' | 'module' | 'url' | 'stdin';
2
+ export interface TableData {
3
+ type: 'table';
4
+ columns: string[];
5
+ rows: Record<string, unknown>[];
6
+ meta: {
7
+ totalRows: number;
8
+ numericColumns: string[];
9
+ booleanColumns: string[];
10
+ categoricalColumns: string[];
11
+ };
12
+ }
13
+ export interface LogData {
14
+ type: 'log';
15
+ format: 'nginx' | 'json' | 'modsec' | 'plain';
16
+ entries: LogEntry[];
17
+ stats: {
18
+ totalLines: number;
19
+ timeRange?: {
20
+ start: string;
21
+ end: string;
22
+ } | undefined;
23
+ statusCodes?: Record<string, number> | undefined;
24
+ methods?: Record<string, number> | undefined;
25
+ topEndpoints?: Record<string, number> | undefined;
26
+ topIPs?: Record<string, number> | undefined;
27
+ errorCount?: number | undefined;
28
+ };
29
+ }
30
+ export interface LogEntry {
31
+ raw: string;
32
+ timestamp?: string | undefined;
33
+ ip?: string | undefined;
34
+ method?: string | undefined;
35
+ path?: string | undefined;
36
+ status?: number | undefined;
37
+ bytes?: number | undefined;
38
+ referer?: string | undefined;
39
+ userAgent?: string | undefined;
40
+ level?: string | undefined;
41
+ message?: string | undefined;
42
+ }
43
+ export interface ModSecData {
44
+ type: 'modsec';
45
+ events: ModSecEvent[];
46
+ stats: {
47
+ totalEvents: number;
48
+ blockedRequests: number;
49
+ uniqueIPs: number;
50
+ severityCounts: Record<string, number>;
51
+ topRules: Record<string, number>;
52
+ topIPs: Record<string, number>;
53
+ attackCategories: Record<string, number>;
54
+ timeRange?: {
55
+ start: string;
56
+ end: string;
57
+ } | undefined;
58
+ };
59
+ }
60
+ export interface ModSecEvent {
61
+ uniqueId: string;
62
+ timestamp: string;
63
+ clientIp: string;
64
+ clientPort?: number | undefined;
65
+ serverIp?: string | undefined;
66
+ serverPort?: number | undefined;
67
+ method: string;
68
+ uri: string;
69
+ protocol?: string | undefined;
70
+ httpCode: number;
71
+ messages: ModSecMessage[];
72
+ action?: string | undefined;
73
+ phase?: number | undefined;
74
+ raw: string;
75
+ }
76
+ export interface ModSecMessage {
77
+ id: string;
78
+ msg: string;
79
+ severity: string;
80
+ tags?: string[] | undefined;
81
+ data?: string | undefined;
82
+ }
83
+ export interface LiveData {
84
+ type: 'live';
85
+ getData: () => Record<string, unknown> | Promise<Record<string, unknown>>;
86
+ refresh?: number;
87
+ title?: string;
88
+ }
89
+ export type ParsedData = TableData | LogData | ModSecData | LiveData;
90
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/quick/types.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,KAAK,GAAG,KAAK,GAAG,QAAQ,GAAG,KAAK,GAAG,OAAO,CAAA;AAI3E,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,OAAO,CAAA;IACb,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAA;IAC/B,IAAI,EAAE;QACJ,SAAS,EAAE,MAAM,CAAA;QACjB,cAAc,EAAE,MAAM,EAAE,CAAA;QACxB,cAAc,EAAE,MAAM,EAAE,CAAA;QACxB,kBAAkB,EAAE,MAAM,EAAE,CAAA;KAC7B,CAAA;CACF;AAED,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,KAAK,CAAA;IACX,MAAM,EAAE,OAAO,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAA;IAC7C,OAAO,EAAE,QAAQ,EAAE,CAAA;IACnB,KAAK,EAAE;QACL,UAAU,EAAE,MAAM,CAAA;QAClB,SAAS,CAAC,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,GAAG,EAAE,MAAM,CAAA;SAAE,GAAG,SAAS,CAAA;QACtD,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAA;QAChD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAA;QAC5C,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAA;QACjD,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAA;QAC3C,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KAChC,CAAA;CACF;AAED,MAAM,WAAW,QAAQ;IACvB,GAAG,EAAE,MAAM,CAAA;IACX,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC9B,EAAE,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACvB,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3B,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACzB,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3B,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1B,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC5B,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC9B,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1B,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAC7B;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,QAAQ,CAAA;IACd,MAAM,EAAE,WAAW,EAAE,CAAA;IACrB,KAAK,EAAE;QACL,WAAW,EAAE,MAAM,CAAA;QACnB,eAAe,EAAE,MAAM,CAAA;QACvB,SAAS,EAAE,MAAM,CAAA;QACjB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;QACtC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;QAChC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;QAC9B,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;QACxC,SAAS,CAAC,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,GAAG,EAAE,MAAM,CAAA;SAAE,GAAG,SAAS,CAAA;KACvD,CAAA;CACF;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC/B,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC7B,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC/B,MAAM,EAAE,MAAM,CAAA;IACd,GAAG,EAAE,MAAM,CAAA;IACX,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC7B,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,aAAa,EAAE,CAAA;IACzB,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3B,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1B,GAAG,EAAE,MAAM,CAAA;CACZ;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAA;IACV,GAAG,EAAE,MAAM,CAAA;IACX,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAA;IAC3B,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAC1B;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;IACzE,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,OAAO,GAAG,UAAU,GAAG,QAAQ,CAAA"}
@@ -0,0 +1,3 @@
1
+ // ─── Input detection ─────────────────────────────────────────────────────────
2
+ export {};
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/quick/types.ts"],"names":[],"mappings":"AAAA,gFAAgF"}
@@ -0,0 +1,3 @@
1
+ export declare function startWatchModule(filePath: string): Promise<void>;
2
+ export declare function startWatchUrl(url: string, interval?: number): Promise<void>;
3
+ //# sourceMappingURL=watch-mode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watch-mode.d.ts","sourceRoot":"","sources":["../../src/quick/watch-mode.ts"],"names":[],"mappings":"AAYA,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAgDtE;AAED,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAmCvF"}
@@ -0,0 +1,156 @@
1
+ import path from 'node:path';
2
+ import tuimon from '../index.js';
3
+ export async function startWatchModule(filePath) {
4
+ const resolved = path.resolve(process.cwd(), filePath);
5
+ let mod;
6
+ try {
7
+ mod = await import(resolved);
8
+ }
9
+ catch (err) {
10
+ console.error(`[tuimon] Failed to import ${filePath}:`, err);
11
+ process.exit(1);
12
+ }
13
+ const dataFn = mod.default ?? (typeof mod === 'function' ? mod : null);
14
+ if (!dataFn || typeof dataFn !== 'function') {
15
+ console.error(`[tuimon] ${filePath} must export a default function that returns data`);
16
+ process.exit(1);
17
+ }
18
+ const refresh = mod.refresh ?? 1000;
19
+ const title = mod.title ?? path.basename(filePath, path.extname(filePath));
20
+ // Get first data call to auto-detect layout
21
+ let firstData;
22
+ try {
23
+ firstData = await Promise.resolve(dataFn());
24
+ }
25
+ catch (err) {
26
+ console.error(`[tuimon] Error calling data function:`, err);
27
+ process.exit(1);
28
+ }
29
+ // Use module's layout or auto-detect from data shape
30
+ const layout = mod.layout ?? autoDetectFromData(firstData, title);
31
+ const dash = await tuimon.start({
32
+ pages: {
33
+ main: {
34
+ html: '',
35
+ default: true,
36
+ layout,
37
+ keys: {
38
+ F5: { label: 'Refresh', action: async () => { await dash.render(await Promise.resolve(dataFn())); } },
39
+ F10: { label: 'Quit', action: () => process.exit(0) },
40
+ },
41
+ },
42
+ },
43
+ refresh,
44
+ data: dataFn,
45
+ renderDelay: 0,
46
+ });
47
+ }
48
+ export async function startWatchUrl(url, interval = 1000) {
49
+ // Fetch first response to detect layout
50
+ let firstData;
51
+ try {
52
+ const res = await fetch(url);
53
+ firstData = await res.json();
54
+ }
55
+ catch (err) {
56
+ console.error(`[tuimon] Failed to fetch ${url}:`, err);
57
+ process.exit(1);
58
+ }
59
+ const title = new URL(url).hostname;
60
+ const layout = autoDetectFromData(firstData, title);
61
+ const dataFn = async () => {
62
+ const res = await fetch(url);
63
+ return await res.json();
64
+ };
65
+ const dash = await tuimon.start({
66
+ pages: {
67
+ main: {
68
+ html: '',
69
+ default: true,
70
+ layout,
71
+ keys: {
72
+ F5: { label: 'Refresh', action: async () => { await dash.render(await dataFn()); } },
73
+ F10: { label: 'Quit', action: () => process.exit(0) },
74
+ },
75
+ },
76
+ },
77
+ refresh: interval,
78
+ data: dataFn,
79
+ renderDelay: 0,
80
+ });
81
+ }
82
+ // ─── Auto-detect layout from a plain data object ────────────────────────────
83
+ function autoDetectFromData(data, title) {
84
+ const stats = [];
85
+ const panels = [];
86
+ for (const [key, value] of Object.entries(data)) {
87
+ if (typeof value === 'number') {
88
+ // 0-100 → gauge, otherwise stat
89
+ if (value >= 0 && value <= 100 && key.match(/cpu|mem|disk|usage|percent|pct|load/i)) {
90
+ stats.push({ id: key, label: formatLabel(key), type: 'gauge' });
91
+ }
92
+ else {
93
+ stats.push({ id: key, label: formatLabel(key), type: 'stat' });
94
+ }
95
+ }
96
+ else if (typeof value === 'string') {
97
+ stats.push({ id: key, label: formatLabel(key), type: 'stat' });
98
+ }
99
+ else if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
100
+ const obj = value;
101
+ // { value, trend?, unit? } → stat
102
+ if ('value' in obj) {
103
+ stats.push({ id: key, label: formatLabel(key), type: 'stat' });
104
+ }
105
+ else {
106
+ // Record<string, number> → line chart (will accumulate)
107
+ const allNumbers = Object.values(obj).every((v) => typeof v === 'number');
108
+ if (allNumbers && Object.keys(obj).length >= 2) {
109
+ panels.push({ id: key, label: formatLabel(key), type: 'line', span: 2 });
110
+ }
111
+ else if (allNumbers) {
112
+ panels.push({ id: key, label: formatLabel(key), type: 'bar' });
113
+ }
114
+ else {
115
+ panels.push({ id: key, label: formatLabel(key), type: 'doughnut' });
116
+ }
117
+ }
118
+ }
119
+ else if (Array.isArray(value)) {
120
+ if (value.length === 0)
121
+ continue;
122
+ const first = value[0];
123
+ if (typeof first === 'string') {
124
+ // Array of strings → event-log
125
+ panels.push({ id: key, label: formatLabel(key), type: 'event-log' });
126
+ }
127
+ else if (typeof first === 'object' && first !== null) {
128
+ if ('status' in first || 'label' in first) {
129
+ panels.push({ id: key, label: formatLabel(key), type: 'status-grid' });
130
+ }
131
+ else if ('text' in first || 'message' in first) {
132
+ panels.push({ id: key, label: formatLabel(key), type: 'event-log' });
133
+ }
134
+ else {
135
+ panels.push({ id: key, label: formatLabel(key), type: 'event-log' });
136
+ }
137
+ }
138
+ }
139
+ }
140
+ // Move excess stats (> 6) to panels as stat
141
+ if (stats.length > 6) {
142
+ const overflow = stats.splice(6);
143
+ for (const s of overflow) {
144
+ panels.unshift(s);
145
+ }
146
+ }
147
+ return { title, stats, panels };
148
+ }
149
+ function formatLabel(key) {
150
+ return key
151
+ .replace(/([A-Z])/g, ' $1')
152
+ .replace(/[-_]/g, ' ')
153
+ .replace(/\b\w/g, (c) => c.toUpperCase())
154
+ .trim();
155
+ }
156
+ //# sourceMappingURL=watch-mode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watch-mode.js","sourceRoot":"","sources":["../../src/quick/watch-mode.ts"],"names":[],"mappings":"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"}
package/dist/server.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { createServer } from 'node:http';
2
- import { readFileSync, existsSync } from 'node:fs';
2
+ import { readFileSync, existsSync, statSync } from 'node:fs';
3
3
  import { join, extname, resolve, sep } from 'node:path';
4
4
  import { fileURLToPath } from 'node:url';
5
5
  // ─── Paths to bundled assets ────────────────────────────────────────────────
@@ -30,7 +30,7 @@ function injectClientScript(html) {
30
30
  }
31
31
  // ─── Serve helpers ──────────────────────────────────────────────────────────
32
32
  function serveFile(res, filePath, transform) {
33
- if (!existsSync(filePath)) {
33
+ if (!existsSync(filePath) || statSync(filePath).isDirectory()) {
34
34
  res.writeHead(404, { 'Content-Type': 'text/plain', Connection: 'close' });
35
35
  res.end('Not Found');
36
36
  return;