@hexidecibel/companion 0.0.1

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 (109) hide show
  1. package/dist/__tests__/task-parser.test.d.ts +2 -0
  2. package/dist/__tests__/task-parser.test.d.ts.map +1 -0
  3. package/dist/__tests__/task-parser.test.js +79 -0
  4. package/dist/__tests__/task-parser.test.js.map +1 -0
  5. package/dist/anthropic-usage.d.ts +5 -0
  6. package/dist/anthropic-usage.d.ts.map +1 -0
  7. package/dist/anthropic-usage.js +112 -0
  8. package/dist/anthropic-usage.js.map +1 -0
  9. package/dist/cert-generator.d.ts +15 -0
  10. package/dist/cert-generator.d.ts.map +1 -0
  11. package/dist/cert-generator.js +298 -0
  12. package/dist/cert-generator.js.map +1 -0
  13. package/dist/config.d.ts +4 -0
  14. package/dist/config.d.ts.map +1 -0
  15. package/dist/config.js +122 -0
  16. package/dist/config.js.map +1 -0
  17. package/dist/encryption.d.ts +28 -0
  18. package/dist/encryption.d.ts.map +1 -0
  19. package/dist/encryption.js +95 -0
  20. package/dist/encryption.js.map +1 -0
  21. package/dist/index.d.ts +3 -0
  22. package/dist/index.d.ts.map +1 -0
  23. package/dist/index.js +211 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/input-injector.d.ts +21 -0
  26. package/dist/input-injector.d.ts.map +1 -0
  27. package/dist/input-injector.js +126 -0
  28. package/dist/input-injector.js.map +1 -0
  29. package/dist/mdns.d.ts +11 -0
  30. package/dist/mdns.d.ts.map +1 -0
  31. package/dist/mdns.js +93 -0
  32. package/dist/mdns.js.map +1 -0
  33. package/dist/parser.d.ts +43 -0
  34. package/dist/parser.d.ts.map +1 -0
  35. package/dist/parser.js +800 -0
  36. package/dist/parser.js.map +1 -0
  37. package/dist/push.d.ts +38 -0
  38. package/dist/push.d.ts.map +1 -0
  39. package/dist/push.js +359 -0
  40. package/dist/push.js.map +1 -0
  41. package/dist/qr-server.d.ts +13 -0
  42. package/dist/qr-server.d.ts.map +1 -0
  43. package/dist/qr-server.js +421 -0
  44. package/dist/qr-server.js.map +1 -0
  45. package/dist/scaffold/generator.d.ts +11 -0
  46. package/dist/scaffold/generator.d.ts.map +1 -0
  47. package/dist/scaffold/generator.js +206 -0
  48. package/dist/scaffold/generator.js.map +1 -0
  49. package/dist/scaffold/templates/index.d.ts +5 -0
  50. package/dist/scaffold/templates/index.d.ts.map +1 -0
  51. package/dist/scaffold/templates/index.js +22 -0
  52. package/dist/scaffold/templates/index.js.map +1 -0
  53. package/dist/scaffold/templates/node-express.d.ts +3 -0
  54. package/dist/scaffold/templates/node-express.d.ts.map +1 -0
  55. package/dist/scaffold/templates/node-express.js +218 -0
  56. package/dist/scaffold/templates/node-express.js.map +1 -0
  57. package/dist/scaffold/templates/python-fastapi.d.ts +3 -0
  58. package/dist/scaffold/templates/python-fastapi.d.ts.map +1 -0
  59. package/dist/scaffold/templates/python-fastapi.js +302 -0
  60. package/dist/scaffold/templates/python-fastapi.js.map +1 -0
  61. package/dist/scaffold/templates/react-mui-website.d.ts +3 -0
  62. package/dist/scaffold/templates/react-mui-website.d.ts.map +1 -0
  63. package/dist/scaffold/templates/react-mui-website.js +405 -0
  64. package/dist/scaffold/templates/react-mui-website.js.map +1 -0
  65. package/dist/scaffold/templates/react-typescript.d.ts +3 -0
  66. package/dist/scaffold/templates/react-typescript.d.ts.map +1 -0
  67. package/dist/scaffold/templates/react-typescript.js +275 -0
  68. package/dist/scaffold/templates/react-typescript.js.map +1 -0
  69. package/dist/scaffold/types.d.ts +55 -0
  70. package/dist/scaffold/types.d.ts.map +1 -0
  71. package/dist/scaffold/types.js +3 -0
  72. package/dist/scaffold/types.js.map +1 -0
  73. package/dist/subagent-watcher.d.ts +24 -0
  74. package/dist/subagent-watcher.d.ts.map +1 -0
  75. package/dist/subagent-watcher.js +307 -0
  76. package/dist/subagent-watcher.js.map +1 -0
  77. package/dist/tls.d.ts +10 -0
  78. package/dist/tls.d.ts.map +1 -0
  79. package/dist/tls.js +77 -0
  80. package/dist/tls.js.map +1 -0
  81. package/dist/tmux-manager.d.ts +71 -0
  82. package/dist/tmux-manager.d.ts.map +1 -0
  83. package/dist/tmux-manager.js +243 -0
  84. package/dist/tmux-manager.js.map +1 -0
  85. package/dist/tool-config.d.ts +33 -0
  86. package/dist/tool-config.d.ts.map +1 -0
  87. package/dist/tool-config.js +211 -0
  88. package/dist/tool-config.js.map +1 -0
  89. package/dist/types.d.ts +218 -0
  90. package/dist/types.d.ts.map +1 -0
  91. package/dist/types.js +3 -0
  92. package/dist/types.js.map +1 -0
  93. package/dist/watcher.d.ts +63 -0
  94. package/dist/watcher.d.ts.map +1 -0
  95. package/dist/watcher.js +596 -0
  96. package/dist/watcher.js.map +1 -0
  97. package/dist/watcher.test.d.ts +2 -0
  98. package/dist/watcher.test.d.ts.map +1 -0
  99. package/dist/watcher.test.js +110 -0
  100. package/dist/watcher.test.js.map +1 -0
  101. package/dist/websocket.d.ts +62 -0
  102. package/dist/websocket.d.ts.map +1 -0
  103. package/dist/websocket.js +1695 -0
  104. package/dist/websocket.js.map +1 -0
  105. package/package.json +71 -0
  106. package/scripts/build.sh +23 -0
  107. package/scripts/install-remote.sh +18 -0
  108. package/scripts/install.sh +558 -0
  109. package/scripts/uninstall.sh +113 -0
@@ -0,0 +1,421 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.createQRRequestHandler = createQRRequestHandler;
40
+ const fs = __importStar(require("fs"));
41
+ const path = __importStar(require("path"));
42
+ const os = __importStar(require("os"));
43
+ const qrcode_1 = __importDefault(require("qrcode"));
44
+ /**
45
+ * Get the server's local IP address (non-loopback)
46
+ */
47
+ function getLocalIP() {
48
+ const interfaces = os.networkInterfaces();
49
+ for (const name of Object.keys(interfaces)) {
50
+ const netInterface = interfaces[name];
51
+ if (!netInterface)
52
+ continue;
53
+ for (const iface of netInterface) {
54
+ // Skip loopback and non-IPv4
55
+ if (iface.family === 'IPv4' && !iface.internal) {
56
+ return iface.address;
57
+ }
58
+ }
59
+ }
60
+ return 'localhost';
61
+ }
62
+ /**
63
+ * Get content type for file extension
64
+ */
65
+ function getContentType(filePath) {
66
+ const ext = path.extname(filePath).toLowerCase();
67
+ const types = {
68
+ '.html': 'text/html',
69
+ '.css': 'text/css',
70
+ '.js': 'application/javascript',
71
+ '.json': 'application/json',
72
+ '.png': 'image/png',
73
+ '.jpg': 'image/jpeg',
74
+ '.jpeg': 'image/jpeg',
75
+ '.gif': 'image/gif',
76
+ '.svg': 'image/svg+xml',
77
+ '.ico': 'image/x-icon',
78
+ };
79
+ return types[ext] || 'text/plain';
80
+ }
81
+ /**
82
+ * Find the web directory (handles both dev and installed paths)
83
+ */
84
+ function findWebDir() {
85
+ // Try built Vite output first (web/dist/), then fall back to source web/
86
+ const bases = [
87
+ path.join(__dirname, '../../web'), // From dist/
88
+ path.join(__dirname, '../../../web'), // From dist/ in installed location
89
+ path.join(process.cwd(), '../web'), // From daemon directory
90
+ path.join(process.cwd(), 'web'), // From project root
91
+ ];
92
+ // Prefer web/dist/ (Vite build output)
93
+ for (const base of bases) {
94
+ const distDir = path.join(base, 'dist');
95
+ if (fs.existsSync(path.join(distDir, 'index.html'))) {
96
+ return distDir;
97
+ }
98
+ }
99
+ // Fall back to web/ root (old vanilla client)
100
+ for (const dir of bases) {
101
+ if (fs.existsSync(path.join(dir, 'index.html'))) {
102
+ return dir;
103
+ }
104
+ }
105
+ return null;
106
+ }
107
+ /**
108
+ * Create an HTTP request handler that serves QR code at /qr and web client at /web
109
+ */
110
+ function createQRRequestHandler(config) {
111
+ const webDir = findWebDir();
112
+ if (webDir) {
113
+ console.log(`Web client: Serving from ${webDir}`);
114
+ }
115
+ else {
116
+ console.log('Web client: Not found (web/ directory missing)');
117
+ }
118
+ return async (req, res) => {
119
+ // Handle CORS preflight
120
+ res.setHeader('Access-Control-Allow-Origin', '*');
121
+ res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
122
+ res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
123
+ if (req.method === 'OPTIONS') {
124
+ res.writeHead(204);
125
+ res.end();
126
+ return;
127
+ }
128
+ const fullUrl = req.url || '/';
129
+ const [urlPath, queryString] = fullUrl.split('?');
130
+ const params = new URLSearchParams(queryString || '');
131
+ // HTTP image upload endpoint - more reliable than WebSocket for large payloads
132
+ if (urlPath === '/upload' && req.method === 'POST') {
133
+ // Verify auth token
134
+ const authHeader = req.headers['authorization'];
135
+ const token = authHeader?.replace('Bearer ', '');
136
+ if (token !== config.token) {
137
+ res.writeHead(401, { 'Content-Type': 'application/json' });
138
+ res.end(JSON.stringify({ success: false, error: 'Unauthorized' }));
139
+ return;
140
+ }
141
+ // Read request body (raw binary image data)
142
+ const chunks = [];
143
+ req.on('data', (chunk) => chunks.push(chunk));
144
+ req.on('end', () => {
145
+ try {
146
+ const body = Buffer.concat(chunks);
147
+ const contentType = req.headers['content-type'] || 'image/jpeg';
148
+ const ext = contentType.includes('png') ? 'png' : 'jpg';
149
+ const filename = `companion-${Date.now()}.${ext}`;
150
+ const filepath = path.join(os.tmpdir(), filename);
151
+ fs.writeFileSync(filepath, body);
152
+ console.log(`HTTP upload: ${filepath} (${body.length} bytes)`);
153
+ res.writeHead(200, { 'Content-Type': 'application/json' });
154
+ res.end(JSON.stringify({ success: true, filepath }));
155
+ }
156
+ catch (err) {
157
+ console.error('HTTP upload error:', err);
158
+ res.writeHead(500, { 'Content-Type': 'application/json' });
159
+ res.end(JSON.stringify({ success: false, error: 'Upload failed' }));
160
+ }
161
+ });
162
+ return;
163
+ }
164
+ // Web client routes - public access, security via WebSocket token
165
+ if (urlPath.startsWith('/web')) {
166
+ if (!webDir) {
167
+ res.writeHead(404, { 'Content-Type': 'text/plain' });
168
+ res.end('Web client not found. Make sure web/ directory exists.');
169
+ return;
170
+ }
171
+ // Determine file to serve
172
+ let filePath = urlPath.replace('/web', '') || '/index.html';
173
+ if (filePath === '/' || filePath === '') {
174
+ filePath = '/index.html';
175
+ }
176
+ const fullPath = path.join(webDir, filePath);
177
+ // Security: prevent directory traversal
178
+ if (!fullPath.startsWith(webDir)) {
179
+ res.writeHead(403, { 'Content-Type': 'text/plain' });
180
+ res.end('Forbidden');
181
+ return;
182
+ }
183
+ try {
184
+ // SPA fallback: if file not found and not a static asset, serve index.html
185
+ let servePath = fullPath;
186
+ if (!fs.existsSync(fullPath)) {
187
+ const ext = path.extname(fullPath);
188
+ if (ext && ext !== '.html') {
189
+ // Static asset not found — genuine 404
190
+ res.writeHead(404, { 'Content-Type': 'text/plain' });
191
+ res.end('Not Found');
192
+ return;
193
+ }
194
+ // Route path — serve index.html for client-side routing
195
+ servePath = path.join(webDir, 'index.html');
196
+ if (!fs.existsSync(servePath)) {
197
+ res.writeHead(404, { 'Content-Type': 'text/plain' });
198
+ res.end('Not Found');
199
+ return;
200
+ }
201
+ }
202
+ const content = fs.readFileSync(servePath);
203
+ const contentType = getContentType(servePath);
204
+ res.writeHead(200, {
205
+ 'Content-Type': contentType,
206
+ 'Content-Length': content.length,
207
+ 'Cache-Control': 'no-cache',
208
+ });
209
+ res.end(content);
210
+ }
211
+ catch (err) {
212
+ console.error('Error serving web file:', err);
213
+ res.writeHead(500, { 'Content-Type': 'text/plain' });
214
+ res.end('Internal Server Error');
215
+ }
216
+ return;
217
+ }
218
+ // QR and JSON endpoints require token auth via query param
219
+ const url = new URL(req.url || '/', `http://${req.headers.host || 'localhost'}`);
220
+ const queryToken = url.searchParams.get('token');
221
+ const isAuthed = queryToken === config.token;
222
+ if (urlPath === '/qr' || urlPath === '/qr.png') {
223
+ if (!isAuthed) {
224
+ res.writeHead(401, { 'Content-Type': 'text/plain' });
225
+ res.end('Unauthorized - token required');
226
+ return;
227
+ }
228
+ try {
229
+ const qrConfig = {
230
+ host: getLocalIP(),
231
+ port: config.port,
232
+ token: config.token,
233
+ tls: config.tls,
234
+ };
235
+ const qrData = JSON.stringify(qrConfig);
236
+ const qrBuffer = await qrcode_1.default.toBuffer(qrData, {
237
+ type: 'png',
238
+ width: 400,
239
+ margin: 2,
240
+ color: {
241
+ dark: '#000000',
242
+ light: '#ffffff',
243
+ },
244
+ });
245
+ res.writeHead(200, {
246
+ 'Content-Type': 'image/png',
247
+ 'Content-Length': qrBuffer.length,
248
+ 'Cache-Control': 'no-cache',
249
+ });
250
+ res.end(qrBuffer);
251
+ }
252
+ catch (err) {
253
+ console.error('Error generating QR code:', err);
254
+ res.writeHead(500, { 'Content-Type': 'text/plain' });
255
+ res.end('Error generating QR code');
256
+ }
257
+ return;
258
+ }
259
+ if (urlPath === '/qr.json') {
260
+ if (!isAuthed) {
261
+ res.writeHead(401, { 'Content-Type': 'application/json' });
262
+ res.end(JSON.stringify({ error: 'Unauthorized - token required' }));
263
+ return;
264
+ }
265
+ const qrConfig = {
266
+ host: getLocalIP(),
267
+ port: config.port,
268
+ token: config.token,
269
+ tls: config.tls,
270
+ };
271
+ res.writeHead(200, { 'Content-Type': 'application/json' });
272
+ res.end(JSON.stringify(qrConfig, null, 2));
273
+ return;
274
+ }
275
+ if (urlPath === '/') {
276
+ // HTML page with token gate - must enter token before seeing QR
277
+ const webClientPath = webDir ? '/web' : '';
278
+ const html = `<!DOCTYPE html>
279
+ <html>
280
+ <head>
281
+ <title>Companion Setup</title>
282
+ <meta name="viewport" content="width=device-width, initial-scale=1">
283
+ <style>
284
+ body {
285
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
286
+ background: #111827;
287
+ color: #f3f4f6;
288
+ min-height: 100vh;
289
+ display: flex;
290
+ flex-direction: column;
291
+ align-items: center;
292
+ justify-content: center;
293
+ margin: 0;
294
+ padding: 20px;
295
+ }
296
+ h1 { margin-bottom: 8px; }
297
+ p { color: #9ca3af; margin-bottom: 24px; }
298
+ img {
299
+ border-radius: 16px;
300
+ background: white;
301
+ padding: 16px;
302
+ }
303
+ .info {
304
+ margin-top: 24px;
305
+ background: #1f2937;
306
+ padding: 16px 24px;
307
+ border-radius: 12px;
308
+ font-size: 14px;
309
+ }
310
+ .info p { margin-bottom: 8px; }
311
+ .info code { color: #3b82f6; }
312
+ .web-link {
313
+ display: inline-block;
314
+ margin-top: 24px;
315
+ padding: 14px 28px;
316
+ background: #3b82f6;
317
+ color: white;
318
+ text-decoration: none;
319
+ border-radius: 10px;
320
+ font-weight: 600;
321
+ transition: background 0.2s;
322
+ }
323
+ .web-link:hover { background: #2563eb; }
324
+ .token-form {
325
+ background: #1f2937;
326
+ padding: 32px;
327
+ border-radius: 16px;
328
+ max-width: 400px;
329
+ width: 100%;
330
+ text-align: center;
331
+ }
332
+ .token-input {
333
+ width: 100%;
334
+ padding: 12px 16px;
335
+ border: 1px solid #374151;
336
+ border-radius: 8px;
337
+ background: #111827;
338
+ color: #f3f4f6;
339
+ font-size: 16px;
340
+ margin-bottom: 16px;
341
+ box-sizing: border-box;
342
+ font-family: monospace;
343
+ }
344
+ .token-input:focus { outline: none; border-color: #3b82f6; }
345
+ .token-btn {
346
+ width: 100%;
347
+ padding: 12px;
348
+ background: #3b82f6;
349
+ color: white;
350
+ border: none;
351
+ border-radius: 8px;
352
+ font-size: 16px;
353
+ font-weight: 600;
354
+ cursor: pointer;
355
+ }
356
+ .token-btn:hover { background: #2563eb; }
357
+ .error { color: #ef4444; font-size: 14px; margin-bottom: 12px; }
358
+ #auth-section { display: block; }
359
+ #qr-section { display: none; }
360
+ </style>
361
+ </head>
362
+ <body>
363
+ <h1>Companion</h1>
364
+
365
+ <div id="auth-section">
366
+ <p>Enter your token to access setup</p>
367
+ <div class="token-form">
368
+ <input type="password" id="token" class="token-input" placeholder="Enter token..." autofocus>
369
+ <div id="error" class="error" style="display:none"></div>
370
+ <button class="token-btn" onclick="authenticate()">Authenticate</button>
371
+ </div>
372
+ <div class="info">
373
+ <p>Server: <code>${getLocalIP()}:${config.port}</code></p>
374
+ </div>
375
+ </div>
376
+
377
+ <div id="qr-section">
378
+ <p>Scan this QR code with the app to connect</p>
379
+ <img id="qr-img" alt="QR Code" width="300" height="300">
380
+ <div class="info">
381
+ <p>Server: <code>${getLocalIP()}:${config.port}</code></p>
382
+ <p>TLS: <code>${config.tls ? 'Enabled' : 'Disabled'}</code></p>
383
+ </div>
384
+ ${webClientPath ? `<a href="${webClientPath}" class="web-link">Open Web Client</a>` : ''}
385
+ </div>
386
+
387
+ <script>
388
+ function authenticate() {
389
+ var token = document.getElementById('token').value;
390
+ if (!token) return;
391
+ // Test by fetching the QR image with the token
392
+ fetch('/qr.png?token=' + encodeURIComponent(token))
393
+ .then(function(res) {
394
+ if (res.ok) {
395
+ document.getElementById('auth-section').style.display = 'none';
396
+ document.getElementById('qr-section').style.display = 'flex';
397
+ document.getElementById('qr-section').style.flexDirection = 'column';
398
+ document.getElementById('qr-section').style.alignItems = 'center';
399
+ document.getElementById('qr-img').src = '/qr.png?token=' + encodeURIComponent(token);
400
+ } else {
401
+ document.getElementById('error').textContent = 'Invalid token';
402
+ document.getElementById('error').style.display = 'block';
403
+ }
404
+ });
405
+ }
406
+ document.getElementById('token').addEventListener('keydown', function(e) {
407
+ if (e.key === 'Enter') authenticate();
408
+ });
409
+ </script>
410
+ </body>
411
+ </html>`;
412
+ res.writeHead(200, { 'Content-Type': 'text/html' });
413
+ res.end(html);
414
+ return;
415
+ }
416
+ // 404 for other paths
417
+ res.writeHead(404, { 'Content-Type': 'text/plain' });
418
+ res.end('Not Found');
419
+ };
420
+ }
421
+ //# sourceMappingURL=qr-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qr-server.js","sourceRoot":"","sources":["../src/qr-server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import { ProjectConfig, ScaffoldProgress, ScaffoldResult } from './types';
2
+ type ProgressCallback = (progress: ScaffoldProgress) => void;
3
+ export declare function scaffoldProject(config: ProjectConfig, onProgress?: ProgressCallback): Promise<ScaffoldResult>;
4
+ export declare function previewScaffold(config: ProjectConfig): Promise<{
5
+ files: string[];
6
+ projectPath: string;
7
+ } | {
8
+ error: string;
9
+ }>;
10
+ export {};
11
+ //# sourceMappingURL=generator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../src/scaffold/generator.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,cAAc,EAAiB,MAAM,SAAS,CAAC;AAgBzF,KAAK,gBAAgB,GAAG,CAAC,QAAQ,EAAE,gBAAgB,KAAK,IAAI,CAAC;AAoB7D,wBAAsB,eAAe,CACnC,MAAM,EAAE,aAAa,EACrB,UAAU,CAAC,EAAE,gBAAgB,GAC5B,OAAO,CAAC,cAAc,CAAC,CA2IzB;AAGD,wBAAsB,eAAe,CACnC,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAUvE"}
@@ -0,0 +1,206 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.scaffoldProject = scaffoldProject;
37
+ exports.previewScaffold = previewScaffold;
38
+ const fs = __importStar(require("fs/promises"));
39
+ const path = __importStar(require("path"));
40
+ const os = __importStar(require("os"));
41
+ const child_process_1 = require("child_process");
42
+ const util_1 = require("util");
43
+ const templates_1 = require("./templates");
44
+ // Expand ~ to home directory
45
+ function expandPath(p) {
46
+ if (p.startsWith('~/')) {
47
+ return path.join(os.homedir(), p.slice(2));
48
+ }
49
+ if (p === '~') {
50
+ return os.homedir();
51
+ }
52
+ return p;
53
+ }
54
+ const execAsync = (0, util_1.promisify)(child_process_1.exec);
55
+ // Replace template variables with actual values
56
+ function interpolate(template, variables) {
57
+ let result = template;
58
+ for (const [key, value] of Object.entries(variables)) {
59
+ result = result.replace(new RegExp(`\\{\\{${key}\\}\\}`, 'g'), value);
60
+ }
61
+ return result;
62
+ }
63
+ // Convert project name to valid identifier (for package names, etc.)
64
+ function toValidName(name) {
65
+ return name
66
+ .toLowerCase()
67
+ .replace(/[^a-z0-9-]/g, '-')
68
+ .replace(/-+/g, '-')
69
+ .replace(/^-|-$/g, '');
70
+ }
71
+ async function scaffoldProject(config, onProgress) {
72
+ const template = (0, templates_1.getTemplate)(config.stackId);
73
+ if (!template) {
74
+ return {
75
+ success: false,
76
+ projectPath: config.location,
77
+ filesCreated: [],
78
+ error: `Unknown template: ${config.stackId}`,
79
+ };
80
+ }
81
+ const projectPath = path.join(expandPath(config.location), toValidName(config.name));
82
+ const filesCreated = [];
83
+ const variables = {
84
+ projectName: toValidName(config.name),
85
+ projectDescription: config.description || `A ${template.name} project`,
86
+ };
87
+ try {
88
+ // Step 1: Create project directory
89
+ onProgress?.({
90
+ step: 'Creating project directory',
91
+ progress: 5,
92
+ complete: false,
93
+ });
94
+ await fs.mkdir(projectPath, { recursive: true });
95
+ // Step 2: Create files from template
96
+ const totalFiles = template.files.length;
97
+ for (let i = 0; i < template.files.length; i++) {
98
+ const file = template.files[i];
99
+ const filePath = path.join(projectPath, interpolate(file.path, variables));
100
+ const fileContent = interpolate(file.template, variables);
101
+ onProgress?.({
102
+ step: 'Creating files',
103
+ detail: file.path,
104
+ progress: 10 + Math.floor((i / totalFiles) * 50),
105
+ complete: false,
106
+ });
107
+ // Ensure directory exists
108
+ await fs.mkdir(path.dirname(filePath), { recursive: true });
109
+ await fs.writeFile(filePath, fileContent, 'utf-8');
110
+ filesCreated.push(file.path);
111
+ }
112
+ // Step 3: Initialize git if requested
113
+ if (config.options.initGit) {
114
+ onProgress?.({
115
+ step: 'Initializing git repository',
116
+ progress: 60,
117
+ complete: false,
118
+ });
119
+ try {
120
+ // Check if git is available
121
+ await execAsync('which git');
122
+ await execAsync('git init', { cwd: projectPath });
123
+ await execAsync('git add .', { cwd: projectPath });
124
+ await execAsync('git commit -m "Initial commit from Companion"', { cwd: projectPath });
125
+ // Step 3b: Create GitHub repo if requested
126
+ if (config.options.createGitHubRepo) {
127
+ onProgress?.({
128
+ step: 'Creating GitHub repository',
129
+ progress: 65,
130
+ complete: false,
131
+ });
132
+ try {
133
+ // Check if gh CLI is available
134
+ await execAsync('which gh');
135
+ const visibility = config.options.privateRepo ? '--private' : '--public';
136
+ const repoName = toValidName(config.name);
137
+ await execAsync(`gh repo create ${repoName} ${visibility} --source=. --remote=origin --push`, { cwd: projectPath, timeout: 30000 });
138
+ }
139
+ catch (ghError) {
140
+ console.warn('GitHub repo creation failed (gh CLI may not be installed or authenticated):', ghError);
141
+ // Non-fatal, continue
142
+ }
143
+ }
144
+ }
145
+ catch (gitError) {
146
+ console.warn('Git init failed (git may not be installed):', gitError);
147
+ // Non-fatal, continue
148
+ }
149
+ }
150
+ // Step 4: Run post-create commands if any
151
+ if (template.postCreate && template.postCreate.length > 0) {
152
+ for (let i = 0; i < template.postCreate.length; i++) {
153
+ const cmd = template.postCreate[i];
154
+ onProgress?.({
155
+ step: cmd.description,
156
+ progress: 70 + Math.floor((i / template.postCreate.length) * 25),
157
+ complete: false,
158
+ });
159
+ try {
160
+ await execAsync(cmd.command, { cwd: projectPath, timeout: 120000 });
161
+ }
162
+ catch (cmdError) {
163
+ console.warn(`Post-create command failed: ${cmd.command}`, cmdError);
164
+ // Non-fatal for MVP, continue
165
+ }
166
+ }
167
+ }
168
+ onProgress?.({
169
+ step: 'Complete',
170
+ progress: 100,
171
+ complete: true,
172
+ });
173
+ return {
174
+ success: true,
175
+ projectPath,
176
+ filesCreated,
177
+ };
178
+ }
179
+ catch (error) {
180
+ const errorMessage = error instanceof Error ? error.message : String(error);
181
+ onProgress?.({
182
+ step: 'Error',
183
+ detail: errorMessage,
184
+ progress: 0,
185
+ complete: true,
186
+ error: errorMessage,
187
+ });
188
+ return {
189
+ success: false,
190
+ projectPath,
191
+ filesCreated,
192
+ error: errorMessage,
193
+ };
194
+ }
195
+ }
196
+ // Preview what will be created without actually creating
197
+ async function previewScaffold(config) {
198
+ const template = (0, templates_1.getTemplate)(config.stackId);
199
+ if (!template) {
200
+ return { error: `Unknown template: ${config.stackId}` };
201
+ }
202
+ const projectPath = path.join(expandPath(config.location), toValidName(config.name));
203
+ const files = template.files.map(f => f.path);
204
+ return { files, projectPath };
205
+ }
206
+ //# sourceMappingURL=generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generator.js","sourceRoot":"","sources":["../../src/scaffold/generator.ts"],"names":[],"mappings":"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"}