@await-widget/runtime 0.0.48 → 0.0.49

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 (2) hide show
  1. package/bin/await-widget.js +22 -57
  2. package/package.json +1 -1
@@ -25,7 +25,6 @@ const crcTable = makeCrcTable();
25
25
  const bridgeInfoDirectory = '.await';
26
26
  const bridgeInfoFileName = 'bridge.json';
27
27
  const singleWidgetPath = '.';
28
- const widgetDirectoryError = 'Run await-widget from a package root or first-level widget folder whose package.json includes @await-widget/runtime.';
29
28
 
30
29
  function main() {
31
30
  const options = parseArgs(process.argv.slice(2));
@@ -139,16 +138,15 @@ function parseAppArgs(args) {
139
138
  }
140
139
 
141
140
  async function startWorkspaceServer(options) {
142
- let roots;
141
+ const workspaceRoot = process.cwd();
142
+ let widgetRoot;
143
143
  try {
144
- roots = await resolveWidgetServerRoots(process.cwd());
144
+ widgetRoot = await selectWidgetRoot(workspaceRoot);
145
145
  } catch (error) {
146
146
  console.error(error.message);
147
147
  process.exit(1);
148
148
  }
149
149
 
150
- const {packageRoot, widgetRoot} = roots;
151
-
152
150
  const token = crypto.randomBytes(6).toString('hex');
153
151
  const bridge = createBridgeState(widgetRoot);
154
152
  const server = http.createServer((request, response) => {
@@ -162,7 +160,7 @@ async function startWorkspaceServer(options) {
162
160
  server.listen(options.port, '0.0.0.0', () => {
163
161
  const address = server.address();
164
162
  const port = typeof address === 'object' && address ? address.port : options.port;
165
- writeBridgeInfo(packageRoot, port, token);
163
+ writeBridgeInfo(workspaceRoot, port, token);
166
164
  console.log(`Await computer connection serving ${widgetRoot}`);
167
165
  printServerUrls(port, token);
168
166
  console.log('Press Ctrl+C to stop.');
@@ -387,51 +385,29 @@ function widgetPathKey(widgets) {
387
385
  return widgets.map(widget => widget.path).sort((left, right) => left.localeCompare(right)).join('\n');
388
386
  }
389
387
 
390
- function findPackageRoot(start) {
388
+ function findBridgeRoot(start) {
391
389
  let current = path.resolve(start);
392
390
  while (true) {
393
- const candidate = path.join(current, 'package.json');
394
- if (fs.existsSync(candidate)) {
391
+ if (fs.existsSync(bridgeInfoPath(current))) {
395
392
  return current;
396
393
  }
397
394
 
398
395
  const parent = path.dirname(current);
399
396
  if (parent === current) {
400
- return null;
397
+ throw new Error('Cannot find Await bridge info. Run npx await-widget first.');
401
398
  }
402
399
 
403
400
  current = parent;
404
401
  }
405
402
  }
406
403
 
407
- async function resolveWidgetServerRoots(start) {
408
- const widgetRoot = path.resolve(start);
409
- const packageRoot = findPackageRoot(widgetRoot);
410
- if (
411
- !packageRoot
412
- || !hasRuntimeDependency(packageRoot)
413
- ) {
414
- throw new Error(widgetDirectoryError);
415
- }
416
-
417
- if (packageRoot === widgetRoot) {
418
- return {packageRoot, widgetRoot: await selectWidgetRoot(packageRoot)};
419
- }
420
-
421
- if (path.dirname(widgetRoot) !== packageRoot || !isValidTopLevelName(path.basename(widgetRoot))) {
422
- throw new Error(widgetDirectoryError);
423
- }
424
-
425
- return {packageRoot, widgetRoot};
426
- }
427
-
428
- function selectWidgetRoot(packageRoot) {
404
+ function selectWidgetRoot(directory) {
429
405
  const options = [
430
- {name: `${path.basename(packageRoot)} (root)`, path: packageRoot},
431
- ...fs.readdirSync(packageRoot, {withFileTypes: true})
432
- .filter(entry => entry.isDirectory() && isValidTopLevelName(entry.name))
406
+ {name: `${path.basename(directory)} (current directory)`, path: directory},
407
+ ...fs.readdirSync(directory, {withFileTypes: true})
408
+ .filter(entry => entry.isDirectory() && isSelectableDirectoryName(entry.name))
433
409
  .sort((left, right) => left.name.localeCompare(right.name))
434
- .map(entry => ({name: entry.name, path: path.join(packageRoot, entry.name)})),
410
+ .map(entry => ({name: entry.name, path: path.join(directory, entry.name)})),
435
411
  ];
436
412
  let selected = 0;
437
413
  let rendered = false;
@@ -479,11 +455,6 @@ function selectWidgetRoot(packageRoot) {
479
455
  });
480
456
  }
481
457
 
482
- function hasRuntimeDependency(packageRoot) {
483
- const manifest = JSON.parse(fs.readFileSync(path.join(packageRoot, 'package.json'), 'utf8'));
484
- return Boolean(manifest.dependencies?.['@await-widget/runtime'] ?? manifest.devDependencies?.['@await-widget/runtime']);
485
- }
486
-
487
458
  function listDesktopWidgets(root) {
488
459
  return [{name: path.basename(root), path: singleWidgetPath}];
489
460
  }
@@ -518,7 +489,7 @@ function safeWidgetPath(root, widgetPath, options = {}) {
518
489
  return root;
519
490
  }
520
491
 
521
- function isValidTopLevelName(name) {
492
+ function isSelectableDirectoryName(name) {
522
493
  return Boolean(name) && !name.includes('/') && !name.includes('\\') && !isExcludedName(name);
523
494
  }
524
495
 
@@ -766,19 +737,11 @@ function resolveBridgeUrl(options) {
766
737
  return options.bridgeUrl;
767
738
  }
768
739
 
769
- const root = findPackageRoot(path.resolve(options.workspace ?? process.cwd()));
770
- if (!root) {
771
- throw new Error('Cannot find package.json for Await bridge lookup.');
772
- }
773
-
740
+ const root = findBridgeRoot(options.workspace ?? process.cwd());
774
741
  return readBridgeUrl(bridgeInfoPath(root));
775
742
  }
776
743
 
777
744
  function readBridgeUrl(infoPath) {
778
- if (!fs.existsSync(infoPath)) {
779
- throw new Error('Cannot find Await bridge info. Run npx await-widget first.');
780
- }
781
-
782
745
  const info = JSON.parse(fs.readFileSync(infoPath, 'utf8'));
783
746
  return info.bridgeUrl;
784
747
  }
@@ -812,7 +775,8 @@ function appCommandResult(options, tool, result) {
812
775
  }
813
776
 
814
777
  function saveCapture(options, result) {
815
- const root = findPackageRoot(options.workspace ? path.resolve(options.workspace) : process.cwd()) ?? process.cwd();
778
+ const workspace = path.resolve(options.workspace ?? process.cwd());
779
+ const root = options.bridgeUrl ? workspace : findBridgeRoot(workspace);
816
780
  const directory = path.join(root, bridgeInfoDirectory, 'captures');
817
781
  const name = safeCaptureFileName(String(result.widgetId ?? 'widget'));
818
782
  const filePath = path.join(directory, `${name}-${Date.now()}.png`);
@@ -1021,14 +985,15 @@ function printHelp() {
1021
985
  await-widget [--port ${defaultPort}]
1022
986
  await-widget app <command> [options]
1023
987
 
1024
- Start the Await computer connection from a package root or first-level widget
1025
- folder whose package.json includes @await-widget/runtime. Starting from the
1026
- package root opens a directory selector.
988
+ Start the Await computer connection from any directory. Choose the current
989
+ directory or one of its direct subdirectories. No package.json or runtime
990
+ dependency is required to start the connection.
1027
991
 
1028
992
  What it does:
1029
993
  - Serves the selected widget folder to Await for live sync.
1030
994
  - Prints a URL to paste into Await's Connect Computer sheet.
1031
- - Writes .await/bridge.json in the package root for app commands.
995
+ - Writes .await/bridge.json in the directory where the connection was started.
996
+ - App commands search the current directory and its parents for bridge info.
1032
997
  - Sends one-shot JSON app commands with await-widget app <command>.
1033
998
 
1034
999
  Examples:
@@ -1040,7 +1005,7 @@ Examples:
1040
1005
  npx await-widget app get-recent-widget-logs --widget-id YourWidget
1041
1006
 
1042
1007
  App command options:
1043
- --workspace <path> Read .await/bridge.json from another package/widget path.
1008
+ --workspace <path> Search this directory and its parents for .await/bridge.json.
1044
1009
  --bridge-url <url> Send directly to a bridge URL instead of reading bridge.json.
1045
1010
  --json <json> Merge raw JSON arguments into the app command.
1046
1011
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@await-widget/runtime",
3
- "version": "0.0.48",
3
+ "version": "0.0.49",
4
4
  "description": "TypeScript declarations for Await widgets.",
5
5
  "license": "MIT",
6
6
  "author": "Maundy",