@uipath/solution-tool 1.203.0-preview.212 → 1.204.0-preview.211

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 (76) hide show
  1. package/README.md +2 -2
  2. package/dist/THIRD-PARTY-NOTICES.md +4 -4
  3. package/dist/deploy-delete-service-gg00vadc.js +22 -0
  4. package/dist/deploy-status-service-cqfrvxpz.js +256 -0
  5. package/dist/deploy.d.ts +11 -4
  6. package/dist/deploy.js +19 -7
  7. package/dist/deployment-search-j34w33b2.js +49 -0
  8. package/dist/{embedded-file-reader-xxqe8vs8.js → embedded-file-reader-rf2g1kfj.js} +2 -2
  9. package/dist/feed-resolver-31gcvnnk.js +27 -0
  10. package/dist/feed-scope-failure-fwtdvvrh.js +18 -0
  11. package/dist/feed-session-sxga31vn.js +17 -0
  12. package/dist/index.js +27 -18
  13. package/dist/init.js +10 -7
  14. package/dist/{list-xjdnbyka.js → list-q4dzkv45.js} +9 -6
  15. package/dist/pack.js +14 -11
  16. package/dist/{packager-tool-7qmx64kz.js → packager-tool-00vh1ktg.js} +1022 -1342
  17. package/dist/packager-tool-1phh2rfx.js +37 -0
  18. package/dist/{packager-tool-vas0xg5h.js → packager-tool-2cntqvdv.js} +5 -3
  19. package/dist/{packager-tool-1haahq17.js → packager-tool-3enm2h28.js} +5 -5
  20. package/dist/{packager-tool-2syrt51a.js → packager-tool-3fv6zc86.js} +1062 -825
  21. package/dist/{packager-tool-grtmkd54.js → packager-tool-3m36mxn7.js} +16 -74
  22. package/dist/packager-tool-40vcj4wv.js +172 -0
  23. package/dist/packager-tool-482eg22x.js +322 -0
  24. package/dist/{packager-tool-k4mskzww.js → packager-tool-5dzjsw5q.js} +3 -3
  25. package/dist/{packager-tool-0f0wt9vh.js → packager-tool-5fjp60dk.js} +3071 -2794
  26. package/dist/{packager-tool-bkwnetqn.js → packager-tool-83rzavkx.js} +383 -88
  27. package/dist/{packager-tool-f423v35w.js → packager-tool-9hj0cfd0.js} +756 -359
  28. package/dist/{packager-tool-7znqtw3f.js → packager-tool-9vvdgbay.js} +8 -6
  29. package/dist/packager-tool-bqre28m1.js +43 -0
  30. package/dist/packager-tool-f5gq77m5.js +28 -0
  31. package/dist/{packager-tool-nzghfa48.js → packager-tool-fv7xyzg2.js} +550 -2
  32. package/dist/{packager-tool-3jrq7smt.js → packager-tool-gb35b4qs.js} +206 -289
  33. package/dist/{packager-tool-4kdt8mys.js → packager-tool-j30xck4w.js} +1008 -647
  34. package/dist/packager-tool-ks8spnq8.js +166 -0
  35. package/dist/packager-tool-q3tgpemc.js +113 -0
  36. package/dist/packager-tool-qdtjywsk.js +173 -0
  37. package/dist/{packager-tool-2p5yh1q9.js → packager-tool-qgaqqq41.js} +320 -151
  38. package/dist/packager-tool-qm24rbae.js +5889 -0
  39. package/dist/{packager-tool-resolver-fmjr60x8.js → packager-tool-resolver-2cbxyq6k.js} +6 -5
  40. package/dist/{packager-tool-znakt6yw.js → packager-tool-vh4ng74p.js} +8 -6
  41. package/dist/packager-tool-vmsxq1pc.js +104 -0
  42. package/dist/packager-tool-zf3929se.js +237 -0
  43. package/dist/packager-tool-zns6n8zp.js +837 -0
  44. package/dist/packager-tool.js +2 -2
  45. package/dist/prepare-solution-resources-p3gzdecy.js +25 -0
  46. package/dist/{project-contributions-cvttys34.js → project-contributions-txe8v6sm.js} +12 -9
  47. package/dist/publish.js +12 -7
  48. package/dist/resource.js +9 -6
  49. package/dist/services/activation.d.ts +17 -2
  50. package/dist/services/deploy-activate-service.d.ts +10 -0
  51. package/dist/services/deploy-delete-service.d.ts +82 -0
  52. package/dist/services/deploy-list-service.d.ts +15 -45
  53. package/dist/services/deploy-run-service.d.ts +36 -23
  54. package/dist/services/deploy-upgrade-service.d.ts +198 -39
  55. package/dist/services/deployment-feed-locator.d.ts +50 -12
  56. package/dist/services/deployment-search-client.d.ts +55 -0
  57. package/dist/services/deployment-search.d.ts +87 -34
  58. package/dist/services/deployment-state.d.ts +119 -0
  59. package/dist/services/feed-resolver.d.ts +31 -0
  60. package/dist/services/feed-session.d.ts +70 -0
  61. package/dist/services/folder-helper.d.ts +4 -27
  62. package/dist/services/http-status.d.ts +9 -0
  63. package/dist/services/incomplete-feed-sweep.d.ts +77 -0
  64. package/dist/services/legacy-deployment-search-v3.d.ts +23 -0
  65. package/dist/services/packages-list-service.d.ts +5 -0
  66. package/dist/services/pipeline-deploy-poll.d.ts +69 -0
  67. package/dist/services/publish-service.d.ts +14 -16
  68. package/dist/services/search-failure.d.ts +27 -0
  69. package/dist/templates/AGENTS.md +60 -20
  70. package/dist/tool.js +27 -18
  71. package/dist/utils/deployment-errors.d.ts +57 -0
  72. package/package.json +2 -2
  73. package/dist/packager-tool-jz2wbfjz.js +0 -2275
  74. package/dist/packager-tool-wtpe9285.js +0 -51960
  75. package/dist/prepare-solution-resources-wds3r8bq.js +0 -22
  76. package/dist/services/personal-workspace-deploy.d.ts +0 -49
@@ -1,20 +1,49 @@
1
- import type { PollFailureReason } from "@uipath/common";
2
- import { DeploymentOperationStatus } from "@uipath/solution-sdk";
3
- export type UpgradeDeploymentFailureReason = "auth_failed"
1
+ import type { CliErrorCode, PollFailureReason, RetryHint } from "@uipath/common";
2
+ import type { PipelineDeploymentStatus } from "@uipath/pipelines-sdk";
3
+ import { type PendingResource } from "./deployment-state";
4
+ export type UpgradeDeploymentFailureReason =
5
+ /** Neither a deployment key nor a name+package pair was given, or both were. */
6
+ "invalid_target" | "auth_failed"
7
+ /**
8
+ * No deployment to upgrade: the key form's lookup found none (unknown key,
9
+ * or a server without the lookup), or the name form's existence check
10
+ * answered 404 for the name in that feed.
11
+ */
12
+ | "deployment_not_found"
13
+ /** The key form's lookup, the name form's existence check, or the version lookup failed for a reason other than "not found". */
14
+ | "lookup_failed"
15
+ /** The key names an uninstalled deployment; an install would create a new one, not upgrade it. */
16
+ | "deployment_uninstalled"
17
+ /**
18
+ * The deployment's newest generation is a Draft: an attempt that never
19
+ * completed — usually one rejected by validation — which the install route
20
+ * reuses for the name. It would re-run that draft, with the configuration it
21
+ * was rejected for, in place of this upgrade, or refuse a different version
22
+ * (`DraftDeploymentHasDifferentPackageVersion`). `discardDraft` discards it
23
+ * and upgrades the live generation instead.
24
+ */
25
+ | "pending_draft"
26
+ /** `discardDraft` was set and the server did not discard the pending draft. */
27
+ | "discard_draft_failed"
28
+ /**
29
+ * The deployment sits in a folder or Personal Workspace feed and the
30
+ * session is an external app. The server does not apply the feed header
31
+ * to client-credentials requests, so the install would create a new
32
+ * tenant-feed deployment instead of upgrading this one.
33
+ */
34
+ | "feed_requires_user_session"
4
35
  /** Personal Workspace could not be resolved (only when `--personal-workspace`). */
5
36
  | "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. */
37
+ /** The target package version is not published in the feed. */
11
38
  | "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. */
39
+ /** The Pipelines install request was refused before anything was queued. */
15
40
  | "request_failed"
16
- /** The upgrade was queued but installing the resulting draft failed. */
17
- | "install_failed"
41
+ /**
42
+ * The pipeline reached a terminal state other than `DeploymentSucceeded`:
43
+ * validation, conflict fixing, scheduling or the install itself failed.
44
+ * The live deployment stays on its previous version.
45
+ */
46
+ | "deploy_failed"
18
47
  /** The install was accepted but did not reach a terminal state in time. */
19
48
  | "install_timeout"
20
49
  /**
@@ -24,6 +53,31 @@ export type UpgradeDeploymentFailureReason = "auth_failed"
24
53
  */
25
54
  | PollFailureReason;
26
55
  export interface UpgradeDeploymentOptions {
56
+ /**
57
+ * Key of the deployment to upgrade, as `deploy list` reports it. Resolved
58
+ * through the Pipelines lookup, which spans every feed in the tenant and
59
+ * answers with the deployment's name, package, current version and feed —
60
+ * so this form needs neither `packageName` nor a feed flag. Either this or
61
+ * `deploymentName` + `packageName`, not both.
62
+ */
63
+ deploymentKey?: string;
64
+ /**
65
+ * Name of the deployment to upgrade — the name it was deployed under, which
66
+ * is how the Pipelines install route addresses it. Goes with `packageName`.
67
+ */
68
+ deploymentName?: string;
69
+ /**
70
+ * The deployment's package, for the name form. Required there because it is
71
+ * a path segment of the install route and the key the version lookup
72
+ * resolves against, and no name-keyed Pipelines route reports it.
73
+ */
74
+ packageName?: string;
75
+ /**
76
+ * Version to upgrade to. Any published version of the same package is
77
+ * accepted, including an older one. Omitted, the newest published version
78
+ * is resolved and used.
79
+ */
80
+ version?: string;
27
81
  /**
28
82
  * Override the active tenant for auth resolution. The CLI's deprecated
29
83
  * `--tenant` flag flows through here; library callers usually omit it.
@@ -32,43 +86,112 @@ export interface UpgradeDeploymentOptions {
32
86
  /** Pin auth to this exact `.uipath/.auth` path. */
33
87
  envFilePath?: string;
34
88
  /**
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).
89
+ * Name form: scope the version lookup, the install and its status poll to
90
+ * the caller's Personal Workspace feed. Key form: redundant — the feed is
91
+ * read from the deployment itself — and accepted for compatibility with
92
+ * the original `deploy upgrade <key> --personal-workspace`; it is rejected
93
+ * only when the deployment turns out to be on the tenant feed.
38
94
  */
39
- version?: string;
95
+ personalWorkspace?: boolean;
40
96
  /**
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.
97
+ * When the deployment's newest generation is a pending Draft — an earlier
98
+ * attempt that never completed, usually one rejected by validation — delete
99
+ * that draft first (`DELETE /pipelines/deployments/{key}`) and upgrade
100
+ * the live generation with its own configuration. Without it such a
101
+ * deployment is refused with `pending_draft`, because the install route
102
+ * would re-run the draft, with the configuration it was rejected for, in
103
+ * place of this upgrade. The name form can find the draft only with a user
104
+ * session (it reads the Solutions search); under an external app, address
105
+ * the deployment by key.
43
106
  */
44
- personalWorkspace?: boolean;
107
+ discardDraft?: boolean;
45
108
  /** Minimum minutes before token expiration to trigger a refresh. Default 10. */
46
109
  loginValidity?: number;
47
110
  /**
48
111
  * 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.
112
+ * terminal state. Validation is already queued server-side; the caller
113
+ * just does not wait for it.
50
114
  */
51
115
  noWait?: boolean;
52
116
  /** Seconds to wait for the install to reach a terminal state. Default 300. */
53
117
  timeout?: number;
54
118
  /** Milliseconds between status polls. Default 5000. */
55
119
  pollInterval?: number;
120
+ /**
121
+ * Host-side cancellation for the status poll (the CLI's Ctrl-C, VS Code's
122
+ * cancel button). `pollUntil` has no default signal, so without this a
123
+ * cancelled upgrade keeps polling until `--timeout`.
124
+ */
125
+ signal?: AbortSignal;
56
126
  }
57
127
  export interface UpgradeDeploymentSuccess {
58
128
  ok: true;
59
129
  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. */
130
+ /**
131
+ * Version deployed before this run. Known only for the key form, whose
132
+ * lookup reports it; the name form makes no read that would.
133
+ */
134
+ fromVersion?: string;
135
+ /** Version the upgrade targeted. */
63
136
  toVersion: string;
64
137
  /**
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.
138
+ * Key of the original install, stable across every upgrade — the one a
139
+ * pipeline should store. Key form only, from the lookup.
140
+ */
141
+ installDeploymentKey?: string;
142
+ /**
143
+ * Id of the Pipelines run performing the upgrade. This is what
144
+ * `uip solution deploy status <id>` reads.
145
+ */
146
+ pipelineDeploymentId: string;
147
+ /**
148
+ * Key of the upgraded deployment record, from the pipeline's terminal
149
+ * status. Undefined with `noWait`.
150
+ */
151
+ deploymentKey?: string;
152
+ /**
153
+ * What the server actually did, from the run's own record:
154
+ * `VersionChange` for a version move, `ConfigurationChange` when the
155
+ * requested version was already the deployed one. Undefined with `noWait`,
156
+ * and when the run reports no deployment record.
157
+ */
158
+ operation?: string;
159
+ /** Terminal pipeline status, or `"Accepted"` when `noWait` returned before polling. */
160
+ status: PipelineDeploymentStatus | "Accepted";
161
+ /**
162
+ * The upgraded deployment's own status, from the run's `deploymentResult`
163
+ * — the difference `status` cannot show between a new version that runs
164
+ * (`SuccessfulActivate`) and one that installed but waits for activation
165
+ * setup (`SuccessfulInstall`, with the previous version still running).
166
+ * Undefined with `noWait`, and when the run reports no deployment record
167
+ * (a recycled run record the poll settled from elsewhere).
168
+ */
169
+ deploymentStatus?: string;
170
+ /** What can be done with the deployment next, from the same record (e.g. `SetupActivation`, `Uninstall`, `Upgrade`). Undefined when `deploymentStatus` is. */
171
+ actions?: string[];
172
+ /**
173
+ * Key of the pending draft `discardDraft` deleted before this upgrade.
174
+ * Undefined when there was none to discard.
68
175
  */
69
- versionChangeKey: string;
70
- /** Terminal status reached, or `Draft`/`InProgress` when `noWait`. */
71
- status: DeploymentOperationStatus;
176
+ discardedDraftKey?: string;
177
+ /**
178
+ * Whether the new version runs, in the deployment record's own words:
179
+ * `Active`, `NeedsSetupToActivate` (installed; "Setup activation" in
180
+ * Orchestrator is still due and the previous version keeps running),
181
+ * `ReadyToActivate`, … From the search row when a user session can read
182
+ * it, otherwise derived from `deploymentStatus` and `actions`
183
+ * (`SuccessfulActivate` → `Active`, `SetupActivation` offered →
184
+ * `NeedsSetupToActivate`, `Activate` offered → `ReadyToActivate`). Absent
185
+ * when neither says, and with `noWait` (STUD-81555).
186
+ */
187
+ activationStatus?: string;
188
+ /**
189
+ * The resources that still need configuration before activation, when the
190
+ * deployment waits for setup and the read succeeded.
191
+ */
192
+ pendingResources?: PendingResource[];
193
+ /** What is left before the new version runs; absent when it does. */
194
+ nextSteps?: string[];
72
195
  }
73
196
  export interface UpgradeDeploymentFailure {
74
197
  ok: false;
@@ -76,19 +199,55 @@ export interface UpgradeDeploymentFailure {
76
199
  message: string;
77
200
  instructions: string;
78
201
  exitCode: number;
202
+ /**
203
+ * Set whenever the failure mode is known, so the CLI does not fall back to
204
+ * `OutputFormatter`'s guess. That guess is wrong for a poll that timed
205
+ * out: the message carries no HTTP status, so it reports `unknown_error` /
206
+ * `RetryWillNotFix` while the instructions beside it say the upgrade may
207
+ * still be running.
208
+ */
209
+ errorCode?: CliErrorCode;
210
+ retry?: RetryHint;
79
211
  }
80
212
  export type UpgradeDeploymentResult = UpgradeDeploymentSuccess | UpgradeDeploymentFailure;
81
213
  /**
82
214
  * 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.
215
+ * deployment to another published version of its package in place — the CLI
216
+ * equivalent of the Orchestrator UI "Upgrade" button — so a blocked redeploy
217
+ * (UV-15356) can be resolved without the UI. Values already set on the
218
+ * deployment are kept: the server carries each unchanged resource's
219
+ * configuration forward and takes only changed specs from the package.
220
+ *
221
+ * Goes through the Pipelines install endpoint, which is a unified
222
+ * install / configuration-change / upgrade: a deployment named
223
+ * `deploymentName` that exists with the same package and a *different*
224
+ * version is upgraded in its own folder. The pipeline validates the package
225
+ * against the target **before** it schedules the install — a failed validation
226
+ * ends the run at `ValidationFailed` with the errors attached, and the live
227
+ * deployment never enters `ValidateError` (SOL-7799).
228
+ *
229
+ * Addressed either by **name + package** or by **deployment key**, and both
230
+ * forms stay on external-app (client-credentials) capable Pipelines endpoints,
231
+ * which is what a CI/CD pipeline needs (SOL-7805). The name form makes no
232
+ * version lookup when `--version` is given, but it does check the name exists
233
+ * first (`pre-activate-steps`): the route takes a name and creates a fresh
234
+ * deployment for one it cannot find, so a typo must fail rather than deploy.
235
+ * `packageName` is required because nothing name-keyed in Pipelines reports
236
+ * it. The key form resolves
237
+ * the key through `GET /pipelines/deployments/by-key/{key}` — S2S-capable,
238
+ * spanning every feed in the tenant, and answering a superseded key with the
239
+ * deployment's current generation — and takes name, package, feed and the
240
+ * version being upgraded from off that answer. The Automation Solutions
241
+ * `GET /api/deployments/{key}` is user-token only and is never called.
86
242
  *
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
243
  * Does not touch `OutputFormatter`/`processContext`.
93
244
  */
94
- export declare function upgradeDeploymentAsync(deploymentKey: string, options?: UpgradeDeploymentOptions): Promise<UpgradeDeploymentResult>;
245
+ export declare function upgradeDeploymentAsync(options: UpgradeDeploymentOptions): Promise<UpgradeDeploymentResult>;
246
+ /**
247
+ * The 1.202 signature, kept so library callers keep compiling:
248
+ * `upgradeDeploymentAsync(deploymentKey, { version, personalWorkspace, … })`.
249
+ * Same as passing `{ deploymentKey, …options }`.
250
+ *
251
+ * @deprecated Pass a single options object with `deploymentKey`.
252
+ */
253
+ export declare function upgradeDeploymentAsync(deploymentKey: string, options?: Omit<UpgradeDeploymentOptions, "deploymentKey" | "deploymentName" | "packageName">): Promise<UpgradeDeploymentResult>;
@@ -1,15 +1,51 @@
1
- import type { DeploymentSearchItemDto2, InitOverrideFunction, SolutionAuthContext } from "@uipath/solution-sdk";
1
+ import type { DeploymentSearchItemDto2, InitOverrideFunction } from "@uipath/solution-sdk";
2
+ import type { SolutionAuthContext } from "@uipath/solution-sdk/auth";
3
+ import { type FeedKind } from "./feed-resolver";
4
+ import type { SkippedFeed } from "./incomplete-feed-sweep";
2
5
  /** A deployment and the feed header every call about it needs. */
3
6
  export interface DeploymentLocation {
4
7
  deployment: DeploymentSearchItemDto2;
5
8
  /** `X-UIPATH-FolderKey` override; undefined for the tenant feed. */
6
9
  scope?: InitOverrideFunction;
10
+ /**
11
+ * The non-tenant feed the deployment was found in; undefined for the
12
+ * tenant feed. What a generated follow-up command needs in order to name
13
+ * its flag (`feedSelectorFlag`) — the override alone cannot be printed.
14
+ */
15
+ feed?: {
16
+ kind: Exclude<FeedKind, "tenant">;
17
+ folderKey: string;
18
+ };
19
+ }
20
+ /**
21
+ * What a sweep across the feeds found, and whether it could ask every feed.
22
+ *
23
+ * A missing `location` means "no such deployment" only when `complete` is
24
+ * true. Otherwise it means "not in the feeds that answered", and a caller
25
+ * that reports it as not found tells an agent never to retry a name that may
26
+ * be fine (#4390).
27
+ */
28
+ export interface DeploymentSweep {
29
+ /** The first exact-name match, tenant first; undefined when none was found. */
30
+ location?: DeploymentLocation;
31
+ /** The feeds that could not be searched, in sweep order. */
32
+ skipped: SkippedFeed[];
33
+ /** True when no feed was skipped. */
34
+ complete: boolean;
7
35
  }
8
36
  /** Auth-resolution knobs the feed sweep forwards to its lookups. */
9
37
  export interface DeploymentLocationOptions {
10
38
  tenant?: string;
11
39
  loginValidity?: number;
12
40
  envFilePath?: string;
41
+ /**
42
+ * Also accept a name whose newest row records a completed uninstall.
43
+ * `deploy delete` exists to remove exactly those records (UV-16671).
44
+ * `activate` and `uninstall` act on a live deployment and leave it off, so
45
+ * a name uninstalled on the tenant and redeployed into a feed resolves to
46
+ * the feed rather than to the tenant's history row.
47
+ */
48
+ includeUninstalled?: boolean;
13
49
  }
14
50
  /**
15
51
  * Locate a deployment and the feed it lives in.
@@ -21,16 +57,18 @@ export interface DeploymentLocationOptions {
21
57
  * to the tenant-scoped search, so an unscoped call is answered "not found".
22
58
  *
23
59
  * 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
60
+ * so the common case costs one request. Only on a tenant miss does the sweep
61
+ * run, and it is best-effort throughout: a feed whose search fails is skipped
62
+ * rather than allowed to end the sweep, since the next feed may hold the
63
+ * record. Skipped is not silent: every skipped feed is in the answer's
64
+ * `skipped`, so a caller can tell a clean miss from one where a feed did not
65
+ * answer. A tenant that exposes many folder feeds therefore pays one search
29
66
  * per feed, but only on a path that was already going to fail.
67
+ *
68
+ * Never throws. A tenant search that fails comes back as a sweep that skipped
69
+ * the tenant feed, and the sweep stops there: a match in a later feed could
70
+ * be another deployment under the same name, and `delete` would remove it.
71
+ * So a tenant search that answers 404 is "could not search", never
72
+ * "not found", on every verb.
30
73
  */
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>;
74
+ export declare function findDeploymentAcrossFeeds(auth: SolutionAuthContext, deploymentName: string, options: DeploymentLocationOptions): Promise<DeploymentSweep>;
@@ -0,0 +1,55 @@
1
+ import { type DeploymentActivationStatus, type DeploymentOperationStatus, type DeploymentSearchItemDto2, type InitOverrideFunction } from "@uipath/solution-sdk";
2
+ import type { SolutionAuthContext } from "@uipath/solution-sdk/auth";
3
+ export type DeploymentSearchSource = "pipelines" | "legacy-v3";
4
+ /** One page of the deployment search, in the terms both routes understand. */
5
+ export interface DeploymentSearchQuery {
6
+ take: number;
7
+ skip: number;
8
+ /**
9
+ * Exact name. Filtered by the server on the Pipelines route; a substring
10
+ * term on the legacy one, so callers keep their exact match.
11
+ */
12
+ deploymentName?: string;
13
+ packageName?: string;
14
+ /** The row's parent folder by full path: exact, case-insensitive, subfolders excluded. */
15
+ targetFolderName?: string;
16
+ searchTerm?: string;
17
+ orderByColumn?: string;
18
+ orderByDirection?: "Ascending" | "Descending";
19
+ operationStatuses?: DeploymentOperationStatus[];
20
+ activationStatuses?: DeploymentActivationStatus[];
21
+ }
22
+ export interface DeploymentSearchPage {
23
+ /** The filtered total; `undefined` when the server omits it. */
24
+ count?: number;
25
+ values: DeploymentSearchItemDto2[];
26
+ /** Which route answered — for logs and tests, never for output. */
27
+ source: DeploymentSearchSource;
28
+ }
29
+ /**
30
+ * The server has only the legacy search, and that one reads user tokens only.
31
+ * Thrown instead of making a request that can only answer 403, so a caller can
32
+ * tell "cannot be read with this login" from an outage — the distinction the
33
+ * application-session gates were written for.
34
+ */
35
+ export declare class DeploymentSearchNeedsUserSessionError extends Error {
36
+ constructor();
37
+ }
38
+ /**
39
+ * Whether an error from the Pipelines search means the server has no such
40
+ * route (and the legacy search should answer), as opposed to a failure of
41
+ * the route itself. Measured on a server without it: the POST falls onto
42
+ * `GET deployments/{deploymentKey}` and answers **405** with no body; a path
43
+ * matching nothing answers 404 with no body. A 404 with *any* body — an
44
+ * `errorCode`, or a plain ProblemDetails — is the route answering, and must
45
+ * reach the caller.
46
+ */
47
+ export declare function isMissingPipelinesSearchRoute(error: unknown): Promise<boolean>;
48
+ /**
49
+ * The one deployment search every command goes through: the Pipelines route
50
+ * (SOL-7807), which reads application sessions too and filters an exact name
51
+ * on the server; the deprecated `/api/v3/search/deployments` only on a server
52
+ * without it. Rows come back as the solution-sdk's DTO either way — the
53
+ * Pipelines row is a superset of it, so its extra fields are dropped.
54
+ */
55
+ export declare function searchDeploymentsPage(auth: SolutionAuthContext, query: DeploymentSearchQuery, scope?: InitOverrideFunction): Promise<DeploymentSearchPage>;
@@ -1,26 +1,45 @@
1
1
  import type { PipelineDeploymentResult, PipelineDeploymentStatus } from "@uipath/pipelines-sdk";
2
- import type { DeploymentOperationStatus, DeploymentSearchItemDto2, InitOverrideFunction, SolutionAuthContext } from "@uipath/solution-sdk";
2
+ import type { DeploymentOperationStatus, DeploymentSearchItemDto2, InitOverrideFunction } from "@uipath/solution-sdk";
3
+ import type { SolutionAuthContext } from "@uipath/solution-sdk/auth";
4
+ export { httpStatusOf } from "./http-status";
3
5
  /**
4
6
  * Look up a deployment by name in the persistent search/list service.
5
- * Returns the matching record, or undefined when no deployment with that
6
- * exact name exists.
7
+ * Returns the deployment's **current generation** — every upgrade and
8
+ * configuration change writes a new row under the same name, and the first
9
+ * row the search happens to return can be an older one — or undefined when
10
+ * no deployment with that exact name exists.
7
11
  *
8
12
  * Throws on transport / server errors. Use {@link findDeploymentBestEffort}
9
13
  * when you want a best-effort lookup that swallows failures.
10
14
  */
11
15
  export declare function findDeploymentByName(auth: SolutionAuthContext, deploymentName: string, scope?: InitOverrideFunction): Promise<DeploymentSearchItemDto2 | undefined>;
16
+ /**
17
+ * The deployment a name currently denotes **if it is still installed** —
18
+ * undefined when the name's newest row records a *completed* uninstall, since
19
+ * the older generations under it belong to a deployment that is gone. A
20
+ * failed or in-flight uninstall leaves the deployment present (see
21
+ * `blocksRedeploy`), so those rows are live. This is the
22
+ * selector for *locating* a deployment to act on (activate, uninstall): a
23
+ * tenant name whose deployment was uninstalled and redeployed into a Personal
24
+ * Workspace must resolve to the workspace, not stop the sweep at the tenant's
25
+ * history row. `findDeploymentByName` keeps the uninstall row for callers
26
+ * that wait on the current operation, whatever it is.
27
+ */
28
+ export declare function findLiveDeploymentByName(auth: SolutionAuthContext, deploymentName: string, scope?: InitOverrideFunction): Promise<DeploymentSearchItemDto2 | undefined>;
29
+ /** A row recording an uninstall that finished: the deployment is gone. */
30
+ export declare function isCompletedUninstall(row: Pick<DeploymentSearchItemDto2, "operation" | "operationStatus"> | undefined): boolean;
12
31
  /**
13
32
  * Every deployment whose `packageName` matches exactly.
14
33
  *
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.
34
+ * Pages the deployment search to exhaustion instead of stopping at the first
35
+ * hit, because the redeploy gate has to report *all* the deployments that
36
+ * already exist, not just one.
18
37
  *
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.
38
+ * `packageName` is the server-side filter, which keeps the result set small;
39
+ * on the deprecated V3 route it also travels as the substring `searchTerm`
40
+ * (see `toLegacyV3Request`), so the lookup still works if that server ignores
41
+ * `packageName`. The client-side `===` check is what makes the answer exact
42
+ * either way.
24
43
  *
25
44
  * Statuses are deliberately unfiltered — callers decide which states matter
26
45
  * (the gate uses {@link blocksRedeploy}; the redeploy-conflict path needs the
@@ -32,6 +51,29 @@ export declare function findDeploymentsByPackageName(auth: SolutionAuthContext,
32
51
  folderPath?: string;
33
52
  scope?: InitOverrideFunction;
34
53
  }): Promise<DeploymentSearchItemDto2[]>;
54
+ /**
55
+ * The record that stands for a deployment *now*.
56
+ *
57
+ * Every operation adds a record: `deploy run` creates the Install record,
58
+ * `deploy upgrade` a VersionChange one, the UI's setup an ActivationSetup one.
59
+ * `deploy list` shows only the newest of each chain, but a key handed out
60
+ * earlier keeps answering `deploymentsGetByKey` as if it were current — the
61
+ * old version, `Active`, `Upgrade` offered, and nothing on it saying it was
62
+ * superseded. Acting on it is what the service refuses with `4005` and what
63
+ * left an agent unable to tell which upgrade had landed (STUD-81555).
64
+ *
65
+ * The chain shares one `installDeploymentKey`, so the current record is the
66
+ * `deploy list` row that carries it. `undefined` means the search answered
67
+ * and no row carries the key; a search that fails **throws**, because "could
68
+ * not look" and "nothing newer" must not read the same — a caller that took
69
+ * a failed search for an empty one would present the stale record as current,
70
+ * which is the very report this lookup exists to prevent.
71
+ */
72
+ export declare function findCurrentDeploymentAsync(auth: SolutionAuthContext, deployment: {
73
+ key: string;
74
+ installDeploymentKey?: string | null;
75
+ packageName: string;
76
+ }, scope?: InitOverrideFunction): Promise<DeploymentSearchItemDto2 | undefined>;
35
77
  /**
36
78
  * Does this record represent a deployment that is really there, so a fresh
37
79
  * `deploy run` of the same package would create a second copy of it?
@@ -48,7 +90,7 @@ export declare function findDeploymentsByPackageName(auth: SolutionAuthContext,
48
90
  * - **`Draft` / `Failed` / `FailedRollback` on an `Install`** — does not block.
49
91
  * The deploy the user is retrying is the one that produced the record, and
50
92
  * our own guidance for a Draft is to fix the errors and rerun `deploy run`
51
- * (see {@link appendDraftDeploymentInstructions}). Blocking would leave the
93
+ * (see {@link appendDeploymentStateInstructions}). Blocking would leave the
52
94
  * user with nothing they are allowed to do.
53
95
  * - **`Draft` / `Failed` / `FailedRollback` on any other operation** — blocks.
54
96
  * An uninstall or an upgrade that failed ran *against* a deployment that is
@@ -88,13 +130,40 @@ export declare function formatExistingDeployments(deployments: DeploymentSearchI
88
130
  * masking a prior error (error paths) or blocking an otherwise-successful
89
131
  * result (success paths, e.g. reading back the resolved install folder).
90
132
  */
91
- export declare function findDeploymentBestEffort(auth: SolutionAuthContext, deploymentName: string, scope?: InitOverrideFunction): Promise<DeploymentSearchItemDto2 | undefined>;
92
133
  /**
93
- * Append a hint to error instructions when the deployment in question is
94
- * stuck in `Draft` state — that condition has a specific remediation that
95
- * generic instructions don't cover.
134
+ * Every search row whose name matches exactly. A name is shared by every
135
+ * generation of a deployment — the original install and each upgrade or
136
+ * configuration change writes a new row under it — so callers that need
137
+ * *this run's* row must pick among these rather than take the first.
96
138
  */
97
- export declare function appendDraftDeploymentInstructions(instructions: string, deployment?: DeploymentSearchItemDto2): string;
139
+ export declare function findDeploymentsByName(auth: SolutionAuthContext, deploymentName: string, scope?: InitOverrideFunction): Promise<DeploymentSearchItemDto2[]>;
140
+ /** Which of a name's rows a caller is looking for. */
141
+ export interface DeploymentRowPreference {
142
+ /**
143
+ * The deployment key the pipelines status endpoint reported for this run.
144
+ * The run record carries its deployment row from creation, so any status
145
+ * read before the record is recycled names the exact row; with it set,
146
+ * only that row is returned, never another generation.
147
+ */
148
+ deploymentKey?: string;
149
+ }
150
+ /**
151
+ * The search row for `deploymentName` a caller is after — or undefined when
152
+ * there is none, or the lookup itself failed (swallowed on purpose: every
153
+ * caller has a better error to report than a transport failure of a
154
+ * best-effort read).
155
+ *
156
+ * With `prefer.deploymentKey`, exactly that row or nothing (and nothing when
157
+ * that row now records an uninstall): this is the form anything that
158
+ * *settles or recovers a run* must use, because a name is not a run. Without a key, the newest row that is not an uninstall — good enough
159
+ * for enrichment (a failure message's context, the folder a deployment
160
+ * landed in), never for vouching that a run finished: a name outlives its
161
+ * generations, the first row the search returns can be the pre-upgrade one,
162
+ * and an `Uninstall` row is the record of a deployment that is gone.
163
+ */
164
+ export declare function findDeploymentBestEffort(auth: SolutionAuthContext, deploymentName: string, scope?: InitOverrideFunction, prefer?: DeploymentRowPreference): Promise<DeploymentSearchItemDto2 | undefined>;
165
+ /** The most recently created of a name's rows, uninstall rows included. */
166
+ export declare function newestDeploymentRow(rows: DeploymentSearchItemDto2[]): DeploymentSearchItemDto2 | undefined;
98
167
  /**
99
168
  * The pipelines service `pipelinesGetPipelineDeploymentStatus` endpoint
100
169
  * returns 404 with errorCode `PipelineDeploymentNotFound` once a deployment
@@ -129,28 +198,12 @@ export type DeployPollRecovery = {
129
198
  operationStatus: DeploymentOperationStatus;
130
199
  };
131
200
  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;
148
201
  /**
149
202
  * Map a search-service `DeploymentOperationStatus` onto the corresponding
150
203
  * terminal `PipelineDeploymentStatus`. Returns undefined for non-terminal
151
204
  * states (caller should keep polling).
152
205
  */
153
- export declare function mapOperationStatusToPipelineStatus(operationStatus: DeploymentOperationStatus | undefined | null): PipelineDeploymentStatus | undefined;
206
+ export declare function mapOperationStatusToPipelineStatus(operationStatus: DeploymentOperationStatus | string | undefined | null): PipelineDeploymentStatus | undefined;
154
207
  /**
155
208
  * Build a synthesized terminal `PipelineDeploymentResult` from a deployment
156
209
  * record fetched via the search API. Used as a fallback when the pipelines