@uipath/solution-tool 1.204.0 → 1.205.0-preview.258

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 (122) hide show
  1. package/README.md +3 -3
  2. package/dist/THIRD-PARTY-NOTICES.md +2 -2
  3. package/dist/archive-extract-x35t9ktj.js +120 -0
  4. package/dist/cleanup-command-service-rc5e42hk.js +149 -0
  5. package/dist/deploy-delete-service-qdbtj3qd.js +25 -0
  6. package/dist/deploy-run-service-m9mg34n5.js +25 -0
  7. package/dist/{deploy-status-service-3req7hje.js → deploy-status-service-kz3nk43q.js} +41 -33
  8. package/dist/deploy.js +23 -17
  9. package/dist/{deployment-search-3mah6f0a.js → deployment-search-jvwyaqek.js} +16 -10
  10. package/dist/{embedded-file-reader-rf2g1kfj.js → embedded-file-reader-z4becc02.js} +2 -2
  11. package/dist/{feed-resolver-bxj9xkgr.js → feed-resolver-3xb7ayx4.js} +10 -9
  12. package/dist/feed-scope-failure-qps17dv3.js +19 -0
  13. package/dist/{feed-session-sxga31vn.js → feed-session-7xqphdrg.js} +3 -3
  14. package/dist/governance-options-amc1v319.js +32 -0
  15. package/dist/index-6wak6hg6.js +667 -0
  16. package/dist/index-prm27bvm.js +138 -0
  17. package/dist/index.js +27 -29
  18. package/dist/init.js +11 -10
  19. package/dist/{list-s5pkkefj.js → list-7jy11vb4.js} +10 -8
  20. package/dist/models/pack-command-types.d.ts +15 -0
  21. package/dist/node-p1scvsw8.js +86 -0
  22. package/dist/pack-command-service-8etwpgm9.js +35 -0
  23. package/dist/pack-project-hjvbvhgx.js +97 -0
  24. package/dist/pack.js +24 -14
  25. package/dist/package-id-c18sx4mz.js +13 -0
  26. package/dist/packager-tool-09fwj7e8.js +171 -0
  27. package/dist/{packager-tool-nfmygm61.js → packager-tool-361zx07h.js} +74 -23
  28. package/dist/packager-tool-37jmavap.js +42 -0
  29. package/dist/{packager-tool-px1j9kre.js → packager-tool-3bwnkjdq.js} +2 -2
  30. package/dist/{packager-tool-gb35b4qs.js → packager-tool-43ahv5mn.js} +192 -96
  31. package/dist/packager-tool-47wzvqw0.js +86 -0
  32. package/dist/{packager-tool-gfhdpkp3.js → packager-tool-4bq36bf5.js} +25 -4
  33. package/dist/packager-tool-4jekgh4s.js +517 -0
  34. package/dist/{packager-tool-zns6n8zp.js → packager-tool-5ddtwzva.js} +1 -1
  35. package/dist/packager-tool-5edvzz80.js +543 -0
  36. package/dist/packager-tool-5y09xhx5.js +1333 -0
  37. package/dist/packager-tool-60af1hw2.js +26 -0
  38. package/dist/{packager-tool-f5gq77m5.js → packager-tool-61pwb567.js} +2 -2
  39. package/dist/{packager-tool-kdwsw2x7.js → packager-tool-69jmxeh0.js} +196 -1519
  40. package/dist/{packager-tool-yrz4mwfn.js → packager-tool-6kz1pv9f.js} +1373 -486
  41. package/dist/{packager-tool-stsnbewn.js → packager-tool-6x35kvbx.js} +17 -8
  42. package/dist/packager-tool-6ybywxxn.js +1809 -0
  43. package/dist/{packager-tool-wfkv9v8b.js → packager-tool-85pen8t9.js} +2196 -3455
  44. package/dist/packager-tool-8ptbmmmp.js +2132 -0
  45. package/dist/{packager-tool-9ex75r32.js → packager-tool-8q4tvv8d.js} +6 -4
  46. package/dist/packager-tool-8rg0s4w9.js +109 -0
  47. package/dist/{packager-tool-7gr2nphb.js → packager-tool-97rcgwvv.js} +224 -6
  48. package/dist/packager-tool-act5r386.js +239 -0
  49. package/dist/packager-tool-amhyxzz6.js +125 -0
  50. package/dist/{packager-tool-j3520gxw.js → packager-tool-an5bpbwe.js} +3556 -1646
  51. package/dist/{packager-tool-e2rtr49j.js → packager-tool-b2nhscfk.js} +15 -31
  52. package/dist/packager-tool-bqw7edje.js +188 -0
  53. package/dist/{packager-tool-4gs8y6pr.js → packager-tool-dwxswyv4.js} +149 -53
  54. package/dist/{packager-tool-fehvgd51.js → packager-tool-e7vczxa8.js} +357 -1370
  55. package/dist/{packager-tool-v8bkkqdb.js → packager-tool-gmwva4yv.js} +5 -5
  56. package/dist/packager-tool-gs3f3tf7.js +103 -0
  57. package/dist/packager-tool-kkfb5kgn.js +182 -0
  58. package/dist/{packager-tool-ds45xby2.js → packager-tool-m74zqwmh.js} +104 -14
  59. package/dist/{packager-tool-fv7xyzg2.js → packager-tool-pbmqk39a.js} +126 -128
  60. package/dist/packager-tool-q5j6k3fy.js +1510 -0
  61. package/dist/packager-tool-qk21gk5m.js +445 -0
  62. package/dist/{packager-tool-bqre28m1.js → packager-tool-qw47eyw7.js} +1 -1
  63. package/dist/packager-tool-resolver-994z3jkj.js +23 -0
  64. package/dist/{packager-tool-gab9y5ct.js → packager-tool-t8gh825q.js} +37 -13
  65. package/dist/{packager-tool-kswwd3hp.js → packager-tool-tx834spe.js} +2376 -4077
  66. package/dist/{packager-tool-zf3929se.js → packager-tool-v1f5e8t9.js} +11 -1
  67. package/dist/{packager-tool-g8kjzrg7.js → packager-tool-wknfv4p5.js} +13 -11
  68. package/dist/{packager-tool-1rzssy0x.js → packager-tool-wy4fx250.js} +19 -18
  69. package/dist/packager-tool-y2k2f6yg.js +68 -0
  70. package/dist/packager-tool.js +2 -2
  71. package/dist/prepare-solution-resources-m1djfj62.js +29 -0
  72. package/dist/project-command-utils-t6pmpvq3.js +90 -0
  73. package/dist/project-contributions-79ndycrx.js +32 -0
  74. package/dist/publish.js +13 -12
  75. package/dist/resource-mutations-c3krjqze.js +36 -0
  76. package/dist/resource-version-lookup-0e3e2j58.js +99 -0
  77. package/dist/resource.js +10 -9
  78. package/dist/restore-command-service-eyx911f2.js +155 -0
  79. package/dist/run-service-p1vzzqe3.js +428 -0
  80. package/dist/services/deploy-activate-service.d.ts +10 -5
  81. package/dist/services/deploy-delete-service.d.ts +8 -4
  82. package/dist/services/deploy-run-service.d.ts +34 -1
  83. package/dist/services/deploy-uninstall-service.d.ts +21 -3
  84. package/dist/services/deploy-upgrade-service.d.ts +35 -1
  85. package/dist/services/deployment-feed-locator.d.ts +15 -4
  86. package/dist/services/deployment-search-client.d.ts +5 -53
  87. package/dist/services/deployment-search.d.ts +58 -3
  88. package/dist/services/deployment-state.d.ts +84 -24
  89. package/dist/services/deployment-validation.d.ts +5 -0
  90. package/dist/services/emit-runtime-dependencies.d.ts +2 -1
  91. package/dist/services/feed-resolver.d.ts +6 -4
  92. package/dist/services/feed-selection.d.ts +47 -0
  93. package/dist/services/http-status.d.ts +2 -7
  94. package/dist/services/pack-command-service.d.ts +9 -0
  95. package/dist/services/pack-project-selection.d.ts +51 -0
  96. package/dist/services/pack-project.d.ts +26 -0
  97. package/dist/services/pack-service.d.ts +7 -3
  98. package/dist/services/package-search-client.d.ts +7 -0
  99. package/dist/services/packager-tool-resolver.d.ts +7 -1
  100. package/dist/services/packages-list-service.d.ts +1 -1
  101. package/dist/services/permanent-deletion-consent.d.ts +110 -0
  102. package/dist/services/pipeline-deploy-poll.d.ts +7 -0
  103. package/dist/services/prepare-solution-resources.d.ts +12 -2
  104. package/dist/services/project-contributions.d.ts +5 -4
  105. package/dist/services/search-failure.d.ts +9 -13
  106. package/dist/services/solution-packager-helpers.d.ts +5 -2
  107. package/dist/services/solution-path.d.ts +1 -1
  108. package/dist/services/uninstall-consent.d.ts +82 -0
  109. package/dist/ship-telemetry-myes7ak5.js +21 -0
  110. package/dist/solution-auth-aead70sw.js +11 -0
  111. package/dist/templates/AGENTS.md +125 -12
  112. package/dist/tool.js +27 -29
  113. package/dist/utils/deployment-errors.d.ts +9 -1
  114. package/package.json +2 -2
  115. package/dist/deploy-delete-service-1zydyyhj.js +0 -22
  116. package/dist/feed-scope-failure-2kndwpf6.js +0 -18
  117. package/dist/packager-tool-f2e9rzxk.js +0 -104
  118. package/dist/packager-tool-resolver-6zwhec62.js +0 -20
  119. package/dist/packager-tool-zdfn32bc.js +0 -4465
  120. package/dist/prepare-solution-resources-jpb5as2s.js +0 -25
  121. package/dist/project-contributions-6wpff2hm.js +0 -30
  122. package/dist/services/legacy-deployment-search-v3.d.ts +0 -23
@@ -1,135 +1,65 @@
1
+ import {
2
+ inspectSolutionPackageProjectTypes,
3
+ trackSolutionShipSucceeded
4
+ } from "./packager-tool-amhyxzz6.js";
1
5
  import {
2
6
  getStudioWebAuthWithOrganizationId,
3
7
  useStudioWebAuth
4
- } from "./packager-tool-v8bkkqdb.js";
8
+ } from "./packager-tool-gmwva4yv.js";
5
9
  import {
6
10
  resolveFeedScopeOrFailureAsync
7
- } from "./packager-tool-9ex75r32.js";
11
+ } from "./packager-tool-8q4tvv8d.js";
8
12
  import {
9
13
  activateDeploymentAsync,
10
- deployRunAsync,
11
- extractDeploymentErrors,
12
- formatDeploymentErrorsAsText,
13
14
  listDeploymentsAsync,
14
15
  listPackagesAsync,
15
16
  uninstallDeploymentAsync,
16
17
  upgradeDeploymentAsync
17
- } from "./packager-tool-kdwsw2x7.js";
18
+ } from "./packager-tool-q5j6k3fy.js";
19
+ import {
20
+ extractDeploymentErrors,
21
+ formatDeploymentErrorsAsText
22
+ } from "./packager-tool-act5r386.js";
18
23
  import {
19
24
  SolutionInitError,
20
25
  solutionInitAsync
21
- } from "./packager-tool-px1j9kre.js";
26
+ } from "./packager-tool-3bwnkjdq.js";
22
27
  import {
23
- GOVERNANCE_OPTION_INSTRUCTIONS,
24
- PackCommandService,
25
- SOLUTION_PATH_INSTRUCTIONS,
26
- SolutionPackOptions,
27
- applyAuthConnection,
28
- checkSolutionPathAsync,
29
- createSolutionPackager,
30
- packSolutionAsync,
31
- readSolutionFileAsUint8Array,
32
- resolveSdkLogLevel,
33
- validateGovernanceOptions
34
- } from "./packager-tool-wfkv9v8b.js";
35
- import {
36
- prepareSolutionResources
37
- } from "./packager-tool-gab9y5ct.js";
38
- import {
39
- ensurePackagerTools,
40
- isUnpackableProjectTypeError,
41
- toolVerbForProjectType
42
- } from "./packager-tool-e2rtr49j.js";
28
+ validatePackProjectOptions
29
+ } from "./packager-tool-gs3f3tf7.js";
43
30
  import {
44
31
  publishSolutionAsync
45
- } from "./packager-tool-g8kjzrg7.js";
46
- import {
47
- Configuration,
48
- PipelinesApi
49
- } from "./packager-tool-7gr2nphb.js";
32
+ } from "./packager-tool-wknfv4p5.js";
50
33
  import {
51
34
  feedScopeInitOverride,
52
35
  listSelectablePublishLocations
53
- } from "./packager-tool-stsnbewn.js";
54
- import {
55
- DeploymentActivationStatus,
56
- DeploymentOperationStatus,
57
- StudioWebIncompatibleProjectError,
58
- UipignoreExcludesProjectError,
59
- buildSolutionUploadFailureOutput,
60
- bundleSolution,
61
- getProjectDebugStatus,
62
- importSolution,
63
- isDebugProvisioningSucceeded,
64
- isDebugProvisioningTerminal,
65
- isSolutionUploadHttpError,
66
- overwriteSolution,
67
- solutionExistsOnStudioWeb
68
- } from "./packager-tool-j3520gxw.js";
36
+ } from "./packager-tool-6x35kvbx.js";
69
37
  import {
70
- applyEntryPointEnhancementAsync,
71
- assertSolutionManifest,
72
- createLocalResource,
73
- createProjectInSolutionBuilder,
74
- createResourceBuilderServices,
75
- createResourceKindMetadataResolver,
76
- exportResourceDefinitionAsync,
77
- findCatalogEntityAsync,
78
- findMatchingLocalResource,
79
- findProjectFile,
80
- findResourceByKeyInRcs,
81
- formatResourceSubtypes,
82
- getRemoteResourceClients,
83
- hasAnyTemplateRow,
84
- hasBareTemplateRow,
85
- isMissingProjectTypeError,
86
- isProjectManifestError,
87
- normalizeFolderPath,
88
- normalizeResourceFileCasing,
89
- readProjectFile,
90
- readSolutionFile,
91
- readSpecProperty,
92
- resolveResourceKindMetadata,
93
- resolveSolutionFilePath,
94
- resourceRefreshAsync,
95
- resourceRemoteSyncAsync,
96
- restoreSolutionFile,
97
- sameResourceSubtype,
98
- saveCasingNormalized,
99
- searchRcsResources,
100
- syncResourcesFromBindings,
101
- toResourceReference,
102
- validateResourceName,
103
- writeSolutionFile
104
- } from "./packager-tool-yrz4mwfn.js";
38
+ Configuration,
39
+ PipelinesApi
40
+ } from "./packager-tool-97rcgwvv.js";
105
41
  import {
106
- ToolResult
107
- } from "./packager-tool-fv7xyzg2.js";
42
+ DeploymentActivationStatus,
43
+ DeploymentOperationStatus
44
+ } from "./packager-tool-an5bpbwe.js";
108
45
  import {
109
46
  getSolutionAuthContext
110
- } from "./packager-tool-f5gq77m5.js";
47
+ } from "./packager-tool-61pwb567.js";
111
48
  import {
112
- resolveSolutionDir,
113
- toPortableRelativePath,
114
- updateUipxSolutionId
115
- } from "./packager-tool-f2e9rzxk.js";
49
+ getLoginStatusAsync
50
+ } from "./packager-tool-43ahv5mn.js";
116
51
  import {
117
- CommandDimensions,
118
52
  DEFAULT_PAGE_SIZE,
119
53
  Option,
120
54
  OutputFormatter,
121
55
  Pagination,
122
56
  PollOutcome,
123
57
  RESULTS,
124
- ShipDimensions,
58
+ addDeprecatedOptionAlias,
125
59
  carriedErrorCode,
126
- carriedInstructions,
127
60
  carriedRetry,
128
- catchError,
129
61
  createHiddenDeprecatedTenantOption,
130
- extractErrorDetails,
131
- extractErrorMessage,
132
- isGuid,
62
+ httpStatusOf,
133
63
  isPreviewBuild,
134
64
  logger,
135
65
  mapPackageMetadataOptions,
@@ -146,18 +76,18 @@ import {
146
76
  unsupportedSolutionProjectType,
147
77
  warnDeprecatedOptionAlias,
148
78
  withCompleter
149
- } from "./packager-tool-kswwd3hp.js";
79
+ } from "./packager-tool-tx834spe.js";
150
80
  import {
151
- getLoginStatusAsync
152
- } from "./packager-tool-gb35b4qs.js";
81
+ CommandDimensions,
82
+ ShipDimensions,
83
+ carriedInstructions,
84
+ catchError,
85
+ extractErrorDetails,
86
+ extractErrorMessage
87
+ } from "./packager-tool-6ybywxxn.js";
153
88
  import {
154
89
  getFileSystem
155
- } from "./packager-tool-zf3929se.js";
156
- import {
157
- strFromU8,
158
- unzip,
159
- unzipSync
160
- } from "./packager-tool-dfrk01gn.js";
90
+ } from "./packager-tool-v1f5e8t9.js";
161
91
  import {
162
92
  __require
163
93
  } from "./packager-tool-1de529jm.js";
@@ -166,7 +96,7 @@ var package_default = {
166
96
  name: "@uipath/solution-tool",
167
97
  author: "UiPath",
168
98
  license: "SEE LICENSE IN LICENSE.txt",
169
- version: "1.204.0",
99
+ version: "1.205.0-preview.258",
170
100
  description: "Create, pack, publish, and deploy UiPath Automation Solutions.",
171
101
  repository: {
172
102
  type: "git",
@@ -229,7 +159,8 @@ var package_default = {
229
159
  "@uipath/packager-tool-connector": "workspace:*",
230
160
  "@uipath/pipelines-sdk": "workspace:*",
231
161
  "@uipath/project-executor": "workspace:*",
232
- "@uipath/resource-builder-sdk": "2025.11.0-alpha6004-4107",
162
+ "@uipath/project-packager": "workspace:*",
163
+ "@uipath/resource-builder-sdk": "2025.11.0-alpha6584-4367",
233
164
  "@uipath/resource-builder-tool": "2025.11.0-alpha6004-4107",
234
165
  "@uipath/solution-packager": "workspace:*",
235
166
  "@uipath/solution-sdk": "workspace:*",
@@ -241,113 +172,6 @@ var package_default = {
241
172
  }
242
173
  };
243
174
 
244
- // src/services/cleanup-command-service.ts
245
- class CleanupCommandService {
246
- packager = null;
247
- fs;
248
- constructor() {
249
- this.fs = getFileSystem();
250
- }
251
- async execute(solutionPath, options, context) {
252
- const check = await checkSolutionPathAsync(this.fs, solutionPath);
253
- if (!check.ok) {
254
- this.reportFailureAndExit(context, check.message, SOLUTION_PATH_INSTRUCTIONS, check.statError, check.errorCode);
255
- return;
256
- }
257
- const { absoluteSolutionPath } = check;
258
- logger.info(options.dryRun ? `
259
- Detecting unused items (dry-run)...
260
- ` : `
261
- Removing unused items...
262
- `);
263
- logger.info("Details:");
264
- logger.info(` Solution: ${absoluteSolutionPath}`);
265
- logger.info("");
266
- const [error, result] = await catchError(this.executeAsync(solutionPath, options));
267
- if (error) {
268
- const msg = error instanceof Error ? error.message : String(error);
269
- this.reportFailureAndExit(context, msg, carriedInstructions(error) ?? "Check that the solution can be loaded, the required packager tools are available, and the current login has access to the tenant.", error);
270
- return;
271
- }
272
- if (result.errorCode !== "SUCCESS" /* Success */) {
273
- this.reportFailureAndExit(context, `Error code: ${result.errorCode} : ${result.message}`, result.instructions ?? result.message ?? "");
274
- return;
275
- }
276
- const changedFilesByProject = result.details?.changedFilesByProject ?? {};
277
- const cleanupByProject = result.details?.cleanupByProject ?? {};
278
- OutputFormatter.success({
279
- Result: RESULTS.Success,
280
- Code: "SolutionCleanup",
281
- Data: {
282
- DryRun: Boolean(options.dryRun),
283
- ChangedFilesByProject: changedFilesByProject,
284
- CleanupByProject: cleanupByProject
285
- }
286
- });
287
- }
288
- reportFailureAndExit(context, message, instructions, error, errorCode) {
289
- OutputFormatter.error({
290
- Result: RESULTS.Failure,
291
- Message: message,
292
- Instructions: instructions,
293
- ErrorCode: errorCode
294
- });
295
- if (error instanceof Error && error.stack) {
296
- logger.error("Stack trace:");
297
- logger.error(error.stack);
298
- }
299
- context.exit(1);
300
- }
301
- async executeAsync(solutionPath, options) {
302
- if (options.loginValidity !== undefined && Number.isNaN(options.loginValidity)) {
303
- return new ToolResult("INTERNAL_ERROR" /* InternalError */, `Invalid --login-validity value: ${options.loginValidity}`, []);
304
- }
305
- const check = await checkSolutionPathAsync(this.fs, solutionPath);
306
- if (!check.ok) {
307
- return new ToolResult("INTERNAL_ERROR" /* InternalError */, check.message, []);
308
- }
309
- const { absoluteSolutionPath, isUisFile } = check;
310
- if (isUisFile && !options.dryRun) {
311
- return new ToolResult("INTERNAL_ERROR" /* InternalError */, `In-place cleanup of a .uis file is not supported: changes would be written to a temporary extraction and then discarded, leaving '${absoluteSolutionPath}' unchanged. Re-run with --dry-run to only detect unused items, or point at an unpacked solution directory to modify it in place.`, []);
312
- }
313
- const [error, result] = await catchError(async () => {
314
- const packager = await this.ensurePackagerAsync();
315
- let inputPath;
316
- if (isUisFile) {
317
- const uint8Array = await readSolutionFileAsUint8Array(this.fs, absoluteSolutionPath);
318
- inputPath = await packager.setupAsync(uint8Array);
319
- } else {
320
- inputPath = await packager.setupAsync(absoluteSolutionPath);
321
- }
322
- await ensurePackagerTools(inputPath, this.fs);
323
- const cleanupOptions = await this.createCleanupOptions(inputPath, options);
324
- return packager.cleanupSolutionAsync(cleanupOptions);
325
- });
326
- if (error) {
327
- return new ToolResult("INTERNAL_ERROR" /* InternalError */, error instanceof Error ? error.message : String(error), [], carriedInstructions(error));
328
- }
329
- return result;
330
- }
331
- async ensurePackagerAsync() {
332
- this.packager ??= await createSolutionPackager();
333
- return this.packager;
334
- }
335
- async createCleanupOptions(inputPath, options) {
336
- const cleanupOptions = new SolutionPackOptions;
337
- cleanupOptions.inputPath = inputPath;
338
- cleanupOptions.cleanupOptions = {
339
- dryRun: options.dryRun ?? false,
340
- skipImports: options.skipImports ?? false
341
- };
342
- cleanupOptions.logLevel = resolveSdkLogLevel();
343
- cleanupOptions.nuGetSourcesConfigPath = options.nugetSourcesConfigPath;
344
- cleanupOptions.excludeConfiguredSources = options.excludeConfiguredSources ?? false;
345
- cleanupOptions.feedFolder = options.feedFolder;
346
- await applyAuthConnection(cleanupOptions, options.loginValidity);
347
- return cleanupOptions;
348
- }
349
- }
350
-
351
175
  // src/commands/cleanup.ts
352
176
  var SOLUTION_CLEANUP_EXAMPLES = [
353
177
  {
@@ -388,7 +212,8 @@ var SOLUTION_CLEANUP_EXAMPLES = [
388
212
  }
389
213
  ];
390
214
  var registerCleanupCommand = (program) => {
391
- program.command("cleanup").description("Remove unused items from every project in a UiPath solution. Accepts a solution directory (containing .uipx) or a .uis file. For a directory the project sources are modified in place. Pass --dry-run to only detect unused items.").argument("<solutionPath>", "Path to a solution directory (containing .uipx) or a .uis file").option("--dry-run", "Detect unused items but do not modify any project files.").option("--skip-imports", "Do not clean up now-unused references to removed items in the project's files.").option("--nuget-sources-config-path <path>", "Path to NuGet sources configuration file").option("--exclude-configured-sources", "Resolve project dependencies only from the tenant feeds and any --nuget-sources-config-path. Drops the built-in UiPath and nuget.org feeds, so a dependency that is not on those feeds fails to restore.").option("--feed-folder <name>", "Resolve project dependencies from this Orchestrator folder's library feed instead of every tenant feed. Accepts a folder name or fully qualified path.").option("--login-validity <minutes>", "Minimum minutes before token expiration to trigger a refresh (default: 10)", (value) => Number.parseInt(value, 10), 10).examples(SOLUTION_CLEANUP_EXAMPLES).trackedAction(processContext, async (solutionPath, options) => {
215
+ program.command("cleanup").description("Remove unused items from every project in a UiPath solution. Accepts a solution directory (containing .uipx) or a .uis file. For a directory the project sources are modified in place. Pass --dry-run to only detect unused items.").argument("<solution-path>", "Path to a solution directory (containing .uipx) or a .uis file").option("--dry-run", "Detect unused items but do not modify any project files.").option("--skip-imports", "Do not clean up now-unused references to removed items in the project's files.").option("--nuget-sources-config-path <path>", "Path to NuGet sources configuration file").option("--exclude-configured-sources", "Resolve project dependencies only from the tenant feeds and any --nuget-sources-config-path. Drops the built-in UiPath and nuget.org feeds, so a dependency that is not on those feeds fails to restore.").option("--feed-folder <name>", "Resolve project dependencies from this Orchestrator folder's library feed instead of every tenant feed. Accepts a folder name or fully qualified path.").option("--login-validity <minutes>", "Minimum minutes before token expiration to trigger a refresh (default: 10)", (value) => Number.parseInt(value, 10), 10).examples(SOLUTION_CLEANUP_EXAMPLES).trackedAction(processContext, async (solutionPath, options) => {
216
+ const { CleanupCommandService } = await import("./cleanup-command-service-rc5e42hk.js");
392
217
  const service = new CleanupCommandService;
393
218
  const cleanupOptions = {
394
219
  dryRun: options.dryRun,
@@ -492,9 +317,11 @@ var SOLUTION_DEPLOY_ACTIVATE_EXAMPLES = [
492
317
  }
493
318
  ];
494
319
  var registerDeployActivateCommand = (program) => {
495
- program.command("activate").description("Activate a deployed solution that was deployed without auto-activation. Activation provisions all solution components.").argument("<deployment-name>", "Name of the deployment to activate. Use 'solution deploy list' to find deployment names.").addOption(createHiddenDeprecatedTenantOption("-t, --tenant <tenant-name>")).option("--timeout <seconds>", "Timeout in seconds for activation polling (default: 360)", (v) => parseInt(v, 10), 360).option("--poll-interval <ms>", "Milliseconds between activation status polls (default: 5000)", (v) => parseInt(v, 10), 5000).option("--login-validity <minutes>", "Minimum minutes before token expiration to trigger a refresh (default: 10)", parseInt, 10).examples(SOLUTION_DEPLOY_ACTIVATE_EXAMPLES).trackedAction(processContext, async (deploymentName, options) => {
320
+ program.command("activate").description("Activate a deployed solution that was deployed without auto-activation. Activation provisions all solution components.").argument("<deployment-name>", "Name of the deployment to activate. Use 'solution deploy list' to find deployment names.").addOption(createHiddenDeprecatedTenantOption("-t, --tenant <tenant-name>")).option("--timeout <seconds>", "Timeout in seconds for activation polling (default: 360)", (v) => parseInt(v, 10), 360).option("--poll-interval <ms>", "Milliseconds between activation status polls (default: 5000)", (v) => parseInt(v, 10), 5000).option("--login-validity <minutes>", "Minimum minutes before token expiration to trigger a refresh (default: 10)", parseInt, 10).addOption(new Option("--feed <name-or-key>", "The feed the deployment lives in (name or folder key, from 'solution feeds list'). Only that feed is searched; without it the tenant feed, your Personal Workspace and the folder feeds are tried in turn. Needs a user session for a feed other than the tenant's. Mutually exclusive with --personal-workspace.").conflicts("personalWorkspace")).option("--personal-workspace", "The deployment lives in your Personal Workspace feed: only that feed is searched. Needs a user session.").examples(SOLUTION_DEPLOY_ACTIVATE_EXAMPLES).trackedAction(processContext, async (deploymentName, options) => {
496
321
  const result = await activateDeploymentAsync(deploymentName, {
497
322
  tenant: options.tenant,
323
+ personalWorkspace: options.personalWorkspace,
324
+ feed: options.feed,
498
325
  timeout: options.timeout,
499
326
  pollInterval: options.pollInterval,
500
327
  loginValidity: options.loginValidity,
@@ -1049,13 +876,15 @@ var SOLUTION_DEPLOY_DELETE_EXAMPLES = [
1049
876
  }
1050
877
  ];
1051
878
  var registerDeployDeleteCommand = (program) => {
1052
- program.command("delete").description("Delete a deployment from the tenant. Use this for a deployment that 'deploy uninstall' cannot remove: one left inactive after an uninstall, one superseded by a newer version, or one left behind by a failed install — Orchestrator refuses to uninstall those with error 4007. The command reads the deployment first, and refuses when its own action list offers actions but not Delete, naming the state and the actions that are available. A record that lists no actions at all says nothing, so there the request goes to the server and the server decides.").argument("<deployment-name>", "Name of the deployment to delete. Use 'solution deploy list' to find deployment names.").addOption(createHiddenDeprecatedTenantOption("-t, --tenant <tenant-name>")).option("--login-validity <minutes>", "Minimum minutes before token expiration to trigger a refresh (default: 10)", parseInt, 10).option("-y, --yes", "Confirm this irreversible operation (required; the CLI never prompts)").examples(SOLUTION_DEPLOY_DELETE_EXAMPLES).trackedAction(processContext, async (deploymentName, options) => {
879
+ program.command("delete").description("Delete a deployment from the tenant. Use this for a deployment that 'deploy uninstall' cannot remove: one left inactive after an uninstall, one superseded by a newer version, or one left behind by a failed install — Orchestrator refuses to uninstall those with error 4007. The command reads the deployment first, and refuses when its own action list offers actions but not Delete, naming the state and the actions that are available. A record that lists no actions at all says nothing, so there the request goes to the server and the server decides.").argument("<deployment-name>", "Name of the deployment to delete. Use 'solution deploy list' to find deployment names.").addOption(createHiddenDeprecatedTenantOption("-t, --tenant <tenant-name>")).option("--login-validity <minutes>", "Minimum minutes before token expiration to trigger a refresh (default: 10)", parseInt, 10).option("-y, --yes", "Confirm this irreversible operation (required; the CLI never prompts)").addOption(new Option("--feed <name-or-key>", "The feed the deployment lives in (name or folder key, from 'solution feeds list'). Only that feed is searched; without it the tenant feed, your Personal Workspace and the folder feeds are tried in turn. Needs a user session for a feed other than the tenant's. Mutually exclusive with --personal-workspace.").conflicts("personalWorkspace")).option("--personal-workspace", "The deployment lives in your Personal Workspace feed: only that feed is searched. Needs a user session.").examples(SOLUTION_DEPLOY_DELETE_EXAMPLES).trackedAction(processContext, async (deploymentName, options) => {
1053
880
  if (!requireConfirmation(options, `delete deployment '${deploymentName}'`)) {
1054
881
  return;
1055
882
  }
1056
- const { deleteDeploymentAsync } = await import("./deploy-delete-service-1zydyyhj.js");
883
+ const { deleteDeploymentAsync } = await import("./deploy-delete-service-qdbtj3qd.js");
1057
884
  const result = await deleteDeploymentAsync(deploymentName, {
1058
885
  tenant: options.tenant,
886
+ personalWorkspace: options.personalWorkspace,
887
+ feed: options.feed,
1059
888
  loginValidity: options.loginValidity
1060
889
  });
1061
890
  if (!result.ok) {
@@ -1388,12 +1217,13 @@ var SOLUTION_DEPLOY_RUN_FEED_EXAMPLE = {
1388
1217
  }
1389
1218
  };
1390
1219
  var registerDeployRunCommand = (program) => {
1391
- const command = program.command("run").description("Deploy a solution package to Orchestrator. Creates a folder, provisions resources, and (by default) activates the solution. The deployment is keyed on --name: a name that does not exist yet gets a NEW deployment in a NEW folder (the normal case), while re-using an existing deployment's name updates that deployment in place — use 'deploy upgrade' when that is what you want. If the package is already deployed the command stops and points you at the upgrade path; pass --yes with a different --name to deploy a second, separate copy anyway. Pass --skip-activate to leave the deployment in 'Inactive (Ready to activate)' state and activate later with 'deploy activate'. A deployment whose resources need 'Setup activation' in Orchestrator is installed but not activated: the command reports Result: Success with ActivationStatus: NeedsSetupToActivate, the resources and the steps left — do not deploy it again. To customize resource settings before deploying, use 'config get' to fetch the default config, 'config set' / 'config link' to edit it, then pass it here with --config-file.").requiredOption("-n, --name <deployment-name>", "Name for the deployment").addOption(withCompleter(new Option("--package-name <name>", "Solution package name to deploy. Use 'solution packages list' to find available names.").makeOptionMandatory(), packageNameCompleter)).addOption(withCompleter(new Option("--package-version <version>", "Solution package version to deploy. Use 'solution packages list' to find available versions.").makeOptionMandatory(), packageVersionCompleter)).requiredOption("--folder-name <name>", "Name for the new Orchestrator folder created for this deployment (created under --parent-folder-path if specified)").addOption(new Option("--parent-folder-path <path>", "Parent folder path (e.g., 'Shared'). Solution folder is created under this.").conflicts("parentFolderKey")).option("--parent-folder-key <key>", "Parent folder key (GUID). Alternative to --parent-folder-path.").addOption(new Option("--personal-workspace", "Deploy into the current user's Personal Workspace. Resolves the workspace name from Orchestrator automatically; needs a user session (an external app has no workspace, and the server ignores the feed header on client-credentials requests). Mutually exclusive with --parent-folder-path and --parent-folder-key.").conflicts(["parentFolderPath", "parentFolderKey"])).option("--config-file <path>", "JSON or YAML configuration file. Generate with: uip solution deploy config get <name> -d config.json, then customize with 'config set' or 'config link'.").addOption(createHiddenDeprecatedTenantOption("-t, --tenant <tenant-name>")).option("--timeout <seconds>", "Timeout in seconds applied per polling phase — deploy and (when not skipped) activate (default: 360 each)", (v) => parseInt(v, 10), 360).option("--poll-interval <ms>", "Milliseconds between status polls during the deploy and activate phases (default: 5000)", (v) => parseInt(v, 10), 5000).option("--login-validity <minutes>", "Minimum minutes before token expiration to trigger a refresh (default: 10)", parseInt, 10).addOption(new Option("--wait", "Deprecated and ignored: every deploy now waits for the install to finish (bounded by --timeout).").hideHelp()).option("--skip-activate", "Skip auto-activation; leave the deployment in 'Inactive (Ready to activate)' state. Activate later with 'uip solution deploy activate <name>'.").option("-y, --yes", "Deploy even when this package already has a deployment. Without it, deploy run looks the package up and stops if it is already deployed. That check is best-effort, not a guarantee: a lookup failure only warns, and under an application (client-credentials) login it never stops the deploy — an existing deployment is reported as a warning, or the check is skipped on servers without the Pipelines deployment search. --yes only skips that check: the install is keyed on --name, so re-using an existing deployment's name updates that deployment in place rather than creating a second copy — pass a different --name for a separate deployment.");
1220
+ const command = program.command("run").description("Deploy a solution package to Orchestrator. Creates a folder, provisions resources, and (by default) activates the solution. The deployment is keyed on --name: a name that does not exist yet gets a NEW deployment in a NEW folder (the normal case), while re-using an existing deployment's name updates that deployment in place — use 'deploy upgrade' when that is what you want. If the package is already deployed the command stops and points you at the upgrade path; pass --yes with a different --name to deploy a second, separate copy anyway. Pass --skip-activate to leave the deployment in 'Inactive (Ready to activate)' state and activate later with 'deploy activate'. A deployment whose resources need 'Setup activation' in Orchestrator is installed but not activated: the command reports Result: Success with ActivationStatus: NeedsSetupToActivate, the resources and the steps left — do not deploy it again. To customize resource settings before deploying, use 'config get' to fetch the default config, 'config set' / 'config link' to edit it, then pass it here with --config-file. When the deploy replaces an installed resource with a link (a config-file link to an existing resource), the server deletes the installed copy and its data, and asks for confirmation first: the command stops and lists those resources unless --acknowledge-permanent-deletion is passed.").requiredOption("-n, --name <deployment-name>", "Name for the deployment").addOption(withCompleter(new Option("--package-name <name>", "Solution package name to deploy. Use 'solution packages list' to find available names.").makeOptionMandatory(), packageNameCompleter)).addOption(withCompleter(new Option("--package-version <version>", "Solution package version to deploy. Use 'solution packages list' to find available versions.").makeOptionMandatory(), packageVersionCompleter)).requiredOption("--folder-name <name>", "Name for the new Orchestrator folder created for this deployment (created under --parent-folder-path if specified)").addOption(new Option("--parent-folder-path <path>", "Parent folder path (e.g., 'Shared'). Solution folder is created under this.").conflicts("parentFolderKey")).option("--parent-folder-key <key>", "Parent folder key (GUID). Alternative to --parent-folder-path.").addOption(new Option("--personal-workspace", "Deploy into the current user's Personal Workspace. Resolves the workspace name from Orchestrator automatically; needs a user session (an external app has no workspace, and the server ignores the feed header on client-credentials requests). Mutually exclusive with --parent-folder-path and --parent-folder-key.").conflicts(["parentFolderPath", "parentFolderKey"])).option("--config-file <path>", "JSON or YAML configuration file. Generate with: uip solution deploy config get <name> -d config.json, then customize with 'config set' or 'config link'.").addOption(createHiddenDeprecatedTenantOption("-t, --tenant <tenant-name>")).option("--timeout <seconds>", "Timeout in seconds applied per polling phase — deploy and (when not skipped) activate (default: 360 each)", (v) => parseInt(v, 10), 360).option("--poll-interval <ms>", "Milliseconds between status polls during the deploy and activate phases (default: 5000)", (v) => parseInt(v, 10), 5000).option("--login-validity <minutes>", "Minimum minutes before token expiration to trigger a refresh (default: 10)", parseInt, 10).addOption(new Option("--wait", "Deprecated and ignored: every deploy now waits for the install to finish (bounded by --timeout).").hideHelp()).option("--skip-activate", "Skip auto-activation; leave the deployment in 'Inactive (Ready to activate)' state. Activate later with 'uip solution deploy activate <name>'.").option("-y, --yes", "Deploy even when this package already has a deployment. Without it, deploy run looks the package up and stops if it is already deployed. That check is best-effort, not a guarantee: a lookup failure only warns, and under an application (client-credentials) login it never stops the deploy — an existing deployment is reported as a warning, or the check is skipped on servers without the Pipelines deployment search. --yes only skips that check: the install is keyed on --name, so re-using an existing deployment's name updates that deployment in place rather than creating a second copy — pass a different --name for a separate deployment.").option("--acknowledge-permanent-deletion", "Confirm that installed resources this deployment replaces with a link are permanently deleted, along with their data. Without it the deploy stops at the server's confirmation request and lists those resources; nothing is installed. With it each listed resource is acknowledged and the same install runs once more, within the same --timeout. Independent of --yes.");
1392
1221
  command.addOption(new Option("--feed <name-or-key>", "Deploy a package from a specific feed (name or folder key, from 'solution feeds list') instead of the tenant feed. Needs a user session: the server ignores the feed header on client-credentials requests, so an external app is refused rather than deploying to the tenant feed by accident. Mutually exclusive with --personal-workspace.").conflicts("personalWorkspace"));
1393
1222
  command.examples([
1394
1223
  ...SOLUTION_DEPLOY_RUN_EXAMPLES,
1395
1224
  SOLUTION_DEPLOY_RUN_FEED_EXAMPLE
1396
1225
  ]).trackedAction(processContext, async (options) => {
1226
+ const { deployRunAsync } = await import("./deploy-run-service-m9mg34n5.js");
1397
1227
  const result = await deployRunAsync({
1398
1228
  tenant: options.tenant,
1399
1229
  deploymentName: options.name,
@@ -1410,6 +1240,7 @@ var registerDeployRunCommand = (program) => {
1410
1240
  loginValidity: options.loginValidity,
1411
1241
  skipActivate: options.skipActivate,
1412
1242
  yes: options.yes,
1243
+ acknowledgePermanentDeletion: options.acknowledgePermanentDeletion,
1413
1244
  signal: processContext.pollSignal
1414
1245
  });
1415
1246
  if (!result.ok) {
@@ -1418,7 +1249,24 @@ var registerDeployRunCommand = (program) => {
1418
1249
  Message: result.message,
1419
1250
  Instructions: result.instructions,
1420
1251
  ErrorCode: result.errorCode,
1421
- Retry: result.retry
1252
+ Retry: result.retry,
1253
+ ...result.permanentDeletionResources ? {
1254
+ Data: {
1255
+ PipelineDeploymentId: result.pipelineDeploymentId,
1256
+ DeploymentKey: result.deploymentKey,
1257
+ PermanentDeletionResources: result.permanentDeletionResources.map((resource) => ({
1258
+ Key: resource.key,
1259
+ Kind: resource.kind ?? null,
1260
+ Name: resource.name
1261
+ }))
1262
+ }
1263
+ } : {},
1264
+ ...result.permanentlyDeletedResources ? {
1265
+ Data: {
1266
+ PipelineDeploymentId: result.pipelineDeploymentId,
1267
+ PermanentlyDeletedResources: result.permanentlyDeletedResources
1268
+ }
1269
+ } : {}
1422
1270
  });
1423
1271
  processContext.exit(result.exitCode);
1424
1272
  return;
@@ -1441,10 +1289,12 @@ var registerDeployRunCommand = (program) => {
1441
1289
  Kind: resource.kind,
1442
1290
  Name: resource.name,
1443
1291
  Type: resource.type ?? null,
1444
- Reason: resource.reason ?? null
1292
+ Reason: resource.reason ?? null,
1293
+ FolderPaths: resource.folderPaths ?? null
1445
1294
  }))
1446
1295
  } : {},
1447
1296
  ...result.nextSteps ? { NextSteps: result.nextSteps } : {},
1297
+ PermanentlyDeletedResources: result.permanentlyDeletedResources,
1448
1298
  DeploymentName: result.deploymentName,
1449
1299
  PackageName: result.packageName,
1450
1300
  PackageVersion: result.packageVersion
@@ -1581,8 +1431,8 @@ var registerDeployStatusCommand = (program) => {
1581
1431
  processContext.exit(1);
1582
1432
  return;
1583
1433
  }
1584
- const { feedScopeInitOverride: feedScopeInitOverride2 } = await import("./feed-resolver-bxj9xkgr.js");
1585
- const { FeedReadRefusedError, feedReadRefusalForApplication } = await import("./feed-session-sxga31vn.js");
1434
+ const { feedScopeInitOverride: feedScopeInitOverride2 } = await import("./feed-resolver-3xb7ayx4.js");
1435
+ const { FeedReadRefusedError, feedReadRefusalForApplication } = await import("./feed-session-7xqphdrg.js");
1586
1436
  const refuseFeed = (action) => {
1587
1437
  const refusal = feedReadRefusalForApplication(auth, action);
1588
1438
  if (!refusal) {
@@ -1601,14 +1451,14 @@ var registerDeployStatusCommand = (program) => {
1601
1451
  if (options.personalWorkspace === true && refuseFeed("Reading a Personal Workspace deployment")) {
1602
1452
  return;
1603
1453
  }
1604
- const { resolveFeedScopeOrFailureAsync: resolveFeedScopeOrFailureAsync2 } = await import("./feed-scope-failure-2kndwpf6.js");
1454
+ const { resolveFeedScopeOrFailureAsync: resolveFeedScopeOrFailureAsync2 } = await import("./feed-scope-failure-qps17dv3.js");
1605
1455
  const [scopeFailure, feedScope] = await resolveFeedScopeOrFailureAsync2(options, auth);
1606
1456
  if (scopeFailure) {
1607
1457
  OutputFormatter.error(scopeFailure);
1608
1458
  processContext.exit(1);
1609
1459
  return;
1610
1460
  }
1611
- const { describeDeploymentAsync, looksLikeDeploymentKey } = await import("./deploy-status-service-3req7hje.js");
1461
+ const { describeDeploymentAsync, looksLikeDeploymentKey } = await import("./deploy-status-service-kz3nk43q.js");
1612
1462
  if (feedScope.kind !== "tenant" && !looksLikeDeploymentKey(deployment) && refuseFeed(`Reading a deployment in the feed '${feedScope.name ?? feedScope.folderKey}'`)) {
1613
1463
  return;
1614
1464
  }
@@ -1649,7 +1499,7 @@ var registerDeployStatusCommand = (program) => {
1649
1499
  const api = new PipelinesApi(configuration);
1650
1500
  const [statusError, result] = await catchError(api.pipelinesGetPipelineDeploymentStatus({ pipelineDeploymentId: deployment }, feedSelected ? feedScopeInitOverride2(feedScope) : undefined));
1651
1501
  if (statusError) {
1652
- const { isPipelineDeploymentNotFoundError } = await import("./deployment-search-3mah6f0a.js");
1502
+ const { isPipelineDeploymentNotFoundError } = await import("./deployment-search-jvwyaqek.js");
1653
1503
  if (await isPipelineDeploymentNotFoundError(statusError)) {
1654
1504
  const [stateError, state] = await catchError(describe());
1655
1505
  if (stateError instanceof FeedReadRefusedError) {
@@ -1741,7 +1591,8 @@ function deploymentStateData(state) {
1741
1591
  Kind: resource.kind,
1742
1592
  Name: resource.name,
1743
1593
  Type: resource.type ?? null,
1744
- Reason: resource.reason ?? null
1594
+ Reason: resource.reason ?? null,
1595
+ FolderPaths: resource.folderPaths ?? null
1745
1596
  }))
1746
1597
  } : {},
1747
1598
  ...state.nextSteps ? { NextSteps: state.nextSteps } : {}
@@ -1764,15 +1615,18 @@ var SOLUTION_DEPLOY_UNINSTALL_EXAMPLES = [
1764
1615
  }
1765
1616
  ];
1766
1617
  var registerDeployUninstallCommand = (program) => {
1767
- program.command("uninstall").description("Uninstall a deployed solution. Removes all provisioned resources and the solution folder.").argument("<deployment-name>", "Name of the deployment to uninstall. Use 'solution deploy list' to find deployment names.").addOption(createHiddenDeprecatedTenantOption("-t, --tenant <tenant-name>")).option("--timeout <seconds>", "Timeout in seconds for uninstall polling (default: 360)", (v) => parseInt(v, 10), 360).option("--poll-interval <ms>", "Milliseconds between uninstall status polls (default: 5000)", (v) => parseInt(v, 10), 5000).option("--login-validity <minutes>", "Minimum minutes before token expiration to trigger a refresh (default: 10)", parseInt, 10).option("-y, --yes", "Confirm this irreversible operation (required; the CLI never prompts)").examples(SOLUTION_DEPLOY_UNINSTALL_EXAMPLES).trackedAction(processContext, async (deploymentName, options) => {
1618
+ program.command("uninstall").description("Uninstall a deployed solution. Removes all provisioned resources and the solution folder.").argument("<deployment-name>", "Name of the deployment to uninstall. Use 'solution deploy list' to find deployment names.").addOption(createHiddenDeprecatedTenantOption("-t, --tenant <tenant-name>")).option("--timeout <seconds>", "Timeout in seconds for uninstall polling (default: 360)", (v) => parseInt(v, 10), 360).option("--poll-interval <ms>", "Milliseconds between uninstall status polls (default: 5000)", (v) => parseInt(v, 10), 5000).option("--login-validity <minutes>", "Minimum minutes before token expiration to trigger a refresh (default: 10)", parseInt, 10).option("-y, --yes", "Confirm this irreversible operation (required; the CLI never prompts)").option("--force", "Force the uninstall past the two refusals Orchestrator lets you override: uncompleted jobs, and the permanent deletion of installed resources that were replaced by links. Also confirms the operation, so --yes is not needed in addition. Flag only; the CLI never prompts.").addOption(new Option("--feed <name-or-key>", "The feed the deployment lives in (name or folder key, from 'solution feeds list'). Only that feed is searched; without it the tenant feed, your Personal Workspace and the folder feeds are tried in turn. Needs a user session for a feed other than the tenant's. Mutually exclusive with --personal-workspace.").conflicts("personalWorkspace")).option("--personal-workspace", "The deployment lives in your Personal Workspace feed: only that feed is searched. Needs a user session.").examples(SOLUTION_DEPLOY_UNINSTALL_EXAMPLES).trackedAction(processContext, async (deploymentName, options) => {
1768
1619
  if (!requireConfirmation(options, `uninstall deployment '${deploymentName}'`)) {
1769
1620
  return;
1770
1621
  }
1771
1622
  const result = await uninstallDeploymentAsync(deploymentName, {
1772
1623
  tenant: options.tenant,
1624
+ personalWorkspace: options.personalWorkspace,
1625
+ feed: options.feed,
1773
1626
  timeout: options.timeout,
1774
1627
  pollInterval: options.pollInterval,
1775
1628
  loginValidity: options.loginValidity,
1629
+ force: options.force,
1776
1630
  signal: processContext.pollSignal
1777
1631
  });
1778
1632
  if (!result.ok) {
@@ -1781,7 +1635,8 @@ var registerDeployUninstallCommand = (program) => {
1781
1635
  Message: result.message,
1782
1636
  Instructions: result.instructions,
1783
1637
  ErrorCode: result.errorCode,
1784
- Retry: result.retry
1638
+ Retry: result.retry,
1639
+ ...result.data ? { Data: result.data } : {}
1785
1640
  });
1786
1641
  processContext.exit(result.exitCode);
1787
1642
  return;
@@ -1943,7 +1798,7 @@ var SOLUTION_DEPLOY_UPGRADE_EXAMPLES = [
1943
1798
  }
1944
1799
  ];
1945
1800
  var registerDeployUpgradeCommand = (program) => {
1946
- program.command("upgrade").description("Upgrade an existing deployment to another published version of its package in place — the CLI equivalent of the Orchestrator UI 'Upgrade' button. Use this when 'deploy run' is blocked because a deployment already exists. The deployment's existing configuration is preserved, so values already set on it (for example a credential asset's secret) are not reset to the package defaults. The package is validated against the target before anything is installed; a validation failure reports the errors and leaves the deployment on its current version. Address the deployment either by key (positional) or by --name with --package-name. Every call this command makes is an external-app (client-credentials) capable Pipelines endpoint, so both forms work from a CI/CD pipeline (on a server that predates the Pipelines deployment lookup, the key form falls back to the Solutions API for a user session); a deployment in a Personal Workspace or folder feed needs a user session, because the server ignores the feed header on client-credentials requests. Waits for the upgrade to finish unless --no-wait is passed; track a running upgrade with 'deploy status <pipeline-deployment-id>'.").argument("[deployment-key]", "Key of the deployment to upgrade, as 'solution deploy list' reports it (Key), or a stored InstallDeploymentKey. Resolved through the Pipelines deployment lookup: the deployment's name, package, current version and feed come from the server, so --package-name and --personal-workspace are not needed. On a server without that lookup, a user session reads the key through the Solutions API instead, where a Personal Workspace deployment needs --personal-workspace. Use either this or --name with --package-name.").option("-n, --name <deployment-name>", "Name of the deployment to upgrade, as reported by 'solution deploy list'. Goes with --package-name. The name is checked to exist first, because the install route would create a new deployment for a name it cannot find; this form never does.").option("--package-name <name>", "The deployment's package, for the --name form. Required there: it identifies the package version to install, and nothing name-keyed in Pipelines reports it.").addOption(createHiddenDeprecatedTenantOption("-t, --tenant <tenant-name>")).option("--version <version>", "Target package version (default: the newest published). Any published version of the same package is accepted, including an older one.").option("--personal-workspace", "With --name: upgrade a deployment in your Personal Workspace feed instead of the tenant. With a key the feed is read from the deployment itself and this flag is not needed, except on a server without the Pipelines deployment lookup, where a key is read on the tenant feed unless you pass it.").option("--discard-draft", "When the deployment has a pending draft (an earlier attempt that never completed, usually one rejected by validation), discard it first and upgrade the live version. Without it such a deployment is refused, because the server would re-run the draft, with the configuration it was rejected for, in place of this upgrade. With --name the draft is found through a user session only; under an external app, pass the deployment key.").option("--login-validity <minutes>", "Minimum minutes before token expiration to trigger a refresh (default: 10)", parseInt, 10).option("--no-wait", "Return as soon as the upgrade is accepted instead of waiting for it to finish.").option("--timeout <seconds>", "Seconds to wait for the upgrade to finish (default: 300)", (v) => parseInt(v, 10), 300).option("--poll-interval <ms>", "Milliseconds between status polls (default: 5000)", (v) => parseInt(v, 10), 5000).examples(SOLUTION_DEPLOY_UPGRADE_EXAMPLES).trackedAction(processContext, async (deploymentKey, options) => {
1801
+ program.command("upgrade").description("Upgrade an existing deployment to another published version of its package in place — the CLI equivalent of the Orchestrator UI 'Upgrade' button. Use this when 'deploy run' is blocked because a deployment already exists. The deployment's existing configuration is preserved, so values already set on it (for example a credential asset's secret) are not reset to the package defaults. The package is validated against the target before anything is installed; a validation failure reports the errors and leaves the deployment on its current version. Address the deployment either by key (positional) or by --name with --package-name. Every call this command makes is an external-app (client-credentials) capable Pipelines endpoint, so both forms work from a CI/CD pipeline (on a server that predates the Pipelines deployment lookup, the key form falls back to the Solutions API for a user session); a deployment in a Personal Workspace or folder feed needs a user session, because the server ignores the feed header on client-credentials requests. Waits for the upgrade to finish unless --no-wait is passed; track a running upgrade with 'deploy status <pipeline-deployment-id>'. When the new version replaces an installed resource with a link, the server deletes the installed copy and its data, and asks for confirmation first: the command stops and lists those resources unless --acknowledge-permanent-deletion is passed.").argument("[deployment-key]", "Key of the deployment to upgrade, as 'solution deploy list' reports it (Key), or a stored InstallDeploymentKey. Resolved through the Pipelines deployment lookup: the deployment's name, package, current version and feed come from the server, so --package-name and --personal-workspace are not needed. On a server without that lookup, a user session reads the key through the Solutions API instead, where a Personal Workspace deployment needs --personal-workspace. Use either this or --name with --package-name.").option("-n, --name <deployment-name>", "Name of the deployment to upgrade, as reported by 'solution deploy list'. Goes with --package-name. The name is checked to exist first, because the install route would create a new deployment for a name it cannot find; this form never does.").option("--package-name <name>", "The deployment's package, for the --name form. Required there: it identifies the package version to install, and nothing name-keyed in Pipelines reports it.").addOption(createHiddenDeprecatedTenantOption("-t, --tenant <tenant-name>")).option("--version <version>", "Target package version (default: the newest published). Any published version of the same package is accepted, including an older one.").option("--personal-workspace", "With --name: upgrade a deployment in your Personal Workspace feed instead of the tenant. With a key the feed is read from the deployment itself and this flag is not needed, except on a server without the Pipelines deployment lookup, where a key is read on the tenant feed unless you pass it.").option("--discard-draft", "When the deployment has a pending draft (an earlier attempt that never completed, usually one rejected by validation), discard it first and upgrade the live version. Without it such a deployment is refused, because the server would re-run the draft, with the configuration it was rejected for, in place of this upgrade. With --name the draft is found through a user session only; under an external app, pass the deployment key.").option("--acknowledge-permanent-deletion", "Confirm that installed resources the new version replaces with a link are permanently deleted, along with their data. Without it the upgrade stops at the server's confirmation request and lists those resources; nothing is installed. With it each listed resource is acknowledged and the same upgrade runs once more, within the same --timeout. Also re-runs a pending draft of the same version that awaits this confirmation instead of refusing it. Has no effect with --no-wait, which never sees the run end: such a draft is then refused as without the flag.").option("--login-validity <minutes>", "Minimum minutes before token expiration to trigger a refresh (default: 10)", parseInt, 10).option("--no-wait", "Return as soon as the upgrade is accepted instead of waiting for it to finish.").option("--timeout <seconds>", "Seconds to wait for the upgrade to finish (default: 300)", (v) => parseInt(v, 10), 300).option("--poll-interval <ms>", "Milliseconds between status polls (default: 5000)", (v) => parseInt(v, 10), 5000).examples(SOLUTION_DEPLOY_UPGRADE_EXAMPLES).trackedAction(processContext, async (deploymentKey, options) => {
1947
1802
  const result = await upgradeDeploymentAsync({
1948
1803
  deploymentKey,
1949
1804
  deploymentName: options.name,
@@ -1952,6 +1807,7 @@ var registerDeployUpgradeCommand = (program) => {
1952
1807
  version: options.version,
1953
1808
  personalWorkspace: options.personalWorkspace,
1954
1809
  discardDraft: options.discardDraft,
1810
+ acknowledgePermanentDeletion: options.acknowledgePermanentDeletion,
1955
1811
  loginValidity: options.loginValidity,
1956
1812
  noWait: options.wait === false,
1957
1813
  timeout: options.timeout,
@@ -1964,7 +1820,18 @@ var registerDeployUpgradeCommand = (program) => {
1964
1820
  Message: result.message,
1965
1821
  Instructions: result.instructions,
1966
1822
  ErrorCode: result.errorCode,
1967
- Retry: result.retry
1823
+ Retry: result.retry,
1824
+ ...result.permanentDeletionResources ? {
1825
+ Data: {
1826
+ PipelineDeploymentId: result.pipelineDeploymentId,
1827
+ DeploymentKey: result.deploymentKey,
1828
+ PermanentDeletionResources: result.permanentDeletionResources.map((resource) => ({
1829
+ Key: resource.key,
1830
+ Kind: resource.kind ?? null,
1831
+ Name: resource.name
1832
+ }))
1833
+ }
1834
+ } : {}
1968
1835
  });
1969
1836
  processContext.exit(result.exitCode);
1970
1837
  return;
@@ -1983,7 +1850,8 @@ var registerDeployUpgradeCommand = (program) => {
1983
1850
  Kind: resource.kind,
1984
1851
  Name: resource.name,
1985
1852
  Type: resource.type ?? null,
1986
- Reason: resource.reason ?? null
1853
+ Reason: resource.reason ?? null,
1854
+ FolderPaths: resource.folderPaths ?? null
1987
1855
  }))
1988
1856
  } : {},
1989
1857
  ...result.nextSteps ? { NextSteps: result.nextSteps } : {},
@@ -1993,7 +1861,8 @@ var registerDeployUpgradeCommand = (program) => {
1993
1861
  PipelineDeploymentId: result.pipelineDeploymentId,
1994
1862
  DeploymentKey: result.deploymentKey,
1995
1863
  InstallDeploymentKey: result.installDeploymentKey,
1996
- DiscardedDraftKey: result.discardedDraftKey
1864
+ DiscardedDraftKey: result.discardedDraftKey,
1865
+ PermanentlyDeletedResources: result.permanentlyDeletedResources
1997
1866
  }
1998
1867
  });
1999
1868
  });
@@ -2060,104 +1929,6 @@ async function writeMissingBriefingFilesAsync(solutionDir) {
2060
1929
  return written;
2061
1930
  }
2062
1931
 
2063
- // ../common/src/zip.ts
2064
- function resolveZipEntryPath(fs, root, entryName) {
2065
- if (entryName.includes("\x00")) {
2066
- throw new Error(`Invalid zip entry path: ${entryName}`);
2067
- }
2068
- const normalizedEntry = entryName.replace(/\\/g, "/");
2069
- if (normalizedEntry.startsWith("/")) {
2070
- throw new Error(`Unsafe absolute zip entry path: ${entryName}`);
2071
- }
2072
- const target = fs.path.resolve(root, normalizedEntry);
2073
- if (!isUnder(fs, root, target)) {
2074
- throw new Error(`Unsafe zip entry path: ${entryName}`);
2075
- }
2076
- return target;
2077
- }
2078
- function isUnder(fs, root, path) {
2079
- const relative = fs.path.relative(root, path);
2080
- return relative === "" || !relative.startsWith("..") && !fs.path.isAbsolute(relative);
2081
- }
2082
- async function assertNoEscapeThroughSymlink(fs, lexicalRoot, realRoot, path, entryName) {
2083
- const resolved = await fs.realpath(path);
2084
- if (isUnder(fs, realRoot, resolved) || isUnder(fs, lexicalRoot, resolved)) {
2085
- return;
2086
- }
2087
- throw new Error(`Unsafe zip entry path (escapes via a symlink at the destination): ${entryName}`);
2088
- }
2089
- async function mkdirUnderRoot(fs, lexicalRoot, realRoot, dir, entryName) {
2090
- const relative = fs.path.relative(lexicalRoot, dir);
2091
- if (relative === "") {
2092
- return;
2093
- }
2094
- let current = lexicalRoot;
2095
- for (const segment of relative.split(/[\\/]/)) {
2096
- if (segment === "") {
2097
- continue;
2098
- }
2099
- current = fs.path.join(current, segment);
2100
- await fs.mkdir(current);
2101
- await assertNoEscapeThroughSymlink(fs, lexicalRoot, realRoot, current, entryName);
2102
- }
2103
- }
2104
- async function extractZipDataToDir(fs, zipData, destinationDir) {
2105
- await fs.mkdir(destinationDir);
2106
- const lexicalRoot = fs.path.resolve(destinationDir);
2107
- const realRoot = await fs.realpath(lexicalRoot);
2108
- const entries = unzipSync(zipData);
2109
- for (const [entryName, content] of Object.entries(entries)) {
2110
- const target = resolveZipEntryPath(fs, lexicalRoot, entryName);
2111
- if (entryName.endsWith("/")) {
2112
- await mkdirUnderRoot(fs, lexicalRoot, realRoot, target, entryName);
2113
- continue;
2114
- }
2115
- await mkdirUnderRoot(fs, lexicalRoot, realRoot, fs.path.dirname(target), entryName);
2116
- await assertNoEscapeThroughSymlink(fs, lexicalRoot, realRoot, target, entryName);
2117
- await fs.writeFile(target, content);
2118
- }
2119
- }
2120
- async function extractArchive(archivePath, destinationDir) {
2121
- const fs = getFileSystem();
2122
- const data = await fs.readFile(archivePath);
2123
- if (data === null) {
2124
- throw new Error(`Archive not found: ${archivePath}`);
2125
- }
2126
- await extractZipDataToDir(fs, data, destinationDir);
2127
- }
2128
-
2129
- // src/services/archive-extract.ts
2130
- var SOLUTION_STORAGE_ENTRY = "SolutionStorage.json";
2131
- function isRootUipxEntry(name) {
2132
- return !name.includes("/") && name.endsWith(".uipx");
2133
- }
2134
- function readSolutionIdField(bytes) {
2135
- if (!bytes) {
2136
- return;
2137
- }
2138
- const [parseError, parsed] = catchError(() => JSON.parse(strFromU8(bytes)));
2139
- if (parseError || !parsed) {
2140
- return;
2141
- }
2142
- const id = parsed.SolutionId;
2143
- return typeof id === "string" && isGuid(id) ? id : undefined;
2144
- }
2145
- function readBundledSolutionId(archive) {
2146
- const [unzipError, entries] = catchError(() => unzipSync(archive, {
2147
- filter: (file) => file.name === SOLUTION_STORAGE_ENTRY || isRootUipxEntry(file.name)
2148
- }));
2149
- if (unzipError || !entries) {
2150
- logger.debug(`Could not inspect the solution archive for its SolutionId: ${unzipError?.message ?? "no entries"}`);
2151
- return;
2152
- }
2153
- const rootUipxName = Object.keys(entries).find(isRootUipxEntry);
2154
- const solutionId = readSolutionIdField(entries[SOLUTION_STORAGE_ENTRY]) ?? readSolutionIdField(rootUipxName ? entries[rootUipxName] : undefined);
2155
- if (!solutionId) {
2156
- logger.debug("No SolutionId found in the solution archive.");
2157
- }
2158
- return solutionId;
2159
- }
2160
-
2161
1932
  // src/commands/download.ts
2162
1933
  var SOLUTION_DOWNLOAD_EXAMPLES = [
2163
1934
  {
@@ -2217,6 +1988,7 @@ async function downloadSolution(solutionId, options, command) {
2217
1988
  const extractedTo = options.extract ? fs.path.join(outputDir, filename.replace(/\.uis$/, "")) : undefined;
2218
1989
  let briefingFiles = [];
2219
1990
  if (extractedTo) {
1991
+ const { extractArchive } = await import("./archive-extract-x35t9ktj.js");
2220
1992
  await extractArchive(outputPath, extractedTo);
2221
1993
  logger.info(`Extracted to ${extractedTo}`);
2222
1994
  briefingFiles = await writeBriefingFiles(extractedTo);
@@ -2337,7 +2109,7 @@ var SOLUTION_NEW_EXAMPLES = [
2337
2109
  }
2338
2110
  ];
2339
2111
  var registerNewCommand = (program) => {
2340
- program.command("init").description("Initialize a new empty UiPath solution. Creates a directory named after the solution containing a .uipx manifest file with an empty Projects array, plus AGENTS.md and CLAUDE.md briefing files that orient AI coding agents to the solution. Use 'solution projects add' to add projects afterward.").argument("<solutionName>", "Solution name or path. Creates a directory with this name containing a .uipx manifest file.").examples(SOLUTION_NEW_EXAMPLES).trackedAction(processContext, async (solutionName) => {
2112
+ program.command("init").description("Initialize a new empty UiPath solution. Creates a directory named after the solution containing a .uipx manifest file with an empty Projects array, plus AGENTS.md and CLAUDE.md briefing files that orient AI coding agents to the solution. Use 'solution projects add' to add projects afterward.").argument("<solution-name>", "Solution name or path. Creates a directory with this name containing a .uipx manifest file.").examples(SOLUTION_NEW_EXAMPLES).trackedAction(processContext, async (solutionName) => {
2341
2113
  const [briefingError, briefingContent] = await catchError(renderBriefingTemplateAsync());
2342
2114
  if (briefingError) {
2343
2115
  OutputFormatter.error({
@@ -2413,6 +2185,17 @@ var SOLUTION_PACK_EXAMPLES = [
2413
2185
  }
2414
2186
  }
2415
2187
  },
2188
+ {
2189
+ Description: "Pack one project of the solution into its own .nupkg instead of the solution .zip, as a stand-alone project packs: no solution resources go into it. --project takes the project's Id from the .uipx or its path relative to the solution; --package-id overrides the id a whole-solution pack would give it.",
2190
+ Command: "uip solution pack ./my-solution ./dist --project MyProcess --package-id Acme.MyProcess --version 1.2.0",
2191
+ Output: {
2192
+ Code: "SolutionPack",
2193
+ Data: {
2194
+ Package: "Acme.MyProcess@1.2.0",
2195
+ Packages: "/home/me/dist/Acme.MyProcess.1.2.0.nupkg"
2196
+ }
2197
+ }
2198
+ },
2416
2199
  {
2417
2200
  Description: "Pack without running the workflow analyzer on the RPA projects. Compilation and validation still run — only the analyzer rules are skipped.",
2418
2201
  Command: "uip solution pack ./my-solution ./dist --version 1.2.0 --skip-analyze",
@@ -2429,7 +2212,7 @@ var SOLUTION_PACK_EXAMPLES = [
2429
2212
  Output: PACKED_1_2_0_OUTPUT
2430
2213
  },
2431
2214
  {
2432
- Description: "Analyze the RPA projects against the governance policy published in AutomationOps for the signed-in tenant. The value is the product whose policy is downloaded — pass StudioWeb for the default one.",
2215
+ Description: "Analyze the RPA projects against the governance policy published in AutomationOps for the signed-in tenant. The value is the product whose policy is downloaded — pass StudioWeb for the default one. Signed in as an external application, the policy is not downloaded yet.",
2433
2216
  Command: "uip solution pack ./my-solution ./dist --version 1.2.0 --governance-product Development",
2434
2217
  Output: PACKED_1_2_0_OUTPUT
2435
2218
  }
@@ -2439,13 +2222,29 @@ function parseIgnoredRules(value, previous = []) {
2439
2222
  return [...new Set([...previous, ...rules])];
2440
2223
  }
2441
2224
  var registerPackCommand = (program) => {
2442
- const command = program.command("pack").description("Pack a UiPath solution into a deployable .zip package. Accepts a solution directory (containing .uipx) or a .uis file. Output is used with 'solution publish' to upload to UiPath. Pass --dry-run to check that the solution packs without producing a package.").argument("<solutionPath>", "Path to a solution directory (containing .uipx) or a .uis file").argument("[output-path]", "Output directory where the packed solution will be saved. Required unless --dry-run is set.").option("-n, --name <name>", "Package name (default: solution folder name or .uis file name)").option("-v, --version <version>", "Package version (default: 1.0.0)", "1.0.0").addOption(new Option("--solution-type <type>", "What kind of solution this is. Omitted by default, which means a standard solution.").choices(["standard", "vertical"]).hideHelp()).option("--nuget-sources-config-path <path>", "Path to NuGet sources configuration file").option("--exclude-configured-sources", "Resolve project dependencies only from the tenant feeds and any --nuget-sources-config-path. Drops the built-in UiPath and nuget.org feeds, so a dependency that is not on those feeds fails to restore.").option("--feed-folder <name>", "Resolve project dependencies from this Orchestrator folder's library feed instead of every tenant feed. Accepts a folder name or fully qualified path.").option("--signing-certificate-path <path>", "Path to .pfx certificate file used to sign each packed project .nupkg").option("--signing-certificate-password <password>", "Certificate password. Use env.ENV_NAME to read from an environment variable.").option("--signing-timestamp-server <url>", "Timestamp server URL").option("--skip-analyze", "Skip the workflow analyzer for every RPA project in the solution. Compilation and validation still run.").option("--ignored-rules <rules>", "Analyzer rule IDs whose findings are ignored for every RPA project, e.g. ST-USG-034,ST-MRD-002. Comma-separated; repeat the flag to add more. The rules still run, but their findings are not reported and do not fail the pack. Applies on top of --governance-file-path or the shipped rules; when the signed-in tenant publishes an AutomationOps policy, the list is not applied and a warning says so.", parseIgnoredRules).option("--governance-file-path <path>", "Analyze every RPA project against this local governance policy file, instead of the analyzer rules shipped with the WorkflowCompiler. When you are signed in the tenant is asked first — about StudioWeb unless --governance-product names another product — and when the tenant publishes a policy of its own, that policy is used instead and this file is ignored with a warning.").option("--governance-product <product>", "Analyze every RPA project against the governance policy published in AutomationOps for the signed-in tenant. The value is the product whose policy is downloaded, e.g. StudioWeb, Development, Business.").addOption(new Option("--automation-ops-profile <profile>").hideHelp());
2225
+ const command = program.command("pack").description("Pack a UiPath solution into a deployable .zip package. Accepts a solution directory (containing .uipx) or a .uis file. Output is used with 'solution publish' to upload to UiPath. Pass --project to pack one project into its own .nupkg instead. Pass --dry-run to check that the solution packs without producing a package.").argument("<solution-path>", "Path to a solution directory (containing .uipx) or a .uis file").argument("[output-path]", "Output directory where the packed solution will be saved. Required unless --dry-run is set.").option("-n, --name <name>", "Package name (default: solution folder name or .uis file name)").option("-v, --version <version>", "Package version (default: 1.0.0)", "1.0.0").addOption(new Option("--solution-type <type>", "What kind of solution this is. Omitted by default, which means a standard solution.").choices(["standard", "vertical"]).hideHelp()).option("--project <id-or-path>", "Pack only this project of the solution into its own .nupkg, instead of the solution .zip. It packs as a stand-alone project: no solution resources go into it. Takes the project's Id from the .uipx, or its path relative to the solution folder; a .uis file is not supported.").option("--package-id <id>", "Package id for the project packed with --project, instead of the id a whole-solution pack gives it (<solution>.<type>.<project folder>). Requires --project.").option("--nuget-sources-config-path <path>", "Path to NuGet sources configuration file").option("--exclude-configured-sources", "Resolve project dependencies only from the tenant feeds and any --nuget-sources-config-path. Drops the built-in UiPath and nuget.org feeds, so a dependency that is not on those feeds fails to restore.").option("--feed-folder <name>", "Resolve project dependencies from this Orchestrator folder's library feed instead of every tenant feed. Accepts a folder name or fully qualified path.").option("--signing-certificate-path <path>", "Path to .pfx certificate file used to sign each packed project .nupkg").option("--signing-certificate-password <password>", "Certificate password. Use env.ENV_NAME to read from an environment variable.").option("--signing-timestamp-server <url>", "Timestamp server URL").option("--skip-analyze", "Skip the workflow analyzer for every RPA project in the solution. Compilation and validation still run.").option("--ignored-rules <rules>", "Analyzer rule IDs whose findings are ignored for every RPA project, e.g. ST-USG-034,ST-MRD-002. Comma-separated; repeat the flag to add more. The rules still run, but their findings are not reported and do not fail the pack. Applies on top of --governance-file-path or the shipped rules; when the signed-in tenant publishes an AutomationOps policy, the list is not applied and a warning says so.", parseIgnoredRules).option("--governance-file-path <path>", "Analyze every RPA project against this local governance policy file, instead of the analyzer rules shipped with the WorkflowCompiler. When you are signed in as a user the tenant is asked first — about StudioWeb unless --governance-product names another product — and when the tenant publishes a policy of its own, that policy is used instead and this file is ignored with a warning.").option("--governance-product <product>", "Analyze every RPA project against the governance policy published in AutomationOps for the signed-in tenant. The value is the product whose policy is downloaded, e.g. StudioWeb, Development, Business. Signed in as an external application, the policy is not downloaded yet (AutomationOps does not accept external-application tokens): the pack uses --governance-file-path if given, otherwise the rules shipped with the WorkflowCompiler.").addOption(new Option("--automation-ops-profile <profile>").hideHelp());
2443
2226
  registerPackageMetadataOptions(command).option("--login-validity <minutes>", "Minimum minutes before token expiration to trigger a refresh (default: 10)", parseInt, 10).option("--dry-run", "Run the full pack pipeline against a temporary directory and discard the output. Catches pack-time failures; does not inspect the produced package contents.").examples(SOLUTION_PACK_EXAMPLES).trackedAction(processContext, async (solutionPath, outputPath, options) => {
2227
+ const {
2228
+ GOVERNANCE_OPTION_INSTRUCTIONS,
2229
+ validateGovernanceOptions
2230
+ } = await import("./governance-options-amc1v319.js");
2231
+ const { PackCommandService } = await import("./pack-command-service-8etwpgm9.js");
2444
2232
  if (!options.dryRun && outputPath === undefined) {
2445
2233
  OutputFormatter.error({
2446
2234
  Result: RESULTS.Failure,
2447
- Message: "Missing required argument: outputPath. Provide an output directory, or pass --dry-run to validate without packing.",
2448
- Instructions: "Run `uip solution pack <solutionPath> <outputPath>` to produce a package, or `uip solution pack <solutionPath> --dry-run` to validate only."
2235
+ Message: "Missing required argument: output-path. Provide an output directory, or pass --dry-run to validate without packing.",
2236
+ Instructions: "Run `uip solution pack <solution-path> <output-path>` to produce a package, or `uip solution pack <solution-path> --dry-run` to validate only."
2237
+ });
2238
+ processContext.exit(1);
2239
+ return;
2240
+ }
2241
+ const projectError = validatePackProjectOptions(options);
2242
+ if (projectError) {
2243
+ OutputFormatter.error({
2244
+ Result: RESULTS.Failure,
2245
+ ErrorCode: "invalid_argument",
2246
+ Message: projectError,
2247
+ Instructions: "Pass --project <id-or-path> to pack one project, and --package-id <id> (not --name) only together with it: `uip solution pack <solution-path> <output-path> --project <id-or-path> [--package-id <id>]`."
2449
2248
  });
2450
2249
  processContext.exit(1);
2451
2250
  return;
@@ -2485,6 +2284,8 @@ var registerPackCommand = (program) => {
2485
2284
  const packOptions = {
2486
2285
  output: outputPath,
2487
2286
  name: options.name,
2287
+ project: options.project,
2288
+ packageId: options.packageId,
2488
2289
  version: options.version,
2489
2290
  solutionType: options.solutionType,
2490
2291
  loginValidity: options.loginValidity,
@@ -2840,40 +2641,6 @@ var registerPackagesCommand = (program) => {
2840
2641
 
2841
2642
  // src/commands/project-add.ts
2842
2643
  import { randomUUID } from "node:crypto";
2843
-
2844
- // src/commands/project-command-utils.ts
2845
- function rejectUnsupportedProjectType(projectType, failureMessage) {
2846
- const reason = unsupportedSolutionProjectType(projectType);
2847
- if (!reason) {
2848
- return false;
2849
- }
2850
- OutputFormatter.error({
2851
- Result: RESULTS.Failure,
2852
- Message: failureMessage,
2853
- Instructions: reason
2854
- });
2855
- processContext.exit(1);
2856
- return true;
2857
- }
2858
- function projectManifestInstructions(fileName, readProjectError, verb) {
2859
- if (fileName !== "uipath.json" || !isMissingProjectTypeError(readProjectError)) {
2860
- return readProjectError.message;
2861
- }
2862
- return `${readProjectError.message} If this is a coded app, scaffold it with 'uip codedapp init <project-path>' — that writes the project.uiproj this command registers — then run 'uip solution projects ${verb} <project-path>' again.`;
2863
- }
2864
- function resourcesPendingForProjectType(projectType) {
2865
- return !hasBareTemplateRow(projectType) && hasAnyTemplateRow(projectType);
2866
- }
2867
- function hostGeneratesResources(projectType) {
2868
- return hasBareTemplateRow(projectType);
2869
- }
2870
- function resourcesPendingWarning(projectType) {
2871
- const verb = toolVerbForProjectType(projectType);
2872
- const needs = verb ? `that needs the '${verb}' tool installed ('uip tools install ${verb}')` : "that needs the tool that owns this project type installed";
2873
- return `No solution resources were generated for this project yet. Run 'uip solution resources refresh' to create them — ${needs}. 'uip solution pack' and 'uip solution upload' do it too.`;
2874
- }
2875
-
2876
- // src/commands/project-add.ts
2877
2644
  var PROJECT_ADD_EXAMPLES = [
2878
2645
  {
2879
2646
  Description: "Register an existing project subfolder in a solution",
@@ -2890,6 +2657,7 @@ var PROJECT_ADD_EXAMPLES = [
2890
2657
  }
2891
2658
  ];
2892
2659
  async function hasProjectInSolution(fs, solutionDir, projectDir, projects) {
2660
+ const { toPortableRelativePath } = await import("./index-6wak6hg6.js");
2893
2661
  const projectDirReal = await canonicalizePath(fs, projectDir);
2894
2662
  for (const project of projects ?? []) {
2895
2663
  const candidateDir = fs.path.resolve(solutionDir, fs.path.dirname(toPortableRelativePath(project.ProjectRelativePath)));
@@ -2905,9 +2673,29 @@ async function canonicalizePath(fs, path) {
2905
2673
  return error || !realPath ? path : realPath;
2906
2674
  }
2907
2675
  var registerProjectAddCommand = (project) => {
2908
- project.command("add").description("Register an existing project subfolder in the .uipx solution manifest. The project folder must already reside inside the solution directory. Use 'projects import' instead to copy an external project into the solution.").argument("<project-path>", "Path to the project folder (must contain project.uiproj, project.json, or uipath.json)").argument("[solutionFile]", "Path to the .uipx solution file (defaults to the nearest .uipx file found by searching up from the project path)").examples(PROJECT_ADD_EXAMPLES).trackedAction(processContext, async (projectPath, solutionFile) => {
2676
+ project.command("add").description("Register an existing project subfolder in the .uipx solution manifest. The project folder must already reside inside the solution directory. Use 'projects import' instead to copy an external project into the solution.").argument("<project-path>", "Path to the project folder (must contain project.uiproj, project.json, or uipath.json), or to that manifest file itself").argument("[solution-file]", "Path to the .uipx solution file (defaults to the nearest .uipx file found by searching up from the project path)").examples(PROJECT_ADD_EXAMPLES).trackedAction(processContext, async (projectPath, solutionFile) => {
2677
+ const {
2678
+ createProjectInSolutionBuilder,
2679
+ findProjectFile,
2680
+ isProjectManifestError,
2681
+ readProjectFile,
2682
+ readSolutionFile,
2683
+ resolveSolutionFilePath,
2684
+ restoreSolutionFile,
2685
+ syncResourcesFromBindings,
2686
+ writeSolutionFile
2687
+ } = await import("./index-prm27bvm.js");
2688
+ const { toPortableRelativePath } = await import("./index-6wak6hg6.js");
2689
+ const {
2690
+ hostGeneratesResources,
2691
+ projectManifestInstructions,
2692
+ rejectUnsupportedProjectType,
2693
+ resolveProjectManifestDirectory,
2694
+ resourcesPendingForProjectType,
2695
+ resourcesPendingWarning
2696
+ } = await import("./project-command-utils-t6pmpvq3.js");
2909
2697
  const fs = getFileSystem();
2910
- const resolvedProjectPath = fs.path.resolve(fs.env.cwd(), projectPath);
2698
+ const resolvedProjectPath = await resolveProjectManifestDirectory(fs, fs.path.resolve(fs.env.cwd(), projectPath));
2911
2699
  const isResolvedProjectPathValid = await fs.exists(resolvedProjectPath);
2912
2700
  if (!isResolvedProjectPathValid) {
2913
2701
  OutputFormatter.error({
@@ -3048,7 +2836,7 @@ import { randomUUID as randomUUID2 } from "node:crypto";
3048
2836
  var PROJECT_IMPORT_EXAMPLES = [
3049
2837
  {
3050
2838
  Description: "Copy an external project folder into a solution",
3051
- Command: "uip solution projects import ./external-project --solutionFile ./my-solution/my-solution.uipx",
2839
+ Command: "uip solution projects import ./external-project --solution-file ./my-solution/my-solution.uipx",
3052
2840
  Output: {
3053
2841
  Code: "ProjectImport",
3054
2842
  Data: {
@@ -3061,7 +2849,25 @@ var PROJECT_IMPORT_EXAMPLES = [
3061
2849
  }
3062
2850
  ];
3063
2851
  var registerProjectImportCommand = (project) => {
3064
- project.command("import").description("Copy an external project folder into the solution directory and register it in the .uipx manifest. Unlike 'projects add' which references an existing subfolder, import copies the source files into the solution tree.").argument("<source>", "Path to the project folder to import (must contain project.uiproj, project.json, or uipath.json)").option("--solutionFile <path>", "Path to the .uipx solution file (defaults to the nearest .uipx file found by searching up from the current directory)").examples(PROJECT_IMPORT_EXAMPLES).trackedAction(processContext, async (sourcePath, options) => {
2852
+ const command = project.command("import").description("Copy an external project folder into the solution directory and register it in the .uipx manifest. Unlike 'projects add' which references an existing subfolder, import copies the source files into the solution tree.").argument("<source>", "Path to the project folder to import (must contain project.uiproj, project.json, or uipath.json)").option("--solution-file <path>", "Path to the .uipx solution file (defaults to the nearest .uipx file found by searching up from the current directory)").examples(PROJECT_IMPORT_EXAMPLES).trackedAction(processContext, async (sourcePath, options) => {
2853
+ const {
2854
+ createProjectInSolutionBuilder,
2855
+ findProjectFile,
2856
+ isProjectManifestError,
2857
+ readProjectFile,
2858
+ readSolutionFile,
2859
+ resolveSolutionFilePath,
2860
+ syncResourcesFromBindings,
2861
+ writeSolutionFile
2862
+ } = await import("./index-prm27bvm.js");
2863
+ const { toPortableRelativePath } = await import("./index-6wak6hg6.js");
2864
+ const {
2865
+ hostGeneratesResources,
2866
+ projectManifestInstructions,
2867
+ rejectUnsupportedProjectType,
2868
+ resourcesPendingForProjectType,
2869
+ resourcesPendingWarning
2870
+ } = await import("./project-command-utils-t6pmpvq3.js");
3065
2871
  const { solutionFile } = options;
3066
2872
  const fs = getFileSystem();
3067
2873
  const cwd = fs.env.cwd();
@@ -3229,6 +3035,7 @@ var registerProjectImportCommand = (project) => {
3229
3035
  }
3230
3036
  });
3231
3037
  });
3038
+ addDeprecatedOptionAlias(command, "--solutionFile <path>", "--solution-file");
3232
3039
  };
3233
3040
 
3234
3041
  // src/commands/project-list.ts
@@ -3246,6 +3053,13 @@ function fallbackProjectName(fs, solutionDir, projectRelativePath) {
3246
3053
  const projectDir = fs.path.dirname(projectRelativePath);
3247
3054
  return projectDir && projectDir !== "." ? fs.path.basename(projectDir) : fs.path.basename(solutionDir);
3248
3055
  }
3056
+ async function createPackageIdReaderAsync(fs, solutionDir, solutionName) {
3057
+ const { readMemberPackageIdAsync } = await import("./package-id-c18sx4mz.js");
3058
+ return async (project) => {
3059
+ const [error, packageId] = await catchError(readMemberPackageIdAsync(fs, project, solutionDir, solutionName));
3060
+ return error ? undefined : packageId ?? undefined;
3061
+ };
3062
+ }
3249
3063
  var PROJECT_LIST_EXAMPLES = [
3250
3064
  {
3251
3065
  Description: "List the local projects registered in the .uipx solution manifest (run from inside the solution dir, or pass --solution-folder)",
@@ -3258,14 +3072,16 @@ var PROJECT_LIST_EXAMPLES = [
3258
3072
  Type: "Process",
3259
3073
  Id: "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
3260
3074
  ProjectRelativePath: "MyProject/project.uiproj",
3261
- ProjectFilePath: "/workspace/my-solution/MyProject/project.uiproj"
3075
+ ProjectFilePath: "/workspace/my-solution/MyProject/project.uiproj",
3076
+ PackageId: "my-solution.Rpa.MyProject"
3262
3077
  }
3263
3078
  ]
3264
3079
  }
3265
3080
  }
3266
3081
  ];
3267
3082
  var registerProjectListCommand = (project) => {
3268
- project.command("list").description("List the projects registered in the local .uipx solution manifest. " + "Reads only on-disk metadata — does not call any backend.").option("--solution-folder <path>", "Path to the solution root folder (defaults to current directory)").examples(PROJECT_LIST_EXAMPLES).trackedAction(processContext, async (options) => {
3083
+ project.command("list").description("List the projects registered in the local .uipx solution manifest, each with the package id a solution pack gives it. " + "Reads only on-disk metadata — does not call any backend.").option("--solution-folder <path>", "Path to the solution root folder (defaults to current directory)").examples(PROJECT_LIST_EXAMPLES).trackedAction(processContext, async (options) => {
3084
+ const { readSolutionFile, resolveSolutionFilePath } = await import("./index-prm27bvm.js");
3269
3085
  const fs = getFileSystem();
3270
3086
  const solutionPath = options.solutionFolder ?? ".";
3271
3087
  const resolvedPath = fs.path.resolve(fs.env.cwd(), solutionPath);
@@ -3300,6 +3116,7 @@ var registerProjectListCommand = (project) => {
3300
3116
  return;
3301
3117
  }
3302
3118
  const solutionDir = fs.path.dirname(resolvedSolutionFile);
3119
+ const readPackageIdAsync = await createPackageIdReaderAsync(fs, solutionDir, fs.path.basename(resolvedSolutionFile).replace(/\.uipx$/i, ""));
3303
3120
  const projects = parsedSolution.solution.Projects ?? [];
3304
3121
  const data = await Promise.all(projects.map(async (p) => {
3305
3122
  const projectFilePath = fs.path.resolve(solutionDir, p.ProjectRelativePath);
@@ -3309,7 +3126,12 @@ var registerProjectListCommand = (project) => {
3309
3126
  Type: p.Type,
3310
3127
  Id: p.Id,
3311
3128
  ProjectRelativePath: p.ProjectRelativePath,
3312
- ProjectFilePath: projectFilePath
3129
+ ProjectFilePath: projectFilePath,
3130
+ PackageId: await readPackageIdAsync({
3131
+ Id: p.Id,
3132
+ Type: p.Type,
3133
+ ProjectRelativePath: p.ProjectRelativePath
3134
+ })
3313
3135
  };
3314
3136
  }));
3315
3137
  OutputFormatter.success({
@@ -3492,10 +3314,20 @@ var PROJECT_REMOVE_EXAMPLES = [
3492
3314
  }
3493
3315
  ];
3494
3316
  var registerProjectRemoveCommand = (project) => {
3495
- project.command("remove").description("Unregister a project from the .uipx solution manifest and remove its entry from the solution builder. Does not delete the project files from disk. Doesn't remove the last project in a solution.").argument("<project-path>", "Path to the project folder to remove").argument("[solutionFile]", "Path to the .uipx solution file (defaults to the nearest .uipx file found by searching up from the project path)").examples(PROJECT_REMOVE_EXAMPLES).trackedAction(processContext, async (projectPath, solutionFile) => {
3317
+ project.command("remove").description("Unregister a project from the .uipx solution manifest and remove its entry from the solution builder. Does not delete the project files from disk. Doesn't remove the last project in a solution.").argument("<project-path>", "Path to the project folder to remove, or to its project manifest file (the form the .uipx records)").argument("[solution-file]", "Path to the .uipx solution file (defaults to the nearest .uipx file found by searching up from the project path)").examples(PROJECT_REMOVE_EXAMPLES).trackedAction(processContext, async (projectPath, solutionFile) => {
3318
+ const {
3319
+ createResourceBuilderServices,
3320
+ readSolutionFile,
3321
+ resolveSolutionFilePath,
3322
+ restoreSolutionFile,
3323
+ writeSolutionFile
3324
+ } = await import("./index-prm27bvm.js");
3325
+ const { toPortableRelativePath } = await import("./index-6wak6hg6.js");
3326
+ const { resolveSolutionSearchStart } = await import("./project-command-utils-t6pmpvq3.js");
3496
3327
  const fs = getFileSystem();
3497
3328
  const resolvedProjectPath = fs.path.resolve(fs.env.cwd(), projectPath);
3498
- const [solutionFileError, resolvedSolutionFile] = await resolveSolutionFilePath(solutionFile, resolvedProjectPath);
3329
+ const searchStart = solutionFile ? resolvedProjectPath : await resolveSolutionSearchStart(fs, resolvedProjectPath);
3330
+ const [solutionFileError, resolvedSolutionFile] = await resolveSolutionFilePath(solutionFile, searchStart);
3499
3331
  if (solutionFileError) {
3500
3332
  OutputFormatter.error({
3501
3333
  Result: RESULTS.Failure,
@@ -3529,7 +3361,11 @@ var registerProjectRemoveCommand = (project) => {
3529
3361
  return;
3530
3362
  }
3531
3363
  const { solution, rawContent: originalSolutionContent } = parsedSolution;
3532
- const projectIndex = (solution.Projects ?? []).findIndex((p) => fs.path.dirname(toPortableRelativePath(p.ProjectRelativePath)) === toPortableRelativePath(relativePath));
3364
+ const requestedPath = toPortableRelativePath(relativePath);
3365
+ const projectIndex = (solution.Projects ?? []).findIndex((p) => {
3366
+ const recorded = toPortableRelativePath(p.ProjectRelativePath);
3367
+ return recorded === requestedPath || fs.path.dirname(recorded) === requestedPath;
3368
+ });
3533
3369
  if (projectIndex === -1) {
3534
3370
  OutputFormatter.error({
3535
3371
  Result: RESULTS.Failure,
@@ -3786,113 +3622,6 @@ var registerProjectCommand = (program) => {
3786
3622
  wireProjectSubcommands(project);
3787
3623
  };
3788
3624
 
3789
- // src/services/ship-telemetry.ts
3790
- var PROJECT_TYPE_MAP = {
3791
- Agent: "low_code_agent",
3792
- Api: "api_workflow",
3793
- AppV2: "coded_app",
3794
- CaseManagement: "case",
3795
- Flow: "flow",
3796
- Process: "rpa",
3797
- ProcessOrchestration: "bpmn",
3798
- WebApp: "coded_app",
3799
- processOrchestration: "bpmn"
3800
- };
3801
- function isRecord(value) {
3802
- return typeof value === "object" && value !== null && !Array.isArray(value);
3803
- }
3804
- function normalizeShipProjectType(projectType) {
3805
- return PROJECT_TYPE_MAP[projectType] ?? projectType.trim().toLowerCase();
3806
- }
3807
- function summarizeShipProjectTypes(projectTypes) {
3808
- const normalized = [
3809
- ...new Set(projectTypes.map((projectType) => projectType.trim()).filter(Boolean).map(normalizeShipProjectType))
3810
- ];
3811
- if (normalized.length === 0) {
3812
- return { projectType: "unknown" };
3813
- }
3814
- if (normalized.length === 1) {
3815
- return { projectType: normalized[0] };
3816
- }
3817
- const sortedProjectTypes = [...normalized];
3818
- sortedProjectTypes.sort((left, right) => left.localeCompare(right));
3819
- return {
3820
- projectType: "mixed",
3821
- projectTypes: sortedProjectTypes.join(",")
3822
- };
3823
- }
3824
- function readProjectTypesFromUipx(content) {
3825
- const parsed = JSON.parse(content);
3826
- if (!isRecord(parsed) || !Array.isArray(parsed.Projects)) {
3827
- return [];
3828
- }
3829
- return parsed.Projects.map((project) => {
3830
- if (!isRecord(project)) {
3831
- return;
3832
- }
3833
- return typeof project.Type === "string" ? project.Type : undefined;
3834
- }).filter((projectType) => projectType !== undefined);
3835
- }
3836
- var MAX_INSPECTABLE_PACKAGE_BYTES = 256 * 1024 * 1024;
3837
- function isProjectManifestEntry(name) {
3838
- return name.endsWith(".uipx");
3839
- }
3840
- function unzipProjectManifests(archive) {
3841
- return new Promise((resolve, reject) => {
3842
- unzip(archive, { filter: (file) => isProjectManifestEntry(file.name) }, (error, entries) => {
3843
- if (error) {
3844
- reject(error);
3845
- return;
3846
- }
3847
- resolve(entries);
3848
- });
3849
- });
3850
- }
3851
- async function inspectSolutionPackageProjectTypes(packagePath) {
3852
- const fs = getFileSystem();
3853
- const [statError, stats] = await catchError(fs.stat(packagePath));
3854
- if (statError || !stats) {
3855
- logger.debug(`[Cli.ShipSucceeded] Could not stat solution package for project type telemetry: ${statError?.message ?? "no stats"}`);
3856
- return { projectType: "unknown" };
3857
- }
3858
- if (stats.size > MAX_INSPECTABLE_PACKAGE_BYTES) {
3859
- logger.debug(`[Cli.ShipSucceeded] Solution package is ${stats.size} bytes, over the ${MAX_INSPECTABLE_PACKAGE_BYTES}-byte inspection cap; skipping project type telemetry.`);
3860
- return { projectType: "unknown" };
3861
- }
3862
- const [readError, archive] = await catchError(fs.readFile(packagePath));
3863
- if (readError || !archive) {
3864
- logger.debug(`[Cli.ShipSucceeded] Could not read solution package for project type telemetry: ${readError?.message ?? "empty archive"}`);
3865
- return { projectType: "unknown" };
3866
- }
3867
- const [unzipError, entries] = await catchError(unzipProjectManifests(new Uint8Array(archive)));
3868
- if (unzipError || !entries) {
3869
- logger.debug(`[Cli.ShipSucceeded] Could not inspect solution package zip: ${unzipError?.message ?? "no entries"}`);
3870
- return { projectType: "unknown" };
3871
- }
3872
- const decoder = new TextDecoder;
3873
- const projectTypes = [];
3874
- for (const [entryName, entryBytes] of Object.entries(entries)) {
3875
- if (!isProjectManifestEntry(entryName)) {
3876
- continue;
3877
- }
3878
- const [parseError, parsedTypes] = await catchError(Promise.resolve().then(() => readProjectTypesFromUipx(decoder.decode(entryBytes))));
3879
- if (parseError) {
3880
- logger.debug(`[Cli.ShipSucceeded] Could not parse ${entryName} for project type telemetry: ${parseError.message}`);
3881
- continue;
3882
- }
3883
- projectTypes.push(...parsedTypes);
3884
- }
3885
- return summarizeShipProjectTypes(projectTypes);
3886
- }
3887
- function trackSolutionShipSucceeded(payload) {
3888
- const { projectTypeSummary, ...rest } = payload;
3889
- return trackShipSucceeded({
3890
- ...rest,
3891
- [ShipDimensions.ProjectType]: projectTypeSummary.projectType,
3892
- [ShipDimensions.ProjectTypes]: projectTypeSummary.projectTypes
3893
- });
3894
- }
3895
-
3896
3625
  // src/commands/publish.ts
3897
3626
  var PUBLISHED_STATUS = "Package is published to Orchestrator but not yet deployed";
3898
3627
  var NEXT_STEPS_MESSAGE = "Package is published to Orchestrator but not yet deployed. " + "Deploy/activate it into an Orchestrator folder before it appears in the " + "processes list or can be started as a job.";
@@ -3987,7 +3716,7 @@ var EXIT_CODES_BY_REASON = {
3987
3716
  poll_timeout: 2
3988
3717
  };
3989
3718
  var registerPublishCommand = (program) => {
3990
- const command = program.command("publish").description("Publish a solution package (.zip) to the UiPath solution feed. The .zip must be produced by 'solution pack'. By default the package lands in the tenant feed; use --personal-workspace to target the current user's Personal Workspace feed. After publishing, use 'solution deploy run' to deploy it.").addOption(createHiddenDeprecatedTenantOption("-t, --tenant <tenant-name>")).argument("<packagePath>", "Path to a .zip package file produced by 'solution pack'.").option("--personal-workspace", "Upload the package into the current user's Personal Workspace feed instead of the tenant feed. Resolves the workspace folder key from Orchestrator automatically.").option("--package-name <name>", "Publish under this package name instead of the one the .zip was packed with. Rewrites the archive's solutionMetadata.json in memory (with a fresh package version key); the file on disk is left untouched. The bundled project packages keep their own names and versions.").option("--package-version <version>", "Publish under this package version instead of the one the .zip was packed with. Use it to clear a 'version already exists' rejection when you have the packed .zip but not the solution source. Same in-memory rewrite as --package-name.").option("--wait", "Wait until the published package is Ready or Active").option("--timeout <seconds>", "Timeout in seconds for package state polling (default: 360)", (v) => parseInt(v, 10), 360).option("--poll-interval <ms>", "Milliseconds between package state polls (default: 5000)", (v) => parseInt(v, 10), 5000).option("--login-validity <minutes>", "Minimum minutes before token expiration to trigger a refresh (default: 10)", parseInt, 10);
3719
+ const command = program.command("publish").description("Publish a solution package (.zip) to the UiPath solution feed. The .zip must be produced by 'solution pack'. By default the package lands in the tenant feed; use --personal-workspace to target the current user's Personal Workspace feed. After publishing, use 'solution deploy run' to deploy it.").addOption(createHiddenDeprecatedTenantOption("-t, --tenant <tenant-name>")).argument("<package-path>", "Path to a .zip package file produced by 'solution pack'.").option("--personal-workspace", "Upload the package into the current user's Personal Workspace feed instead of the tenant feed. Resolves the workspace folder key from Orchestrator automatically.").option("--package-name <name>", "Publish under this package name instead of the one the .zip was packed with. Rewrites the archive's solutionMetadata.json in memory (with a fresh package version key); the file on disk is left untouched. The bundled project packages keep their own names and versions.").option("--package-version <version>", "Publish under this package version instead of the one the .zip was packed with. Use it to clear a 'version already exists' rejection when you have the packed .zip but not the solution source. Same in-memory rewrite as --package-name.").option("--wait", "Wait until the published package is Ready or Active").option("--timeout <seconds>", "Timeout in seconds for package state polling (default: 360)", (v) => parseInt(v, 10), 360).option("--poll-interval <ms>", "Milliseconds between package state polls (default: 5000)", (v) => parseInt(v, 10), 5000).option("--login-validity <minutes>", "Minimum minutes before token expiration to trigger a refresh (default: 10)", parseInt, 10);
3991
3720
  command.addOption(new Option("--feed <name-or-key>", "Publish into a feed by its name or folder key (from 'solution feeds list') instead of the tenant feed. Mutually exclusive with --personal-workspace.").conflicts("personalWorkspace"));
3992
3721
  command.examples([...SOLUTION_PUBLISH_EXAMPLES, SOLUTION_PUBLISH_FEED_EXAMPLE]).trackedAction(processContext, async (packagePath, options) => {
3993
3722
  const result = await publishSolutionAsync(packagePath, {
@@ -4050,6 +3779,7 @@ var registerPublishCommand = (program) => {
4050
3779
  });
4051
3780
  });
4052
3781
  };
3782
+
4053
3783
  // src/commands/resource-add.ts
4054
3784
  var RESOURCE_ADD_EXAMPLES = [
4055
3785
  {
@@ -4089,7 +3819,14 @@ var RESOURCE_ADD_EXAMPLES = [
4089
3819
  ];
4090
3820
  var registerResourceAddCommand = (resource) => {
4091
3821
  resource.command("add").description("Add a resource to the solution. Use --source local to create a virtual stub, " + "or --source remote to import an existing Orchestrator resource. Idempotent: " + "if a resource with the same (kind, name, folder) already exists, it is returned unchanged.").option("--source <source>", "Resource source: local (virtual stub) or remote (import from Orchestrator)").option("--kind <kind>", "Resource kind (e.g. Queue, Asset, Bucket, Process, Connection, App, Index, Trigger, Entity, ChoiceSet). Case-insensitive, matched against SDK metadata.").option("--name <name>", "Resource name").option("--type <type>", "Resource subtype, case-insensitive (e.g. Text/Integer/Bool/Credential/Secret or stringAsset/credentialAsset for Asset, connector type for Connection). Rejected when the kind does not declare it or has no subtypes (Queue); with --source remote it must match the resource's type and narrows same-name matches.").option("--folder-path <path>", "Orchestrator folder path for remote lookup. Required to disambiguate when more than one remote match exists. Not valid with --source local.").option("--cloud-key <guid>", "Skip remote search and import this exact resource key. Only valid with --source remote.").option("--solution-folder <path>", "Path to the solution root folder (defaults to current directory)").option("--login-validity <minutes>", "Minimum minutes before token expiration to trigger a refresh (default: 10)", parseInt, 10).examples(RESOURCE_ADD_EXAMPLES).trackedAction(processContext, async (options) => {
4092
- const validation = validateOptions(options);
3822
+ const {
3823
+ assertSolutionManifest,
3824
+ createResourceBuilderServices,
3825
+ normalizeResourceFileCasing,
3826
+ saveCasingNormalized
3827
+ } = await import("./index-prm27bvm.js");
3828
+ const { getSolutionAuthContext: getSolutionAuthContext2 } = await import("./solution-auth-aead70sw.js");
3829
+ const validation = await validateOptions(options);
4093
3830
  if (!validation.ok) {
4094
3831
  OutputFormatter.error({
4095
3832
  Result: RESULTS.Failure,
@@ -4122,7 +3859,7 @@ var registerResourceAddCommand = (resource) => {
4122
3859
  return;
4123
3860
  }
4124
3861
  if (source === "remote") {
4125
- const [authError] = await catchError(getSolutionAuthContext({
3862
+ const [authError] = await catchError(getSolutionAuthContext2({
4126
3863
  loginValidity: options.loginValidity
4127
3864
  }));
4128
3865
  if (authError) {
@@ -4217,7 +3954,8 @@ function canonicalizeKind(kind) {
4217
3954
  return trimmed.charAt(0).toLowerCase() + trimmed.slice(1);
4218
3955
  }
4219
3956
  var GUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
4220
- function validateOptions(options) {
3957
+ async function validateOptions(options) {
3958
+ const { validateResourceName } = await import("./index-prm27bvm.js");
4221
3959
  if (!options.source) {
4222
3960
  return {
4223
3961
  ok: false,
@@ -4291,6 +4029,7 @@ function validateOptions(options) {
4291
4029
  async function resolveTypeInput(services, kind, type) {
4292
4030
  if (type === undefined)
4293
4031
  return { ok: true, type };
4032
+ const { formatResourceSubtypes, resolveResourceKindMetadata } = await import("./resource-mutations-c3krjqze.js");
4294
4033
  const metadata = await resolveResourceKindMetadata(services, kind, type);
4295
4034
  if (metadata?.typeMatched) {
4296
4035
  return { ok: true, type: metadata.type ?? type };
@@ -4320,6 +4059,13 @@ function formatCandidates(matches) {
4320
4059
  `);
4321
4060
  }
4322
4061
  async function runAdd(builder, services, rawInput) {
4062
+ const { findMatchingLocalResource } = await import("./index-prm27bvm.js");
4063
+ const {
4064
+ createLocalResource,
4065
+ findResourceByKeyInRcs,
4066
+ sameResourceSubtype,
4067
+ searchRcsResources
4068
+ } = await import("./resource-mutations-c3krjqze.js");
4323
4069
  const typeResolution = await resolveTypeInput(services, rawInput.kind, rawInput.type);
4324
4070
  if (!typeResolution.ok)
4325
4071
  return typeResolution.outcome;
@@ -4381,7 +4127,7 @@ async function runAdd(builder, services, rawInput) {
4381
4127
  instructions: searchError.message
4382
4128
  };
4383
4129
  }
4384
- const inFolder = filterMatchesByFolder(matches, input.folderPath);
4130
+ const inFolder = await filterMatchesByFolder(matches, input.folderPath);
4385
4131
  if (inFolder.length === 0) {
4386
4132
  return {
4387
4133
  kind: "error",
@@ -4478,7 +4224,8 @@ ${formatCandidates(filtered)}`
4478
4224
  data: toResourceAddData(imported, refreshed.folders, "remote", statusToOutputStatus(response.status))
4479
4225
  };
4480
4226
  }
4481
- function filterMatchesByFolder(matches, folderPath) {
4227
+ async function filterMatchesByFolder(matches, folderPath) {
4228
+ const { normalizeFolderPath } = await import("./index-prm27bvm.js");
4482
4229
  const normalized = normalizeFolderPath(folderPath);
4483
4230
  if (!normalized)
4484
4231
  return matches;
@@ -4506,8 +4253,31 @@ function toResourceAddData(resource, folders, source, status) {
4506
4253
  };
4507
4254
  }
4508
4255
 
4509
- // src/commands/resource-edit.ts
4256
+ // src/commands/resource-command-utils.ts
4510
4257
  var RESOURCE_KEY_REGEX = /^[A-Za-z0-9._:-]{1,256}$/;
4258
+ function validateResourceKeyArgument(resourceKey) {
4259
+ if (!resourceKey || resourceKey.trim().length === 0) {
4260
+ OutputFormatter.error({
4261
+ Result: RESULTS.Failure,
4262
+ Message: "Missing required argument <resource-key>",
4263
+ Instructions: "Pass the solution resource key as a positional argument. Use 'uip solution resources list' to discover keys."
4264
+ });
4265
+ processContext.exit(1);
4266
+ return false;
4267
+ }
4268
+ if (!RESOURCE_KEY_REGEX.test(resourceKey)) {
4269
+ OutputFormatter.error({
4270
+ Result: RESULTS.Failure,
4271
+ Message: "<resource-key> contains unsupported characters",
4272
+ Instructions: "Resource keys use letters, digits, and '. _ - :' only. Use 'uip solution resources list' to find a valid key."
4273
+ });
4274
+ processContext.exit(1);
4275
+ return false;
4276
+ }
4277
+ return true;
4278
+ }
4279
+
4280
+ // src/commands/resource-edit.ts
4511
4281
  var REMOTE_FAILURE_MESSAGE = {
4512
4282
  solution_not_found: "Failed to edit resource",
4513
4283
  not_a_solution: "Failed to edit resource",
@@ -4600,24 +4370,15 @@ var RESOURCE_EDIT_EXAMPLES = [
4600
4370
  ];
4601
4371
  var registerResourceEditCommand = (resource) => {
4602
4372
  resource.command("edit").description("Edit a resource's spec properties by key. Pass --patch with a JSON object " + "of property → value; the JSON is merged into the existing spec. Properties " + "the SDK metadata marks as reference/read-only/unknown are silently ignored. " + "Use 'uip solution resources get <key>' to inspect the current spec; the " + "get↔edit shapes match, so a round-trip is straightforward. " + "Pass --source remote instead of --patch to take the values from the cloud " + "definition the resource was imported from — the only way to pick up a change " + "made in Orchestrator or Data Fabric after the import, since 'resources refresh' " + "never overwrites an imported resource.").argument("<resource-key>", "Solution resource key (a GUID, or a compound key such as MyFunction.api.MyFunction.1:1.0.0)").option("--patch <json>", `JSON object of spec property → value (e.g. '{"retentionPeriod":14}'). Pass '-' to read the JSON from stdin.`).option("--source <source>", "Where the new values come from: 'local' (default, use --patch) or 'remote' (the cloud definition this resource was imported from)", "local").option("--force", "With --source remote, write the cloud definition over the local one. Without it the command only reports what would change and writes nothing.").option("--login-validity <minutes>", "Minimum minutes before token expiration to trigger a refresh (default: 10). Only used by --source remote.", "10").option("--solution-folder <path>", "Path to the solution root folder (defaults to current directory)").examples(RESOURCE_EDIT_EXAMPLES).trackedAction(processContext, async (resourceKey, options) => {
4603
- if (!resourceKey || resourceKey.trim().length === 0) {
4604
- OutputFormatter.error({
4605
- Result: RESULTS.Failure,
4606
- Message: "Missing required argument <resource-key>",
4607
- Instructions: "Pass the solution resource key as a positional argument. Use 'uip solution resources list' to discover keys."
4608
- });
4609
- processContext.exit(1);
4610
- return;
4611
- }
4612
- if (!RESOURCE_KEY_REGEX.test(resourceKey)) {
4613
- OutputFormatter.error({
4614
- Result: RESULTS.Failure,
4615
- Message: "<resource-key> contains unsupported characters",
4616
- Instructions: "Resource keys use letters, digits, and '. _ - :' only. Use 'uip solution resources list' to find a valid key."
4617
- });
4618
- processContext.exit(1);
4373
+ if (!validateResourceKeyArgument(resourceKey)) {
4619
4374
  return;
4620
4375
  }
4376
+ const {
4377
+ assertSolutionManifest,
4378
+ createResourceBuilderServices,
4379
+ normalizeResourceFileCasing,
4380
+ saveCasingNormalized
4381
+ } = await import("./index-prm27bvm.js");
4621
4382
  const source = (options.source ?? "local").toLowerCase();
4622
4383
  if (source !== "local" && source !== "remote") {
4623
4384
  OutputFormatter.error({
@@ -4753,6 +4514,7 @@ var registerResourceEditCommand = (resource) => {
4753
4514
  });
4754
4515
  };
4755
4516
  async function handleRemoteSourceAsync(resourceKey, options) {
4517
+ const { resourceRemoteSyncAsync } = await import("./index-prm27bvm.js");
4756
4518
  const result = await resourceRemoteSyncAsync(options.solutionFolder ?? ".", resourceKey, {
4757
4519
  force: options.force === true,
4758
4520
  loginValidity: options.loginValidity ? parseInt(options.loginValidity, 10) : undefined
@@ -4833,7 +4595,6 @@ async function readStdin() {
4833
4595
  }
4834
4596
 
4835
4597
  // src/commands/resource-get.ts
4836
- var NOT_FOUND_PATTERN2 = /not\s+found/i;
4837
4598
  var RESOURCE_GET_EXAMPLES = [
4838
4599
  {
4839
4600
  Description: "Get the configuration for a single solution resource (run from inside the solution dir, or pass --solution-folder)",
@@ -4891,6 +4652,11 @@ var RESOURCE_GET_EXAMPLES = [
4891
4652
  ];
4892
4653
  var registerResourceGetCommand = (resource) => {
4893
4654
  resource.command("get").description("Get the configuration of a solution resource by key. Returns the resource spec, locks, and metadata as the SDK exposes them. " + "Use --include-dependencies to also retrieve configurations for every dependency the resource references.").argument("<resource-key>", "Solution resource key (GUID, or composite key like 'TestRPA.process.TestRPA:1.0.0' for packages)").option("--solution-folder <path>", "Path to the solution root folder (defaults to current directory)").option("--include-dependencies", "Also return configurations for the resource's dependencies").option("--login-validity <minutes>", "Minimum minutes before token expiration to trigger a refresh (default: 10)", "10").examples(RESOURCE_GET_EXAMPLES).trackedAction(processContext, async (resourceKey, options) => {
4655
+ const {
4656
+ createResourceBuilderServices,
4657
+ readResourceConfigurationsAsync
4658
+ } = await import("./index-prm27bvm.js");
4659
+ const { getSolutionAuthContext: getSolutionAuthContext2 } = await import("./solution-auth-aead70sw.js");
4894
4660
  const solutionPath = options.solutionFolder ?? ".";
4895
4661
  if (!resourceKey || resourceKey.trim() === "") {
4896
4662
  OutputFormatter.error({
@@ -4914,7 +4680,7 @@ var registerResourceGetCommand = (resource) => {
4914
4680
  return;
4915
4681
  }
4916
4682
  const loginValidityMinutes = options.loginValidity ? parseInt(options.loginValidity, 10) : undefined;
4917
- const [authError] = await catchError(getSolutionAuthContext({
4683
+ const [authError] = await catchError(getSolutionAuthContext2({
4918
4684
  loginValidity: loginValidityMinutes
4919
4685
  }));
4920
4686
  if (authError) {
@@ -4946,87 +4712,32 @@ var registerResourceGetCommand = (resource) => {
4946
4712
  processContext.exit(1);
4947
4713
  return;
4948
4714
  }
4949
- const includeDeps = options.includeDependencies === true;
4950
- const [fetchError, data] = await catchError(includeDeps ? builder.getAllConfigurationsAsync(resourceKey) : builder.getConfigurationAsync(resourceKey));
4951
- if (!fetchError) {
4952
- const resource2 = await refreshArtefactSpecAsync(builder, data, includeDeps);
4953
- if (!includeDeps) {
4954
- await attachLiveSpecOnMismatchAsync(services, resource2, data);
4955
- }
4956
- await builder.disposeAsync();
4957
- OutputFormatter.success({
4958
- Result: RESULTS.Success,
4959
- Code: includeDeps ? "ResourceConfigurations" : "ResourceConfiguration",
4960
- Data: data
4961
- });
4962
- return;
4963
- }
4964
- if (NOT_FOUND_PATTERN2.test(fetchError.message)) {
4965
- const [remoteError, remoteData] = await catchError(getRemoteConfiguration(services, resourceKey, includeDeps));
4966
- await builder.disposeAsync();
4967
- if (!remoteError) {
4968
- OutputFormatter.success({
4969
- Result: RESULTS.Success,
4970
- Code: includeDeps ? "ResourceConfigurations" : "ResourceConfiguration",
4971
- Data: remoteData
4972
- });
4973
- return;
4974
- }
4715
+ const [fetchError, data] = await catchError(options.includeDependencies === true ? readResourceConfigurationsAsync(services, builder, resourceKey) : readWithLiveSpecAsync(services, builder, resourceKey));
4716
+ await builder.disposeAsync();
4717
+ if (fetchError) {
4975
4718
  OutputFormatter.error({
4976
4719
  Result: RESULTS.Failure,
4977
4720
  Message: "Failed to get resource configuration",
4978
- Instructions: await extractErrorMessage(remoteError)
4721
+ Instructions: await extractErrorMessage(fetchError)
4979
4722
  });
4980
4723
  processContext.exit(1);
4981
4724
  return;
4982
4725
  }
4983
- await builder.disposeAsync();
4984
- OutputFormatter.error({
4985
- Result: RESULTS.Failure,
4986
- Message: "Failed to get resource configuration",
4987
- Instructions: await extractErrorMessage(fetchError)
4726
+ OutputFormatter.success({
4727
+ Result: RESULTS.Success,
4728
+ Code: options.includeDependencies === true ? "ResourceConfigurations" : "ResourceConfiguration",
4729
+ Data: data
4988
4730
  });
4989
- processContext.exit(1);
4990
4731
  });
4991
4732
  };
4992
- async function getRemoteConfiguration(services, resourceKey, includeDependencies) {
4993
- const reference = await findRemoteReferenceByKey(services, resourceKey);
4994
- if (!reference) {
4995
- throw new Error(`Resource '${resourceKey}' was not found in the solution or in the resource catalog`);
4996
- }
4997
- const { importer } = getRemoteResourceClients(services);
4998
- const payload = await importer.exportResourceAsync(reference);
4999
- const definitions = payload.resourceDefinitions ?? [];
5000
- const primary = definitions.find((d) => d.key === resourceKey) ?? definitions[0];
5001
- if (!primary) {
5002
- throw new Error(`FPS export for '${resourceKey}' returned no resource definitions`);
5003
- }
5004
- if (!includeDependencies) {
5005
- return mapDefinitionToConfiguration(primary);
5006
- }
5007
- const all = {
5008
- resources: definitions.map((d) => ({
5009
- ...mapDefinitionToConfiguration(d),
5010
- name: d.name ?? "",
5011
- kind: d.kind ?? "",
5012
- dependencies: (d.dependencies ?? []).map((dep) => ({
5013
- kind: dep.kind ?? "",
5014
- name: dep.name ?? ""
5015
- }))
5016
- }))
5017
- };
5018
- return all;
5019
- }
5020
- function mapDefinitionToConfiguration(def) {
5021
- return {
5022
- key: def.key ?? "",
5023
- spec: def.spec ?? {},
5024
- locks: def.locks ?? [],
5025
- apiVersion: def.apiVersion,
5026
- isOverridable: def.isOverridable
5027
- };
4733
+ async function readWithLiveSpecAsync(services, builder, resourceKey) {
4734
+ const { readResourceConfigurationAsync } = await import("./index-prm27bvm.js");
4735
+ const { configuration, resource } = await readResourceConfigurationAsync(services, builder, resourceKey);
4736
+ await attachLiveSpecOnMismatchAsync(services, resource, configuration);
4737
+ return configuration;
5028
4738
  }
5029
4739
  async function attachLiveSpecOnMismatchAsync(services, resource, config) {
4740
+ const { getRemoteResourceClients } = await import("./index-prm27bvm.js");
5030
4741
  const overwriteData = config.resourceOverwrite;
5031
4742
  const overwrite = overwriteData?.resourceOverwrite?.overwrite;
5032
4743
  if (overwriteData?.matchingOverwriteConfiguration !== false || !overwrite || !resource) {
@@ -5039,104 +4750,6 @@ async function attachLiveSpecOnMismatchAsync(services, resource, config) {
5039
4750
  }
5040
4751
  config.liveSpec = exported.spec;
5041
4752
  }
5042
- async function refreshArtefactSpecAsync(builder, data, includeDeps) {
5043
- const [loadError, solution] = await catchError(builder.context.loadAsync());
5044
- if (loadError || !solution) {
5045
- return;
5046
- }
5047
- let requestedResource;
5048
- const configs = includeDeps ? data.resources ?? [] : [data];
5049
- for (const config of configs) {
5050
- if (!config?.key) {
5051
- continue;
5052
- }
5053
- const resource = solution.resources.find((r) => r.key === config.key);
5054
- if (!includeDeps) {
5055
- requestedResource = resource;
5056
- }
5057
- if (!resource?.projectKey) {
5058
- continue;
5059
- }
5060
- config.spec = await applyEntryPointEnhancementAsync(builder.context, resource, config.spec ?? {});
5061
- }
5062
- return requestedResource;
5063
- }
5064
- async function findRemoteReferenceByKey(services, resourceKey) {
5065
- const entity = await findCatalogEntityAsync(getRemoteResourceClients(services).catalog, {}, (item) => item.entityKey === resourceKey);
5066
- return entity ? toResourceReference(entity) : null;
5067
- }
5068
-
5069
- // src/services/resource-version-lookup.ts
5070
- var VERSION_PROPERTY = "version";
5071
- var LOOKUP_CONCURRENCY = 5;
5072
- async function resolveResourceVersionsAsync(services, builder, targets) {
5073
- const versions = new Map;
5074
- if (targets.length === 0) {
5075
- return versions;
5076
- }
5077
- const resolveKind = await createResourceKindMetadataResolver(services);
5078
- const versioned = [];
5079
- for (const target of targets) {
5080
- const metadata = await resolveKind(target.kind, target.type);
5081
- if (metadata?.specProperties.has(VERSION_PROPERTY)) {
5082
- versioned.push(target);
5083
- }
5084
- }
5085
- if (versioned.length === 0) {
5086
- return versions;
5087
- }
5088
- const { importer } = getRemoteResourceClients(services);
5089
- for (let i = 0;i < versioned.length; i += LOOKUP_CONCURRENCY) {
5090
- const batch = versioned.slice(i, i + LOOKUP_CONCURRENCY);
5091
- const resolved = await Promise.all(batch.map((target) => target.source === "Local" ? readLocalVersionAsync(builder, target) : readRemoteVersionAsync(importer, target)));
5092
- for (const [id, version] of resolved) {
5093
- if (version !== undefined) {
5094
- versions.set(id, version);
5095
- }
5096
- }
5097
- }
5098
- return versions;
5099
- }
5100
- async function readLocalVersionAsync(builder, target) {
5101
- const [error, configuration] = await catchError(builder.getConfigurationAsync(target.key));
5102
- if (error || !configuration) {
5103
- warnLookupFailed(target, error);
5104
- return [target.id, undefined];
5105
- }
5106
- return [target.id, readVersion(configuration.spec)];
5107
- }
5108
- async function readRemoteVersionAsync(importer, target) {
5109
- const reference = {
5110
- kind: target.kind,
5111
- type: target.type,
5112
- key: target.key,
5113
- name: target.name,
5114
- folder: target.folderFullyQualifiedName ? {
5115
- fullyQualifiedName: target.folderFullyQualifiedName,
5116
- folderKey: target.folderKey
5117
- } : undefined
5118
- };
5119
- const [error, primary] = await catchError(exportResourceDefinitionAsync(importer, reference));
5120
- if (error) {
5121
- warnLookupFailed(target, error);
5122
- return [target.id, undefined];
5123
- }
5124
- if (!primary) {
5125
- logger.warn(`Export for ${target.kind} '${target.name ?? target.key}' returned no definition for that key; version omitted.`);
5126
- return [target.id, undefined];
5127
- }
5128
- return [target.id, readVersion(primary.spec)];
5129
- }
5130
- function readVersion(spec) {
5131
- const value = readSpecProperty(spec, VERSION_PROPERTY);
5132
- if (value === undefined || value === null || value === "") {
5133
- return;
5134
- }
5135
- return typeof value === "string" ? value : String(value);
5136
- }
5137
- function warnLookupFailed(target, error) {
5138
- logger.warn(`Failed to read the version of ${target.kind} '${target.name ?? target.key}': ${error?.message ?? "no configuration returned"}`);
5139
- }
5140
4753
 
5141
4754
  // src/commands/resource-list.ts
5142
4755
  var RESOURCE_LIST_EXAMPLES = [
@@ -5177,6 +4790,8 @@ var RESOURCE_LIST_EXAMPLES = [
5177
4790
  ];
5178
4791
  var registerResourceListCommand = (resource) => {
5179
4792
  resource.command("list").description("List resources in the solution and/or available in Orchestrator. " + "Shows local solution resources, remote Orchestrator resources, or both.").option("--solution-folder <path>", "Path to the solution root folder (defaults to current directory)").option("--kind <kind>", "Filter by resource kind (e.g. Queue, Asset, Bucket, Process, Connection, App, Index, Trigger, Entity, ChoiceSet). Any kind RCS indexes is accepted.").option("--search <term>", "Filter resources by name").option("--source <source>", "Resource source: all, local, or remote (default: all)", "all").option("--include-version", "Also report each resource's version, for the kinds that carry one (app, appVersion, package, process). " + "Remote rows report the version live in the folder, local rows the version the solution pins. " + "Costs one extra call per resource, so it is off by default.").option("-l, --limit <number>", "Number of resources to return", parseLimit, DEFAULT_PAGE_SIZE).option("--offset <number>", "Only 0 is accepted: the resource catalog pages by cursor. Use --next-page instead", parseOffset).option("--next-page <cursor>", "Cursor from a previous response's Pagination.NextPage").option("--login-validity <minutes>", "Minimum minutes before token expiration to trigger a refresh (default: 10)", parseInt, 10).examples(RESOURCE_LIST_EXAMPLES).trackedAction(processContext, async (options) => {
4793
+ const { createResourceBuilderServices } = await import("./index-prm27bvm.js");
4794
+ const { getSolutionAuthContext: getSolutionAuthContext2 } = await import("./solution-auth-aead70sw.js");
5180
4795
  const solutionPath = options.solutionFolder ?? ".";
5181
4796
  const fs = getFileSystem();
5182
4797
  const resolvedPath = fs.path.resolve(fs.env.cwd(), solutionPath);
@@ -5205,7 +4820,7 @@ var registerResourceListCommand = (resource) => {
5205
4820
  return;
5206
4821
  }
5207
4822
  const normalizedKind = options.kind;
5208
- const [authError] = await catchError(getSolutionAuthContext({
4823
+ const [authError] = await catchError(getSolutionAuthContext2({
5209
4824
  loginValidity: options.loginValidity
5210
4825
  }));
5211
4826
  if (authError) {
@@ -5353,6 +4968,7 @@ function versionLookupId(entry) {
5353
4968
  return `${entry.Source}|${entry.Key}|${entry.Folder ?? ""}`;
5354
4969
  }
5355
4970
  async function annotateVersions(services, builder, entries) {
4971
+ const { resolveResourceVersionsAsync } = await import("./resource-version-lookup-0e3e2j58.js");
5356
4972
  const targets = new Map;
5357
4973
  for (const entry of entries) {
5358
4974
  if (entry.Key === "") {
@@ -5384,6 +5000,7 @@ async function annotateVersions(services, builder, entries) {
5384
5000
  }
5385
5001
  }
5386
5002
  async function allRemotePage(services, search, pageCursor) {
5003
+ const { getRemoteResourceClients } = await import("./index-prm27bvm.js");
5387
5004
  const rcs = getRemoteResourceClients(services).catalog;
5388
5005
  const result = await rcs.searchFolderEntities({
5389
5006
  name: search,
@@ -5450,9 +5067,10 @@ var RESOURCE_REFRESH_EXAMPLES = [
5450
5067
  Imported: 1,
5451
5068
  Skipped: 5,
5452
5069
  Pruned: 0,
5070
+ ProjectResourcesCreated: 2,
5453
5071
  ReconciledSpecs: 1,
5454
5072
  Warnings: [],
5455
- Status: "Synced 3 resources (5 already in solution). Refresh never overwrites an imported resource — to pull a changed cloud definition, run 'uip solution resources edit <resource-key> --source remote'."
5073
+ Status: "Synced 3 resources (5 already in solution, 2 project resources generated). Refresh never overwrites an imported resource — to pull a changed cloud definition, run 'uip solution resources edit <resource-key> --source remote'."
5456
5074
  }
5457
5075
  }
5458
5076
  }
@@ -5465,31 +5083,39 @@ var FAILURE_MESSAGE = {
5465
5083
  };
5466
5084
  var registerResourceRefreshSubcommand = (resource) => {
5467
5085
  resource.command("refresh").description("Re-scan all projects in the solution and sync each project's authored files into the solution resource JSONs. " + "Bindings: creates new resources for `bindings_v2.json` entries not yet in the solution, imports from Orchestrator when a matching resource exists, and removes duplicate copies of the solution's own projects that earlier runs imported from a deployed folder. " + "Project contributions: each project's owning tool reports what its authored files add to the solution resources, and refresh persists it onto the matching resource. " + "Run this after editing a project's bindings or any file the project's tool contributes from, to update the solution resource inventory. " + "Refresh is import-only for cloud resources: it never overwrites an imported resource, so local edits survive; a project's own artefact resources are rewritten from the project's files on every run. " + "To pull a cloud definition that changed after the import, use 'uip solution resources edit <resource-key> --source remote'.").option("--solution-folder <path>", "Path to the solution root folder (defaults to current directory)").option("--login-validity <minutes>", "Minimum minutes before token expiration to trigger a refresh (default: 10)", "10").examples(RESOURCE_REFRESH_EXAMPLES).trackedAction(processContext, async (options) => {
5086
+ const { resourceRefreshAsync } = await import("./index-prm27bvm.js");
5468
5087
  const loginValidityMinutes = options.loginValidity ? parseInt(options.loginValidity, 10) : undefined;
5469
5088
  const solutionFolder = options.solutionFolder ?? ".";
5470
5089
  const fs = getFileSystem();
5471
5090
  let contributions;
5472
5091
  const [
5473
- { ensurePackagerTools: ensurePackagerTools2 },
5474
- { projectSubTypesFrom },
5092
+ { ensurePackagerTools },
5093
+ { projectBindingsFrom, projectSubTypesFrom },
5475
5094
  {
5476
5095
  applyProjectContributions,
5477
5096
  collectProjectContributions,
5478
5097
  contributionErrorMessages
5479
5098
  }
5480
5099
  ] = await Promise.all([
5481
- import("./packager-tool-resolver-6zwhec62.js"),
5482
- import("./prepare-solution-resources-jpb5as2s.js"),
5483
- import("./project-contributions-6wpff2hm.js")
5100
+ import("./packager-tool-resolver-994z3jkj.js"),
5101
+ import("./prepare-solution-resources-m1djfj62.js"),
5102
+ import("./project-contributions-79ndycrx.js")
5484
5103
  ]);
5485
5104
  const resolveProjectSubTypesAsync = async () => {
5486
- await ensurePackagerTools2(solutionFolder, fs);
5105
+ await ensurePackagerTools(solutionFolder, fs);
5487
5106
  contributions = await collectProjectContributions(solutionFolder, fs);
5488
5107
  return projectSubTypesFrom(contributions);
5489
5108
  };
5109
+ const resolveProjectBindingsAsync = async () => {
5110
+ if (!contributions) {
5111
+ throw new Error("the project tools could not be loaded");
5112
+ }
5113
+ return projectBindingsFrom(contributions);
5114
+ };
5490
5115
  const result = await resourceRefreshAsync(solutionFolder, {
5491
5116
  loginValidity: loginValidityMinutes,
5492
- resolveProjectSubTypesAsync
5117
+ resolveProjectSubTypesAsync,
5118
+ resolveProjectBindingsAsync
5493
5119
  });
5494
5120
  if (!result.ok) {
5495
5121
  OutputFormatter.error({
@@ -5501,6 +5127,7 @@ var registerResourceRefreshSubcommand = (resource) => {
5501
5127
  return;
5502
5128
  }
5503
5129
  const prunedNote = result.pruned > 0 ? `, ${result.pruned} duplicates removed` : "";
5130
+ const projectNote = result.projectResourcesCreated > 0 ? `, ${result.projectResourcesCreated} project resources generated` : "";
5504
5131
  const skippedNote = result.skipped > 0 ? " Refresh never overwrites an imported resource — to pull a changed cloud definition, run 'uip solution resources edit <resource-key> --source remote'." : "";
5505
5132
  let applied = { updated: 0, warnings: [] };
5506
5133
  if (contributions) {
@@ -5529,16 +5156,16 @@ var registerResourceRefreshSubcommand = (resource) => {
5529
5156
  Imported: result.imported,
5530
5157
  Skipped: result.skipped,
5531
5158
  Pruned: result.pruned,
5159
+ ProjectResourcesCreated: result.projectResourcesCreated,
5532
5160
  ReconciledSpecs: applied.updated,
5533
5161
  Warnings: warnings,
5534
- Status: `Synced ${result.created + result.imported} resources (${result.skipped} already in solution${prunedNote}).${skippedNote}`
5162
+ Status: `Synced ${result.created + result.imported} resources (${result.skipped} already in solution${prunedNote}${projectNote}).${skippedNote}`
5535
5163
  }
5536
5164
  });
5537
5165
  });
5538
5166
  };
5539
5167
 
5540
5168
  // src/commands/resource-remove.ts
5541
- var RESOURCE_KEY_REGEX2 = /^[A-Za-z0-9._:-]{1,256}$/;
5542
5169
  var RESOURCE_REMOVE_EXAMPLES = [
5543
5170
  {
5544
5171
  Description: "Remove a resource by its solution key",
@@ -5556,24 +5183,15 @@ var RESOURCE_REMOVE_EXAMPLES = [
5556
5183
  ];
5557
5184
  var registerResourceRemoveCommand = (resource) => {
5558
5185
  resource.command("remove").description("Remove a resource from the solution by its key. Use 'uip solution resources list' " + "or 'uip solution resources get' to discover the key first. " + "Purely local — no auth required, doesn't touch any bindings_v2.json.").argument("<resource-key>", "Solution resource key (a GUID, or a compound key such as MyFunction.api.MyFunction.1:1.0.0)").option("--solution-folder <path>", "Path to the solution root folder (defaults to current directory)").examples(RESOURCE_REMOVE_EXAMPLES).trackedAction(processContext, async (resourceKey, options) => {
5559
- if (!resourceKey || resourceKey.trim().length === 0) {
5560
- OutputFormatter.error({
5561
- Result: RESULTS.Failure,
5562
- Message: "Missing required argument <resource-key>",
5563
- Instructions: "Pass the solution resource key as a positional argument. Use 'uip solution resources list' to discover keys."
5564
- });
5565
- processContext.exit(1);
5566
- return;
5567
- }
5568
- if (!RESOURCE_KEY_REGEX2.test(resourceKey)) {
5569
- OutputFormatter.error({
5570
- Result: RESULTS.Failure,
5571
- Message: "<resource-key> contains unsupported characters",
5572
- Instructions: "Resource keys use letters, digits, and '. _ - :' only. Use 'uip solution resources list' to find a valid key."
5573
- });
5574
- processContext.exit(1);
5186
+ if (!validateResourceKeyArgument(resourceKey)) {
5575
5187
  return;
5576
5188
  }
5189
+ const {
5190
+ assertSolutionManifest,
5191
+ createResourceBuilderServices,
5192
+ normalizeResourceFileCasing,
5193
+ saveCasingNormalized
5194
+ } = await import("./index-prm27bvm.js");
5577
5195
  const fs = getFileSystem();
5578
5196
  const resolvedPath = fs.path.resolve(fs.env.cwd(), options.solutionFolder ?? ".");
5579
5197
  if (!await fs.exists(resolvedPath)) {
@@ -5680,118 +5298,6 @@ var registerResourceCommand = (program) => {
5680
5298
  registerResourceEditCommand(resources);
5681
5299
  };
5682
5300
 
5683
- // src/services/restore-command-service.ts
5684
- class RestoreCommandService {
5685
- packager = null;
5686
- fs;
5687
- constructor() {
5688
- this.fs = getFileSystem();
5689
- }
5690
- async execute(solutionPath, options, context) {
5691
- const check = await checkSolutionPathAsync(this.fs, solutionPath);
5692
- if (!check.ok) {
5693
- OutputFormatter.error({
5694
- Result: RESULTS.Failure,
5695
- Message: check.message,
5696
- Instructions: SOLUTION_PATH_INSTRUCTIONS,
5697
- ErrorCode: check.errorCode
5698
- });
5699
- if (check.statError?.stack) {
5700
- logger.error("Stack trace:");
5701
- logger.error(check.statError.stack);
5702
- }
5703
- context.exit(1);
5704
- return;
5705
- }
5706
- const { absoluteSolutionPath, isUisFile } = check;
5707
- const solutionName = isUisFile ? this.fs.path.basename(solutionPath, ".uis") : this.fs.path.basename(solutionPath);
5708
- logger.info(`
5709
- Restoring solution dependencies...
5710
- `);
5711
- logger.info("Details:");
5712
- logger.info(` Solution: ${absoluteSolutionPath}`);
5713
- logger.info("");
5714
- const [error, result] = await catchError(this.executeAsync(solutionPath, options));
5715
- if (error) {
5716
- const msg = error instanceof Error ? error.message : String(error);
5717
- OutputFormatter.error({
5718
- Result: RESULTS.Failure,
5719
- ...isUnpackableProjectTypeError(error) ? { ErrorCode: "invalid_argument" } : {},
5720
- Message: msg,
5721
- Instructions: carriedInstructions(error) ?? "Check that you are logged in (`uip auth login`) and that the solution path is accessible, then rerun: uip solution restore <solutionPath>"
5722
- });
5723
- if (error instanceof Error && error.stack && !isUnpackableProjectTypeError(error)) {
5724
- logger.error("Stack trace:");
5725
- logger.error(error.stack);
5726
- }
5727
- context.exit(1);
5728
- return;
5729
- }
5730
- if (result.errorCode !== "SUCCESS" /* Success */) {
5731
- OutputFormatter.error({
5732
- Result: RESULTS.Failure,
5733
- Message: `Error code: ${result.errorCode} : ${result.message}`,
5734
- Instructions: "Resolve the reported dependency issue, ensure you are logged in with `uip auth login`, then rerun: uip solution restore <solutionPath>"
5735
- });
5736
- context.exit(1);
5737
- return;
5738
- }
5739
- OutputFormatter.success({
5740
- Result: RESULTS.Success,
5741
- Code: "SolutionRestore",
5742
- Data: {
5743
- Solution: solutionName,
5744
- Status: "Restored"
5745
- }
5746
- });
5747
- }
5748
- async executeAsync(solutionPath, options) {
5749
- const check = await checkSolutionPathAsync(this.fs, solutionPath);
5750
- if (!check.ok) {
5751
- if (check.statError) {
5752
- throw check.statError;
5753
- }
5754
- return new ToolResult("INTERNAL_ERROR" /* InternalError */, check.message, []);
5755
- }
5756
- const { absoluteSolutionPath, isUisFile } = check;
5757
- const solutionName = isUisFile ? this.fs.path.basename(solutionPath, ".uis") : this.fs.path.basename(solutionPath);
5758
- const packager = await this.ensurePackagerAsync();
5759
- let inputPath;
5760
- if (isUisFile) {
5761
- const uint8Array = await readSolutionFileAsUint8Array(this.fs, absoluteSolutionPath);
5762
- inputPath = await packager.setupAsync(uint8Array);
5763
- } else {
5764
- inputPath = await packager.setupAsync(absoluteSolutionPath);
5765
- }
5766
- await ensurePackagerTools(inputPath, this.fs);
5767
- const restoreOptions = await this.createRestoreOptions(inputPath, solutionName, options);
5768
- return packager.restoreSolutionAsync(restoreOptions);
5769
- }
5770
- async ensurePackagerAsync() {
5771
- if (!this.packager) {
5772
- this.packager = await createSolutionPackager();
5773
- }
5774
- return this.packager;
5775
- }
5776
- async createRestoreOptions(inputPath, solutionName, options) {
5777
- const restoreOptions = new SolutionPackOptions;
5778
- restoreOptions.inputPath = inputPath;
5779
- restoreOptions.configuration = "Release" /* Release */;
5780
- restoreOptions.excludeConfiguredSources = options.excludeConfiguredSources ?? false;
5781
- restoreOptions.package = {
5782
- id: solutionName,
5783
- version: "1.0.0",
5784
- author: "",
5785
- description: ""
5786
- };
5787
- restoreOptions.logLevel = resolveSdkLogLevel();
5788
- restoreOptions.nuGetSourcesConfigPath = options.nugetSourcesConfigPath;
5789
- restoreOptions.feedFolder = options.feedFolder;
5790
- await applyAuthConnection(restoreOptions, options.loginValidity);
5791
- return restoreOptions;
5792
- }
5793
- }
5794
-
5795
5301
  // src/commands/restore.ts
5796
5302
  var SOLUTION_RESTORE_EXAMPLES = [
5797
5303
  {
@@ -5807,7 +5313,8 @@ var SOLUTION_RESTORE_EXAMPLES = [
5807
5313
  }
5808
5314
  ];
5809
5315
  var registerRestoreCommand = (program) => {
5810
- program.command("restore").description("Restore NuGet dependencies for every project in a UiPath solution using the authenticated session. Accepts a solution directory (containing .uipx) or a .uis file. Resolves dependencies in place and does not produce a package — run it before 'uip solution pack'.").argument("<solutionPath>", "Path to a solution directory (containing .uipx) or a .uis file").option("--nuget-sources-config-path <path>", "Path to NuGet sources configuration file").option("--exclude-configured-sources", "Resolve project dependencies only from the tenant feeds and any --nuget-sources-config-path. Drops the built-in UiPath and nuget.org feeds, so a dependency that is not on those feeds fails to restore.").option("--feed-folder <name>", "Resolve project dependencies from this Orchestrator folder's library feed instead of every tenant feed. Accepts a folder name or fully qualified path.").option("--login-validity <minutes>", "Minimum minutes before token expiration to trigger a refresh (default: 10)", parseInt, 10).examples(SOLUTION_RESTORE_EXAMPLES).trackedAction(processContext, async (solutionPath, options) => {
5316
+ program.command("restore").description("Restore NuGet dependencies for every project in a UiPath solution using the authenticated session. Accepts a solution directory (containing .uipx) or a .uis file. Resolves dependencies in place and does not produce a package — run it before 'uip solution pack'.").argument("<solution-path>", "Path to a solution directory (containing .uipx) or a .uis file").option("--nuget-sources-config-path <path>", "Path to NuGet sources configuration file").option("--exclude-configured-sources", "Resolve project dependencies only from the tenant feeds and any --nuget-sources-config-path. Drops the built-in UiPath and nuget.org feeds, so a dependency that is not on those feeds fails to restore.").option("--feed-folder <name>", "Resolve project dependencies from this Orchestrator folder's library feed instead of every tenant feed. Accepts a folder name or fully qualified path.").option("--login-validity <minutes>", "Minimum minutes before token expiration to trigger a refresh (default: 10)", parseInt, 10).examples(SOLUTION_RESTORE_EXAMPLES).trackedAction(processContext, async (solutionPath, options) => {
5317
+ const { RestoreCommandService } = await import("./restore-command-service-eyx911f2.js");
5811
5318
  const service = new RestoreCommandService;
5812
5319
  await service.execute(solutionPath, {
5813
5320
  loginValidity: options.loginValidity,
@@ -5817,541 +5324,6 @@ var registerRestoreCommand = (program) => {
5817
5324
  }, processContext);
5818
5325
  });
5819
5326
  };
5820
- // ../executor/project-executor/src/models/run-status.ts
5821
- var TERMINAL_RUN_STATUSES = [
5822
- "Succeeded" /* Succeeded */,
5823
- "Faulted" /* Faulted */,
5824
- "Cancelled" /* Cancelled */
5825
- ];
5826
- function isTerminalRunStatus(status) {
5827
- return TERMINAL_RUN_STATUSES.includes(status);
5828
- }
5829
-
5830
- // ../executor/project-executor/src/models/run-result.ts
5831
- class RunResult {
5832
- status;
5833
- errorCode;
5834
- rawStatus;
5835
- message;
5836
- jobKey;
5837
- instanceId;
5838
- runId;
5839
- traceId;
5840
- steps;
5841
- output;
5842
- url;
5843
- details;
5844
- constructor(status, errorCode = "None" /* None */, message) {
5845
- this.status = status;
5846
- this.errorCode = errorCode;
5847
- this.message = message;
5848
- }
5849
- get isSuccess() {
5850
- return this.status === "Succeeded" /* Succeeded */ && this.errorCode === "None" /* None */;
5851
- }
5852
- get isTerminal() {
5853
- return isTerminalRunStatus(this.status);
5854
- }
5855
- static succeeded(init = {}) {
5856
- return Object.assign(new RunResult("Succeeded" /* Succeeded */, "None" /* None */), init);
5857
- }
5858
- static failed(errorCode, message, init = {}) {
5859
- return Object.assign(new RunResult("Faulted" /* Faulted */, errorCode, message), init);
5860
- }
5861
- }
5862
- // ../executor/project-executor/src/services/executor-tool-import.ts
5863
- async function importExecutorToolModule(specifier) {
5864
- try {
5865
- return { module: await import(specifier) };
5866
- } catch (error) {
5867
- return {
5868
- error: error instanceof Error ? error : new Error(String(error))
5869
- };
5870
- }
5871
- }
5872
-
5873
- // ../executor/project-executor/src/services/executor-tool-module.ts
5874
- var EXECUTOR_FACTORY_EXPORT = "createExecutorFactory";
5875
- function isExecutorFactoryModule(module) {
5876
- return typeof module === "object" && module !== null && typeof module[EXECUTOR_FACTORY_EXPORT] === "function";
5877
- }
5878
-
5879
- // ../executor/project-executor/src/services/executors-factory-repository.ts
5880
- class ExecutorsFactoryRepository {
5881
- factoryMap = new Map;
5882
- onConflict;
5883
- constructor(onConflict) {
5884
- this.onConflict = onConflict ?? ((message) => console.warn(message));
5885
- }
5886
- registerProjectExecutorFactory(factory) {
5887
- for (const projectType of factory.supportedTypes) {
5888
- const existing = this.factoryMap.get(projectType);
5889
- if (existing) {
5890
- if (existing.constructor?.name !== factory.constructor?.name) {
5891
- this.onConflict(`Executor factory conflict for project type '${projectType}': ` + `'${existing.constructor?.name}' already registered, ` + `ignoring '${factory.constructor?.name}'.`);
5892
- }
5893
- continue;
5894
- }
5895
- this.factoryMap.set(projectType, factory);
5896
- }
5897
- }
5898
- canHandleProject(projectType) {
5899
- return this.factoryMap.has(projectType);
5900
- }
5901
- getProjectExecutorFactory(projectType) {
5902
- const factory = this.factoryMap.get(projectType);
5903
- if (!factory) {
5904
- throw new Error(`Cannot run project type '${projectType}': no runner is installed for it. ` + `Project types that can be run: ${this.registeredTypes.join(", ") || "none"}.`);
5905
- }
5906
- return factory;
5907
- }
5908
- get registeredTypes() {
5909
- return [...this.factoryMap.keys()];
5910
- }
5911
- reset() {
5912
- this.factoryMap.clear();
5913
- }
5914
- }
5915
- var REGISTRY_KEY = Symbol.for("@uipath/project-executor/executorsFactoryRepository");
5916
- var _global = globalThis;
5917
- if (!_global[REGISTRY_KEY]) {
5918
- _global[REGISTRY_KEY] = new ExecutorsFactoryRepository;
5919
- }
5920
- var executorsFactoryRepository = _global[REGISTRY_KEY];
5921
-
5922
- // ../executor/project-executor/src/services/executor-factory-provider.ts
5923
- var PROVIDER_KEY = Symbol.for("@uipath/project-executor/executorFactoryProvider");
5924
- var _global2 = globalThis;
5925
- function registerExecutorFactoryFromModule(module, source) {
5926
- if (!isExecutorFactoryModule(module)) {
5927
- throw new Error(`${source} does not export ${EXECUTOR_FACTORY_EXPORT}().`);
5928
- }
5929
- const factory = module.createExecutorFactory();
5930
- executorsFactoryRepository.registerProjectExecutorFactory(factory);
5931
- return factory;
5932
- }
5933
- async function ensureExecutorFactory(verb, packageName) {
5934
- const provider = _global2[PROVIDER_KEY];
5935
- if (provider) {
5936
- await provider(verb);
5937
- return;
5938
- }
5939
- if (!packageName) {
5940
- throw new Error(`Running this project type needs the executor factory for '${verb}', and no package provides it.`);
5941
- }
5942
- const specifier = `${packageName}/executor-tool`;
5943
- const { module, error } = await importExecutorToolModule(specifier);
5944
- if (error) {
5945
- throw new Error(`Running this project type needs '${packageName}'. Install it.`, { cause: error });
5946
- }
5947
- registerExecutorFactoryFromModule(module, specifier);
5948
- }
5949
- // ../executor/project-executor/src/services/executor-logger.ts
5950
- var noopExecutorLogger = {
5951
- info: () => {},
5952
- warn: () => {},
5953
- error: () => {}
5954
- };
5955
- // ../executor/project-executor/src/services/project-runner.ts
5956
- class ProjectRunner {
5957
- fileSystem;
5958
- logger;
5959
- registry;
5960
- constructor(deps) {
5961
- this.fileSystem = deps.fileSystem;
5962
- this.logger = deps.logger ?? noopExecutorLogger;
5963
- this.registry = deps.registry ?? executorsFactoryRepository;
5964
- }
5965
- canRun(projectType) {
5966
- return this.registry.canHandleProject(projectType);
5967
- }
5968
- get runnableTypes() {
5969
- return this.registry.registeredTypes;
5970
- }
5971
- async runAsync(options, cancellationToken) {
5972
- const { projectType, name } = options.project;
5973
- if (!this.canRun(projectType)) {
5974
- const known = this.runnableTypes.join(", ") || "none";
5975
- return RunResult.failed("UnsupportedProjectType" /* UnsupportedProjectType */, `Cannot run project '${name}' (project type '${projectType}'): ` + `no runner is installed for it. Project types that can be run: ${known}.`);
5976
- }
5977
- let executor;
5978
- try {
5979
- const factory = this.registry.getProjectExecutorFactory(projectType);
5980
- executor = await factory.createAsync(this.logger, this.fileSystem);
5981
- this.logger.info(`Running ${name} (${projectType}) on ${options.target}.`);
5982
- return await executor.runAsync(options, cancellationToken);
5983
- } catch (error) {
5984
- return RunResult.failed("Unknown" /* Unknown */, messageOf(error));
5985
- } finally {
5986
- try {
5987
- await executor?.dispose();
5988
- } catch (error) {
5989
- this.logger.warn(`Failed to dispose the ${projectType} executor: ${messageOf(error)}`);
5990
- }
5991
- }
5992
- }
5993
- }
5994
- function messageOf(error) {
5995
- return error instanceof Error ? error.message : String(error);
5996
- }
5997
- // src/services/executor-tool-resolver.ts
5998
- var PROJECT_TYPE_TO_TOOL = new Map([
5999
- ["Process", "rpa"],
6000
- ["Tests", "rpa"],
6001
- ["WebApp", "rpa"],
6002
- ["Agent", "agent"],
6003
- ["Api", "api-workflow"]
6004
- ]);
6005
- var TOOL_TO_PACKAGE = new Map([
6006
- ["rpa", "@uipath/rpa-tool"],
6007
- ["agent", "@uipath/agent-tool"],
6008
- ["api-workflow", "@uipath/api-workflow-tool"]
6009
- ]);
6010
- function hasExecutorToolFor(projectType) {
6011
- return PROJECT_TYPE_TO_TOOL.has(projectType);
6012
- }
6013
- async function ensureExecutorTools(projectTypes) {
6014
- const neededTools = new Set;
6015
- for (const type of projectTypes) {
6016
- if (executorsFactoryRepository.canHandleProject(type))
6017
- continue;
6018
- const toolVerb = PROJECT_TYPE_TO_TOOL.get(type);
6019
- if (toolVerb) {
6020
- neededTools.add(toolVerb);
6021
- } else {
6022
- logger.warn(`No installable tool runs project type '${type}'. Run may fail.`);
6023
- }
6024
- }
6025
- for (const toolVerb of neededTools) {
6026
- logger.info(`Loading executor factory for '${toolVerb}' to run project types...`);
6027
- await ensureExecutorFactory(toolVerb, TOOL_TO_PACKAGE.get(toolVerb));
6028
- }
6029
- }
6030
- function projectDirOf(fs, declaredPath) {
6031
- const dir = fs.path.dirname(declaredPath);
6032
- return dir && dir !== "." ? dir : "";
6033
- }
6034
- async function readSolutionProjects(solutionDir, fs) {
6035
- const entries = await fs.readdir(solutionDir);
6036
- const uipxFile = entries.find((f) => f.endsWith(".uipx"));
6037
- if (!uipxFile) {
6038
- throw new Error(`No .uipx solution file found in '${solutionDir}'. ` + `Pass a solution directory or run 'uip solution init' first.`);
6039
- }
6040
- const content = await fs.readFile(fs.path.join(solutionDir, uipxFile));
6041
- if (!content) {
6042
- throw new Error(`Solution file '${uipxFile}' is empty.`);
6043
- }
6044
- const json = typeof content === "string" ? content : new TextDecoder().decode(content);
6045
- const [parseError, solution] = catchError(() => JSON.parse(json));
6046
- if (parseError) {
6047
- throw new Error(`Failed to parse ${uipxFile}: ${parseError.message}`);
6048
- }
6049
- return (solution.Projects ?? []).map((p) => {
6050
- const relativePath = projectDirOf(fs, p.ProjectRelativePath ?? "");
6051
- return {
6052
- name: p.Name || fs.path.basename(relativePath || solutionDir) || "",
6053
- projectType: p.Type ?? "",
6054
- relativePath
6055
- };
6056
- });
6057
- }
6058
-
6059
- // src/services/provision-debug-service.ts
6060
- function nextDebugVersion() {
6061
- return `1.0.${Math.floor(Date.now() / 1000)}`;
6062
- }
6063
- async function defaultGetSolutionBuilder(solutionDir) {
6064
- const services = await createResourceBuilderServices();
6065
- return services.getSolutionBuilder(solutionDir, true);
6066
- }
6067
- async function provisionSolutionForDebugAsync(options, deps = {}) {
6068
- const listLocations = deps.listLocations ?? listSelectablePublishLocations;
6069
- const pack = deps.pack ?? packSolutionAsync;
6070
- const publish = deps.publish ?? publishSolutionAsync;
6071
- const getBuilder = deps.getSolutionBuilder ?? defaultGetSolutionBuilder;
6072
- const newSessionId = deps.newSessionId ?? (() => crypto.randomUUID());
6073
- const authOptions = {
6074
- tenant: options.tenant,
6075
- loginValidity: options.loginValidity
6076
- };
6077
- const getDebugStatus = deps.getDebugStatus ?? (async (solutionKey2, debugSessionId) => {
6078
- const auth = await getSolutionAuthContext(authOptions);
6079
- return getProjectDebugStatus({ basePath: auth.basePath, accessToken: auth.accessToken }, solutionKey2, debugSessionId);
6080
- });
6081
- logger.info("Resolving the personal workspace to deploy into...");
6082
- const [locationsError, locations] = await catchError(listLocations(authOptions));
6083
- if (locationsError) {
6084
- return fail(`Could not resolve a personal workspace to deploy into: ${locationsError.message}`);
6085
- }
6086
- const personal = locations.find((l) => l.isMyPersonalWorkspace);
6087
- if (!personal) {
6088
- return fail("This account has no personal workspace, so there is nowhere to deploy the solution for a debug run. " + "Ask an administrator to enable a personal workspace, or run with --no-provision-resources — " + "the run then starts without a deployment, and cross-project calls will not resolve.");
6089
- }
6090
- const version = options.version ?? nextDebugVersion();
6091
- const fs = getFileSystem();
6092
- const outputPath = fs.path.join(fs.env.tmpdir(), "uip-solution-run", newSessionId());
6093
- const uploaded = await packAndUploadAsync({
6094
- options,
6095
- authOptions,
6096
- pack,
6097
- publish,
6098
- version,
6099
- outputPath
6100
- });
6101
- if (!uploaded.ok) {
6102
- return fail(uploaded.message);
6103
- }
6104
- const packageVersionKey = uploaded.packageVersionKey;
6105
- logger.info("Provisioning the solution's resources for the run...");
6106
- const [builderError, builder] = await catchError(getBuilder(options.solutionDir));
6107
- if (builderError) {
6108
- return fail(`Could not read the solution: ${builderError.message}`);
6109
- }
6110
- const sessionId = newSessionId();
6111
- const [debugError, debug] = await catchError(builder.debugProjectAsync(personal.key, options.solutionName, sessionId, packageVersionKey, true));
6112
- let solutionKey;
6113
- if (!debugError && debug.complete === false) {
6114
- const [, definition] = await catchError(builder.context.loadAsync());
6115
- solutionKey = definition?.key;
6116
- }
6117
- await builder.disposeAsync().catch(() => {});
6118
- if (debugError) {
6119
- return fail(`Provisioning the solution failed: ${debugError.message}`);
6120
- }
6121
- if (debug.complete === false) {
6122
- if (!solutionKey) {
6123
- return fail("The cloud is still provisioning the solution, but its key could not be read back from the .uipx, so the provisioning cannot be waited on. Retry the run.");
6124
- }
6125
- return waitForProvisioningAsync({
6126
- solutionKey,
6127
- sessionId,
6128
- packageVersionKey,
6129
- options,
6130
- getDebugStatus
6131
- });
6132
- }
6133
- const folderPath = debug.folderFullyQualifiedName;
6134
- logger.info(folderPath ? `Solution provisioned into ${folderPath}.` : "Solution provisioned.");
6135
- return {
6136
- ok: true,
6137
- folderPath,
6138
- packageVersionKey
6139
- };
6140
- }
6141
- function fail(message) {
6142
- return { ok: false, message };
6143
- }
6144
- async function packAndUploadAsync(args) {
6145
- const { options, authOptions, version } = args;
6146
- logger.info("Packing the solution...");
6147
- const [packError, packed] = await catchError(args.pack(options.solutionDir, {
6148
- output: args.outputPath,
6149
- name: options.solutionName,
6150
- version,
6151
- loginValidity: options.loginValidity
6152
- }));
6153
- if (packError) {
6154
- return {
6155
- ok: false,
6156
- message: `Packing the solution failed: ${packError.message}`
6157
- };
6158
- }
6159
- if (!packed.ok) {
6160
- return {
6161
- ok: false,
6162
- message: `Packing the solution failed: ${packed.message}`
6163
- };
6164
- }
6165
- const packagePath = packed.packages?.[0];
6166
- if (!packagePath) {
6167
- return {
6168
- ok: false,
6169
- message: "Packing the solution produced no package."
6170
- };
6171
- }
6172
- logger.info("Uploading the solution to the personal workspace...");
6173
- const [publishError, published] = await catchError(args.publish(packagePath, {
6174
- ...authOptions,
6175
- personalWorkspace: true,
6176
- packageVersion: version
6177
- }));
6178
- if (publishError) {
6179
- return {
6180
- ok: false,
6181
- message: `Uploading the solution failed: ${publishError.message}`
6182
- };
6183
- }
6184
- if (!published.ok) {
6185
- return {
6186
- ok: false,
6187
- message: `Uploading the solution failed: ${published.message}`
6188
- };
6189
- }
6190
- if (!published.packageVersionKey) {
6191
- return {
6192
- ok: false,
6193
- message: "The solution was uploaded but the feed did not report a package version, so it cannot be provisioned. Retry the run."
6194
- };
6195
- }
6196
- return { ok: true, packageVersionKey: published.packageVersionKey };
6197
- }
6198
- async function waitForProvisioningAsync(args) {
6199
- const { solutionKey, sessionId, packageVersionKey, options } = args;
6200
- const timeoutMs = options.provisioningTimeoutMs ?? 360000;
6201
- logger.info("Waiting for the cloud to finish provisioning...");
6202
- const poll = await pollUntil({
6203
- fn: () => args.getDebugStatus(solutionKey, sessionId),
6204
- until: (info2) => isDebugProvisioningTerminal(info2.status),
6205
- getStatus: (info2) => info2.status ?? "pending",
6206
- label: `solution provisioning (session ${sessionId})`,
6207
- logPrefix: "provision",
6208
- timeoutMs,
6209
- intervalMs: options.provisioningPollIntervalMs ?? 5000,
6210
- maxConsecutiveErrors: 5,
6211
- signal: processContext.pollSignal
6212
- });
6213
- if (poll.outcome !== PollOutcome.Completed || !poll.data) {
6214
- return fail(describeIncompleteWait(poll, timeoutMs));
6215
- }
6216
- const info = poll.data;
6217
- if (!isDebugProvisioningSucceeded(info.status)) {
6218
- const details = (info.errors ?? []).map((error) => error.resource ? `${error.resource.kind ?? "resource"} '${error.resource.name ?? error.resource.key ?? ""}': ${error.message}` : error.message).join(`
6219
- `);
6220
- return fail(`Provisioning the solution failed (${info.status}).` + (details ? `
6221
- ${details}` : ""));
6222
- }
6223
- logger.info("Solution provisioned.");
6224
- return { ok: true, packageVersionKey };
6225
- }
6226
- function describeIncompleteWait(poll, timeoutMs) {
6227
- const lastStatus = poll.data?.status ?? "unknown";
6228
- if (poll.outcome === PollOutcome.Interrupted) {
6229
- return `The wait for the solution's provisioning was cancelled (last status: ${lastStatus}). ` + "The cloud may still finish it.";
6230
- }
6231
- if (poll.outcome === PollOutcome.Failed || poll.outcome === PollOutcome.Aborted) {
6232
- return `Checking the solution's provisioning status failed: ${poll.error?.message ?? "too many consecutive errors"} ` + `(last status: ${lastStatus}). The provisioning itself may still be running or have finished — ` + "retry the run to check.";
6233
- }
6234
- return `The solution was uploaded, but the cloud did not finish provisioning it within ${Math.round(timeoutMs / 1000)}s ` + `(last status: ${lastStatus}). ` + "Running again will not help: each run uploads a new version and provisions that one too. " + "To run a project that calls another project, deploy the solution once " + "('uip solution pack' → 'publish' → 'deploy run') and then run with " + "--no-provision-resources --folder-path <deployed folder>.";
6235
- }
6236
-
6237
- // src/services/run-service.ts
6238
- async function runSolutionAsync(options, deps, cancellationToken) {
6239
- const { fileSystem } = deps;
6240
- const solutionDir = fileSystem.path.resolve(options.solutionPath);
6241
- const [readError, projects] = await catchError(readSolutionProjects(solutionDir, fileSystem));
6242
- if (readError) {
6243
- return RunResult.failed("InvalidInput" /* InvalidInput */, readError.message);
6244
- }
6245
- const runnable = projects.filter((p) => hasExecutorToolFor(p.projectType));
6246
- if (runnable.length === 0) {
6247
- const seen = projects.map((p) => `${p.name} (${p.projectType})`).join(", ") || "none";
6248
- return RunResult.failed("UnsupportedProjectType" /* UnsupportedProjectType */, `No project in this solution can be run. Projects: ${seen}.`);
6249
- }
6250
- const [selectionError, selected] = selectProject(runnable, options.projectName);
6251
- if (selectionError) {
6252
- return RunResult.failed("InvalidInput" /* InvalidInput */, selectionError);
6253
- }
6254
- const provision = deps.provisionForDebug ?? provisionSolutionForDebugAsync;
6255
- const shouldProvision = options.provisionResources ?? projects.length > 1;
6256
- const [executorOutcome, provisionOutcome] = await Promise.allSettled([
6257
- ensureExecutorTools([selected.projectType]),
6258
- shouldProvision ? provision({
6259
- solutionDir,
6260
- solutionName: fileSystem.path.basename(solutionDir),
6261
- tenant: options.tenant,
6262
- loginValidity: options.loginValidity
6263
- }) : Promise.resolve(undefined)
6264
- ]);
6265
- if (executorOutcome.status === "rejected") {
6266
- return RunResult.failed("PrepareFailed" /* PrepareFailed */, `Could not load the runner for project type '${selected.projectType}': ${describeError(executorOutcome.reason)}`);
6267
- }
6268
- if (provisionOutcome.status === "rejected") {
6269
- return RunResult.failed("PrepareFailed" /* PrepareFailed */, `Could not deploy the solution before the run: ${describeError(provisionOutcome.reason)}`);
6270
- }
6271
- let folderPath = options.folderPath;
6272
- const provisioned = provisionOutcome.value;
6273
- if (provisioned) {
6274
- if (!provisioned.ok) {
6275
- return RunResult.failed("PrepareFailed" /* PrepareFailed */, provisioned.message ?? "Could not deploy the solution before the run.");
6276
- }
6277
- folderPath = provisioned.folderPath;
6278
- }
6279
- const projectPath = fileSystem.path.resolve(solutionDir, selected.relativePath);
6280
- logger.debug(`Running '${selected.name}' (${selected.projectType}) from ${projectPath}` + `${options.entryPoint ? ` with entry point ${options.entryPoint}` : " with its default entry point"}`);
6281
- const connection = await resolveConnection(folderPath, options, deps);
6282
- const runner = new ProjectRunner({
6283
- fileSystem,
6284
- logger: deps.logger
6285
- });
6286
- return runner.runAsync({
6287
- project: {
6288
- name: selected.name,
6289
- projectType: selected.projectType,
6290
- projectPath
6291
- },
6292
- entryPoint: options.entryPoint,
6293
- inputArguments: options.inputArguments,
6294
- target: "Local" /* Local */,
6295
- connection,
6296
- siblingProjects: projects.filter((p) => p !== selected).map((p) => ({
6297
- name: p.name,
6298
- projectType: p.projectType,
6299
- projectPath: fileSystem.path.resolve(solutionDir, p.relativePath)
6300
- })),
6301
- timeoutMs: options.timeoutMs
6302
- }, cancellationToken);
6303
- }
6304
- async function resolveConnection(folderPath, options, deps) {
6305
- const getLoginStatus = deps.getLoginStatus ?? getLoginStatusAsync;
6306
- const [loginError, status] = await catchError(getLoginStatus({
6307
- ensureTokenValidityMinutes: options.loginValidity
6308
- }));
6309
- if (loginError || status.loginStatus !== "Logged in") {
6310
- logger.debug(`No signed-in session for the run: ${loginError?.message ?? status.loginStatus}. ` + "A project type that needs one will say so.");
6311
- return {
6312
- folderPath,
6313
- baseUrl: "",
6314
- accessToken: "",
6315
- organizationId: "",
6316
- organizationName: ""
6317
- };
6318
- }
6319
- return {
6320
- folderPath,
6321
- baseUrl: status.baseUrl ?? "",
6322
- accessToken: status.accessToken ?? "",
6323
- organizationId: status.organizationId ?? "",
6324
- organizationName: status.organizationName ?? "",
6325
- tenantId: status.tenantId,
6326
- tenantName: status.tenantName
6327
- };
6328
- }
6329
- function describeError(reason) {
6330
- const message = reason instanceof Error ? reason.message : String(reason);
6331
- const instructions = carriedInstructions(reason);
6332
- return instructions ? `${message} ${instructions}` : message;
6333
- }
6334
- function selectProject(runnable, requested) {
6335
- if (requested) {
6336
- const match = runnable.find((p) => p.name === requested);
6337
- if (!match) {
6338
- const names = runnable.map((p) => p.name).join(", ");
6339
- return [
6340
- `Project '${requested}' is not a runnable project in this solution. Runnable projects: ${names}.`,
6341
- runnable[0]
6342
- ];
6343
- }
6344
- return [undefined, match];
6345
- }
6346
- if (runnable.length > 1) {
6347
- const names = runnable.map((p) => p.name).join(", ");
6348
- return [
6349
- `This solution has more than one runnable project, so one has to be named with --project-name. Runnable projects: ${names}.`,
6350
- runnable[0]
6351
- ];
6352
- }
6353
- return [undefined, runnable[0]];
6354
- }
6355
5327
 
6356
5328
  // src/commands/run.ts
6357
5329
  var ERROR_CODE_BY_RUN_ERROR = {
@@ -6366,7 +5338,7 @@ var NEVER_STARTED = new Set([
6366
5338
  "Unauthorized" /* Unauthorized */
6367
5339
  ]);
6368
5340
  var registerRunCommand = (program) => {
6369
- program.command("run", { hidden: true }).description("Run a project from a UiPath solution. Currently supports RPA projects, agents and API Workflows.").argument("<solutionPath>", "Path to a solution directory (containing .uipx)").option("--project-name <name>", "Name of the project to run. Required only when the solution has more than one runnable project.").option("--entry-point <path>", "Entry point to execute (for RPA, a workflow such as Main.xaml). Defaults to the project's own entry point.").option("--input-arguments <json>", `Input arguments for the entry point, as a JSON object string (e.g. '{"name": "World"}').`).option("--folder-path <path>", "Orchestrator folder the run reports itself under, when the runtime needs one. Ignored when the solution is deployed, which uses the folder it deploys into.").option("--provision-resources", "Pack and deploy the solution into your personal workspace before running, even when the solution holds a single project. Done automatically for a solution with more than one project.").option("--no-provision-resources", "Run without deploying the solution first. Cross-project calls will not resolve.").option("--login-validity <minutes>", "Minimum minutes before token expiration to trigger a refresh (default: 10).", Number.parseInt, 10).trackedAction(processContext, async (solutionPath, options) => {
5341
+ program.command("run", { hidden: true }).description("Run a project from a UiPath solution. Currently supports RPA projects, agents and API Workflows.").argument("<solution-path>", "Path to a solution directory (containing .uipx)").option("--project-name <name>", "Name of the project to run. Required only when the solution has more than one runnable project.").option("--entry-point <path>", "Entry point to execute (for RPA, a workflow such as Main.xaml). Defaults to the project's own entry point.").option("--input-arguments <json>", `Input arguments for the entry point, as a JSON object string (e.g. '{"name": "World"}').`).option("--folder-path <path>", "Orchestrator folder the run reports itself under, when the runtime needs one. Ignored when the solution is deployed, which uses the folder it deploys into.").option("--provision-resources", "Pack and deploy the solution into your personal workspace before running, even when the solution holds a single project. Done automatically for a solution with more than one project.").option("--no-provision-resources", "Run without deploying the solution first. Cross-project calls will not resolve.").option("--login-validity <minutes>", "Minimum minutes before token expiration to trigger a refresh (default: 10).", Number.parseInt, 10).trackedAction(processContext, async (solutionPath, options) => {
6370
5342
  const [inputError, inputArguments] = parseInputArguments(options.inputArguments);
6371
5343
  if (inputError) {
6372
5344
  OutputFormatter.error({
@@ -6378,6 +5350,7 @@ var registerRunCommand = (program) => {
6378
5350
  processContext.exit(1);
6379
5351
  return;
6380
5352
  }
5353
+ const { runSolutionAsync } = await import("./run-service-p1vzzqe3.js");
6381
5354
  const result = await runSolutionAsync({
6382
5355
  solutionPath,
6383
5356
  projectName: options.projectName,
@@ -6493,7 +5466,26 @@ var SOLUTION_UPLOAD_EXAMPLES = [
6493
5466
  }
6494
5467
  ];
6495
5468
  var registerUploadCommand = (program) => {
6496
- program.command("upload").description("Upload a solution to UiPath Studio Web for browser-based editing. Accepts a solution directory, .uipx file, or .uis file. If Studio Web has no solution with the bundled SolutionId, the solution is imported as new and the local .uipx is updated with the assigned id; otherwise it is overwritten in place, with the replaced contents recorded first as a restorable version (skip with --no-snapshot). The output field Data.Action says which happened: 'Imported' or 'Overwritten'.").argument("<solutionPath>", "Path to a solution directory (containing .uipx), a .uipx file, or a .uis file.").option("--force", "Skip the existence check and overwrite the Studio Web solution named by the bundled SolutionId directly. Not normally needed — an upload overwrites an existing cloud solution on its own. Fails if that solution does not exist. No effect when no SolutionId is bundled (a .uis archive without one): the upload imports as new.").option("--no-snapshot", "Do not record a restorable pre-overwrite version of the cloud solution before replacing its contents. Changes made in Studio Web since the last upload are lost; local files are unaffected. No effect when the upload imports a new solution.").option("--login-validity <minutes>", "Minimum minutes before token expiration to trigger a refresh (default: 10)", parseInt, 10).examples(SOLUTION_UPLOAD_EXAMPLES).trackedAction(processContext, async (solutionPath, options) => {
5469
+ program.command("upload").description("Upload a solution to UiPath Studio Web for browser-based editing. Accepts a solution directory, .uipx file, or .uis file. If Studio Web has no solution with the bundled SolutionId, the solution is imported as new and the local .uipx is updated with the assigned id; otherwise it is overwritten in place, with the replaced contents recorded first as a restorable version (skip with --no-snapshot). The output field Data.Action says which happened: 'Imported' or 'Overwritten'.").argument("<solution-path>", "Path to a solution directory (containing .uipx), a .uipx file, or a .uis file.").option("--force", "Skip the existence check and overwrite the Studio Web solution named by the bundled SolutionId directly. Not normally needed — an upload overwrites an existing cloud solution on its own. Fails if that solution does not exist. No effect when no SolutionId is bundled (a .uis archive without one): the upload imports as new.").option("--no-snapshot", "Do not record a restorable pre-overwrite version of the cloud solution before replacing its contents. Changes made in Studio Web since the last upload are lost; local files are unaffected. No effect when the upload imports a new solution.").option("--login-validity <minutes>", "Minimum minutes before token expiration to trigger a refresh (default: 10)", parseInt, 10).examples(SOLUTION_UPLOAD_EXAMPLES).trackedAction(processContext, async (solutionPath, options) => {
5470
+ const {
5471
+ buildSolutionUploadFailureOutput,
5472
+ bundleSolution,
5473
+ importSolution,
5474
+ isSolutionUploadHttpError,
5475
+ overwriteSolution,
5476
+ resolveSolutionDir,
5477
+ StudioWebIncompatibleProjectError,
5478
+ solutionExistsOnStudioWeb,
5479
+ UipignoreExcludesProjectError
5480
+ } = await import("./index-6wak6hg6.js");
5481
+ const { readBundledSolutionId } = await import("./archive-extract-x35t9ktj.js");
5482
+ const { isUnpackableProjectTypeError } = await import("./packager-tool-resolver-994z3jkj.js");
5483
+ const { prepareSolutionResources } = await import("./prepare-solution-resources-m1djfj62.js");
5484
+ const {
5485
+ inspectSolutionPackageProjectTypes: inspectSolutionPackageProjectTypes2,
5486
+ summarizeShipProjectTypes,
5487
+ trackSolutionShipSucceeded: trackSolutionShipSucceeded2
5488
+ } = await import("./ship-telemetry-myes7ak5.js");
6497
5489
  const fs = getFileSystem();
6498
5490
  const [loginError, loginStatus] = await catchError(getLoginStatusAsync({
6499
5491
  ensureTokenValidityMinutes: options.loginValidity
@@ -6551,10 +5543,12 @@ var registerUploadCommand = (program) => {
6551
5543
  if (prepareError) {
6552
5544
  const errorCode = carriedErrorCode(prepareError) ?? (isUnpackableProjectTypeError(prepareError) ? "invalid_argument" : undefined);
6553
5545
  const contributionCode = prepareError.contributionCode;
5546
+ const retry = carriedRetry(prepareError);
6554
5547
  OutputFormatter.error({
6555
5548
  Result: RESULTS.Failure,
6556
5549
  Message: prepareError.message,
6557
5550
  ...errorCode ? { ErrorCode: errorCode } : {},
5551
+ ...retry ? { Retry: retry } : {},
6558
5552
  ...typeof contributionCode === "string" ? { Context: { errorCode: contributionCode } } : {},
6559
5553
  Instructions: carriedInstructions(prepareError) ?? "Fix the reported problem in the project's files, then re-run the upload."
6560
5554
  });
@@ -6686,8 +5680,8 @@ var registerUploadCommand = (program) => {
6686
5680
  Response: result
6687
5681
  }
6688
5682
  });
6689
- const projectTypeSummary = bundledProjectTypes.length > 0 ? summarizeShipProjectTypes(bundledProjectTypes) : await inspectSolutionPackageProjectTypes(uisPath);
6690
- trackSolutionShipSucceeded({
5683
+ const projectTypeSummary = bundledProjectTypes.length > 0 ? summarizeShipProjectTypes(bundledProjectTypes) : await inspectSolutionPackageProjectTypes2(uisPath);
5684
+ trackSolutionShipSucceeded2({
6691
5685
  [ShipDimensions.ShipKind]: "upload",
6692
5686
  [ShipDimensions.Target]: "studio_web",
6693
5687
  [CommandDimensions.CommandName]: "uip solution upload",
@@ -6710,19 +5704,12 @@ async function updateLocalSolutionId(fs, result, solutionId, uipxPath) {
6710
5704
  const shouldUpdateUipx = uipxPath !== undefined && returnedSolutionId !== undefined && returnedSolutionId !== solutionId;
6711
5705
  const rewroteLocalSolutionId = shouldUpdateUipx && solutionId !== undefined;
6712
5706
  if (shouldUpdateUipx && returnedSolutionId && uipxPath) {
5707
+ const { updateUipxSolutionId } = await import("./index-6wak6hg6.js");
6713
5708
  await updateUipxSolutionId(fs, uipxPath, returnedSolutionId);
6714
5709
  logger.info(solutionId ? `Studio Web assigned SolutionId ${returnedSolutionId} — the local .uipx now points at it (was ${solutionId}).` : `Studio Web assigned SolutionId ${returnedSolutionId} — the local .uipx now points at it.`);
6715
5710
  }
6716
5711
  return { returnedSolutionId, rewroteLocalSolutionId };
6717
5712
  }
6718
- function httpStatusOf(error) {
6719
- if (error instanceof Error && "status" in error) {
6720
- const status = error.status;
6721
- if (typeof status === "number")
6722
- return status;
6723
- }
6724
- return;
6725
- }
6726
5713
  function isSolutionNotFoundError(error) {
6727
5714
  return httpStatusOf(error) === 404;
6728
5715
  }
@@ -6749,7 +5736,7 @@ async function buildProbeFailureOutput(probeError, solutionId, identity) {
6749
5736
  }
6750
5737
  function probeAuthInstructions(solutionId, identity) {
6751
5738
  const actor = identity?.type === "Application" ? `This session acts as external application ${identity.clientId ?? "(client id unknown)"}: it needs a Studio Web grant that can read a solution.` : identity?.type === "User" ? "This session acts as a user: check that your account has Studio Web access in this tenant." : "Check that this session may read a solution in Studio Web — an external application needs a StudioWebS2S grant, a user needs Studio Web access in the tenant.";
6752
- return `Studio Web refused the read, and the session is authenticated, so ` + `re-running 'uip login' mints the same token and fails the same way. ` + `${actor} Also confirm solution ${solutionId} lives in the organization ` + `and tenant this session logged into. Nothing was uploaded.`;
5739
+ return `Studio Web refused the read, and the session is authenticated, so re-running 'uip login' mints the same token and fails the same way. ${actor} Also confirm solution ${solutionId} lives in the organization and tenant this session logged into. Nothing was uploaded.`;
6753
5740
  }
6754
5741
  function outputError(message) {
6755
5742
  OutputFormatter.error({
@@ -6782,7 +5769,7 @@ var registerCommands = async (program) => {
6782
5769
  registerResourceCommand(program);
6783
5770
  registerDeleteCommand(program);
6784
5771
  if (isPreviewBuild()) {
6785
- const { registerListCommand } = await import("./list-s5pkkefj.js");
5772
+ const { registerListCommand } = await import("./list-7jy11vb4.js");
6786
5773
  registerListCommand(program);
6787
5774
  }
6788
5775
  registerFeedsCommand(program);
@@ -6790,4 +5777,4 @@ var registerCommands = async (program) => {
6790
5777
 
6791
5778
  export { metadata, registerCommands };
6792
5779
 
6793
- //# debugId=E572428E1F435ACA64756E2164756E21
5780
+ //# debugId=CB17F3BA78F310B564756E2164756E21