framer-dalton 0.0.12 → 0.0.13

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.
package/dist/cli.js CHANGED
@@ -10,7 +10,7 @@ import { z } from 'zod';
10
10
  import { fileURLToPath } from 'url';
11
11
  import { createTRPCClient, httpLink } from '@trpc/client';
12
12
 
13
- /* @framer/ai CLI v0.0.12 */
13
+ /* @framer/ai CLI v0.0.13 */
14
14
  var __defProp = Object.defineProperty;
15
15
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
16
16
  function openUrl(url) {
@@ -134,11 +134,10 @@ function extractProjectId(input) {
134
134
  if (/^[a-zA-Z0-9]+$/.test(input)) {
135
135
  return input;
136
136
  }
137
- const match = input.match(/\/projects\/[^/]+--([a-zA-Z0-9]+)/);
138
- if (match) {
139
- return match[1];
140
- }
141
- const slugMatch = input.match(/^(?:.+--)?([a-zA-Z0-9]+)(?:-[a-zA-Z0-9]+)?$/);
137
+ const candidate = input.match(/\/projects\/([^/?#]+)/)?.[1] ?? input;
138
+ const slugMatch = candidate.match(
139
+ /^(?:.+--)?([a-zA-Z0-9]+)(?:-[a-zA-Z0-9]+)?$/
140
+ );
142
141
  if (slugMatch) {
143
142
  return slugMatch[1];
144
143
  }
@@ -313,20 +312,30 @@ __name(parseCode, "parseCode");
313
312
  async function acquireKeyFromBrowser(projectId) {
314
313
  const state = crypto.randomBytes(16).toString("hex");
315
314
  return new Promise((resolve, reject) => {
316
- let pendingResult = null;
315
+ let settled = false;
316
+ let pendingApiKey = null;
317
+ function settle(fn) {
318
+ if (settled) return;
319
+ settled = true;
320
+ cleanup();
321
+ fn();
322
+ }
323
+ __name(settle, "settle");
317
324
  const server = http.createServer((req, res) => {
318
325
  const url = new URL(req.url ?? "/", `http://127.0.0.1`);
319
326
  if (url.pathname === "/done") {
320
327
  const theme2 = parseTheme(url.searchParams.get("theme"));
321
328
  res.writeHead(200, { "Content-Type": "text/html" });
322
- res.end(successHtml(theme2));
323
- if (pendingResult) {
324
- const { apiKey: apiKey2 } = pendingResult;
325
- pendingResult = null;
326
- cleanup();
327
- print("\u2713 Agent authorized");
328
- resolve(apiKey2);
329
- }
329
+ res.end(successHtml(theme2), () => {
330
+ if (pendingApiKey) {
331
+ const apiKey2 = pendingApiKey;
332
+ pendingApiKey = null;
333
+ settle(() => {
334
+ print("\u2713 Agent authorized");
335
+ resolve(apiKey2);
336
+ });
337
+ }
338
+ });
330
339
  return;
331
340
  }
332
341
  if (url.pathname === "/error") {
@@ -346,9 +355,9 @@ async function acquireKeyFromBrowser(projectId) {
346
355
  const code = parseCode(url.searchParams.get("code")) ?? legacyCode;
347
356
  if (code !== null) {
348
357
  res.writeHead(200, { "Content-Type": "text/html" });
349
- res.end(codeHtml(code, theme));
350
- cleanup();
351
- reject(new Error(codeMessages[code]));
358
+ res.end(codeHtml(code, theme), () => {
359
+ settle(() => reject(new Error(codeMessages[code])));
360
+ });
352
361
  return;
353
362
  }
354
363
  const apiKey = url.searchParams.get("apiKey");
@@ -358,7 +367,7 @@ async function acquireKeyFromBrowser(projectId) {
358
367
  res.end();
359
368
  return;
360
369
  }
361
- pendingResult = { apiKey, theme };
370
+ pendingApiKey = apiKey;
362
371
  res.writeHead(302, { Location: `/done?theme=${theme}` });
363
372
  res.end();
364
373
  });
@@ -366,9 +375,10 @@ async function acquireKeyFromBrowser(projectId) {
366
375
  const pollTimer = setInterval(() => {
367
376
  const apiKey = getApiKey(projectId);
368
377
  if (apiKey) {
369
- cleanup();
370
- print("\u2713 API key detected from config");
371
- resolve(apiKey);
378
+ settle(() => {
379
+ print("\u2713 API key detected from config");
380
+ resolve(apiKey);
381
+ });
372
382
  }
373
383
  }, POLL_INTERVAL_MS);
374
384
  const HINT_MS = 55e3;
@@ -385,25 +395,31 @@ async function acquireKeyFromBrowser(projectId) {
385
395
  print("Waiting for authorization in browser...");
386
396
  }, HINT_MS);
387
397
  const timer = setTimeout(() => {
388
- cleanup();
389
- reject(
390
- new Error(
391
- "Browser authorization timed out. Use `framer project auth <projectUrlOrId> <apiKey>` instead."
398
+ settle(
399
+ () => reject(
400
+ new Error(
401
+ "Browser authorization timed out. Use `framer project auth <projectUrlOrId> <apiKey>` instead."
402
+ )
392
403
  )
393
404
  );
394
405
  }, TIMEOUT_MS);
406
+ let cleaned = false;
395
407
  function cleanup() {
408
+ if (cleaned) return;
409
+ cleaned = true;
396
410
  clearTimeout(timer);
397
411
  clearTimeout(hintTimer);
398
412
  clearInterval(pollTimer);
399
413
  server.close();
414
+ server.closeAllConnections();
400
415
  }
401
416
  __name(cleanup, "cleanup");
402
- server.listen(0, "127.0.0.1", async () => {
417
+ server.keepAliveTimeout = 0;
418
+ server.unref();
419
+ server.listen(0, "127.0.0.1", () => {
403
420
  const addr = server.address();
404
421
  if (!addr || typeof addr === "string") {
405
- cleanup();
406
- reject(new Error("Failed to start callback server."));
422
+ settle(() => reject(new Error("Failed to start callback server.")));
407
423
  return;
408
424
  }
409
425
  const callbackUrl = `http://127.0.0.1:${addr.port}/callback`;
@@ -412,13 +428,14 @@ async function acquireKeyFromBrowser(projectId) {
412
428
  deeplink.searchParams.set("state", state);
413
429
  deeplink.searchParams.set("projectId", projectId);
414
430
  const deeplinkStr = deeplink.toString();
415
- const opened = await openUrl(deeplinkStr);
416
- if (opened) {
417
- print("Waiting for authorization in browser...");
418
- } else {
419
- printError("Could not open browser. Open this URL manually:");
420
- printError(deeplinkStr);
421
- }
431
+ openUrl(deeplinkStr).then((opened) => {
432
+ if (opened) {
433
+ print("Waiting for authorization in browser...");
434
+ } else {
435
+ printError("Could not open browser. Open this URL manually:");
436
+ printError(deeplinkStr);
437
+ }
438
+ });
422
439
  });
423
440
  });
424
441
  }
@@ -14929,7 +14946,7 @@ ${typeDef}`);
14929
14946
  __name(renderDocs, "renderDocs");
14930
14947
  var __filename$1 = fileURLToPath(import.meta.url);
14931
14948
  var __dirname$1 = path4.dirname(__filename$1);
14932
- var VERSION = "0.0.12" ;
14949
+ var VERSION = "0.0.13" ;
14933
14950
  var RELAY_PORT = Number(process.env.FRAMER_CLI_PORT) || 19988;
14934
14951
  var client = createTRPCClient({
14935
14952
  links: [
@@ -13,7 +13,7 @@ import { createRequire } from 'module';
13
13
  import * as vm from 'vm';
14
14
  import { connect } from 'framer-api';
15
15
 
16
- /* @framer/ai relay server v0.0.12 */
16
+ /* @framer/ai relay server v0.0.13 */
17
17
  var __defProp = Object.defineProperty;
18
18
  var __knownSymbol = (name, symbol) => (symbol = Symbol[name]) ? symbol : /* @__PURE__ */ Symbol.for("Symbol." + name);
19
19
  var __typeError = (msg) => {
@@ -91,7 +91,7 @@ function log(message) {
91
91
  __name(log, "log");
92
92
  var __filename$1 = fileURLToPath(import.meta.url);
93
93
  path.dirname(__filename$1);
94
- var VERSION = "0.0.12" ;
94
+ var VERSION = "0.0.13" ;
95
95
  var RELAY_PORT = Number(process.env.FRAMER_CLI_PORT) || 19988;
96
96
  createTRPCClient({
97
97
  links: [
@@ -796,6 +796,7 @@ var appRouter = t.router({
796
796
  error: "Failed to get connection for session"
797
797
  };
798
798
  }
799
+ const start = performance.now();
799
800
  const result = await executeWithReconnect(
800
801
  session,
801
802
  framer,
@@ -804,8 +805,11 @@ var appRouter = t.router({
804
805
  () => sessionManager.reconnect(session),
805
806
  execId
806
807
  );
808
+ const elapsed = (performance.now() - start).toFixed(0);
807
809
  if (result.error) {
808
- log(`exec.error ${tag} error="${result.error}"`);
810
+ log(`exec.error ${tag} ${elapsed}ms error="${result.error}"`);
811
+ } else {
812
+ log(`exec.done ${tag} ${elapsed}ms`);
809
813
  }
810
814
  return result;
811
815
  } catch (_) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "framer-dalton",
3
- "version": "0.0.12",
3
+ "version": "0.0.13",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "framer-dalton": "./dist/cli.js"