@cluesmith/codev 1.4.10 → 1.4.12

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.
@@ -28,11 +28,10 @@ if (isNaN(port) || port < 1 || port > 65535) {
28
28
  const fullFilePath = filePath;
29
29
  const displayPath = path.basename(filePath);
30
30
  /**
31
- * Find the open template
32
- * Template is bundled with agent-farm package in templates/ directory
31
+ * Find a template file
32
+ * Templates are bundled with agent-farm package in templates/ directory
33
33
  */
34
- function findTemplatePath() {
35
- const filename = 'open.html';
34
+ function findTemplatePath(filename) {
36
35
  // Templates are at package root: packages/codev/templates/
37
36
  // From compiled: dist/agent-farm/servers/ -> ../../../templates/
38
37
  // From source: src/agent-farm/servers/ -> ../../../templates/
@@ -41,7 +40,7 @@ function findTemplatePath() {
41
40
  return pkgPath;
42
41
  throw new Error(`Template not found: ${filename}`);
43
42
  }
44
- const templatePath = findTemplatePath();
43
+ const templatePath = findTemplatePath('open.html');
45
44
  // Validate file exists
46
45
  if (!fs.existsSync(fullFilePath)) {
47
46
  console.error(`File not found: ${fullFilePath}`);
@@ -63,6 +62,9 @@ const isImage = imageExtensions.includes(ext);
63
62
  // Video detection
64
63
  const videoExtensions = ['webm', 'mp4', 'mov', 'avi'];
65
64
  const isVideo = videoExtensions.includes(ext);
65
+ // STL (3D model) detection
66
+ const isSTL = ext === 'stl';
67
+ const stlTemplatePath = isSTL ? findTemplatePath('stl-viewer.html') : null;
66
68
  // MIME type mapping for images
67
69
  const imageMimeTypes = {
68
70
  png: 'image/png',
@@ -90,7 +92,23 @@ const server = http.createServer((req, res) => {
90
92
  res.end();
91
93
  return;
92
94
  }
93
- // Serve annotation viewer
95
+ // Serve STL viewer for STL files
96
+ if (req.method === 'GET' && (req.url === '/' || req.url === '/index.html') && isSTL && stlTemplatePath) {
97
+ try {
98
+ let template = fs.readFileSync(stlTemplatePath, 'utf-8');
99
+ // Replace placeholders
100
+ template = template.replace(/\{\{FILE_PATH\}\}/g, fullFilePath);
101
+ template = template.replace(/\{\{FILE\}\}/g, displayPath);
102
+ res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
103
+ res.end(template);
104
+ }
105
+ catch (err) {
106
+ res.writeHead(500, { 'Content-Type': 'text/plain' });
107
+ res.end('Error loading STL viewer: ' + err.message);
108
+ }
109
+ return;
110
+ }
111
+ // Serve annotation viewer for other files
94
112
  if (req.method === 'GET' && (req.url === '/' || req.url === '/index.html')) {
95
113
  try {
96
114
  let template = fs.readFileSync(templatePath, 'utf-8');
@@ -193,6 +211,28 @@ const server = http.createServer((req, res) => {
193
211
  }
194
212
  return;
195
213
  }
214
+ // Handle STL content (GET /api/stl)
215
+ if (req.method === 'GET' && req.url?.startsWith('/api/stl')) {
216
+ if (!isSTL) {
217
+ res.writeHead(400, { 'Content-Type': 'text/plain' });
218
+ res.end('Not an STL file');
219
+ return;
220
+ }
221
+ try {
222
+ const stlData = fs.readFileSync(fullFilePath);
223
+ res.writeHead(200, {
224
+ 'Content-Type': 'model/stl',
225
+ 'Content-Length': stlData.length,
226
+ 'Cache-Control': 'no-cache'
227
+ });
228
+ res.end(stlData);
229
+ }
230
+ catch (err) {
231
+ res.writeHead(500, { 'Content-Type': 'text/plain' });
232
+ res.end('Error reading STL: ' + err.message);
233
+ }
234
+ return;
235
+ }
196
236
  // Handle file save
197
237
  if (req.method === 'POST' && req.url === '/save') {
198
238
  let body = '';
@@ -1 +1 @@
1
- {"version":3,"file":"open-server.js","sourceRoot":"","sources":["../../../src/agent-farm/servers/open-server.ts"],"names":[],"mappings":";AAEA;;;GAGG;AAEH,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;AAE3C,iCAAiC;AACjC,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE;KAC1B,IAAI,CAAC,aAAa,CAAC;KACnB,WAAW,CAAC,0CAA0C,CAAC;KACvD,QAAQ,CAAC,QAAQ,EAAE,mBAAmB,CAAC;KACvC,QAAQ,CAAC,YAAY,EAAE,mBAAmB,CAAC;KAC3C,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AAEvB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;AAC1B,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACnC,MAAM,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;AAEzB,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,KAAK,EAAE,CAAC;IAC5C,OAAO,CAAC,KAAK,CAAC,wBAAwB,IAAI,CAAC,CAAC,CAAC,0CAA0C,CAAC,CAAC;IACzF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,QAAQ;AACR,MAAM,YAAY,GAAG,QAAQ,CAAC;AAC9B,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AAE5C;;;GAGG;AACH,SAAS,gBAAgB;IACvB,MAAM,QAAQ,GAAG,WAAW,CAAC;IAE7B,2DAA2D;IAC3D,iEAAiE;IACjE,8DAA8D;IAC9D,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,qBAAqB,EAAE,QAAQ,CAAC,CAAC;IACzE,IAAI,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,OAAO,CAAC;IAE3C,MAAM,IAAI,KAAK,CAAC,uBAAuB,QAAQ,EAAE,CAAC,CAAC;AACrD,CAAC;AAED,MAAM,YAAY,GAAG,gBAAgB,EAAE,CAAC;AAExC,uBAAuB;AACvB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;IACjC,OAAO,CAAC,KAAK,CAAC,mBAAmB,YAAY,EAAE,CAAC,CAAC;IACjD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,8BAA8B;AAC9B,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;AAC1D,MAAM,OAAO,GAA2B;IACtC,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE,YAAY,EAAE,GAAG,EAAE,YAAY,EAAE,GAAG,EAAE,YAAY;IACxE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;IACtC,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,KAAK;IAC1C,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM;CACxC,CAAC;AACF,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC;AACjC,MAAM,UAAU,GAAG,GAAG,KAAK,IAAI,CAAC;AAEhC,kBAAkB;AAClB,MAAM,eAAe,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;AACrE,MAAM,OAAO,GAAG,eAAe,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;AAE9C,kBAAkB;AAClB,MAAM,eAAe,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;AACtD,MAAM,OAAO,GAAG,eAAe,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;AAE9C,+BAA+B;AAC/B,MAAM,cAAc,GAA2B;IAC7C,GAAG,EAAE,WAAW;IAChB,GAAG,EAAE,YAAY;IACjB,IAAI,EAAE,YAAY;IAClB,GAAG,EAAE,WAAW;IAChB,IAAI,EAAE,YAAY;IAClB,GAAG,EAAE,eAAe;CACrB,CAAC;AAEF,+BAA+B;AAC/B,MAAM,cAAc,GAA2B;IAC7C,IAAI,EAAE,YAAY;IAClB,GAAG,EAAE,WAAW;IAChB,GAAG,EAAE,iBAAiB;IACtB,GAAG,EAAE,iBAAiB;CACvB,CAAC;AAEF,gBAAgB;AAChB,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;IAC5C,eAAe;IACf,GAAG,CAAC,SAAS,CAAC,6BAA6B,EAAE,GAAG,CAAC,CAAC;IAClD,GAAG,CAAC,SAAS,CAAC,8BAA8B,EAAE,oBAAoB,CAAC,CAAC;IACpE,GAAG,CAAC,SAAS,CAAC,8BAA8B,EAAE,cAAc,CAAC,CAAC;IAE9D,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAC7B,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QACnB,GAAG,CAAC,GAAG,EAAE,CAAC;QACV,OAAO;IACT,CAAC;IAED,0BAA0B;IAC1B,IAAI,GAAG,CAAC,MAAM,KAAK,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,GAAG,IAAI,GAAG,CAAC,GAAG,KAAK,aAAa,CAAC,EAAE,CAAC;QAC3E,IAAI,CAAC;YACH,IAAI,QAAQ,GAAG,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;YAEtD,4BAA4B;YAC5B,MAAM,SAAS,GAAG,EAAE,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;YAC5C,MAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,CAAC;YAEhC,uBAAuB;YACvB,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,qBAAqB,EAAE,EAAE,CAAC,CAAC;YACvD,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,oBAAoB,EAAE,YAAY,CAAC,CAAC;YAChE,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,eAAe,EAAE,WAAW,CAAC,CAAC;YAC1D,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC;YACnD,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,sBAAsB,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;YACxE,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,mBAAmB,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;YAClE,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,mBAAmB,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;YAClE,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,oBAAoB,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;YAEpE,IAAI,OAAO,EAAE,CAAC;gBACZ,2EAA2E;gBAC3E,QAAQ,GAAG,QAAQ,CAAC,OAAO,CACzB,gDAAgD,EAChD,aAAa,QAAQ,IAAI,CAC1B,CAAC;YACJ,CAAC;iBAAM,IAAI,OAAO,EAAE,CAAC;gBACnB,2EAA2E;gBAC3E,QAAQ,GAAG,QAAQ,CAAC,OAAO,CACzB,gDAAgD,EAChD,aAAa,QAAQ,IAAI,CAC1B,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACN,2CAA2C;gBAC3C,MAAM,WAAW,GAAG,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;gBAC3D,iFAAiF;gBACjF,+EAA+E;gBAC/E,MAAM,cAAc,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,cAAc,EAAE,aAAa,CAAC,CAAC;gBAC1F,QAAQ,GAAG,QAAQ,CAAC,OAAO,CACzB,gDAAgD,EAChD,QAAQ,cAAc,IAAI,CAC3B,CAAC;YACJ,CAAC;YAED,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,0BAA0B,EAAE,CAAC,CAAC;YACnE,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACpB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,YAAY,EAAE,CAAC,CAAC;YACrD,GAAG,CAAC,GAAG,CAAC,wBAAwB,GAAI,GAAa,CAAC,OAAO,CAAC,CAAC;QAC7D,CAAC;QACD,OAAO;IACT,CAAC;IAED,iCAAiC;IACjC,IAAI,GAAG,CAAC,MAAM,KAAK,KAAK,IAAI,GAAG,CAAC,GAAG,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACzD,IAAI,CAAC;YACH,yBAAyB;YACzB,MAAM,WAAW,GAAG,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;YAC3D,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,2BAA2B,EAAE,CAAC,CAAC;YACpE,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACvB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,YAAY,EAAE,CAAC,CAAC;YACrD,GAAG,CAAC,GAAG,CAAC,sBAAsB,GAAI,GAAa,CAAC,OAAO,CAAC,CAAC;QAC3D,CAAC;QACD,OAAO;IACT,CAAC;IAED,wCAAwC;IACxC,qEAAqE;IACrE,IAAI,GAAG,CAAC,MAAM,KAAK,KAAK,IAAI,GAAG,CAAC,GAAG,EAAE,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC9D,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,YAAY,EAAE,CAAC,CAAC;YACrD,GAAG,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;YAC7B,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,EAAE,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;YAChD,MAAM,QAAQ,GAAG,cAAc,CAAC,GAAG,CAAC,IAAI,0BAA0B,CAAC;YACnE,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE;gBACjB,cAAc,EAAE,QAAQ;gBACxB,gBAAgB,EAAE,SAAS,CAAC,MAAM;gBAClC,eAAe,EAAE,UAAU,CAAE,oCAAoC;aAClE,CAAC,CAAC;YACH,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACrB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,YAAY,EAAE,CAAC,CAAC;YACrD,GAAG,CAAC,GAAG,CAAC,uBAAuB,GAAI,GAAa,CAAC,OAAO,CAAC,CAAC;QAC5D,CAAC;QACD,OAAO;IACT,CAAC;IAED,wCAAwC;IACxC,qEAAqE;IACrE,IAAI,GAAG,CAAC,MAAM,KAAK,KAAK,IAAI,GAAG,CAAC,GAAG,EAAE,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC9D,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,YAAY,EAAE,CAAC,CAAC;YACrD,GAAG,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;YAC5B,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,EAAE,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;YAChD,MAAM,QAAQ,GAAG,cAAc,CAAC,GAAG,CAAC,IAAI,0BAA0B,CAAC;YACnE,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE;gBACjB,cAAc,EAAE,QAAQ;gBACxB,gBAAgB,EAAE,SAAS,CAAC,MAAM;gBAClC,eAAe,EAAE,UAAU,CAAE,oCAAoC;aAClE,CAAC,CAAC;YACH,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACrB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,YAAY,EAAE,CAAC,CAAC;YACrD,GAAG,CAAC,GAAG,CAAC,uBAAuB,GAAI,GAAa,CAAC,OAAO,CAAC,CAAC;QAC5D,CAAC;QACD,OAAO;IACT,CAAC;IAED,mBAAmB;IACnB,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,IAAI,GAAG,CAAC,GAAG,KAAK,OAAO,EAAE,CAAC;QACjD,IAAI,IAAI,GAAG,EAAE,CAAC;QACd,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,IAAI,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC5D,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;YACjB,IAAI,CAAC;gBACH,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAE3C,8CAA8C;gBAC9C,IAAI,IAAI,KAAK,YAAY,EAAE,CAAC;oBAC1B,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,YAAY,EAAE,CAAC,CAAC;oBACrD,GAAG,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;oBACzC,OAAO;gBACT,CAAC;gBAED,EAAE,CAAC,aAAa,CAAC,YAAY,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;gBACjD,OAAO,CAAC,GAAG,CAAC,UAAU,YAAY,EAAE,CAAC,CAAC;gBAEtC,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC;gBAC3D,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YAC7C,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,YAAY,EAAE,CAAC,CAAC;gBACrD,GAAG,CAAC,GAAG,CAAC,qBAAqB,GAAI,GAAa,CAAC,OAAO,CAAC,CAAC;YAC1D,CAAC;QACH,CAAC,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IAED,0BAA0B;IAC1B,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,YAAY,EAAE,CAAC,CAAC;IACrD,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;AACvB,CAAC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE;IACvB,OAAO,CAAC,GAAG,CAAC,iCAAiC,IAAI,EAAE,CAAC,CAAC;IACrD,OAAO,CAAC,GAAG,CAAC,SAAS,YAAY,EAAE,CAAC,CAAC;AACvC,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"open-server.js","sourceRoot":"","sources":["../../../src/agent-farm/servers/open-server.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cluesmith/codev",
3
- "version": "1.4.10",
3
+ "version": "1.4.12",
4
4
  "description": "Codev CLI - AI-assisted software development framework",
5
5
  "type": "module",
6
6
  "bin": {
@@ -30,6 +30,7 @@ af start [options]
30
30
  - `-c, --cmd <command>` - Command to run in architect terminal
31
31
  - `-p, --port <port>` - Port for architect terminal
32
32
  - `--no-role` - Skip loading architect role prompt
33
+ - `--allow-insecure-remote` - Bind to 0.0.0.0 for remote access (see below)
33
34
 
34
35
  **Description:**
35
36
 
@@ -51,7 +52,59 @@ af start -p 4300
51
52
 
52
53
  # Start with specific command
53
54
  af start -c "claude --model opus"
55
+
56
+ # Start with remote access enabled
57
+ af start --allow-insecure-remote
58
+ ```
59
+
60
+ #### Remote Access
61
+
62
+ By default, Agent Farm binds to `localhost` (127.0.0.1), making it accessible only from the local machine. To access the dashboard from another device (e.g., a tablet, phone, or another computer on your network):
63
+
64
+ ```bash
65
+ af start --allow-insecure-remote
66
+ ```
67
+
68
+ This binds the server to `0.0.0.0`, making it accessible from any network interface.
69
+
70
+ **Finding your machine's IP:**
71
+ ```bash
72
+ # macOS
73
+ ipconfig getifaddr en0 # WiFi
74
+ ipconfig getifaddr en1 # Ethernet
75
+
76
+ # Linux
77
+ hostname -I | awk '{print $1}'
78
+ ```
79
+
80
+ **Accessing remotely:**
54
81
  ```
82
+ http://<your-ip>:4200
83
+ ```
84
+
85
+ **⚠️ Security Warning:**
86
+
87
+ The `--allow-insecure-remote` flag provides **no authentication**. Anyone on your network can:
88
+ - View and interact with all terminals
89
+ - Execute commands as your user
90
+ - Access and modify your code
91
+
92
+ **Only use this on trusted networks** (home WiFi, isolated development networks). Never use on:
93
+ - Public WiFi (coffee shops, airports)
94
+ - Shared office networks without VPN
95
+ - Any network with untrusted users
96
+
97
+ **For secure remote access**, consider:
98
+ 1. **SSH tunneling** (recommended):
99
+ ```bash
100
+ # On remote machine, tunnel to your dev machine
101
+ ssh -L 4200:localhost:4200 user@your-dev-machine
102
+ # Then open http://localhost:4200 on the remote machine
103
+ ```
104
+
105
+ 2. **VPN** - Access your home/office network securely
106
+
107
+ 3. **Tailscale/ZeroTier** - Mesh VPN for secure device-to-device connections
55
108
 
56
109
  ---
57
110
 
@@ -0,0 +1,473 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>{{FILE}} - STL Viewer</title>
7
+ <style>
8
+ * {
9
+ margin: 0;
10
+ padding: 0;
11
+ box-sizing: border-box;
12
+ }
13
+
14
+ body {
15
+ background: #1a1a2e;
16
+ color: #e0e0e0;
17
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
18
+ overflow: hidden;
19
+ height: 100vh;
20
+ display: flex;
21
+ flex-direction: column;
22
+ }
23
+
24
+ #header {
25
+ background: #16213e;
26
+ padding: 8px 16px;
27
+ display: flex;
28
+ align-items: center;
29
+ justify-content: space-between;
30
+ border-bottom: 1px solid #0f3460;
31
+ flex-shrink: 0;
32
+ }
33
+
34
+ #filename {
35
+ font-size: 14px;
36
+ color: #94a3b8;
37
+ }
38
+
39
+ #info {
40
+ font-size: 12px;
41
+ color: #64748b;
42
+ }
43
+
44
+ #controls {
45
+ display: flex;
46
+ gap: 8px;
47
+ align-items: center;
48
+ }
49
+
50
+ .control-group {
51
+ display: flex;
52
+ gap: 4px;
53
+ padding: 0 8px;
54
+ border-right: 1px solid #0f3460;
55
+ }
56
+
57
+ .control-group:last-child {
58
+ border-right: none;
59
+ }
60
+
61
+ .control-label {
62
+ font-size: 10px;
63
+ color: #64748b;
64
+ margin-right: 4px;
65
+ align-self: center;
66
+ }
67
+
68
+ button {
69
+ background: #0f3460;
70
+ color: #e0e0e0;
71
+ border: 1px solid #1e4976;
72
+ padding: 4px 8px;
73
+ border-radius: 4px;
74
+ cursor: pointer;
75
+ font-size: 11px;
76
+ transition: background 0.2s;
77
+ min-width: 28px;
78
+ }
79
+
80
+ button:hover {
81
+ background: #1e4976;
82
+ }
83
+
84
+ button.active {
85
+ background: #2563eb;
86
+ border-color: #3b82f6;
87
+ }
88
+
89
+ button.view-btn {
90
+ font-family: monospace;
91
+ font-weight: bold;
92
+ }
93
+
94
+ button.view-btn.positive {
95
+ color: #4ade80;
96
+ }
97
+
98
+ button.view-btn.negative {
99
+ color: #f87171;
100
+ }
101
+
102
+ #canvas-container {
103
+ flex: 1;
104
+ position: relative;
105
+ }
106
+
107
+ #canvas {
108
+ display: block;
109
+ width: 100%;
110
+ height: 100%;
111
+ }
112
+
113
+ #loading {
114
+ position: absolute;
115
+ top: 50%;
116
+ left: 50%;
117
+ transform: translate(-50%, -50%);
118
+ text-align: center;
119
+ color: #94a3b8;
120
+ }
121
+
122
+ #loading .spinner {
123
+ width: 40px;
124
+ height: 40px;
125
+ border: 3px solid #0f3460;
126
+ border-top-color: #3b82f6;
127
+ border-radius: 50%;
128
+ animation: spin 1s linear infinite;
129
+ margin: 0 auto 12px;
130
+ }
131
+
132
+ @keyframes spin {
133
+ to { transform: rotate(360deg); }
134
+ }
135
+
136
+ #error {
137
+ position: absolute;
138
+ top: 50%;
139
+ left: 50%;
140
+ transform: translate(-50%, -50%);
141
+ text-align: center;
142
+ color: #ef4444;
143
+ display: none;
144
+ }
145
+
146
+ .hidden {
147
+ display: none !important;
148
+ }
149
+
150
+ /* Axes legend */
151
+ #axes-legend {
152
+ position: absolute;
153
+ bottom: 16px;
154
+ left: 16px;
155
+ background: rgba(22, 33, 62, 0.9);
156
+ padding: 8px 12px;
157
+ border-radius: 4px;
158
+ font-size: 11px;
159
+ font-family: monospace;
160
+ }
161
+
162
+ #axes-legend div {
163
+ margin: 2px 0;
164
+ }
165
+
166
+ .axis-x { color: #ef4444; }
167
+ .axis-y { color: #22c55e; }
168
+ .axis-z { color: #3b82f6; }
169
+ </style>
170
+ </head>
171
+ <body>
172
+ <div id="header">
173
+ <div>
174
+ <span id="filename">{{FILE}}</span>
175
+ <span id="info"></span>
176
+ </div>
177
+ <div id="controls">
178
+ <div class="control-group">
179
+ <span class="control-label">View:</span>
180
+ <button id="viewTop" class="view-btn positive" title="Top (+Y)">+Y</button>
181
+ <button id="viewBottom" class="view-btn negative" title="Bottom (-Y)">-Y</button>
182
+ <button id="viewFront" class="view-btn positive" title="Front (+Z)">+Z</button>
183
+ <button id="viewBack" class="view-btn negative" title="Back (-Z)">-Z</button>
184
+ <button id="viewRight" class="view-btn positive" title="Right (+X)">+X</button>
185
+ <button id="viewLeft" class="view-btn negative" title="Left (-X)">-X</button>
186
+ </div>
187
+ <div class="control-group">
188
+ <button id="viewIso" title="Isometric view">Iso</button>
189
+ <button id="resetBtn" title="Fit model to view">Fit</button>
190
+ </div>
191
+ <div class="control-group">
192
+ <button id="wireframeBtn" title="Toggle wireframe mode">Wire</button>
193
+ <button id="axesBtn" class="active" title="Toggle axes">Axes</button>
194
+ <button id="gridBtn" class="active" title="Toggle grid">Grid</button>
195
+ </div>
196
+ </div>
197
+ </div>
198
+
199
+ <div id="canvas-container">
200
+ <canvas id="canvas"></canvas>
201
+ <div id="loading">
202
+ <div class="spinner"></div>
203
+ <div>Loading STL...</div>
204
+ </div>
205
+ <div id="error">
206
+ <div style="font-size: 48px; margin-bottom: 12px;">⚠️</div>
207
+ <div id="error-message">Failed to load STL file</div>
208
+ </div>
209
+ <div id="axes-legend">
210
+ <div class="axis-x">X → Right</div>
211
+ <div class="axis-y">Y → Up</div>
212
+ <div class="axis-z">Z → Front</div>
213
+ </div>
214
+ </div>
215
+
216
+ <!-- Three.js from CDN (using r128 which has global builds) -->
217
+ <script src="https://cdn.jsdelivr.net/npm/three@0.128.0/build/three.min.js"></script>
218
+ <script src="https://cdn.jsdelivr.net/npm/three@0.128.0/examples/js/loaders/STLLoader.js"></script>
219
+ <script src="https://cdn.jsdelivr.net/npm/three@0.128.0/examples/js/controls/OrbitControls.js"></script>
220
+
221
+ <script>
222
+ // Configuration
223
+ const FILE_PATH = '{{FILE_PATH}}';
224
+ const FILE_NAME = '{{FILE}}';
225
+
226
+ // Three.js setup
227
+ let scene, camera, renderer, controls, mesh;
228
+ let axesHelper, gridHelper;
229
+ let wireframeMode = false;
230
+ let showAxes = true;
231
+ let showGrid = true;
232
+ let modelCenter = new THREE.Vector3();
233
+ let cameraDistance = 100;
234
+
235
+ // DOM elements
236
+ const canvas = document.getElementById('canvas');
237
+ const container = document.getElementById('canvas-container');
238
+ const loading = document.getElementById('loading');
239
+ const error = document.getElementById('error');
240
+ const errorMessage = document.getElementById('error-message');
241
+ const info = document.getElementById('info');
242
+
243
+ // Buttons
244
+ const resetBtn = document.getElementById('resetBtn');
245
+ const wireframeBtn = document.getElementById('wireframeBtn');
246
+ const axesBtn = document.getElementById('axesBtn');
247
+ const gridBtn = document.getElementById('gridBtn');
248
+ const viewTop = document.getElementById('viewTop');
249
+ const viewBottom = document.getElementById('viewBottom');
250
+ const viewFront = document.getElementById('viewFront');
251
+ const viewBack = document.getElementById('viewBack');
252
+ const viewRight = document.getElementById('viewRight');
253
+ const viewLeft = document.getElementById('viewLeft');
254
+ const viewIso = document.getElementById('viewIso');
255
+
256
+ function init() {
257
+ // Scene
258
+ scene = new THREE.Scene();
259
+ scene.background = new THREE.Color(0x1a1a2e);
260
+
261
+ // Camera
262
+ camera = new THREE.PerspectiveCamera(
263
+ 45,
264
+ container.clientWidth / container.clientHeight,
265
+ 0.1,
266
+ 10000
267
+ );
268
+ camera.position.set(100, 100, 100);
269
+
270
+ // Renderer
271
+ renderer = new THREE.WebGLRenderer({ canvas, antialias: true });
272
+ renderer.setSize(container.clientWidth, container.clientHeight);
273
+ renderer.setPixelRatio(window.devicePixelRatio);
274
+
275
+ // Controls
276
+ controls = new THREE.OrbitControls(camera, renderer.domElement);
277
+ controls.enableDamping = true;
278
+ controls.dampingFactor = 0.1;
279
+ controls.screenSpacePanning = true;
280
+
281
+ // Lighting
282
+ const ambientLight = new THREE.AmbientLight(0x404040, 0.5);
283
+ scene.add(ambientLight);
284
+
285
+ const directionalLight1 = new THREE.DirectionalLight(0xffffff, 0.8);
286
+ directionalLight1.position.set(1, 1, 1);
287
+ scene.add(directionalLight1);
288
+
289
+ const directionalLight2 = new THREE.DirectionalLight(0xffffff, 0.4);
290
+ directionalLight2.position.set(-1, -1, -1);
291
+ scene.add(directionalLight2);
292
+
293
+ // Grid
294
+ gridHelper = new THREE.GridHelper(200, 20, 0x0f3460, 0x0f3460);
295
+ scene.add(gridHelper);
296
+
297
+ // Axes helper (X=red, Y=green, Z=blue)
298
+ axesHelper = new THREE.AxesHelper(50);
299
+ scene.add(axesHelper);
300
+
301
+ // Load STL
302
+ loadSTL();
303
+
304
+ // Event listeners
305
+ window.addEventListener('resize', onResize);
306
+
307
+ // Control buttons
308
+ resetBtn.addEventListener('click', fitToView);
309
+ wireframeBtn.addEventListener('click', toggleWireframe);
310
+ axesBtn.addEventListener('click', toggleAxes);
311
+ gridBtn.addEventListener('click', toggleGrid);
312
+
313
+ // View buttons
314
+ viewTop.addEventListener('click', () => setView(0, 1, 0));
315
+ viewBottom.addEventListener('click', () => setView(0, -1, 0));
316
+ viewFront.addEventListener('click', () => setView(0, 0, 1));
317
+ viewBack.addEventListener('click', () => setView(0, 0, -1));
318
+ viewRight.addEventListener('click', () => setView(1, 0, 0));
319
+ viewLeft.addEventListener('click', () => setView(-1, 0, 0));
320
+ viewIso.addEventListener('click', () => setView(1, 1, 1));
321
+
322
+ // Animation loop
323
+ animate();
324
+ }
325
+
326
+ function loadSTL() {
327
+ const loader = new THREE.STLLoader();
328
+
329
+ // Load from API endpoint
330
+ loader.load(
331
+ '/api/stl',
332
+ (geometry) => {
333
+ // Center geometry
334
+ geometry.computeBoundingBox();
335
+ const center = new THREE.Vector3();
336
+ geometry.boundingBox.getCenter(center);
337
+ geometry.translate(-center.x, -center.y, -center.z);
338
+
339
+ // Move to sit on grid (optional - comment out to keep centered)
340
+ const minY = geometry.boundingBox.min.y - center.y;
341
+ geometry.translate(0, -minY, 0);
342
+
343
+ // Recalculate bounding box after translation
344
+ geometry.computeBoundingBox();
345
+
346
+ // Material
347
+ const material = new THREE.MeshPhongMaterial({
348
+ color: 0x3b82f6,
349
+ specular: 0x111111,
350
+ shininess: 30,
351
+ flatShading: false
352
+ });
353
+
354
+ mesh = new THREE.Mesh(geometry, material);
355
+ scene.add(mesh);
356
+
357
+ // Calculate model center and size
358
+ const box = new THREE.Box3().setFromObject(mesh);
359
+ box.getCenter(modelCenter);
360
+ const size = box.getSize(new THREE.Vector3());
361
+ cameraDistance = Math.max(size.x, size.y, size.z) * 2;
362
+
363
+ // Scale grid and axes to model size
364
+ const maxDim = Math.max(size.x, size.y, size.z);
365
+ const gridSize = Math.ceil(maxDim * 2 / 10) * 10; // Round up to nearest 10
366
+ scene.remove(gridHelper);
367
+ gridHelper = new THREE.GridHelper(gridSize, gridSize / 5, 0x0f3460, 0x0f3460);
368
+ scene.add(gridHelper);
369
+
370
+ scene.remove(axesHelper);
371
+ axesHelper = new THREE.AxesHelper(gridSize / 2);
372
+ scene.add(axesHelper);
373
+
374
+ // Fit camera to model
375
+ fitToView();
376
+
377
+ // Update info
378
+ const triangles = geometry.attributes.position.count / 3;
379
+ info.textContent = ` — ${triangles.toLocaleString()} triangles`;
380
+
381
+ // Hide loading
382
+ loading.classList.add('hidden');
383
+ },
384
+ (progress) => {
385
+ // Progress callback (optional)
386
+ },
387
+ (err) => {
388
+ console.error('Error loading STL:', err);
389
+ loading.classList.add('hidden');
390
+ error.style.display = 'block';
391
+ errorMessage.textContent = 'Failed to load STL file: ' + (err.message || 'Unknown error');
392
+ }
393
+ );
394
+ }
395
+
396
+ function fitToView() {
397
+ if (!mesh) return;
398
+
399
+ const box = new THREE.Box3().setFromObject(mesh);
400
+ const size = box.getSize(new THREE.Vector3());
401
+ const center = box.getCenter(new THREE.Vector3());
402
+
403
+ const maxDim = Math.max(size.x, size.y, size.z);
404
+ const fov = camera.fov * (Math.PI / 180);
405
+ cameraDistance = maxDim / (2 * Math.tan(fov / 2)) * 1.5;
406
+
407
+ // Isometric view
408
+ setView(1, 1, 1);
409
+ }
410
+
411
+ function setView(x, y, z) {
412
+ if (!mesh) return;
413
+
414
+ const box = new THREE.Box3().setFromObject(mesh);
415
+ const center = box.getCenter(new THREE.Vector3());
416
+
417
+ // Normalize direction
418
+ const dir = new THREE.Vector3(x, y, z).normalize();
419
+
420
+ // Set camera position
421
+ camera.position.copy(center).add(dir.multiplyScalar(cameraDistance));
422
+
423
+ // Set up vector (handle top/bottom views)
424
+ if (Math.abs(y) > 0.9) {
425
+ camera.up.set(0, 0, y > 0 ? -1 : 1);
426
+ } else {
427
+ camera.up.set(0, 1, 0);
428
+ }
429
+
430
+ // Look at center
431
+ controls.target.copy(center);
432
+ camera.lookAt(center);
433
+ controls.update();
434
+ }
435
+
436
+ function toggleWireframe() {
437
+ wireframeMode = !wireframeMode;
438
+ if (mesh) {
439
+ mesh.material.wireframe = wireframeMode;
440
+ }
441
+ wireframeBtn.classList.toggle('active', wireframeMode);
442
+ }
443
+
444
+ function toggleAxes() {
445
+ showAxes = !showAxes;
446
+ axesHelper.visible = showAxes;
447
+ axesBtn.classList.toggle('active', showAxes);
448
+ document.getElementById('axes-legend').style.display = showAxes ? 'block' : 'none';
449
+ }
450
+
451
+ function toggleGrid() {
452
+ showGrid = !showGrid;
453
+ gridHelper.visible = showGrid;
454
+ gridBtn.classList.toggle('active', showGrid);
455
+ }
456
+
457
+ function onResize() {
458
+ camera.aspect = container.clientWidth / container.clientHeight;
459
+ camera.updateProjectionMatrix();
460
+ renderer.setSize(container.clientWidth, container.clientHeight);
461
+ }
462
+
463
+ function animate() {
464
+ requestAnimationFrame(animate);
465
+ controls.update();
466
+ renderer.render(scene, camera);
467
+ }
468
+
469
+ // Start
470
+ init();
471
+ </script>
472
+ </body>
473
+ </html>