@hatchway/cli 0.50.83 → 0.50.84

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.
@@ -0,0 +1,279 @@
1
+ // Hatchway CLI - Built with Rollup
2
+ import { existsSync, mkdirSync, readFileSync, appendFileSync } from 'node:fs';
3
+ import { resolve, join } from 'node:path';
4
+ import { EventEmitter } from 'node:events';
5
+
6
+ /**
7
+ * Get the workspace root directory for the runner.
8
+ * This is where projects will be stored.
9
+ */
10
+ function getWorkspaceRoot() {
11
+ // Check environment variable first
12
+ const envWorkspace = process.env.WORKSPACE_ROOT;
13
+ if (envWorkspace && existsSync(envWorkspace)) {
14
+ return resolve(envWorkspace);
15
+ }
16
+ // Default to a workspace directory in the user's home
17
+ const homeDir = process.env.HOME || process.env.USERPROFILE || '/tmp';
18
+ const defaultWorkspace = resolve(homeDir, 'hatchway-workspace');
19
+ return defaultWorkspace;
20
+ }
21
+
22
+ /**
23
+ * LogBuffer - File-backed circular buffer for log entries
24
+ *
25
+ * Maintains an in-memory buffer of the most recent 100 entries
26
+ * and persists all logs to a file for full history access.
27
+ */
28
+ const DEFAULT_BUFFER_SIZE = 100;
29
+ // Stable, absolute logs dir beside the built apps (workspace root) — a relative
30
+ // 'logs' resolved against process.cwd(), so writing/reading diverged when the
31
+ // runner was launched from different directories (TUI copy showed 0 lines).
32
+ const LOG_DIR = join(getWorkspaceRoot(), 'logs');
33
+ const LOG_FILE = 'runner-tui.log';
34
+ class LogBuffer extends EventEmitter {
35
+ constructor(options) {
36
+ super();
37
+ this.buffer = [];
38
+ this.maxSize = options?.maxSize ?? DEFAULT_BUFFER_SIZE;
39
+ this.sessionStartTime = Date.now();
40
+ // Set up log file path
41
+ const logDir = options?.logDir ?? LOG_DIR;
42
+ if (!existsSync(logDir)) {
43
+ mkdirSync(logDir, { recursive: true });
44
+ }
45
+ this.logFilePath = join(logDir, LOG_FILE);
46
+ // Write session start marker
47
+ this.writeToFile(`\n${'='.repeat(60)}\n`);
48
+ this.writeToFile(`SESSION START: ${new Date().toISOString()}\n`);
49
+ this.writeToFile(`${'='.repeat(60)}\n\n`);
50
+ }
51
+ /**
52
+ * Add a log entry to the buffer and file
53
+ */
54
+ add(entry) {
55
+ // Add to in-memory buffer (circular)
56
+ this.buffer.push(entry);
57
+ if (this.buffer.length > this.maxSize) {
58
+ this.buffer.shift();
59
+ }
60
+ // Write to file
61
+ this.writeToFile(this.formatEntryForFile(entry));
62
+ // Emit event for subscribers (TUI components)
63
+ this.emit('log', entry);
64
+ }
65
+ /**
66
+ * Get the most recent N entries from memory
67
+ */
68
+ getRecent(count) {
69
+ const n = count ?? this.maxSize;
70
+ return this.buffer.slice(-n);
71
+ }
72
+ /**
73
+ * Get all entries currently in memory
74
+ */
75
+ getAll() {
76
+ return [...this.buffer];
77
+ }
78
+ /**
79
+ * Get filtered entries from memory
80
+ */
81
+ getFiltered(filter) {
82
+ return this.buffer.filter(entry => this.matchesFilter(entry, filter));
83
+ }
84
+ /**
85
+ * Read entries from the log file (for full history)
86
+ * Returns parsed log entries from the current session
87
+ */
88
+ readFromFile(maxLines) {
89
+ if (!existsSync(this.logFilePath)) {
90
+ return [];
91
+ }
92
+ try {
93
+ const content = readFileSync(this.logFilePath, 'utf-8');
94
+ const lines = content.split('\n').filter(line => line.trim());
95
+ // Find the last session marker and only read from there
96
+ let sessionStart = 0;
97
+ for (let i = lines.length - 1; i >= 0; i--) {
98
+ if (lines[i].includes('SESSION START:')) {
99
+ sessionStart = i + 1;
100
+ break;
101
+ }
102
+ }
103
+ const sessionLines = lines.slice(sessionStart);
104
+ const entries = [];
105
+ for (const line of sessionLines) {
106
+ const parsed = this.parseLogLine(line);
107
+ if (parsed) {
108
+ entries.push(parsed);
109
+ }
110
+ }
111
+ if (maxLines && entries.length > maxLines) {
112
+ return entries.slice(-maxLines);
113
+ }
114
+ return entries;
115
+ }
116
+ catch (error) {
117
+ console.error('Failed to read log file:', error);
118
+ return [];
119
+ }
120
+ }
121
+ /**
122
+ * Get the log file path for external access
123
+ */
124
+ getLogFilePath() {
125
+ return this.logFilePath;
126
+ }
127
+ /**
128
+ * Convert buffer contents to plain text (for copying)
129
+ */
130
+ toText(entries) {
131
+ const items = entries ?? this.buffer;
132
+ return items.map(entry => this.formatEntryForDisplay(entry)).join('\n');
133
+ }
134
+ /**
135
+ * Clear the in-memory buffer (file is preserved)
136
+ */
137
+ clear() {
138
+ this.buffer = [];
139
+ this.emit('clear');
140
+ }
141
+ /**
142
+ * Subscribe to new log entries
143
+ */
144
+ onLog(callback) {
145
+ this.on('log', callback);
146
+ return () => this.off('log', callback);
147
+ }
148
+ // Private methods
149
+ writeToFile(content) {
150
+ try {
151
+ appendFileSync(this.logFilePath, content);
152
+ }
153
+ catch (error) {
154
+ // Silently fail - don't break logging if file write fails
155
+ }
156
+ }
157
+ formatEntryForFile(entry) {
158
+ const timestamp = new Date(entry.timestamp).toISOString();
159
+ const level = entry.level.toUpperCase().padEnd(7);
160
+ const category = entry.category.padEnd(12);
161
+ let line = `[${timestamp}] [${level}] [${category}] ${entry.message}`;
162
+ if (entry.toolName) {
163
+ line += ` | tool=${entry.toolName}`;
164
+ if (entry.toolArgs) {
165
+ line += ` args=${entry.toolArgs}`;
166
+ }
167
+ }
168
+ if (entry.buildId) {
169
+ line += ` | build=${entry.buildId}`;
170
+ }
171
+ if (entry.data && Object.keys(entry.data).length > 0) {
172
+ line += ` | data=${JSON.stringify(entry.data)}`;
173
+ }
174
+ return line + '\n';
175
+ }
176
+ formatEntryForDisplay(entry) {
177
+ const time = new Date(entry.timestamp).toLocaleTimeString('en-US', {
178
+ hour12: false,
179
+ hour: '2-digit',
180
+ minute: '2-digit',
181
+ second: '2-digit',
182
+ });
183
+ const levelIcon = {
184
+ debug: ' ',
185
+ info: '●',
186
+ success: '✓',
187
+ warn: '⚠',
188
+ error: '✗',
189
+ }[entry.level];
190
+ if (entry.toolName) {
191
+ return `${time} 🔧 ${entry.toolName}${entry.toolArgs ? ` ${entry.toolArgs}` : ''}`;
192
+ }
193
+ return `${time} ${levelIcon} ${entry.message}`;
194
+ }
195
+ parseLogLine(line) {
196
+ // Parse format: [ISO_TIMESTAMP] [LEVEL ] [CATEGORY ] message | key=value...
197
+ const match = line.match(/^\[([^\]]+)\] \[([^\]]+)\] \[([^\]]+)\] (.+)$/);
198
+ if (!match) {
199
+ return null;
200
+ }
201
+ const [, timestamp, levelRaw, categoryRaw, rest] = match;
202
+ const level = levelRaw.trim().toLowerCase();
203
+ const category = categoryRaw.trim();
204
+ // Parse message and optional fields
205
+ const parts = rest.split(' | ');
206
+ const message = parts[0];
207
+ const entry = {
208
+ id: `${Date.parse(timestamp)}-${Math.random().toString(36).slice(2, 8)}`,
209
+ timestamp: Date.parse(timestamp),
210
+ level,
211
+ category,
212
+ message,
213
+ };
214
+ // Parse optional key=value pairs
215
+ for (let i = 1; i < parts.length; i++) {
216
+ const [key, ...valueParts] = parts[i].split('=');
217
+ const value = valueParts.join('=');
218
+ switch (key) {
219
+ case 'tool':
220
+ entry.toolName = value;
221
+ break;
222
+ case 'args':
223
+ entry.toolArgs = value;
224
+ break;
225
+ case 'build':
226
+ entry.buildId = value;
227
+ break;
228
+ case 'data':
229
+ try {
230
+ entry.data = JSON.parse(value);
231
+ }
232
+ catch {
233
+ // Ignore parse errors
234
+ }
235
+ break;
236
+ }
237
+ }
238
+ return entry;
239
+ }
240
+ matchesFilter(entry, filter) {
241
+ if (filter.levels && !filter.levels.includes(entry.level)) {
242
+ return false;
243
+ }
244
+ if (filter.categories && !filter.categories.includes(entry.category)) {
245
+ return false;
246
+ }
247
+ if (filter.buildId && entry.buildId !== filter.buildId) {
248
+ return false;
249
+ }
250
+ if (filter.verbose === false && entry.verbose) {
251
+ return false;
252
+ }
253
+ if (filter.search) {
254
+ const searchLower = filter.search.toLowerCase();
255
+ const messageMatch = entry.message.toLowerCase().includes(searchLower);
256
+ const toolMatch = entry.toolName?.toLowerCase().includes(searchLower);
257
+ const argsMatch = entry.toolArgs?.toLowerCase().includes(searchLower);
258
+ if (!messageMatch && !toolMatch && !argsMatch) {
259
+ return false;
260
+ }
261
+ }
262
+ return true;
263
+ }
264
+ }
265
+ // Singleton instance
266
+ let instance = null;
267
+ function getLogBuffer() {
268
+ if (!instance) {
269
+ instance = new LogBuffer();
270
+ }
271
+ return instance;
272
+ }
273
+ function createLogBuffer(options) {
274
+ instance = new LogBuffer(options);
275
+ return instance;
276
+ }
277
+
278
+ export { getWorkspaceRoot as a, createLogBuffer as c, getLogBuffer as g };
279
+ //# sourceMappingURL=log-buffer-eHyX6VEc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log-buffer-eHyX6VEc.js","sources":["../../src/lib/workspace.ts","../../src/lib/logging/log-buffer.ts"],"sourcesContent":["import { resolve } from 'node:path';\nimport { existsSync } from 'node:fs';\n\n/**\n * Get the workspace root directory for the runner.\n * This is where projects will be stored.\n */\nexport function getWorkspaceRoot(): string {\n // Check environment variable first\n const envWorkspace = process.env.WORKSPACE_ROOT;\n if (envWorkspace && existsSync(envWorkspace)) {\n return resolve(envWorkspace);\n }\n\n // Default to a workspace directory in the user's home\n const homeDir = process.env.HOME || process.env.USERPROFILE || '/tmp';\n const defaultWorkspace = resolve(homeDir, 'hatchway-workspace');\n\n return defaultWorkspace;\n}\n","/**\n * LogBuffer - File-backed circular buffer for log entries\n * \n * Maintains an in-memory buffer of the most recent 100 entries\n * and persists all logs to a file for full history access.\n */\n\nimport { existsSync, mkdirSync, appendFileSync, readFileSync, writeFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { EventEmitter } from 'node:events';\nimport { getWorkspaceRoot } from '../workspace.js';\nimport type { LogEntry, LogFilter } from './types.js';\n\nconst DEFAULT_BUFFER_SIZE = 100;\n// Stable, absolute logs dir beside the built apps (workspace root) — a relative\n// 'logs' resolved against process.cwd(), so writing/reading diverged when the\n// runner was launched from different directories (TUI copy showed 0 lines).\nconst LOG_DIR = join(getWorkspaceRoot(), 'logs');\nconst LOG_FILE = 'runner-tui.log';\n\nexport class LogBuffer extends EventEmitter {\n private buffer: LogEntry[] = [];\n private maxSize: number;\n private logFilePath: string;\n private sessionStartTime: number;\n\n constructor(options?: { maxSize?: number; logDir?: string }) {\n super();\n this.maxSize = options?.maxSize ?? DEFAULT_BUFFER_SIZE;\n this.sessionStartTime = Date.now();\n \n // Set up log file path\n const logDir = options?.logDir ?? LOG_DIR;\n if (!existsSync(logDir)) {\n mkdirSync(logDir, { recursive: true });\n }\n this.logFilePath = join(logDir, LOG_FILE);\n \n // Write session start marker\n this.writeToFile(`\\n${'='.repeat(60)}\\n`);\n this.writeToFile(`SESSION START: ${new Date().toISOString()}\\n`);\n this.writeToFile(`${'='.repeat(60)}\\n\\n`);\n }\n\n /**\n * Add a log entry to the buffer and file\n */\n add(entry: LogEntry): void {\n // Add to in-memory buffer (circular)\n this.buffer.push(entry);\n if (this.buffer.length > this.maxSize) {\n this.buffer.shift();\n }\n\n // Write to file\n this.writeToFile(this.formatEntryForFile(entry));\n\n // Emit event for subscribers (TUI components)\n this.emit('log', entry);\n }\n\n /**\n * Get the most recent N entries from memory\n */\n getRecent(count?: number): LogEntry[] {\n const n = count ?? this.maxSize;\n return this.buffer.slice(-n);\n }\n\n /**\n * Get all entries currently in memory\n */\n getAll(): LogEntry[] {\n return [...this.buffer];\n }\n\n /**\n * Get filtered entries from memory\n */\n getFiltered(filter: LogFilter): LogEntry[] {\n return this.buffer.filter(entry => this.matchesFilter(entry, filter));\n }\n\n /**\n * Read entries from the log file (for full history)\n * Returns parsed log entries from the current session\n */\n readFromFile(maxLines?: number): LogEntry[] {\n if (!existsSync(this.logFilePath)) {\n return [];\n }\n\n try {\n const content = readFileSync(this.logFilePath, 'utf-8');\n const lines = content.split('\\n').filter(line => line.trim());\n \n // Find the last session marker and only read from there\n let sessionStart = 0;\n for (let i = lines.length - 1; i >= 0; i--) {\n if (lines[i].includes('SESSION START:')) {\n sessionStart = i + 1;\n break;\n }\n }\n\n const sessionLines = lines.slice(sessionStart);\n const entries: LogEntry[] = [];\n\n for (const line of sessionLines) {\n const parsed = this.parseLogLine(line);\n if (parsed) {\n entries.push(parsed);\n }\n }\n\n if (maxLines && entries.length > maxLines) {\n return entries.slice(-maxLines);\n }\n\n return entries;\n } catch (error) {\n console.error('Failed to read log file:', error);\n return [];\n }\n }\n\n /**\n * Get the log file path for external access\n */\n getLogFilePath(): string {\n return this.logFilePath;\n }\n\n /**\n * Convert buffer contents to plain text (for copying)\n */\n toText(entries?: LogEntry[]): string {\n const items = entries ?? this.buffer;\n return items.map(entry => this.formatEntryForDisplay(entry)).join('\\n');\n }\n\n /**\n * Clear the in-memory buffer (file is preserved)\n */\n clear(): void {\n this.buffer = [];\n this.emit('clear');\n }\n\n /**\n * Subscribe to new log entries\n */\n onLog(callback: (entry: LogEntry) => void): () => void {\n this.on('log', callback);\n return () => this.off('log', callback);\n }\n\n // Private methods\n\n private writeToFile(content: string): void {\n try {\n appendFileSync(this.logFilePath, content);\n } catch (error) {\n // Silently fail - don't break logging if file write fails\n }\n }\n\n private formatEntryForFile(entry: LogEntry): string {\n const timestamp = new Date(entry.timestamp).toISOString();\n const level = entry.level.toUpperCase().padEnd(7);\n const category = entry.category.padEnd(12);\n \n let line = `[${timestamp}] [${level}] [${category}] ${entry.message}`;\n \n if (entry.toolName) {\n line += ` | tool=${entry.toolName}`;\n if (entry.toolArgs) {\n line += ` args=${entry.toolArgs}`;\n }\n }\n \n if (entry.buildId) {\n line += ` | build=${entry.buildId}`;\n }\n \n if (entry.data && Object.keys(entry.data).length > 0) {\n line += ` | data=${JSON.stringify(entry.data)}`;\n }\n \n return line + '\\n';\n }\n\n private formatEntryForDisplay(entry: LogEntry): string {\n const time = new Date(entry.timestamp).toLocaleTimeString('en-US', {\n hour12: false,\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n });\n \n const levelIcon = {\n debug: ' ',\n info: '●',\n success: '✓',\n warn: '⚠',\n error: '✗',\n }[entry.level];\n\n if (entry.toolName) {\n return `${time} 🔧 ${entry.toolName}${entry.toolArgs ? ` ${entry.toolArgs}` : ''}`;\n }\n\n return `${time} ${levelIcon} ${entry.message}`;\n }\n\n private parseLogLine(line: string): LogEntry | null {\n // Parse format: [ISO_TIMESTAMP] [LEVEL ] [CATEGORY ] message | key=value...\n const match = line.match(/^\\[([^\\]]+)\\] \\[([^\\]]+)\\] \\[([^\\]]+)\\] (.+)$/);\n if (!match) {\n return null;\n }\n\n const [, timestamp, levelRaw, categoryRaw, rest] = match;\n const level = levelRaw.trim().toLowerCase() as LogEntry['level'];\n const category = categoryRaw.trim() as LogEntry['category'];\n\n // Parse message and optional fields\n const parts = rest.split(' | ');\n const message = parts[0];\n\n const entry: LogEntry = {\n id: `${Date.parse(timestamp)}-${Math.random().toString(36).slice(2, 8)}`,\n timestamp: Date.parse(timestamp),\n level,\n category,\n message,\n };\n\n // Parse optional key=value pairs\n for (let i = 1; i < parts.length; i++) {\n const [key, ...valueParts] = parts[i].split('=');\n const value = valueParts.join('=');\n \n switch (key) {\n case 'tool':\n entry.toolName = value;\n break;\n case 'args':\n entry.toolArgs = value;\n break;\n case 'build':\n entry.buildId = value;\n break;\n case 'data':\n try {\n entry.data = JSON.parse(value);\n } catch {\n // Ignore parse errors\n }\n break;\n }\n }\n\n return entry;\n }\n\n private matchesFilter(entry: LogEntry, filter: LogFilter): boolean {\n if (filter.levels && !filter.levels.includes(entry.level)) {\n return false;\n }\n \n if (filter.categories && !filter.categories.includes(entry.category)) {\n return false;\n }\n \n if (filter.buildId && entry.buildId !== filter.buildId) {\n return false;\n }\n \n if (filter.verbose === false && entry.verbose) {\n return false;\n }\n \n if (filter.search) {\n const searchLower = filter.search.toLowerCase();\n const messageMatch = entry.message.toLowerCase().includes(searchLower);\n const toolMatch = entry.toolName?.toLowerCase().includes(searchLower);\n const argsMatch = entry.toolArgs?.toLowerCase().includes(searchLower);\n \n if (!messageMatch && !toolMatch && !argsMatch) {\n return false;\n }\n }\n \n return true;\n }\n}\n\n// Singleton instance\nlet instance: LogBuffer | null = null;\n\nexport function getLogBuffer(): LogBuffer {\n if (!instance) {\n instance = new LogBuffer();\n }\n return instance;\n}\n\nexport function createLogBuffer(options?: { maxSize?: number; logDir?: string }): LogBuffer {\n instance = new LogBuffer(options);\n return instance;\n}\n"],"names":[],"mappings":"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"}
@@ -4,7 +4,7 @@ import 'chalk';
4
4
  import { userInfo, homedir } from 'node:os';
5
5
  import { join } from 'node:path';
6
6
  import { B as Banner } from './Banner-_pJB7dCO.js';
7
- import 'node:fs';
7
+ import './log-buffer-eHyX6VEc.js';
8
8
  import 'node:events';
9
9
  import 'node:stream';
10
10
  import 'node:process';
@@ -15,6 +15,7 @@ import 'node:child_process';
15
15
  import { c as configManager } from './config-manager-DST6RbP8.js';
16
16
  import 'assert';
17
17
  import 'events';
18
+ import 'node:fs';
18
19
  import 'module';
19
20
  import 'node:buffer';
20
21
  import 'conf';
@@ -608,7 +609,7 @@ async function startRunner(config) {
608
609
  console.log('\n Starting Hatchway Runner...\n');
609
610
  console.log(` Runner ID: ${config.runnerId}`);
610
611
  console.log(' Connecting to remote server...\n');
611
- const { runCommand } = await import('./run-B0hKXBzX.js');
612
+ const { runCommand } = await import('./run-DbXViD2C.js');
612
613
  await runCommand({
613
614
  secret: config.key,
614
615
  runnerId: config.runnerId,
@@ -619,7 +620,7 @@ async function startRunner(config) {
619
620
  */
620
621
  async function startLocalMode() {
621
622
  console.log('\n Starting Hatchway in Local Mode...\n');
622
- const { startCommand } = await import('./start-B5Vi66EE.js');
623
+ const { startCommand } = await import('./start-BEIpWjyK.js');
623
624
  await startCommand({});
624
625
  }
625
626
  /**
@@ -630,7 +631,7 @@ async function runInitialization(config) {
630
631
  const workspace = config.workspace.startsWith('~')
631
632
  ? config.workspace.replace('~', homedir())
632
633
  : config.workspace;
633
- const { initTUICommand } = await import('./init-tui-CzevU6HY.js');
634
+ const { initTUICommand } = await import('./init-tui-Cgxsmmn-.js');
634
635
  // Build options based on form input
635
636
  const options = {
636
637
  workspace,
@@ -648,4 +649,4 @@ async function runInitialization(config) {
648
649
  }
649
650
 
650
651
  export { mainTUICommand };
651
- //# sourceMappingURL=main-tui-H7JUmYEf.js.map
652
+ //# sourceMappingURL=main-tui-D580QurF.js.map