@uipath/solution-tool 1.201.0-preview.133 → 1.202.0-preview.134

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 (47) hide show
  1. package/dist/deploy.d.ts +6 -1
  2. package/dist/deploy.js +15 -16
  3. package/dist/{index-2fj08e7n.js → index-gpd94m28.js} +27 -27
  4. package/dist/{index-w03qc9m8.js → index-sby22td6.js} +4 -4
  5. package/dist/index.js +16 -19
  6. package/dist/init.js +10 -13
  7. package/dist/{js-yaml-4ypbq2tt.js → js-yaml-b2jq67kn.js} +16 -16
  8. package/dist/{list-skbehtq2.js → list-3mrc9s3f.js} +7 -11
  9. package/dist/models/pack-command-types.d.ts +8 -0
  10. package/dist/pack.js +9 -12
  11. package/dist/{packager-tool-krd5v2r5.js → packager-tool-0qva0ebq.js} +129 -53
  12. package/dist/{packager-tool-0v6na3yp.js → packager-tool-1de529jm.js} +9 -7
  13. package/dist/{packager-tool-9vehmnke.js → packager-tool-3hbsdwjm.js} +6 -661
  14. package/dist/{packager-tool-fzwxq48d.js → packager-tool-3y92zbg2.js} +3 -3
  15. package/dist/{packager-tool-f7kj5fpa.js → packager-tool-5pfxgc8z.js} +19 -11
  16. package/dist/{packager-tool-9w3k4e77.js → packager-tool-b16qemg2.js} +494 -198
  17. package/dist/{packager-tool-zbp5p149.js → packager-tool-bahvrjbv.js} +592 -264
  18. package/dist/{packager-tool-129wn232.js → packager-tool-dfrk01gn.js} +198 -2
  19. package/dist/{packager-tool-67ssxgph.js → packager-tool-fh8pb2th.js} +3 -5
  20. package/dist/{packager-tool-c29pg93e.js → packager-tool-hc6ybtdw.js} +5 -5
  21. package/dist/{packager-tool-bcpknnr8.js → packager-tool-hgx66d1p.js} +1656 -558
  22. package/dist/{packager-tool-2yz7m5ny.js → packager-tool-nq2nq71y.js} +21282 -20197
  23. package/dist/{packager-tool-wjhn59ft.js → packager-tool-t89r1edr.js} +596 -180
  24. package/dist/{packager-tool-vpr77gre.js → packager-tool-x3ehbhsn.js} +3 -2
  25. package/dist/{packager-tool-yktm4v4r.js → packager-tool-xntjj1bt.js} +1 -1
  26. package/dist/packager-tool.d.ts +4 -3
  27. package/dist/packager-tool.js +4 -4
  28. package/dist/publish.js +8 -11
  29. package/dist/resource.js +7 -10
  30. package/dist/services/activation.d.ts +9 -1
  31. package/dist/services/deploy-run-service.d.ts +25 -1
  32. package/dist/services/deploy-uninstall-service.d.ts +20 -1
  33. package/dist/services/deploy-upgrade-service.d.ts +94 -0
  34. package/dist/services/deployment-feed-locator.d.ts +36 -0
  35. package/dist/services/deployment-search.d.ts +88 -7
  36. package/dist/services/pack-command-service.d.ts +15 -0
  37. package/dist/services/package-metadata-rewrite.d.ts +9 -5
  38. package/dist/services/publish-service.d.ts +11 -9
  39. package/dist/services/solution-path.d.ts +34 -0
  40. package/dist/templates/AGENTS.md +183 -16
  41. package/dist/tool.js +18 -21
  42. package/package.json +2 -2
  43. package/dist/browser-strategy-yccf8mtd.js +0 -99
  44. package/dist/node-strategy-12qfy0nv.js +0 -348
  45. package/dist/packager-tool-5arsyj36.js +0 -11
  46. package/dist/packager-tool-7eva0peq.js +0 -265
  47. package/dist/packager-tool-9qecd4wb.js +0 -14
@@ -29,7 +29,8 @@ class ToolsFactoryRepository {
29
29
  getProjectToolFactory(projectType) {
30
30
  const factory = this.projectFactoryMap.get(projectType);
31
31
  if (!factory) {
32
- throw new Error(`No tool factory found for project type '${projectType}'`);
32
+ const known = [...this.projectFactoryMap.keys()].join(", ");
33
+ throw new Error(`Cannot pack project type '${projectType}': no packager is installed for it. ` + `Project types that can be packed: ${known || "none"}.`);
33
34
  }
34
35
  return factory;
35
36
  }
@@ -892,4 +893,4 @@ I18nManager.registerTranslations("zu", zu);
892
893
  I18nManager.setLocale("en");
893
894
  export { ToolResult, toolsFactoryRepository };
894
895
 
895
- //# debugId=A70248815AC3C8A364756E2164756E21
896
+ //# debugId=EE7F0622AB4476C164756E2164756E21
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  catchError,
3
3
  getAuthContext
4
- } from "./packager-tool-bcpknnr8.js";
4
+ } from "./packager-tool-hgx66d1p.js";
5
5
 
6
6
  // src/services/studio-web-auth-middleware.ts
7
7
  var studioWebAuthByCommand = new WeakMap;
@@ -1,9 +1,10 @@
1
1
  /**
2
2
  * Register the factories solution-tool owns: the ResourceBuilder *solution*
3
3
  * factory (essential to every pack; no CLI verb can own it) plus the project
4
- * factories for the types no CLI tool owns — Connector and AppV2. Project
5
- * wrapper tools (flow, agent, case, maestro, api-workflow, function) ship
6
- * their own `packager-tool` entry point and are loaded on demand.
4
+ * factory for Connector, the one project type no CLI tool owns — there is no
5
+ * `connector` verb. Every other project type is registered by the tool that
6
+ * owns it, through that tool's own `packager-tool` entry point, loaded on
7
+ * demand by `ensurePackagerTools` (AGENTS.md Hard Rule #18).
7
8
  *
8
9
  * Explicit, not a module-load side effect: `ensurePackagerTools` calls this at
9
10
  * the start of every pack / restore / cleanup, which is the only code that
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  registerPackagerFactories
3
- } from "./packager-tool-9vehmnke.js";
4
- import"./packager-tool-vpr77gre.js";
5
- import"./packager-tool-129wn232.js";
6
- import"./packager-tool-0v6na3yp.js";
3
+ } from "./packager-tool-3hbsdwjm.js";
4
+ import"./packager-tool-x3ehbhsn.js";
5
+ import"./packager-tool-dfrk01gn.js";
6
+ import"./packager-tool-1de529jm.js";
7
7
  export {
8
8
  registerPackagerFactories
9
9
  };
package/dist/publish.js CHANGED
@@ -1,17 +1,14 @@
1
1
  import {
2
2
  publishSolutionAsync
3
- } from "./packager-tool-f7kj5fpa.js";
4
- import"./packager-tool-c29pg93e.js";
5
- import"./packager-tool-9w3k4e77.js";
6
- import"./packager-tool-fzwxq48d.js";
7
- import"./packager-tool-bcpknnr8.js";
8
- import"./packager-tool-9qecd4wb.js";
9
- import"./packager-tool-7eva0peq.js";
10
- import"./packager-tool-5arsyj36.js";
11
- import"./packager-tool-129wn232.js";
12
- import"./packager-tool-0v6na3yp.js";
3
+ } from "./packager-tool-5pfxgc8z.js";
4
+ import"./packager-tool-hc6ybtdw.js";
5
+ import"./packager-tool-b16qemg2.js";
6
+ import"./packager-tool-3y92zbg2.js";
7
+ import"./packager-tool-hgx66d1p.js";
8
+ import"./packager-tool-dfrk01gn.js";
9
+ import"./packager-tool-1de529jm.js";
13
10
  export {
14
11
  publishSolutionAsync
15
12
  };
16
13
 
17
- //# debugId=DA463E68D9A9E64264756E2164756E21
14
+ //# debugId=AD7DDE48BF35E04564756E2164756E21
package/dist/resource.js CHANGED
@@ -1,16 +1,13 @@
1
1
  import {
2
2
  resourceRefreshAsync
3
- } from "./packager-tool-krd5v2r5.js";
4
- import"./packager-tool-vpr77gre.js";
5
- import"./packager-tool-fzwxq48d.js";
6
- import"./packager-tool-bcpknnr8.js";
7
- import"./packager-tool-9qecd4wb.js";
8
- import"./packager-tool-7eva0peq.js";
9
- import"./packager-tool-5arsyj36.js";
10
- import"./packager-tool-129wn232.js";
11
- import"./packager-tool-0v6na3yp.js";
3
+ } from "./packager-tool-0qva0ebq.js";
4
+ import"./packager-tool-x3ehbhsn.js";
5
+ import"./packager-tool-3y92zbg2.js";
6
+ import"./packager-tool-hgx66d1p.js";
7
+ import"./packager-tool-dfrk01gn.js";
8
+ import"./packager-tool-1de529jm.js";
12
9
  export {
13
10
  resourceRefreshAsync
14
11
  };
15
12
 
16
- //# debugId=EF371AE5DDFD388A64756E2164756E21
13
+ //# debugId=54ED39ED9D918B1A64756E2164756E21
@@ -1,11 +1,19 @@
1
1
  import { type PollUntilResult } from "@uipath/common";
2
2
  import type { DeploymentStatus } from "@uipath/pipelines-sdk";
3
- import type { DeploymentSearchItemDto2, SolutionAuthContext } from "@uipath/solution-sdk";
3
+ import type { DeploymentSearchItemDto2, InitOverrideFunction, SolutionAuthContext } from "@uipath/solution-sdk";
4
4
  export type ActivationOptions = {
5
5
  timeoutSeconds: number;
6
6
  pollIntervalMs: number;
7
7
  /** Host-side cancellation. Falls back to `processContext.pollSignal` (CLI's Ctrl-C) when omitted. */
8
8
  signal?: AbortSignal;
9
+ /**
10
+ * `X-UIPATH-FolderKey` override for the feed the deployment lives in.
11
+ * Omitted for the tenant feed. Every call below resolves against the
12
+ * tenant feed without it, so a Personal Workspace or folder-feed
13
+ * deployment is answered "not found" — see
14
+ * {@link findDeploymentAcrossFeeds}.
15
+ */
16
+ scope?: InitOverrideFunction;
9
17
  };
10
18
  export type ActivationResult =
11
19
  /** Pre-activate steps lookup or activate call failed. */
@@ -1,3 +1,4 @@
1
+ import { type CliErrorCode, type RetryHint } from "@uipath/common";
1
2
  import { type FeedScope } from "./feed-resolver";
2
3
  /** Discriminator for {@link DeployFailure}; library callers can ignore the tag and read `.message`/`.instructions`. */
3
4
  export type DeployFailureReason = "auth_failed" | "folder_resolution_failed" | "config_file_not_found" | "config_file_read_failed" | "config_file_parse_failed" | "install_request_failed"
@@ -62,8 +63,21 @@ export interface DeployOptions {
62
63
  pollInterval?: number;
63
64
  /** Minimum minutes before token expiration to trigger a refresh. Default 10. */
64
65
  loginValidity?: number;
66
+ /**
67
+ * Feed / Personal Workspace deploys only: poll the new deployment to a
68
+ * terminal state instead of returning as soon as the install is accepted.
69
+ * The tenant path always polls, so this changes nothing there.
70
+ */
71
+ wait?: boolean;
65
72
  /** Skip auto-activation; leave deployment in "Inactive (Ready to activate)" state. */
66
73
  skipActivate?: boolean;
74
+ /**
75
+ * Deploy even when the package already has a deployment in the target feed.
76
+ * Off by default: `deploy run` always creates a *new* deployment in a *new*
77
+ * folder, so repeating it quietly multiplies folders (UV-15362). Callers
78
+ * that really do want a second, independent copy opt in here.
79
+ */
80
+ yes?: boolean;
67
81
  /** Host-side cancellation for both poll loops (e.g. VS Code's cancel button); replaces `processContext.pollSignal`. */
68
82
  signal?: AbortSignal;
69
83
  }
@@ -72,7 +86,8 @@ export interface DeploySuccess {
72
86
  /**
73
87
  * Tenant path: `"DeploymentSucceeded"` after polling reaches terminal.
74
88
  * Feed/PW path: `"DeploymentStarted"` — the AS auto-install endpoint
75
- * returns at request acceptance, before terminal state is observable.
89
+ * returns at request acceptance, before terminal state is observable — or
90
+ * `"DeploymentSucceeded"` when `wait` was set and the poll got there.
76
91
  */
77
92
  status: string;
78
93
  /** Tenant only — populated from Pipelines install result. Feed/PW returns no key. */
@@ -115,6 +130,15 @@ export interface DeployFailure {
115
130
  exitCode: number;
116
131
  /** Set whenever an install was initiated (post-`pipelinesInstall` paths). */
117
132
  pipelineDeploymentId?: string;
133
+ /**
134
+ * Set whenever the failure mode is known, so the CLI does not fall back to
135
+ * `OutputFormatter`'s guess. The guess is wrong for a poll that timed out:
136
+ * the message carries no HTTP status, so it defaults to `unknown_error` /
137
+ * `RetryWillNotFix` while the instructions right next to it say the deploy
138
+ * may still be running.
139
+ */
140
+ errorCode?: CliErrorCode;
141
+ retry?: RetryHint;
118
142
  }
119
143
  export type DeployResult = DeploySuccess | DeployFailure;
120
144
  /**
@@ -1,4 +1,11 @@
1
+ import { type CliErrorCode, type RetryHint } from "@uipath/common";
1
2
  export type UninstallDeploymentFailureReason = "auth_failed" | "uninstall_request_failed"
3
+ /**
4
+ * Orchestrator refused the uninstall because the deployment still had an
5
+ * operation running, and it was still running when the wait ran out —
6
+ * recommended exit 2, same as a poll timeout.
7
+ */
8
+ | "uninstall_blocked"
2
9
  /** Uninstall poll didn't reach a terminal state — recommended exit 2 (CI distinguishability). */
3
10
  | "poll_timeout" | "poll_failed" | "poll_aborted"
4
11
  /** Uninstall reached a terminal state but it was `FailedUninstall`. */
@@ -11,7 +18,11 @@ export interface UninstallDeploymentOptions {
11
18
  tenant?: string;
12
19
  /** Pin auth to this exact `.uipath/.auth` path. */
13
20
  envFilePath?: string;
14
- /** Timeout in seconds for uninstall polling. Default 360. */
21
+ /**
22
+ * Timeout in seconds for the whole uninstall: waiting out an operation
23
+ * that blocks the request, then polling the uninstall to a terminal
24
+ * state. Default 360.
25
+ */
15
26
  timeout?: number;
16
27
  /** Milliseconds between uninstall status polls. Default 5000. */
17
28
  pollInterval?: number;
@@ -36,6 +47,14 @@ export interface UninstallDeploymentFailure {
36
47
  message: string;
37
48
  instructions: string;
38
49
  exitCode: number;
50
+ /**
51
+ * Set whenever the failure mode is known, so the CLI does not fall back to
52
+ * `OutputFormatter`'s guess. The guess is wrong for a blocked uninstall:
53
+ * an HTTP 400 defaults to `invalid_argument` / `RetryWillNotFix`, telling
54
+ * an agent never to retry a condition that clears by itself.
55
+ */
56
+ errorCode?: CliErrorCode;
57
+ retry?: RetryHint;
39
58
  }
40
59
  export type UninstallDeploymentResult = UninstallDeploymentSuccess | UninstallDeploymentFailure;
41
60
  /**
@@ -0,0 +1,94 @@
1
+ import type { PollFailureReason } from "@uipath/common";
2
+ import { DeploymentOperationStatus } from "@uipath/solution-sdk";
3
+ export type UpgradeDeploymentFailureReason = "auth_failed"
4
+ /** Personal Workspace could not be resolved (only when `--personal-workspace`). */
5
+ | "personal_workspace_failed"
6
+ /** No deployment with the given key (or not visible in the chosen scope). */
7
+ | "deployment_not_found"
8
+ /** The deployment is already at the newest version and no `--version` was given. */
9
+ | "no_upgrade_available"
10
+ /** The target package/version could not be resolved to a package-version key. */
11
+ | "package_not_found"
12
+ /** Requested a version other than the latest, which the package search can't key. */
13
+ | "unsupported_version"
14
+ /** The upgrade HTTP request failed. */
15
+ | "request_failed"
16
+ /** The upgrade was queued but installing the resulting draft failed. */
17
+ | "install_failed"
18
+ /** The install was accepted but did not reach a terminal state in time. */
19
+ | "install_timeout"
20
+ /**
21
+ * The status poll itself gave up (too many consecutive errors), or was
22
+ * interrupted / aborted. Distinct from `install_timeout`: the deadline was
23
+ * never reached, so a longer `--timeout` is not the fix.
24
+ */
25
+ | PollFailureReason;
26
+ export interface UpgradeDeploymentOptions {
27
+ /**
28
+ * Override the active tenant for auth resolution. The CLI's deprecated
29
+ * `--tenant` flag flows through here; library callers usually omit it.
30
+ */
31
+ tenant?: string;
32
+ /** Pin auth to this exact `.uipath/.auth` path. */
33
+ envFilePath?: string;
34
+ /**
35
+ * Version to upgrade to. Defaults to the deployment's newest available
36
+ * version. Only the latest published version is resolvable today (same
37
+ * limitation as Personal Workspace deploy).
38
+ */
39
+ version?: string;
40
+ /**
41
+ * Scope the deployment lookup and the upgrade to the caller's Personal
42
+ * Workspace feed. A tenant deployment is upgraded in its own root folder.
43
+ */
44
+ personalWorkspace?: boolean;
45
+ /** Minimum minutes before token expiration to trigger a refresh. Default 10. */
46
+ loginValidity?: number;
47
+ /**
48
+ * Return as soon as the install is accepted, without polling for the
49
+ * terminal state. The version still moves; the caller just does not wait.
50
+ */
51
+ noWait?: boolean;
52
+ /** Seconds to wait for the install to reach a terminal state. Default 300. */
53
+ timeout?: number;
54
+ /** Milliseconds between status polls. Default 5000. */
55
+ pollInterval?: number;
56
+ }
57
+ export interface UpgradeDeploymentSuccess {
58
+ ok: true;
59
+ deploymentName: string;
60
+ /** Version the deployment ran before the upgrade (null when the API omits it). */
61
+ fromVersion?: string | null;
62
+ /** Version the upgrade targets. */
63
+ toVersion: string;
64
+ /**
65
+ * Key of the VersionChange deployment the upgrade created. This is NOT the
66
+ * key that was passed in — the server makes a new record — and it is the
67
+ * one `deploy status`-style follow-ups must address.
68
+ */
69
+ versionChangeKey: string;
70
+ /** Terminal status reached, or `Draft`/`InProgress` when `noWait`. */
71
+ status: DeploymentOperationStatus;
72
+ }
73
+ export interface UpgradeDeploymentFailure {
74
+ ok: false;
75
+ reason: UpgradeDeploymentFailureReason;
76
+ message: string;
77
+ instructions: string;
78
+ exitCode: number;
79
+ }
80
+ export type UpgradeDeploymentResult = UpgradeDeploymentSuccess | UpgradeDeploymentFailure;
81
+ /**
82
+ * Programmatic core of `uip solution deploy upgrade`. Moves an existing
83
+ * deployment to a newer package version in place — the CLI equivalent of the
84
+ * Orchestrator UI "Upgrade" button, so a blocked redeploy (UV-15356) can be
85
+ * resolved without the UI.
86
+ *
87
+ * Two server calls, because one is not enough:
88
+ * `POST /api/deployments/{key}/upgrade` only queues the move as a second
89
+ * deployment record (`VersionChange`, status `Draft`) and leaves the live
90
+ * version alone, then `POST /api/deployments/{draftKey}/run` installs it.
91
+ * Waits for the install to reach a terminal state unless `noWait` is set.
92
+ * Does not touch `OutputFormatter`/`processContext`.
93
+ */
94
+ export declare function upgradeDeploymentAsync(deploymentKey: string, options?: UpgradeDeploymentOptions): Promise<UpgradeDeploymentResult>;
@@ -0,0 +1,36 @@
1
+ import type { DeploymentSearchItemDto2, InitOverrideFunction, SolutionAuthContext } from "@uipath/solution-sdk";
2
+ /** A deployment and the feed header every call about it needs. */
3
+ export interface DeploymentLocation {
4
+ deployment: DeploymentSearchItemDto2;
5
+ /** `X-UIPATH-FolderKey` override; undefined for the tenant feed. */
6
+ scope?: InitOverrideFunction;
7
+ }
8
+ /** Auth-resolution knobs the feed sweep forwards to its lookups. */
9
+ export interface DeploymentLocationOptions {
10
+ tenant?: string;
11
+ loginValidity?: number;
12
+ envFilePath?: string;
13
+ }
14
+ /**
15
+ * Locate a deployment and the feed it lives in.
16
+ *
17
+ * `uninstall` and `activate` take no feed flag, so they have to work this out
18
+ * themselves: every Pipelines call about a deployment resolves against the
19
+ * tenant feed unless it carries `X-UIPATH-FolderKey`, and a deployment created
20
+ * by `deploy run --personal-workspace` or `--feed <folder-feed>` is invisible
21
+ * to the tenant-scoped search, so an unscoped call is answered "not found".
22
+ *
23
+ * Tenant first — that is the default feed and the one most deployments live in,
24
+ * so the common case costs one request. A tenant-search transport error
25
+ * propagates (callers treat it as a lookup failure). Only on a tenant miss does
26
+ * the sweep run, and it is best-effort throughout: a feed whose search fails is
27
+ * skipped rather than allowed to end the sweep, since the next feed may hold
28
+ * the record. A tenant that exposes many folder feeds therefore pays one search
29
+ * per feed, but only on a path that was already going to fail.
30
+ */
31
+ export declare function findDeploymentAcrossFeeds(auth: SolutionAuthContext, deploymentName: string, options: DeploymentLocationOptions): Promise<DeploymentLocation | undefined>;
32
+ /**
33
+ * {@link findDeploymentAcrossFeeds} that never throws — for callers that want
34
+ * the feed scope when it can be had but must not fail when it cannot.
35
+ */
36
+ export declare function findDeploymentAcrossFeedsBestEffort(auth: SolutionAuthContext, deploymentName: string, options: DeploymentLocationOptions): Promise<DeploymentLocation | undefined>;
@@ -10,20 +10,85 @@ import type { DeploymentOperationStatus, DeploymentSearchItemDto2, InitOverrideF
10
10
  */
11
11
  export declare function findDeploymentByName(auth: SolutionAuthContext, deploymentName: string, scope?: InitOverrideFunction): Promise<DeploymentSearchItemDto2 | undefined>;
12
12
  /**
13
- * Best-effort lookup of the deployment that blocks a redeploy of `packageName`.
14
- * Pages `searchSearchDeployments22` by substring like {@link findDeploymentByName},
15
- * then returns the first row whose `packageName` matches exactly (and, when
16
- * `folderPath` is given, whose `folderPath` matches too). Swallows any lookup
17
- * failure and returns undefined so the caller's original error always surfaces.
13
+ * Every deployment whose `packageName` matches exactly.
14
+ *
15
+ * Pages `searchSearchDeployments22` to exhaustion instead of stopping at the
16
+ * first hit, because the redeploy gate has to report *all* the deployments
17
+ * that already exist, not just one.
18
+ *
19
+ * Sends two filters on purpose. `packageName` is the request's own server-side
20
+ * filter, which keeps the result set small; `searchTerm` is the substring
21
+ * filter the other call sites here already rely on, so the lookup still works
22
+ * if the server ignores `packageName`. The client-side `===` check is what
23
+ * makes the answer exact either way.
24
+ *
25
+ * Statuses are deliberately unfiltered — callers decide which states matter
26
+ * (the gate uses {@link blocksRedeploy}; the redeploy-conflict path needs the
27
+ * failed/running rows the gate ignores).
28
+ *
29
+ * Throws on transport / server errors; callers decide whether to swallow.
30
+ */
31
+ export declare function findDeploymentsByPackageName(auth: SolutionAuthContext, packageName: string, options?: {
32
+ folderPath?: string;
33
+ scope?: InitOverrideFunction;
34
+ }): Promise<DeploymentSearchItemDto2[]>;
35
+ /**
36
+ * Does this record represent a deployment that is really there, so a fresh
37
+ * `deploy run` of the same package would create a second copy of it?
38
+ *
39
+ * The status alone does not answer that — the row's `operation` is overwritten
40
+ * by whatever ran last, so the same status means opposite things depending on
41
+ * which verb produced it. Read the pair:
42
+ *
43
+ * - **Anything `InProgress`** — blocks. The deployment is there until the
44
+ * operation finishes, an uninstall included.
45
+ * - **`Successful`** — blocks, except a successful `Uninstall`: that history
46
+ * row outlives the deployment, and blocking on it would make a package
47
+ * permanently undeployable after its first uninstall.
48
+ * - **`Draft` / `Failed` / `FailedRollback` on an `Install`** — does not block.
49
+ * The deploy the user is retrying is the one that produced the record, and
50
+ * our own guidance for a Draft is to fix the errors and rerun `deploy run`
51
+ * (see {@link appendDraftDeploymentInstructions}). Blocking would leave the
52
+ * user with nothing they are allowed to do.
53
+ * - **`Draft` / `Failed` / `FailedRollback` on any other operation** — blocks.
54
+ * An uninstall or an upgrade that failed ran *against* a deployment that is
55
+ * still there and still holds its folder; the retry verb is uninstall or
56
+ * upgrade, not `deploy run`.
57
+ *
58
+ * A record we cannot classify — no `operation`, or a status outside the enum —
59
+ * falls open (does not block). The guard is a rail against accidental
60
+ * duplication, not a safety interlock.
18
61
  */
19
- export declare function findDeploymentByPackageName(auth: SolutionAuthContext, packageName: string, folderPath?: string, scope?: InitOverrideFunction): Promise<DeploymentSearchItemDto2 | undefined>;
62
+ export declare function blocksRedeploy(deployment: DeploymentSearchItemDto2): boolean;
63
+ /**
64
+ * How many deployments the summary names before it starts counting. Exported so
65
+ * callers that decorate those deployments (the redeploy gate resolves a folder
66
+ * per named deployment) bound their work by the same number instead of keeping
67
+ * a second copy of it in sync by hand.
68
+ */
69
+ export declare const MAX_LISTED_DEPLOYMENTS = 5;
70
+ /**
71
+ * One human-readable line naming the deployments that already exist, for the
72
+ * redeploy gate's error message. Long lists are cut short — a package deployed
73
+ * forty times should not produce forty clauses.
74
+ *
75
+ * `folderPath` on the record is the deployment's *parent* folder, so every
76
+ * deployment of one package under `Shared` reports `Shared` — which hides
77
+ * exactly what the reader needs to see. `folderByKey` maps
78
+ * `installedRootFolderKey` onto the real solution folder when the caller could
79
+ * resolve it; the parent is the fallback. `installedRootFolderName` is never
80
+ * used: the record echoes the *requested* name back there, so a
81
+ * collision-renamed deployment reads as living in a folder it does not
82
+ * (UV-15346).
83
+ */
84
+ export declare function formatExistingDeployments(deployments: DeploymentSearchItemDto2[], folderByKey?: Map<string, string>): string;
20
85
  /**
21
86
  * Best-effort deployment lookup: returns undefined on any failure instead of
22
87
  * propagating, so callers can read the record opportunistically — without
23
88
  * masking a prior error (error paths) or blocking an otherwise-successful
24
89
  * result (success paths, e.g. reading back the resolved install folder).
25
90
  */
26
- export declare function findDeploymentBestEffort(auth: SolutionAuthContext, deploymentName: string): Promise<DeploymentSearchItemDto2 | undefined>;
91
+ export declare function findDeploymentBestEffort(auth: SolutionAuthContext, deploymentName: string, scope?: InitOverrideFunction): Promise<DeploymentSearchItemDto2 | undefined>;
27
92
  /**
28
93
  * Append a hint to error instructions when the deployment in question is
29
94
  * stuck in `Draft` state — that condition has a specific remediation that
@@ -64,6 +129,22 @@ export type DeployPollRecovery = {
64
129
  operationStatus: DeploymentOperationStatus;
65
130
  };
66
131
  export declare function interpretFailedDeployPoll(deployment: DeploymentSearchItemDto2 | undefined): DeployPollRecovery | undefined;
132
+ /**
133
+ * Has a freshly created deployment finished moving? Answers the question
134
+ * `deploy run --wait` asks on every poll.
135
+ *
136
+ * `Draft` is deliberately *not* settled here, even though
137
+ * {@link mapOperationStatusToPipelineStatus} maps it to `DeploymentFailed`.
138
+ * The two are asked about different moments. That mapper answers for a
139
+ * deployment whose install was already observed running, so a Draft record
140
+ * there means the install never completed. The `--wait` poll starts before the
141
+ * install does, and the pipeline parks a new deployment in `Draft` until it
142
+ * promotes it to `InProgress` — so reading Draft as a verdict reported a
143
+ * healthy Personal Workspace deploy as failed seconds after starting it. Same
144
+ * reasoning as the `Draft` note in {@link interpretFailedDeployPoll}: a Draft
145
+ * that never moves is caught by the poll timeout instead.
146
+ */
147
+ export declare function isSettledDeployOperationStatus(operationStatus: DeploymentOperationStatus | undefined | null): boolean;
67
148
  /**
68
149
  * Map a search-service `DeploymentOperationStatus` onto the corresponding
69
150
  * terminal `PipelineDeploymentStatus`. Returns undefined for non-terminal
@@ -18,6 +18,21 @@ export declare class PackCommandService {
18
18
  * Execute the pack command and return result (for programmatic usage and testing)
19
19
  */
20
20
  executeAsync(solutionPath: string, options: PackCommandOptions): Promise<ToolResult>;
21
+ /**
22
+ * Copy a solution directory into a fresh temp workspace so a dry run can
23
+ * mutate it freely. Returns `undefined` when no copy is needed (a real
24
+ * pack, or a `.uis` input), which leaves the caller on the original path.
25
+ *
26
+ * The copy keeps the source's basename: `createPackOptions` derives the
27
+ * package name from the user-supplied path, but member-project and
28
+ * `.uipx` lookups walk the copied tree, so the two must agree.
29
+ */
30
+ private copyDirectoryForDryRun;
31
+ /**
32
+ * Remove a dry-run copy. Best-effort: the copy lives in the OS temp dir and
33
+ * the user never sees the path, so failures only log at debug.
34
+ */
35
+ private discardDryRunCopy;
21
36
  /**
22
37
  * Find the member project directory that is equal to or contains the
23
38
  * resolved output path, if any. Manifest read errors are ignored here —
@@ -24,11 +24,15 @@ export interface PackageMetadataRewriteResult {
24
24
  * downloaded with `packages download`) cannot re-pack it.
25
25
  *
26
26
  * Only `solutionMetadata.json` carries the solution-level name and version. The
27
- * project packages bundled under `files/` keep their own identities — they are
28
- * addressed by `resources.json` / `configurations/**` through their own
29
- * `<project>.<type>.<project>:<version>` keys, which are independent of the
30
- * solution package's name and version. So this rewrite deliberately touches one
31
- * entry and copies everything else through byte-for-byte.
27
+ * project packages bundled under `files/<projectId>/` keep their own identities:
28
+ * each process resource in the split `resources/**` tree names its package id in
29
+ * `spec.packageName` and points at the sibling `package`-kind resource by uuid
30
+ * (`spec.package.key`). The bundled package's version is not in the resource
31
+ * tree at all it rides in the payload file name,
32
+ * `files/<projectId>/<packageId>.<version>.nupkg`. None of it
33
+ * derives from the solution package's name or version, so this rewrite
34
+ * deliberately touches one entry and copies everything else through
35
+ * byte-for-byte.
32
36
  *
33
37
  * `spec.packageVersionKey` is always regenerated. The feed honors the key from
34
38
  * the archive verbatim, so carrying the source package's key over would file the
@@ -1,7 +1,7 @@
1
1
  import { type ErrorContext, type RetryHint } from "@uipath/common";
2
2
  import { type FeedScope } from "./feed-resolver";
3
3
  /** Discriminator for {@link PublishFailure}; library callers can ignore the tag and read `.message` / `.ok`. */
4
- export type PublishFailureReason = "auth_failed" | "file_not_found" | "not_a_zip" | "not_packed" | "file_read_failed" | "metadata_rewrite_failed" | "personal_workspace_resolution_failed" | "feed_resolution_failed" | "upload_failed" | "upload_rejected" | "upload_version_conflict" | "upload_network" | "poll_timeout" | "poll_failed" | "poll_aborted" | "publish_failed";
4
+ export type PublishFailureReason = "auth_failed" | "file_not_found" | "not_a_zip" | "not_packed" | "project_package" | "file_read_failed" | "metadata_rewrite_failed" | "personal_workspace_resolution_failed" | "feed_resolution_failed" | "upload_failed" | "upload_rejected" | "upload_version_conflict" | "upload_network" | "poll_timeout" | "poll_failed" | "poll_aborted" | "publish_failed";
5
5
  export interface PublishOptions {
6
6
  /** Override the active tenant for auth resolution. The CLI's deprecated `--tenant` flag flows through here. */
7
7
  tenant?: string;
@@ -35,10 +35,10 @@ export interface PublishSuccess {
35
35
  /** Orchestrator's stable key for this exact version (uuid). Always populated. */
36
36
  packageVersionKey: string;
37
37
  /**
38
- * Package name as published. Optional because PW publish enriches metadata
39
- * via a follow-up `packagesGetVersion` call that can briefly 404 due to
40
- * feed indexing lag — when that happens, the upload is still authoritative
41
- * but the human-readable name is absent.
38
+ * Package name as published. Optional because a feed/PW publish enriches
39
+ * metadata via a follow-up, feed-scoped `packagesGetVersion` call; if that
40
+ * call fails the upload is still authoritative but the human-readable name
41
+ * is absent.
42
42
  */
43
43
  packageName?: string;
44
44
  /** Package version (semver). Optional for the same reason as `packageName`. */
@@ -79,9 +79,11 @@ export type PublishResult = PublishSuccess | PublishFailure;
79
79
  * - **Tenant feed (default)**: `PipelinesApi.pipelinesPackageUpload` —
80
80
  * returns a full DTO including packageName/version/state. The CI service
81
81
  * principal is authorized for this endpoint; do not unify on the AS path.
82
- * - **Personal Workspace** (`personalWorkspace: true`): `PackagesApi.packagesUpload`
83
- * with `locationKey` set to the PW folder key — returns a packageVersionKey
84
- * GUID only. A follow-up `packagesGetVersion` enriches metadata best-effort
85
- * (can 404 on indexing lag handled gracefully).
82
+ * - **Personal Workspace or folder feed** (`personalWorkspace: true` /
83
+ * `feed`): `PackagesApi.packagesUpload` with `locationKey` set to the feed's
84
+ * folder key — returns a packageVersionKey GUID only. A follow-up
85
+ * `packagesGetVersion` enriches metadata best-effort, and must carry the
86
+ * same feed scope as the upload: unscoped, it 404s for anything outside the
87
+ * tenant feed.
86
88
  */
87
89
  export declare function publishSolutionAsync(packagePath: string, options?: PublishOptions): Promise<PublishResult>;
@@ -0,0 +1,34 @@
1
+ import { type CliErrorCode } from "@uipath/common";
2
+ import type { FileSystemStats, IFileSystem } from "@uipath/filesystem";
3
+ /**
4
+ * Next-step hint for a bad `<solutionPath>`. Restore, pack and cleanup accept
5
+ * exactly the same two shapes, so they give the same advice.
6
+ */
7
+ export declare const SOLUTION_PATH_INSTRUCTIONS = "Ensure the solution path exists and points to a solution directory (containing .uipx) or a .uis file.";
8
+ export type SolutionPathFailureKind =
9
+ /** `stat` threw — the path may well exist, but it could not be read. */
10
+ "unreadable"
11
+ /** `stat` came back empty — there is no such path. */
12
+ | "missing"
13
+ /** The path is there but is neither a directory nor a `.uis` file. */
14
+ | "wrong-type";
15
+ export type SolutionPathCheck = {
16
+ ok: true;
17
+ absoluteSolutionPath: string;
18
+ isUisFile: boolean;
19
+ stats: FileSystemStats;
20
+ } | {
21
+ ok: false;
22
+ absoluteSolutionPath: string;
23
+ kind: SolutionPathFailureKind;
24
+ message: string;
25
+ errorCode?: CliErrorCode;
26
+ statError?: Error;
27
+ };
28
+ /**
29
+ * Resolve `solutionPath` and say what it is: a solution directory, a `.uis`
30
+ * file, or one of three ways of being unusable. Callers render a failure in
31
+ * their own idiom — an OutputFormatter envelope on the CLI paths, a ToolResult
32
+ * on the programmatic ones.
33
+ */
34
+ export declare function checkSolutionPathAsync(fs: IFileSystem, solutionPath: string): Promise<SolutionPathCheck>;