@houwert/conductor 0.27.0 → 0.27.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.
@@ -7,11 +7,13 @@ exports.parseFlowFile = parseFlowFile;
7
7
  exports.parseFlowString = parseFlowString;
8
8
  exports.executeFlow = executeFlow;
9
9
  exports.resolvePoint = resolvePoint;
10
+ exports.resolvePath = resolvePath;
10
11
  /**
11
12
  * Native Conductor YAML flow parser and executor.
12
13
  * Parses flow YAML files and executes commands directly using IOSDriver / AndroidDriver.
13
14
  */
14
15
  const promises_1 = __importDefault(require("fs/promises"));
16
+ const node_fs_1 = require("node:fs");
15
17
  const path_1 = __importDefault(require("path"));
16
18
  const node_vm_1 = __importDefault(require("node:vm"));
17
19
  const js_yaml_1 = __importDefault(require("js-yaml"));
@@ -1368,8 +1370,72 @@ async function executeCommandBody(key, val, driver, opts) {
1368
1370
  }
1369
1371
  }
1370
1372
  // ── Utilities ─────────────────────────────────────────────────────────────────
1373
+ // Resolve a `file:` reference from within a flow. A path starting with `@` is an
1374
+ // alias of the form `@name/rest`, where `name` maps to a directory declared under
1375
+ // `paths:` in the nearest `config.yaml`. Everything else keeps the historical
1376
+ // behavior: resolved relative to the flow file's directory (`cwd`).
1377
+ // Mirrors the plexinc/maestro FlowPathResolver.
1371
1378
  function resolvePath(filePath, cwd) {
1372
- return path_1.default.isAbsolute(filePath) ? filePath : path_1.default.join(cwd ?? process.cwd(), filePath);
1379
+ const base = cwd ?? process.cwd();
1380
+ if (filePath.startsWith('@'))
1381
+ return resolvePathAlias(filePath, base);
1382
+ return path_1.default.isAbsolute(filePath) ? filePath : path_1.default.join(base, filePath);
1383
+ }
1384
+ const CONFIG_FILE_NAMES = ['config.yaml', 'config.yml'];
1385
+ // Cache discovered config → paths map for the process lifetime (flows are short-lived).
1386
+ const configPathsCache = new Map();
1387
+ function resolvePathAlias(requestedPath, startDir) {
1388
+ const body = requestedPath.slice(1);
1389
+ const separator = body.indexOf('/');
1390
+ const alias = separator >= 0 ? body.slice(0, separator) : body;
1391
+ const remainder = separator >= 0 ? body.slice(separator + 1) : '';
1392
+ const configPath = findWorkspaceConfig(startDir);
1393
+ if (!configPath) {
1394
+ throw new Error(`Path alias '@${alias}' used but no config.yaml was found in any parent directory. ` +
1395
+ 'Declare aliases under `paths:` in a workspace config.yaml.');
1396
+ }
1397
+ const paths = readWorkspacePaths(configPath);
1398
+ const target = paths[alias];
1399
+ if (target === undefined) {
1400
+ const known = Object.keys(paths).sort();
1401
+ throw new Error(`Unknown path alias '@${alias}' referenced in a flow. ` +
1402
+ `Known aliases in ${configPath}: [${known.join(', ')}]`);
1403
+ }
1404
+ const configDir = path_1.default.dirname(path_1.default.resolve(configPath));
1405
+ const targetDir = path_1.default.normalize(path_1.default.resolve(configDir, target));
1406
+ if (!(0, node_fs_1.existsSync)(targetDir) || !(0, node_fs_1.statSync)(targetDir).isDirectory()) {
1407
+ throw new Error(`Path alias '@${alias}' points to '${targetDir}', which is not an existing directory.`);
1408
+ }
1409
+ return path_1.default.normalize(path_1.default.resolve(targetDir, remainder));
1410
+ }
1411
+ function findWorkspaceConfig(startDir) {
1412
+ let dir = path_1.default.resolve(startDir);
1413
+ while (dir) {
1414
+ for (const name of CONFIG_FILE_NAMES) {
1415
+ const candidate = path_1.default.join(dir, name);
1416
+ if ((0, node_fs_1.existsSync)(candidate))
1417
+ return candidate;
1418
+ }
1419
+ const parent = path_1.default.dirname(dir);
1420
+ dir = parent === dir ? null : parent;
1421
+ }
1422
+ return null;
1423
+ }
1424
+ function readWorkspacePaths(configPath) {
1425
+ const cached = configPathsCache.get(configPath);
1426
+ if (cached)
1427
+ return cached;
1428
+ let paths = {};
1429
+ try {
1430
+ const doc = js_yaml_1.default.load((0, node_fs_1.readFileSync)(configPath, 'utf-8'));
1431
+ if (doc && typeof doc.paths === 'object' && doc.paths)
1432
+ paths = doc.paths;
1433
+ }
1434
+ catch {
1435
+ // A malformed config leaves aliases unresolved; the unknown-alias error below is clearer.
1436
+ }
1437
+ configPathsCache.set(configPath, paths);
1438
+ return paths;
1373
1439
  }
1374
1440
  function resolveAppId(val, cmdName) {
1375
1441
  if (typeof val === 'string' && val)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@houwert/conductor",
3
- "version": "0.27.0",
3
+ "version": "0.27.1",
4
4
  "description": "CLI tool for mobile app interactions — optimized for AI agents",
5
5
  "license": "MIT",
6
6
  "repository": {