@uipath/cli 1.203.0-preview.182 → 1.203.0-preview.205

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.
@@ -551,7 +551,7 @@ var package_default = {
551
551
  name: "@uipath/cli",
552
552
  author: "UiPath",
553
553
  license: "SEE LICENSE IN LICENSE.txt",
554
- version: "1.203.0-preview.182",
554
+ version: "1.203.0-preview.205",
555
555
  description: "Cross platform CLI for UiPath",
556
556
  repository: {
557
557
  type: "git",
@@ -2758,13 +2758,12 @@ async function storeMatchesVersionLine(fs, storePath, targetVersion) {
2758
2758
  const version = asRecord(marker)?.version;
2759
2759
  return typeof version === "string" && matchesCliVersionLine(version, line);
2760
2760
  }
2761
- async function readSkillDescription(fs, skillMdPath) {
2761
+ async function readSkillFrontmatter(fs, skillMdPath) {
2762
2762
  const [err, content] = await catchError(fs.readFile(skillMdPath, { encoding: "utf-8" }));
2763
2763
  if (err || !content)
2764
- return;
2765
- const head = content.length > 2048 ? content.slice(0, 2048) : content;
2766
- const { meta } = parseSkillMd(head);
2767
- return meta.description;
2764
+ return {};
2765
+ const { meta } = parseSkillMd(content);
2766
+ return meta["user-invocable"] === true ? { description: meta.description, userInvocable: true } : { description: meta.description };
2768
2767
  }
2769
2768
  var MAX_SKILL_SCAN_DEPTH = 16;
2770
2769
  async function collectSkillDirs(fs, dir, depth = 0, visited = new Set, report) {
@@ -2797,8 +2796,8 @@ async function collectSkillDirs(fs, dir, depth = 0, visited = new Set, report) {
2797
2796
  continue;
2798
2797
  const skillMdPath = fs.path.join(entryPath, "SKILL.md");
2799
2798
  if (await fs.exists(skillMdPath)) {
2800
- const description = await readSkillDescription(fs, skillMdPath);
2801
- skills.push({ name: entry, skillDir: entryPath, description });
2799
+ const frontmatter = await readSkillFrontmatter(fs, skillMdPath);
2800
+ skills.push({ name: entry, skillDir: entryPath, ...frontmatter });
2802
2801
  continue;
2803
2802
  }
2804
2803
  skills.push(...await collectSkillDirs(fs, entryPath, depth + 1, visited, report));
@@ -2910,8 +2909,13 @@ async function removeFromManifest(storePath, skillNames, agents) {
2910
2909
  }
2911
2910
  }
2912
2911
  if (manifest.extraFiles) {
2913
- for (const agent of agents)
2912
+ const remaining = Object.values(manifest.skills);
2913
+ for (const agent of agents) {
2914
+ if (remaining.some((entry) => entry.agents.includes(agent))) {
2915
+ continue;
2916
+ }
2914
2917
  delete manifest.extraFiles[agent];
2918
+ }
2915
2919
  if (Object.keys(manifest.extraFiles).length === 0) {
2916
2920
  manifest.extraFiles = undefined;
2917
2921
  }
@@ -8144,6 +8148,7 @@ var def8 = {
8144
8148
  var def9 = {
8145
8149
  localSubdir: [".opencode", "skills"],
8146
8150
  globalSubdir: [".config", "opencode", "skills"],
8151
+ commandsFolder: "commands",
8147
8152
  detect: () => verifiedCommandOnPath(["opencode"], /opencode/i, ["--help"])
8148
8153
  };
8149
8154
 
@@ -8240,10 +8245,32 @@ async function listFilesRelative(fs, dir) {
8240
8245
  await walk("");
8241
8246
  return out;
8242
8247
  }
8248
+ async function isSymlink(fs, path5) {
8249
+ const [, real] = await catchError(fs.realpath(path5));
8250
+ const [, realParent] = await catchError(fs.realpath(fs.path.dirname(path5)));
8251
+ if (!real || !realParent)
8252
+ return false;
8253
+ return real !== fs.path.join(realParent, fs.path.basename(path5));
8254
+ }
8255
+ async function entryPresent(fs, target) {
8256
+ if (await fs.exists(target))
8257
+ return true;
8258
+ const [, names] = await catchError(fs.readdir(fs.path.dirname(target)));
8259
+ return (names ?? []).includes(fs.path.basename(target));
8260
+ }
8261
+ async function mayOverwriteOwned(fs, agentRoot, rel, target, owned) {
8262
+ if (!owned.has(rel))
8263
+ return false;
8264
+ if (!await fs.exists(target))
8265
+ return false;
8266
+ return await resolveOwnedPath(fs, agentRoot, rel) !== null;
8267
+ }
8243
8268
  async function removeEmptyDirs(fs, dir) {
8244
8269
  const stats = await fs.stat(dir);
8245
8270
  if (!stats?.isDirectory())
8246
8271
  return;
8272
+ if (await isSymlink(fs, dir))
8273
+ return;
8247
8274
  for (const name of await fs.readdir(dir)) {
8248
8275
  const child = fs.path.join(dir, name);
8249
8276
  const childStats = await fs.stat(child);
@@ -8253,6 +8280,37 @@ async function removeEmptyDirs(fs, dir) {
8253
8280
  if ((await fs.readdir(dir)).length === 0)
8254
8281
  await fs.rm(dir);
8255
8282
  }
8283
+ function isSafeOwnedRel(rel) {
8284
+ const segments = rel.split("/");
8285
+ return segments.length >= 2 && segments.every((seg) => seg !== "" && seg !== "." && seg !== ".." && !seg.includes("\\") && !seg.includes(":"));
8286
+ }
8287
+ async function resolveOwnedPath(fs, agentRoot, rel) {
8288
+ if (!isSafeOwnedRel(rel)) {
8289
+ logger.debug(`Ignoring unsafe owned path in manifest: ${rel}`);
8290
+ return null;
8291
+ }
8292
+ const segments = rel.split("/");
8293
+ const target = fs.path.join(agentRoot, ...segments);
8294
+ const [, realFolder] = await catchError(fs.realpath(fs.path.join(agentRoot, segments[0])));
8295
+ const [, realParent] = await catchError(fs.realpath(fs.path.dirname(target)));
8296
+ if (!realFolder || !realParent)
8297
+ return null;
8298
+ const fromFolder = fs.path.relative(realFolder, realParent);
8299
+ if (fromFolder.split(/[\\/]/)[0] === ".." || fs.path.isAbsolute(fromFolder)) {
8300
+ logger.debug(`Ignoring owned path that leaves its folder: ${rel}`);
8301
+ return null;
8302
+ }
8303
+ if (await isSymlink(fs, target)) {
8304
+ logger.debug(`Ignoring owned path that is now a symlink: ${rel}`);
8305
+ return null;
8306
+ }
8307
+ const stats = await fs.stat(target);
8308
+ if (!stats?.isFile()) {
8309
+ logger.debug(`Ignoring owned path that is no longer a file: ${rel}`);
8310
+ return null;
8311
+ }
8312
+ return target;
8313
+ }
8256
8314
  async function installExtraFolders(agent, storePath, skillsDir, owned = []) {
8257
8315
  const extraFolders = AGENT_DEFS[agent].extraFolders ?? [];
8258
8316
  if (extraFolders.length === 0)
@@ -8261,6 +8319,7 @@ async function installExtraFolders(agent, storePath, skillsDir, owned = []) {
8261
8319
  const agentRoot = fs.path.dirname(skillsDir);
8262
8320
  const ownedSet = new Set(owned);
8263
8321
  const copied = [];
8322
+ const kept = new Set;
8264
8323
  for (const folder of extraFolders) {
8265
8324
  const source = fs.path.join(storePath, folder);
8266
8325
  if (!await fs.exists(source))
@@ -8268,8 +8327,9 @@ async function installExtraFolders(agent, storePath, skillsDir, owned = []) {
8268
8327
  for (const rel of await listFilesRelative(fs, source)) {
8269
8328
  const relFromRoot = `${folder}/${rel}`;
8270
8329
  const target = fs.path.join(agentRoot, folder, ...rel.split("/"));
8271
- if (await fs.exists(target) && !ownedSet.has(relFromRoot)) {
8330
+ if (await entryPresent(fs, target) && !await mayOverwriteOwned(fs, agentRoot, relFromRoot, target, ownedSet)) {
8272
8331
  logger.info(` ${agent}: kept existing ${relFromRoot} (not overwritten)`);
8332
+ kept.add(relFromRoot);
8273
8333
  continue;
8274
8334
  }
8275
8335
  const data = await fs.readFile(fs.path.join(source, ...rel.split("/")));
@@ -8282,10 +8342,10 @@ async function installExtraFolders(agent, storePath, skillsDir, owned = []) {
8282
8342
  }
8283
8343
  const copiedSet = new Set(copied);
8284
8344
  for (const stale of ownedSet) {
8285
- if (copiedSet.has(stale))
8345
+ if (copiedSet.has(stale) || kept.has(stale))
8286
8346
  continue;
8287
- const target = fs.path.join(agentRoot, ...stale.split("/"));
8288
- if (await fs.exists(target))
8347
+ const target = await resolveOwnedPath(fs, agentRoot, stale);
8348
+ if (target && await fs.exists(target))
8289
8349
  await fs.rm(target);
8290
8350
  }
8291
8351
  for (const folder of extraFolders) {
@@ -8293,17 +8353,81 @@ async function installExtraFolders(agent, storePath, skillsDir, owned = []) {
8293
8353
  }
8294
8354
  return copied;
8295
8355
  }
8356
+ function isCommandFile(agent, rel) {
8357
+ const folder = AGENT_DEFS[agent].commandsFolder;
8358
+ return folder !== undefined && rel.startsWith(`${folder}/`);
8359
+ }
8360
+ var SAFE_COMMAND_NAME = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
8361
+ function renderSkillCommand(skill) {
8362
+ const description = skill.description ?? `Run the ${skill.name} skill.`;
8363
+ return [
8364
+ "---",
8365
+ `description: ${JSON.stringify(description)}`,
8366
+ "---",
8367
+ "",
8368
+ `Load the \`${skill.name}\` skill with the skill tool, then follow its instructions.`,
8369
+ "",
8370
+ "$ARGUMENTS",
8371
+ ""
8372
+ ].join(`
8373
+ `);
8374
+ }
8375
+ async function installSkillCommands(agent, skills, skillsDir, owned = []) {
8376
+ const folder = AGENT_DEFS[agent].commandsFolder;
8377
+ if (folder === undefined)
8378
+ return [];
8379
+ const fs = getFileSystem();
8380
+ const agentRoot = fs.path.dirname(skillsDir);
8381
+ const ownedSet = new Set(owned);
8382
+ const written = [];
8383
+ const kept = new Set;
8384
+ for (const skill of skills) {
8385
+ if (!skill.userInvocable)
8386
+ continue;
8387
+ if (!SAFE_COMMAND_NAME.test(skill.name)) {
8388
+ logger.info(` ${agent}: no slash command for ${skill.name} (unsupported characters in name)`);
8389
+ continue;
8390
+ }
8391
+ const rel = `${folder}/${skill.name}.md`;
8392
+ const target = fs.path.join(agentRoot, folder, `${skill.name}.md`);
8393
+ if (await entryPresent(fs, target) && !await mayOverwriteOwned(fs, agentRoot, rel, target, ownedSet)) {
8394
+ logger.info(` ${agent}: kept existing ${rel} (not overwritten)`);
8395
+ kept.add(rel);
8396
+ continue;
8397
+ }
8398
+ await fs.writeFile(target, renderSkillCommand(skill));
8399
+ written.push(rel);
8400
+ }
8401
+ if (written.length > 0) {
8402
+ logger.info(` ${agent}: installed ${folder}/`);
8403
+ }
8404
+ const writtenSet = new Set(written);
8405
+ for (const stale of ownedSet) {
8406
+ if (writtenSet.has(stale) || kept.has(stale))
8407
+ continue;
8408
+ const target = await resolveOwnedPath(fs, agentRoot, stale);
8409
+ if (target && await fs.exists(target))
8410
+ await fs.rm(target);
8411
+ }
8412
+ if (ownedSet.size > 0) {
8413
+ await removeEmptyDirs(fs, fs.path.join(agentRoot, folder));
8414
+ }
8415
+ return written;
8416
+ }
8296
8417
  async function uninstallExtraFolders(skillsDir, owned) {
8297
8418
  if (owned.length === 0)
8298
8419
  return;
8299
8420
  const fs = getFileSystem();
8300
8421
  const agentRoot = fs.path.dirname(skillsDir);
8422
+ const topFolders = new Set;
8301
8423
  for (const rel of owned) {
8302
- const target = fs.path.join(agentRoot, ...rel.split("/"));
8303
- if (await fs.exists(target))
8424
+ if (!isSafeOwnedRel(rel))
8425
+ continue;
8426
+ topFolders.add(rel.split("/")[0]);
8427
+ const target = await resolveOwnedPath(fs, agentRoot, rel);
8428
+ if (target && await fs.exists(target))
8304
8429
  await fs.rm(target);
8305
8430
  }
8306
- const topFolders = new Set(owned.map((rel) => rel.split("/")[0]));
8307
8431
  for (const folder of topFolders) {
8308
8432
  await removeEmptyDirs(fs, fs.path.join(agentRoot, folder));
8309
8433
  }
@@ -8841,10 +8965,18 @@ async function runOneAgent(agent, operation, resolved) {
8841
8965
  installedNames.push(skill.name);
8842
8966
  }
8843
8967
  const [, priorOwned] = await catchError(readExtraFiles(storePath, agent));
8844
- const [extraFoldersError, extraFiles] = await catchError(installExtraFolders(agent, storePath, skillsDir, priorOwned ?? []));
8968
+ const ownedCommands = (priorOwned ?? []).filter((rel) => isCommandFile(agent, rel));
8969
+ const ownedExtra = (priorOwned ?? []).filter((rel) => !isCommandFile(agent, rel));
8970
+ const [extraFoldersError, extraFolderFiles] = await catchError(installExtraFolders(agent, storePath, skillsDir, ownedExtra));
8845
8971
  if (extraFoldersError) {
8846
8972
  return new Error(`Failed to install extra folders for ${agent}: ${extraFoldersError.message}`);
8847
8973
  }
8974
+ const installedSkills = selectedSkills.filter((s) => installedNames.includes(s.name));
8975
+ const [commandsError, commandFiles] = await catchError(installSkillCommands(agent, installedSkills, skillsDir, ownedCommands));
8976
+ if (commandsError) {
8977
+ return new Error(`Failed to install slash commands for ${agent}: ${commandsError.message}`);
8978
+ }
8979
+ const extraFiles = [...extraFolderFiles, ...commandFiles];
8848
8980
  if (isDefaultSource) {
8849
8981
  const installedSet = new Set(installedNames);
8850
8982
  const [catalogError] = await catchError(writeSkillCatalog(skillsDir, selectedSkills.filter((s) => installedSet.has(s.name)), {
@@ -9589,4 +9721,4 @@ function getManualCommandForInstallError(error, fallback) {
9589
9721
 
9590
9722
  export { package_default, VALID_CHANNELS, HIDDEN_CHANNELS, PUBLIC_CHANNELS, withConfigLock, SECRET_FIELD_PATHS, migrateVersionConfig, versionMigrationNotice, resolveConfigFilePathAsync, loadConfigAsync, resolveUpdateChannel, resolveRuntimeChannel, isPreviewVersion, isValidVersionPin, majorOf, resolvePinnedVersion, isExactPin, versionLinePrefix, formatVersionPin, dist_default5 as dist_default, dist_default6 as dist_default1, dist_default7 as dist_default2, getGlobalNpmUipathDir, DISABLE_AUTOINSTALL_ENV, DISABLE_TOOL_LINE_CHECK_ENV, InstallRefusedError, isBundledDistribution, isAutoInstallDisabled, isToolLineCheckDisabled, TOOLS_WHITELIST, COMMAND_ALIASES, ALIASES_BY_COMMAND, WHITELIST_BY_COMMAND, WHITELIST_BY_SHORT_NAME, isValidSemver, compareSemver, resolveToolPackageName, parsePackageSpec, describeCandidateFailure, getEffectiveRegistry, isDevMode, truncateVersionsForDisplay, toolService, SkillSourceError, SkillsRegistryAuthError, resolveSkillSource, getContentStoreForRead, getAvailableSkills, readManifest, removeFromManifest, readExtraFiles, AGENT_DEFS, getSkillsDir, getSkillsDestinationHint, hasDistinctGlobalPath, skillOwnerOf, uninstallExtraFolders, uninstallSkill, rejectIfGlobalOnly, getSkillsSourceFailureDetails, buildSkillCatalog, removeSkillCatalog, searchSkillCatalog, ALL_AGENTS, AGENT_DISPLAY_NAMES, promptAgentSelection, SkillsError, resolveSkillsTargetVersion, resolveRootDir, resolveSkillsContext, runAgentInstalls, runSkillsUpdate, getInstalledTools, toolFailureRemediation, collapsePinnedLineErrors, todayLocal, readState, recordToolUpdateDate, mergeState, TOOLS_UPDATE_PHASES, runToolsUpdate, runUpdate };
9591
9723
 
9592
- //# debugId=3050532AE7B8A57C64756E2164756E21
9724
+ //# debugId=452E6333FCBBBE5F64756E2164756E21
package/dist/index.js CHANGED
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runNode
4
- } from "./index-4q45kdqv.js";
4
+ } from "./index-59rge93d.js";
5
5
  import {
6
6
  registerRobotClientLoader
7
7
  } from "./index-vmn69waj.js";
8
- import"./index-pxqxy1sx.js";
8
+ import"./index-eb9q7r0k.js";
9
9
  import {
10
10
  TELEMETRY_DRAIN_ARGV,
11
11
  configureLogger,
@@ -96,7 +96,7 @@ function isModuleNotFound(e) {
96
96
  async function setUpIntegratedProxyAuth() {
97
97
  let undici;
98
98
  try {
99
- undici = await import("./index-r3carw1e.js");
99
+ undici = await import("./index-7kfg2zz1.js");
100
100
  } catch (e) {
101
101
  if (isModuleNotFound(e)) {
102
102
  undici = undefined;
@@ -4086,13 +4086,14 @@ var require_fast_uri = __commonJS(function(exports, module) {
4086
4086
  if (!malformedIPLiteral) {
4087
4087
  malformedHost = canonicalizeHost(parsed, options, schemeHandler, isIP);
4088
4088
  }
4089
- if (!schemeHandler || schemeHandler && !schemeHandler.skipNormalize) {
4090
- if (uri.indexOf("%") !== -1) {
4091
- if (parsed.host !== undefined && !malformedIPLiteral) {
4092
- const host = isIP ? parsed.host : normalizePercentEncoding(parsed.host, true);
4093
- parsed.host = reescapeHostDelimiters(host, isIP);
4094
- }
4089
+ if (uri.indexOf("%") !== -1 && parsed.host !== undefined && !malformedIPLiteral) {
4090
+ let host = isIP ? parsed.host : normalizePercentEncoding(parsed.host, true);
4091
+ if (!isIP) {
4092
+ host = normalizePercentEncoding(host.toLowerCase());
4095
4093
  }
4094
+ parsed.host = reescapeHostDelimiters(host, isIP);
4095
+ }
4096
+ if (!schemeHandler || schemeHandler && !schemeHandler.skipNormalize) {
4096
4097
  if (parsed.path) {
4097
4098
  parsed.path = normalizePathEncoding(parsed.path);
4098
4099
  }
@@ -14607,4 +14608,4 @@ export {
14607
14608
  ResourceTemplate
14608
14609
  };
14609
14610
 
14610
- //# debugId=625311095E46947F64756E2164756E21
14611
+ //# debugId=038F92E5009A5ACC64756E2164756E21
@@ -84,7 +84,7 @@ async function executeCommand(command) {
84
84
  const previousSink = getOutputSink();
85
85
  setGlobalSink(sink);
86
86
  const [error] = await catchError(async () => {
87
- const { run } = await import("./cli-v2cbt36x.js");
87
+ const { run } = await import("./cli-akjte1tb.js");
88
88
  await runWithAuthProfile(undefined, () => runWithSink(sink, () => run(context)));
89
89
  });
90
90
  if (error) {
@@ -140,7 +140,7 @@ Pass the command without the 'uip' prefix. Example: "login status --output json"
140
140
 
141
141
  // src/mcp/server.ts
142
142
  async function startMcpServer(program) {
143
- const { McpServer } = await import("./mcp-z5911fjd.js");
143
+ const { McpServer } = await import("./mcp-g5sxmbpy.js");
144
144
  const { StdioServerTransport } = await import("./stdio-q0nbdmwt.js");
145
145
  const toolDescription = introspectCommands(program);
146
146
  const server = new McpServer({
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  runUpdate
3
- } from "./index-pxqxy1sx.js";
3
+ } from "./index-eb9q7r0k.js";
4
4
  import"./index-7pvwjzsq.js";
5
5
  import"./index-g8ck9tv6.js";
6
6
  import"./index-hrt7fpkk.js";
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@uipath/cli",
3
3
  "author": "UiPath",
4
4
  "license": "SEE LICENSE IN LICENSE.txt",
5
- "version": "1.203.0-preview.182",
5
+ "version": "1.203.0-preview.205",
6
6
  "description": "Cross platform CLI for UiPath",
7
7
  "repository": {
8
8
  "type": "git",
@@ -36,5 +36,5 @@
36
36
  "kerberos": "7.0.0",
37
37
  "node-expose-sspi": "0.1.60"
38
38
  },
39
- "gitHead": "f4f19f4d98117736cd2b34629dc1564ae6761aef"
39
+ "gitHead": "d8d19829030cc590c630bebfc60a9d9fc7fa8c31"
40
40
  }