@ricsam/r5dctl 0.0.120 → 0.0.122
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.
- package/README.md +3 -1
- package/dist/cjs/cli.cjs +123 -16
- package/dist/cjs/package.json +1 -1
- package/dist/mjs/cli.mjs +119 -16
- package/dist/mjs/package.json +1 -1
- package/dist/types/cli.d.ts +52 -4
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -59,6 +59,8 @@ r5dctl -p <project> create branch <branch> --source worktree:<branch> [--working
|
|
|
59
59
|
r5dctl -p <project> describe branch-operation <operation-id>
|
|
60
60
|
r5dctl -p <project> delete branch <branch> [<branch>...] # preview the sessions that would be deleted, exit 1
|
|
61
61
|
r5dctl -p <project> delete branch <branch> [<branch>...] --confirm # delete the branches and their sessions through the platform
|
|
62
|
+
r5dctl -p <project> delete branch <branch> --confirm --no-wait # accept the deletion and print its branch id instead of waiting
|
|
63
|
+
r5dctl -p <project> describe branch-deletion <branch-id> # pending, failed, or completed
|
|
62
64
|
r5dctl -p <project> get envs
|
|
63
65
|
r5dctl -p <project> get envs --show-values
|
|
64
66
|
r5dctl -p <project> get env API_KEY
|
|
@@ -127,7 +129,7 @@ pull requests.
|
|
|
127
129
|
|
|
128
130
|
`create branch` creates a linked worktree branch through the platform from an existing branch's checkout, with the same `--source worktree:<branch>` and `--working-tree carry|clean` semantics as `session start --new-worktree` (carry is the default) and no session prompt. `--worker <label>` selects the connected worker that cuts the checkout; omitted, the platform chooses one, and an r5d worker shell's temporary credential is always bound to its own worker. The command returns as soon as the operation is accepted and prints its id; `describe branch-operation <operation-id>` reports `provisioning`, `ready`, or `failed` with the worker and any error. Neither prints a commit hash: read the branch with git in its checkout once it is ready.
|
|
129
131
|
|
|
130
|
-
`delete branch` removes one or more branches and every session on them through the platform, which is the only supported way to remove a linked worktree: the platform owns those checkouts, so never run `git worktree remove`, `git worktree prune`, or `git branch -D` inside a project checkout. Without `--confirm` it prints each branch and its sessions and exits non-zero without deleting anything. With `--confirm` the
|
|
132
|
+
`delete branch` removes one or more branches and every session on them through the platform, which is the only supported way to remove a linked worktree: the platform owns those checkouts, so never run `git worktree remove`, `git worktree prune`, or `git branch -D` inside a project checkout. Without `--confirm` it prints each branch and its sessions and exits non-zero without deleting anything. With `--confirm` each branch is resolved to the exact managed branch it names today, its deletion is accepted at once by the platform, and the command waits (polling every 2 seconds, up to 10 minutes) until the platform reports it completed before requesting the next one; a failure does not stop the remaining deletions, and the exit status is non-zero if any branch failed. `--no-wait` prints the accepted branch id instead of waiting; `describe branch-deletion <branch-id>` reports `pending` (with the retry reason when the worker has not answered yet), `failed` with the platform's error, or `completed`, and answers `completed` for a branch id that no longer exists. The deletion stays bound to that branch id: a same-name branch created afterwards is never deleted by an old request, and re-running the command for a branch whose deletion failed retries it. The primary branch `main` is refused before anything is deleted, as is a branch with a running agent or active process (stop them first); a name that only has sessions and no managed branch is refused too (delete those sessions with `delete session`). On a server that predates the route, the command explains that the server does not support `delete branch` yet instead of reporting a missing branch.
|
|
131
133
|
|
|
132
134
|
`get branches` lists every branch the project knows about, including managed branches without sessions. A worker whose workspace sync found a configured branch's checkout directory missing, or present but not a linked worktree of the project, skips that branch and reports it; the listing then shows `checkout=missing on <worker>` or `checkout=not_a_worktree on <worker>`, and `workspace status` prints a `Missing checkouts on <worker>` line. Recover either by deleting the branch with `delete branch <branch> --confirm` or by reconnecting that worker, which recreates the checkout without snapshotting the project's other checkouts.
|
|
133
135
|
|
package/dist/cjs/cli.cjs
CHANGED
|
@@ -28,6 +28,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
28
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
29
|
var cli_exports = {};
|
|
30
30
|
__export(cli_exports, {
|
|
31
|
+
BRANCH_DELETION_POLL_INTERVAL_MS: () => BRANCH_DELETION_POLL_INTERVAL_MS,
|
|
32
|
+
BRANCH_DELETION_WAIT_TIMEOUT_MS: () => BRANCH_DELETION_WAIT_TIMEOUT_MS,
|
|
31
33
|
advanceTransientDevicePollBackoff: () => advanceTransientDevicePollBackoff,
|
|
32
34
|
branchDeletionConfirmationMessage: () => branchDeletionConfirmationMessage,
|
|
33
35
|
branchDeletionsConfirmationMessage: () => branchDeletionsConfirmationMessage,
|
|
@@ -77,6 +79,7 @@ __export(cli_exports, {
|
|
|
77
79
|
renderBranchDeletion: () => renderBranchDeletion,
|
|
78
80
|
renderBranchDeletionPreview: () => renderBranchDeletionPreview,
|
|
79
81
|
renderBranchDeletionResult: () => renderBranchDeletionResult,
|
|
82
|
+
renderBranchDeletionStatus: () => renderBranchDeletionStatus,
|
|
80
83
|
renderBranchList: () => renderBranchList,
|
|
81
84
|
renderBranchOperation: () => renderBranchOperation,
|
|
82
85
|
renderConversationForkResponse: () => renderConversationForkResponse,
|
|
@@ -102,6 +105,7 @@ __export(cli_exports, {
|
|
|
102
105
|
resolveCommandExecution: () => resolveCommandExecution,
|
|
103
106
|
runR5dctlCli: () => runR5dctlCli,
|
|
104
107
|
summarizeEnvData: () => summarizeEnvData,
|
|
108
|
+
waitForBranchDeletion: () => waitForBranchDeletion,
|
|
105
109
|
waitForSessionProvisioning: () => waitForSessionProvisioning,
|
|
106
110
|
writeConfig: () => writeConfig
|
|
107
111
|
});
|
|
@@ -247,8 +251,13 @@ const SHARED_HELP_ENTRIES = [
|
|
|
247
251
|
},
|
|
248
252
|
{
|
|
249
253
|
section: "branches",
|
|
250
|
-
usage: "-p <project> delete branch <branch> [<branch>...] [--confirm]",
|
|
251
|
-
description: "Delete one or more branches and their sessions through the platform; without --confirm, only preview what would be deleted."
|
|
254
|
+
usage: "-p <project> delete branch <branch> [<branch>...] [--confirm] [--no-wait]",
|
|
255
|
+
description: "Delete one or more branches and their sessions through the platform; without --confirm, only preview what would be deleted. Each deletion is accepted at once and awaited until the platform finishes it; --no-wait prints the accepted branch ids instead."
|
|
256
|
+
},
|
|
257
|
+
{
|
|
258
|
+
section: "branches",
|
|
259
|
+
usage: "-p <project> describe branch-deletion <branch-id>",
|
|
260
|
+
description: "Show whether an accepted branch deletion is pending, failed, or completed."
|
|
252
261
|
},
|
|
253
262
|
{
|
|
254
263
|
section: "envs",
|
|
@@ -656,16 +665,21 @@ function parseBranchCreateArgs(args) {
|
|
|
656
665
|
function parseBranchDeleteArgs(args) {
|
|
657
666
|
const branchNames = [];
|
|
658
667
|
let confirmed = false;
|
|
668
|
+
let noWait = false;
|
|
659
669
|
for (const arg of args) {
|
|
660
670
|
if (arg === "--confirm") {
|
|
661
671
|
confirmed = true;
|
|
662
672
|
continue;
|
|
663
673
|
}
|
|
674
|
+
if (arg === "--no-wait") {
|
|
675
|
+
noWait = true;
|
|
676
|
+
continue;
|
|
677
|
+
}
|
|
664
678
|
if (arg.startsWith("-")) throw new Error(`Unknown delete branch flag: ${arg}`);
|
|
665
679
|
if (branchNames.includes(arg)) throw new Error(`Branch ${arg} was given more than once`);
|
|
666
680
|
branchNames.push(arg);
|
|
667
681
|
}
|
|
668
|
-
return { branchNames, confirmed };
|
|
682
|
+
return { branchNames, confirmed, noWait };
|
|
669
683
|
}
|
|
670
684
|
const PRIMARY_BRANCH_NAME = "main";
|
|
671
685
|
function isUnsupportedServerRoute(error) {
|
|
@@ -693,12 +707,66 @@ async function createBranchThroughPlatform(client, projectRef, input) {
|
|
|
693
707
|
})
|
|
694
708
|
);
|
|
695
709
|
}
|
|
710
|
+
const BRANCH_DELETION_POLL_INTERVAL_MS = 2e3;
|
|
711
|
+
const BRANCH_DELETION_WAIT_TIMEOUT_MS = 10 * 60 * 1e3;
|
|
712
|
+
async function waitForBranchDeletion(client, projectRef, branchId, options = {}) {
|
|
713
|
+
const pollIntervalMs = options.pollIntervalMs ?? BRANCH_DELETION_POLL_INTERVAL_MS;
|
|
714
|
+
const timeoutMs = options.timeoutMs ?? BRANCH_DELETION_WAIT_TIMEOUT_MS;
|
|
715
|
+
const wait = options.sleep ?? ((ms) => (0, import_promises.setTimeout)(ms));
|
|
716
|
+
const deadline = Date.now() + timeoutMs;
|
|
717
|
+
for (; ; ) {
|
|
718
|
+
const status = await client.projects.branches.describeDeletion(projectRef, branchId);
|
|
719
|
+
if (status.status === "completed") return;
|
|
720
|
+
if (status.status === "failed") throw new Error(status.error ?? "Branch deletion failed");
|
|
721
|
+
if (Date.now() >= deadline) {
|
|
722
|
+
throw new Error(
|
|
723
|
+
`Branch deletion ${branchId} is still pending after ${Math.round(timeoutMs / 1e3)}s${status.retryReason ? ` (${status.retryReason})` : ""}; it continues on the platform, re-run to keep waiting`
|
|
724
|
+
);
|
|
725
|
+
}
|
|
726
|
+
await wait(pollIntervalMs);
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
async function resolveUncertainAcceptance(client, projectRef, branchId, error) {
|
|
730
|
+
if (error.status !== 503) return null;
|
|
731
|
+
try {
|
|
732
|
+
const status = await client.projects.branches.describeDeletion(projectRef, branchId);
|
|
733
|
+
return { status: status.status };
|
|
734
|
+
} catch {
|
|
735
|
+
return null;
|
|
736
|
+
}
|
|
737
|
+
}
|
|
696
738
|
async function deleteBranchThroughPlatform(client, projectRef, branchName, options) {
|
|
697
739
|
if (branchName === PRIMARY_BRANCH_NAME) throw new Error(`The primary branch ${branchName} cannot be deleted`);
|
|
698
740
|
const branch = await client.projects.branches.describe(projectRef, branchName);
|
|
699
741
|
if (!options.confirmed) return { kind: "preview", branch };
|
|
700
|
-
|
|
701
|
-
|
|
742
|
+
if (!branch.branchId) {
|
|
743
|
+
throw new Error(
|
|
744
|
+
`Branch ${branchName} has no managed checkout, only ${branch.sessions.length} session(s); delete those with \`delete session <id>\``
|
|
745
|
+
);
|
|
746
|
+
}
|
|
747
|
+
const branchId = branch.branchId;
|
|
748
|
+
let accepted;
|
|
749
|
+
try {
|
|
750
|
+
accepted = await requireServerRouteSupport("delete branch", () => client.projects.branches.delete(projectRef, branchName, { branchId }));
|
|
751
|
+
} catch (error) {
|
|
752
|
+
const landed = error instanceof import_r5d_api.R5dctlApiError ? await resolveUncertainAcceptance(client, projectRef, branchId, error) : null;
|
|
753
|
+
if (!landed) throw error;
|
|
754
|
+
const sessionIds = branch.sessions.map((session) => session.id);
|
|
755
|
+
accepted = landed.status === "completed" ? { status: "completed", branchId, branchName, sessionIds } : { status: "pending", branchId, branchName, workerLabel: "", sessionIds };
|
|
756
|
+
}
|
|
757
|
+
if (accepted.status === "completed" && accepted.sessionIds.length > 0) {
|
|
758
|
+
return { kind: "deleted", result: { branchName, branchId, deletedSessionIds: accepted.sessionIds } };
|
|
759
|
+
}
|
|
760
|
+
if (accepted.status === "completed") return { kind: "deleted", result: { branchName, branchId, deletedSessionIds: [] } };
|
|
761
|
+
if (options.noWait) {
|
|
762
|
+
return { kind: "accepted", result: { branchName, branchId, sessionIds: accepted.sessionIds, workerLabel: accepted.workerLabel } };
|
|
763
|
+
}
|
|
764
|
+
await waitForBranchDeletion(client, projectRef, branchId, {
|
|
765
|
+
...options.pollIntervalMs !== void 0 ? { pollIntervalMs: options.pollIntervalMs } : {},
|
|
766
|
+
...options.timeoutMs !== void 0 ? { timeoutMs: options.timeoutMs } : {},
|
|
767
|
+
...options.sleep ? { sleep: options.sleep } : {}
|
|
768
|
+
});
|
|
769
|
+
return { kind: "deleted", result: { branchName, branchId, deletedSessionIds: accepted.sessionIds } };
|
|
702
770
|
}
|
|
703
771
|
async function deleteBranchesThroughPlatform(client, projectRef, branchNames, options) {
|
|
704
772
|
if (branchNames.length === 0) throw new Error("Missing branch name");
|
|
@@ -716,9 +784,15 @@ async function deleteBranchesThroughPlatform(client, projectRef, branchNames, op
|
|
|
716
784
|
for (const branchName of branchNames) {
|
|
717
785
|
let result;
|
|
718
786
|
try {
|
|
719
|
-
const deletion = await deleteBranchThroughPlatform(client, projectRef, branchName, {
|
|
720
|
-
|
|
721
|
-
|
|
787
|
+
const deletion = await deleteBranchThroughPlatform(client, projectRef, branchName, {
|
|
788
|
+
confirmed: true,
|
|
789
|
+
...options.noWait !== void 0 ? { noWait: options.noWait } : {},
|
|
790
|
+
...options.pollIntervalMs !== void 0 ? { pollIntervalMs: options.pollIntervalMs } : {},
|
|
791
|
+
...options.timeoutMs !== void 0 ? { timeoutMs: options.timeoutMs } : {},
|
|
792
|
+
...options.sleep ? { sleep: options.sleep } : {}
|
|
793
|
+
});
|
|
794
|
+
if (deletion.kind === "preview") throw new Error(`Branch ${branchName} was only previewed`);
|
|
795
|
+
result = deletion.kind === "deleted" ? { branchName, deleted: true, deletedSessionIds: deletion.result.deletedSessionIds } : { branchName, deleted: false, accepted: true, branchId: deletion.result.branchId, sessionIds: deletion.result.sessionIds };
|
|
722
796
|
} catch (error) {
|
|
723
797
|
result = {
|
|
724
798
|
branchName,
|
|
@@ -732,7 +806,21 @@ async function deleteBranchesThroughPlatform(client, projectRef, branchNames, op
|
|
|
732
806
|
return { kind: "deleted", results };
|
|
733
807
|
}
|
|
734
808
|
function renderBranchDeletionResult(result) {
|
|
735
|
-
|
|
809
|
+
if (result.deleted) return renderBranchDeletion(result);
|
|
810
|
+
if (result.accepted) {
|
|
811
|
+
return `Accepted deletion of branch ${result.branchName} (${result.sessionIds.length} session(s)); it continues on the platform. Check with \`describe branch-deletion ${result.branchId}\`.
|
|
812
|
+
`;
|
|
813
|
+
}
|
|
814
|
+
return `Failed to delete branch ${result.branchName}: ${result.error}
|
|
815
|
+
`;
|
|
816
|
+
}
|
|
817
|
+
function renderBranchDeletionStatus(status) {
|
|
818
|
+
const lines = [`Branch: ${status.branchName ?? "(deleted)"}`, `Branch id: ${status.branchId}`, `Status: ${status.status}`];
|
|
819
|
+
if (status.workerLabel) lines.push(`Worker: ${status.workerLabel}`);
|
|
820
|
+
if (status.attempts !== void 0) lines.push(`Attempts: ${status.attempts}`);
|
|
821
|
+
if (status.retryReason) lines.push(`Retrying: ${status.retryReason}`);
|
|
822
|
+
if (status.error) lines.push(`Error: ${status.error}`);
|
|
823
|
+
return `${lines.join("\n")}
|
|
736
824
|
`;
|
|
737
825
|
}
|
|
738
826
|
function branchDeletionsConfirmationMessage(branches) {
|
|
@@ -742,7 +830,7 @@ function branchDeletionsConfirmationMessage(branches) {
|
|
|
742
830
|
return `Nothing was deleted. Re-run with --confirm to delete ${branches.length} branches and their ${sessionCount} session(s).`;
|
|
743
831
|
}
|
|
744
832
|
function branchDeletionsFailureMessage(results) {
|
|
745
|
-
return `Failed to delete ${results.filter((result) => !result.deleted).length} of ${results.length} branch(es).`;
|
|
833
|
+
return `Failed to delete ${results.filter((result) => !result.deleted && !result.accepted).length} of ${results.length} branch(es).`;
|
|
746
834
|
}
|
|
747
835
|
function renderBranchDeletionPreview(branch) {
|
|
748
836
|
const count = branch.sessions.length;
|
|
@@ -1830,7 +1918,8 @@ function renderBranchList(branches) {
|
|
|
1830
1918
|
if (branches.length === 0) return "No branches found.\n";
|
|
1831
1919
|
const lines = branches.map((branch) => {
|
|
1832
1920
|
const checkout = branch.checkoutState ? ` checkout=${branch.checkoutState}${branch.checkoutStateWorkerLabel ? ` on ${branch.checkoutStateWorkerLabel}` : ""}` : "";
|
|
1833
|
-
|
|
1921
|
+
const deletion = branch.deletion ? ` deletion=${branch.deletion.status}${branch.deletion.error ? ` (${branch.deletion.error})` : ""}` : "";
|
|
1922
|
+
return `${branch.branchName} sessions=${branch.sessionCount}${checkout}${deletion}`;
|
|
1834
1923
|
});
|
|
1835
1924
|
if (branches.some((branch) => branch.checkoutState)) {
|
|
1836
1925
|
lines.push(`Workspace sync skips a branch whose checkout is missing or not a worktree; ${CHECKOUT_RECOVERY_HINT}.`);
|
|
@@ -3091,10 +3180,15 @@ async function executeR5dctlCommand(client, json, args) {
|
|
|
3091
3180
|
requireValue(args[offset], "Missing project reference"),
|
|
3092
3181
|
requireValue(args[offset + 1], "Missing branch name")
|
|
3093
3182
|
);
|
|
3094
|
-
write(
|
|
3183
|
+
write(
|
|
3184
|
+
result,
|
|
3185
|
+
`Project: ${result.project.path}
|
|
3095
3186
|
Branch: ${result.branchName}
|
|
3096
|
-
|
|
3097
|
-
`)
|
|
3187
|
+
Branch id: ${result.branchId ?? "(no managed branch)"}
|
|
3188
|
+
${result.deletion ? `Deletion: ${result.deletion.status}${result.deletion.error ? ` (${result.deletion.error})` : ""}
|
|
3189
|
+
` : ""}Sessions: ${result.sessions.length}
|
|
3190
|
+
`
|
|
3191
|
+
);
|
|
3098
3192
|
return;
|
|
3099
3193
|
}
|
|
3100
3194
|
if (first === "projects" && second === "branches" && third === "create" || first === "create" && second === "branch") {
|
|
@@ -3122,9 +3216,10 @@ Sessions: ${result.sessions.length}
|
|
|
3122
3216
|
if (first === "projects" && second === "branches" && third === "delete" || first === "delete" && second === "branch") {
|
|
3123
3217
|
const offset = first === "delete" ? 2 : 3;
|
|
3124
3218
|
const projectRef = requireValue(args[offset], "Missing project reference");
|
|
3125
|
-
const { branchNames, confirmed } = parseBranchDeleteArgs(args.slice(offset + 1));
|
|
3219
|
+
const { branchNames, confirmed, noWait } = parseBranchDeleteArgs(args.slice(offset + 1));
|
|
3126
3220
|
const deletion = await deleteBranchesThroughPlatform(client, projectRef, branchNames, {
|
|
3127
3221
|
confirmed,
|
|
3222
|
+
noWait,
|
|
3128
3223
|
// Each deletion is its own round trip, so a reader sees results as they land.
|
|
3129
3224
|
onResult: (result) => {
|
|
3130
3225
|
if (!json) process.stdout.write(renderBranchDeletionResult(result));
|
|
@@ -3135,7 +3230,15 @@ Sessions: ${result.sessions.length}
|
|
|
3135
3230
|
throw new Error(branchDeletionsConfirmationMessage(deletion.branches));
|
|
3136
3231
|
}
|
|
3137
3232
|
if (json) write({ results: deletion.results }, "");
|
|
3138
|
-
if (deletion.results.some((result) => !result.deleted)) throw new Error(branchDeletionsFailureMessage(deletion.results));
|
|
3233
|
+
if (deletion.results.some((result) => !result.deleted && !result.accepted)) throw new Error(branchDeletionsFailureMessage(deletion.results));
|
|
3234
|
+
return;
|
|
3235
|
+
}
|
|
3236
|
+
if (first === "projects" && second === "branches" && third === "describe-deletion" || first === "describe" && second === "branch-deletion") {
|
|
3237
|
+
const offset = first === "describe" ? 2 : 3;
|
|
3238
|
+
const projectRef = requireValue(args[offset], "Missing project reference");
|
|
3239
|
+
const branchId = requireValue(args[offset + 1], "Missing branch id");
|
|
3240
|
+
const status = await requireServerRouteSupport("describe branch-deletion", () => client.projects.branches.describeDeletion(projectRef, branchId));
|
|
3241
|
+
write(status, renderBranchDeletionStatus(status));
|
|
3139
3242
|
return;
|
|
3140
3243
|
}
|
|
3141
3244
|
if (first === "get" && second === "envs") {
|
|
@@ -3928,6 +4031,8 @@ async function main(argv = process.argv.slice(2)) {
|
|
|
3928
4031
|
}
|
|
3929
4032
|
// Annotate the CommonJS export names for ESM import in node:
|
|
3930
4033
|
0 && (module.exports = {
|
|
4034
|
+
BRANCH_DELETION_POLL_INTERVAL_MS,
|
|
4035
|
+
BRANCH_DELETION_WAIT_TIMEOUT_MS,
|
|
3931
4036
|
advanceTransientDevicePollBackoff,
|
|
3932
4037
|
branchDeletionConfirmationMessage,
|
|
3933
4038
|
branchDeletionsConfirmationMessage,
|
|
@@ -3977,6 +4082,7 @@ async function main(argv = process.argv.slice(2)) {
|
|
|
3977
4082
|
renderBranchDeletion,
|
|
3978
4083
|
renderBranchDeletionPreview,
|
|
3979
4084
|
renderBranchDeletionResult,
|
|
4085
|
+
renderBranchDeletionStatus,
|
|
3980
4086
|
renderBranchList,
|
|
3981
4087
|
renderBranchOperation,
|
|
3982
4088
|
renderConversationForkResponse,
|
|
@@ -4002,6 +4108,7 @@ async function main(argv = process.argv.slice(2)) {
|
|
|
4002
4108
|
resolveCommandExecution,
|
|
4003
4109
|
runR5dctlCli,
|
|
4004
4110
|
summarizeEnvData,
|
|
4111
|
+
waitForBranchDeletion,
|
|
4005
4112
|
waitForSessionProvisioning,
|
|
4006
4113
|
writeConfig
|
|
4007
4114
|
});
|
package/dist/cjs/package.json
CHANGED
package/dist/mjs/cli.mjs
CHANGED
|
@@ -142,8 +142,13 @@ const SHARED_HELP_ENTRIES = [
|
|
|
142
142
|
},
|
|
143
143
|
{
|
|
144
144
|
section: "branches",
|
|
145
|
-
usage: "-p <project> delete branch <branch> [<branch>...] [--confirm]",
|
|
146
|
-
description: "Delete one or more branches and their sessions through the platform; without --confirm, only preview what would be deleted."
|
|
145
|
+
usage: "-p <project> delete branch <branch> [<branch>...] [--confirm] [--no-wait]",
|
|
146
|
+
description: "Delete one or more branches and their sessions through the platform; without --confirm, only preview what would be deleted. Each deletion is accepted at once and awaited until the platform finishes it; --no-wait prints the accepted branch ids instead."
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
section: "branches",
|
|
150
|
+
usage: "-p <project> describe branch-deletion <branch-id>",
|
|
151
|
+
description: "Show whether an accepted branch deletion is pending, failed, or completed."
|
|
147
152
|
},
|
|
148
153
|
{
|
|
149
154
|
section: "envs",
|
|
@@ -551,16 +556,21 @@ function parseBranchCreateArgs(args) {
|
|
|
551
556
|
function parseBranchDeleteArgs(args) {
|
|
552
557
|
const branchNames = [];
|
|
553
558
|
let confirmed = false;
|
|
559
|
+
let noWait = false;
|
|
554
560
|
for (const arg of args) {
|
|
555
561
|
if (arg === "--confirm") {
|
|
556
562
|
confirmed = true;
|
|
557
563
|
continue;
|
|
558
564
|
}
|
|
565
|
+
if (arg === "--no-wait") {
|
|
566
|
+
noWait = true;
|
|
567
|
+
continue;
|
|
568
|
+
}
|
|
559
569
|
if (arg.startsWith("-")) throw new Error(`Unknown delete branch flag: ${arg}`);
|
|
560
570
|
if (branchNames.includes(arg)) throw new Error(`Branch ${arg} was given more than once`);
|
|
561
571
|
branchNames.push(arg);
|
|
562
572
|
}
|
|
563
|
-
return { branchNames, confirmed };
|
|
573
|
+
return { branchNames, confirmed, noWait };
|
|
564
574
|
}
|
|
565
575
|
const PRIMARY_BRANCH_NAME = "main";
|
|
566
576
|
function isUnsupportedServerRoute(error) {
|
|
@@ -588,12 +598,66 @@ async function createBranchThroughPlatform(client, projectRef, input) {
|
|
|
588
598
|
})
|
|
589
599
|
);
|
|
590
600
|
}
|
|
601
|
+
const BRANCH_DELETION_POLL_INTERVAL_MS = 2e3;
|
|
602
|
+
const BRANCH_DELETION_WAIT_TIMEOUT_MS = 10 * 60 * 1e3;
|
|
603
|
+
async function waitForBranchDeletion(client, projectRef, branchId, options = {}) {
|
|
604
|
+
const pollIntervalMs = options.pollIntervalMs ?? BRANCH_DELETION_POLL_INTERVAL_MS;
|
|
605
|
+
const timeoutMs = options.timeoutMs ?? BRANCH_DELETION_WAIT_TIMEOUT_MS;
|
|
606
|
+
const wait = options.sleep ?? ((ms) => sleep(ms));
|
|
607
|
+
const deadline = Date.now() + timeoutMs;
|
|
608
|
+
for (; ; ) {
|
|
609
|
+
const status = await client.projects.branches.describeDeletion(projectRef, branchId);
|
|
610
|
+
if (status.status === "completed") return;
|
|
611
|
+
if (status.status === "failed") throw new Error(status.error ?? "Branch deletion failed");
|
|
612
|
+
if (Date.now() >= deadline) {
|
|
613
|
+
throw new Error(
|
|
614
|
+
`Branch deletion ${branchId} is still pending after ${Math.round(timeoutMs / 1e3)}s${status.retryReason ? ` (${status.retryReason})` : ""}; it continues on the platform, re-run to keep waiting`
|
|
615
|
+
);
|
|
616
|
+
}
|
|
617
|
+
await wait(pollIntervalMs);
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
async function resolveUncertainAcceptance(client, projectRef, branchId, error) {
|
|
621
|
+
if (error.status !== 503) return null;
|
|
622
|
+
try {
|
|
623
|
+
const status = await client.projects.branches.describeDeletion(projectRef, branchId);
|
|
624
|
+
return { status: status.status };
|
|
625
|
+
} catch {
|
|
626
|
+
return null;
|
|
627
|
+
}
|
|
628
|
+
}
|
|
591
629
|
async function deleteBranchThroughPlatform(client, projectRef, branchName, options) {
|
|
592
630
|
if (branchName === PRIMARY_BRANCH_NAME) throw new Error(`The primary branch ${branchName} cannot be deleted`);
|
|
593
631
|
const branch = await client.projects.branches.describe(projectRef, branchName);
|
|
594
632
|
if (!options.confirmed) return { kind: "preview", branch };
|
|
595
|
-
|
|
596
|
-
|
|
633
|
+
if (!branch.branchId) {
|
|
634
|
+
throw new Error(
|
|
635
|
+
`Branch ${branchName} has no managed checkout, only ${branch.sessions.length} session(s); delete those with \`delete session <id>\``
|
|
636
|
+
);
|
|
637
|
+
}
|
|
638
|
+
const branchId = branch.branchId;
|
|
639
|
+
let accepted;
|
|
640
|
+
try {
|
|
641
|
+
accepted = await requireServerRouteSupport("delete branch", () => client.projects.branches.delete(projectRef, branchName, { branchId }));
|
|
642
|
+
} catch (error) {
|
|
643
|
+
const landed = error instanceof R5dctlApiError ? await resolveUncertainAcceptance(client, projectRef, branchId, error) : null;
|
|
644
|
+
if (!landed) throw error;
|
|
645
|
+
const sessionIds = branch.sessions.map((session) => session.id);
|
|
646
|
+
accepted = landed.status === "completed" ? { status: "completed", branchId, branchName, sessionIds } : { status: "pending", branchId, branchName, workerLabel: "", sessionIds };
|
|
647
|
+
}
|
|
648
|
+
if (accepted.status === "completed" && accepted.sessionIds.length > 0) {
|
|
649
|
+
return { kind: "deleted", result: { branchName, branchId, deletedSessionIds: accepted.sessionIds } };
|
|
650
|
+
}
|
|
651
|
+
if (accepted.status === "completed") return { kind: "deleted", result: { branchName, branchId, deletedSessionIds: [] } };
|
|
652
|
+
if (options.noWait) {
|
|
653
|
+
return { kind: "accepted", result: { branchName, branchId, sessionIds: accepted.sessionIds, workerLabel: accepted.workerLabel } };
|
|
654
|
+
}
|
|
655
|
+
await waitForBranchDeletion(client, projectRef, branchId, {
|
|
656
|
+
...options.pollIntervalMs !== void 0 ? { pollIntervalMs: options.pollIntervalMs } : {},
|
|
657
|
+
...options.timeoutMs !== void 0 ? { timeoutMs: options.timeoutMs } : {},
|
|
658
|
+
...options.sleep ? { sleep: options.sleep } : {}
|
|
659
|
+
});
|
|
660
|
+
return { kind: "deleted", result: { branchName, branchId, deletedSessionIds: accepted.sessionIds } };
|
|
597
661
|
}
|
|
598
662
|
async function deleteBranchesThroughPlatform(client, projectRef, branchNames, options) {
|
|
599
663
|
if (branchNames.length === 0) throw new Error("Missing branch name");
|
|
@@ -611,9 +675,15 @@ async function deleteBranchesThroughPlatform(client, projectRef, branchNames, op
|
|
|
611
675
|
for (const branchName of branchNames) {
|
|
612
676
|
let result;
|
|
613
677
|
try {
|
|
614
|
-
const deletion = await deleteBranchThroughPlatform(client, projectRef, branchName, {
|
|
615
|
-
|
|
616
|
-
|
|
678
|
+
const deletion = await deleteBranchThroughPlatform(client, projectRef, branchName, {
|
|
679
|
+
confirmed: true,
|
|
680
|
+
...options.noWait !== void 0 ? { noWait: options.noWait } : {},
|
|
681
|
+
...options.pollIntervalMs !== void 0 ? { pollIntervalMs: options.pollIntervalMs } : {},
|
|
682
|
+
...options.timeoutMs !== void 0 ? { timeoutMs: options.timeoutMs } : {},
|
|
683
|
+
...options.sleep ? { sleep: options.sleep } : {}
|
|
684
|
+
});
|
|
685
|
+
if (deletion.kind === "preview") throw new Error(`Branch ${branchName} was only previewed`);
|
|
686
|
+
result = deletion.kind === "deleted" ? { branchName, deleted: true, deletedSessionIds: deletion.result.deletedSessionIds } : { branchName, deleted: false, accepted: true, branchId: deletion.result.branchId, sessionIds: deletion.result.sessionIds };
|
|
617
687
|
} catch (error) {
|
|
618
688
|
result = {
|
|
619
689
|
branchName,
|
|
@@ -627,7 +697,21 @@ async function deleteBranchesThroughPlatform(client, projectRef, branchNames, op
|
|
|
627
697
|
return { kind: "deleted", results };
|
|
628
698
|
}
|
|
629
699
|
function renderBranchDeletionResult(result) {
|
|
630
|
-
|
|
700
|
+
if (result.deleted) return renderBranchDeletion(result);
|
|
701
|
+
if (result.accepted) {
|
|
702
|
+
return `Accepted deletion of branch ${result.branchName} (${result.sessionIds.length} session(s)); it continues on the platform. Check with \`describe branch-deletion ${result.branchId}\`.
|
|
703
|
+
`;
|
|
704
|
+
}
|
|
705
|
+
return `Failed to delete branch ${result.branchName}: ${result.error}
|
|
706
|
+
`;
|
|
707
|
+
}
|
|
708
|
+
function renderBranchDeletionStatus(status) {
|
|
709
|
+
const lines = [`Branch: ${status.branchName ?? "(deleted)"}`, `Branch id: ${status.branchId}`, `Status: ${status.status}`];
|
|
710
|
+
if (status.workerLabel) lines.push(`Worker: ${status.workerLabel}`);
|
|
711
|
+
if (status.attempts !== void 0) lines.push(`Attempts: ${status.attempts}`);
|
|
712
|
+
if (status.retryReason) lines.push(`Retrying: ${status.retryReason}`);
|
|
713
|
+
if (status.error) lines.push(`Error: ${status.error}`);
|
|
714
|
+
return `${lines.join("\n")}
|
|
631
715
|
`;
|
|
632
716
|
}
|
|
633
717
|
function branchDeletionsConfirmationMessage(branches) {
|
|
@@ -637,7 +721,7 @@ function branchDeletionsConfirmationMessage(branches) {
|
|
|
637
721
|
return `Nothing was deleted. Re-run with --confirm to delete ${branches.length} branches and their ${sessionCount} session(s).`;
|
|
638
722
|
}
|
|
639
723
|
function branchDeletionsFailureMessage(results) {
|
|
640
|
-
return `Failed to delete ${results.filter((result) => !result.deleted).length} of ${results.length} branch(es).`;
|
|
724
|
+
return `Failed to delete ${results.filter((result) => !result.deleted && !result.accepted).length} of ${results.length} branch(es).`;
|
|
641
725
|
}
|
|
642
726
|
function renderBranchDeletionPreview(branch) {
|
|
643
727
|
const count = branch.sessions.length;
|
|
@@ -1725,7 +1809,8 @@ function renderBranchList(branches) {
|
|
|
1725
1809
|
if (branches.length === 0) return "No branches found.\n";
|
|
1726
1810
|
const lines = branches.map((branch) => {
|
|
1727
1811
|
const checkout = branch.checkoutState ? ` checkout=${branch.checkoutState}${branch.checkoutStateWorkerLabel ? ` on ${branch.checkoutStateWorkerLabel}` : ""}` : "";
|
|
1728
|
-
|
|
1812
|
+
const deletion = branch.deletion ? ` deletion=${branch.deletion.status}${branch.deletion.error ? ` (${branch.deletion.error})` : ""}` : "";
|
|
1813
|
+
return `${branch.branchName} sessions=${branch.sessionCount}${checkout}${deletion}`;
|
|
1729
1814
|
});
|
|
1730
1815
|
if (branches.some((branch) => branch.checkoutState)) {
|
|
1731
1816
|
lines.push(`Workspace sync skips a branch whose checkout is missing or not a worktree; ${CHECKOUT_RECOVERY_HINT}.`);
|
|
@@ -2986,10 +3071,15 @@ async function executeR5dctlCommand(client, json, args) {
|
|
|
2986
3071
|
requireValue(args[offset], "Missing project reference"),
|
|
2987
3072
|
requireValue(args[offset + 1], "Missing branch name")
|
|
2988
3073
|
);
|
|
2989
|
-
write(
|
|
3074
|
+
write(
|
|
3075
|
+
result,
|
|
3076
|
+
`Project: ${result.project.path}
|
|
2990
3077
|
Branch: ${result.branchName}
|
|
2991
|
-
|
|
2992
|
-
`)
|
|
3078
|
+
Branch id: ${result.branchId ?? "(no managed branch)"}
|
|
3079
|
+
${result.deletion ? `Deletion: ${result.deletion.status}${result.deletion.error ? ` (${result.deletion.error})` : ""}
|
|
3080
|
+
` : ""}Sessions: ${result.sessions.length}
|
|
3081
|
+
`
|
|
3082
|
+
);
|
|
2993
3083
|
return;
|
|
2994
3084
|
}
|
|
2995
3085
|
if (first === "projects" && second === "branches" && third === "create" || first === "create" && second === "branch") {
|
|
@@ -3017,9 +3107,10 @@ Sessions: ${result.sessions.length}
|
|
|
3017
3107
|
if (first === "projects" && second === "branches" && third === "delete" || first === "delete" && second === "branch") {
|
|
3018
3108
|
const offset = first === "delete" ? 2 : 3;
|
|
3019
3109
|
const projectRef = requireValue(args[offset], "Missing project reference");
|
|
3020
|
-
const { branchNames, confirmed } = parseBranchDeleteArgs(args.slice(offset + 1));
|
|
3110
|
+
const { branchNames, confirmed, noWait } = parseBranchDeleteArgs(args.slice(offset + 1));
|
|
3021
3111
|
const deletion = await deleteBranchesThroughPlatform(client, projectRef, branchNames, {
|
|
3022
3112
|
confirmed,
|
|
3113
|
+
noWait,
|
|
3023
3114
|
// Each deletion is its own round trip, so a reader sees results as they land.
|
|
3024
3115
|
onResult: (result) => {
|
|
3025
3116
|
if (!json) process.stdout.write(renderBranchDeletionResult(result));
|
|
@@ -3030,7 +3121,15 @@ Sessions: ${result.sessions.length}
|
|
|
3030
3121
|
throw new Error(branchDeletionsConfirmationMessage(deletion.branches));
|
|
3031
3122
|
}
|
|
3032
3123
|
if (json) write({ results: deletion.results }, "");
|
|
3033
|
-
if (deletion.results.some((result) => !result.deleted)) throw new Error(branchDeletionsFailureMessage(deletion.results));
|
|
3124
|
+
if (deletion.results.some((result) => !result.deleted && !result.accepted)) throw new Error(branchDeletionsFailureMessage(deletion.results));
|
|
3125
|
+
return;
|
|
3126
|
+
}
|
|
3127
|
+
if (first === "projects" && second === "branches" && third === "describe-deletion" || first === "describe" && second === "branch-deletion") {
|
|
3128
|
+
const offset = first === "describe" ? 2 : 3;
|
|
3129
|
+
const projectRef = requireValue(args[offset], "Missing project reference");
|
|
3130
|
+
const branchId = requireValue(args[offset + 1], "Missing branch id");
|
|
3131
|
+
const status = await requireServerRouteSupport("describe branch-deletion", () => client.projects.branches.describeDeletion(projectRef, branchId));
|
|
3132
|
+
write(status, renderBranchDeletionStatus(status));
|
|
3034
3133
|
return;
|
|
3035
3134
|
}
|
|
3036
3135
|
if (first === "get" && second === "envs") {
|
|
@@ -3822,6 +3921,8 @@ async function main(argv = process.argv.slice(2)) {
|
|
|
3822
3921
|
}
|
|
3823
3922
|
}
|
|
3824
3923
|
export {
|
|
3924
|
+
BRANCH_DELETION_POLL_INTERVAL_MS,
|
|
3925
|
+
BRANCH_DELETION_WAIT_TIMEOUT_MS,
|
|
3825
3926
|
advanceTransientDevicePollBackoff,
|
|
3826
3927
|
branchDeletionConfirmationMessage,
|
|
3827
3928
|
branchDeletionsConfirmationMessage,
|
|
@@ -3871,6 +3972,7 @@ export {
|
|
|
3871
3972
|
renderBranchDeletion,
|
|
3872
3973
|
renderBranchDeletionPreview,
|
|
3873
3974
|
renderBranchDeletionResult,
|
|
3975
|
+
renderBranchDeletionStatus,
|
|
3874
3976
|
renderBranchList,
|
|
3875
3977
|
renderBranchOperation,
|
|
3876
3978
|
renderConversationForkResponse,
|
|
@@ -3896,6 +3998,7 @@ export {
|
|
|
3896
3998
|
resolveCommandExecution,
|
|
3897
3999
|
runR5dctlCli,
|
|
3898
4000
|
summarizeEnvData,
|
|
4001
|
+
waitForBranchDeletion,
|
|
3899
4002
|
waitForSessionProvisioning,
|
|
3900
4003
|
writeConfig
|
|
3901
4004
|
};
|
package/dist/mjs/package.json
CHANGED
package/dist/types/cli.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { R5dctlApiError, R5dctlClient, type R5dctlConversationForkResponse, type R5dctlConversationHeadResponse, type R5dctlConversationRenderOptions, type R5dctlConversationResponse, type R5dctlConversationNodeResponse, type R5dctlConversationOverviewResponse, type R5dctlConversationWorkDetail, type R5dctlConversationWorkResponse, type R5dctlEnvData, type R5dctlK8sResourceHistory, type R5dctlK8sUsage, type R5dctlK8sWorkload, type R5dctlProcessInspection, type R5dctlProcessListInput, type R5dctlProcessLog, type R5dctlProcessRun, type R5dctlBranch, type
|
|
1
|
+
import { R5dctlApiError, R5dctlClient, type R5dctlConversationForkResponse, type R5dctlConversationHeadResponse, type R5dctlConversationRenderOptions, type R5dctlConversationResponse, type R5dctlConversationNodeResponse, type R5dctlConversationOverviewResponse, type R5dctlConversationWorkDetail, type R5dctlConversationWorkResponse, type R5dctlEnvData, type R5dctlK8sResourceHistory, type R5dctlK8sUsage, type R5dctlK8sWorkload, type R5dctlProcessInspection, type R5dctlProcessListInput, type R5dctlProcessLog, type R5dctlProcessRun, type R5dctlBranch, type R5dctlBranchDeletionStatus, type R5dctlBranchDescription, type R5dctlBranchOperation, type R5dctlSessionSummary, type R5dctlSessionClaim, type R5dctlSessionClaimListResponse, type R5dctlSessionEvent, type R5dctlSessionStartInput, type R5dctlWorkspaceStatus, type R5dctlWorkspaceSyncResult, type R5dctlWorkingTreeMode, type R5dctlWorktreeSource, type R5dctlPromptDelivery, type R5dctlSessionMode, type ChatMode, type ModelTier } from "@ricsam/r5d-api";
|
|
2
2
|
export type GlobalOptions = {
|
|
3
3
|
baseUrl?: string;
|
|
4
4
|
json: boolean;
|
|
@@ -90,6 +90,7 @@ export declare function parseBranchCreateArgs(args: string[]): R5dctlBranchCreat
|
|
|
90
90
|
export declare function parseBranchDeleteArgs(args: string[]): {
|
|
91
91
|
branchNames: string[];
|
|
92
92
|
confirmed: boolean;
|
|
93
|
+
noWait: boolean;
|
|
93
94
|
};
|
|
94
95
|
/** An older server strips unknown routes and answers with this generic 404; a route's own not-found carries a specific message. */
|
|
95
96
|
export declare function isUnsupportedServerRoute(error: unknown): error is R5dctlApiError;
|
|
@@ -101,10 +102,39 @@ export type R5dctlBranchDeletionOutcome = {
|
|
|
101
102
|
branch: R5dctlBranchDescription;
|
|
102
103
|
} | {
|
|
103
104
|
kind: "deleted";
|
|
104
|
-
result:
|
|
105
|
+
result: {
|
|
106
|
+
branchName: string;
|
|
107
|
+
branchId: string;
|
|
108
|
+
deletedSessionIds: string[];
|
|
109
|
+
};
|
|
110
|
+
} | {
|
|
111
|
+
kind: "accepted";
|
|
112
|
+
result: {
|
|
113
|
+
branchName: string;
|
|
114
|
+
branchId: string;
|
|
115
|
+
sessionIds: string[];
|
|
116
|
+
workerLabel: string;
|
|
117
|
+
};
|
|
105
118
|
};
|
|
119
|
+
/** The platform answers an accepted deletion at once; the checkout and chats disappear behind this poll. */
|
|
120
|
+
export declare const BRANCH_DELETION_POLL_INTERVAL_MS = 2000;
|
|
121
|
+
export declare const BRANCH_DELETION_WAIT_TIMEOUT_MS: number;
|
|
122
|
+
/**
|
|
123
|
+
* Wait for one accepted deletion, keyed by its exact branch incarnation. A
|
|
124
|
+
* `completed` status is the terminal success; a `failed` status carries the
|
|
125
|
+
* platform's reason and is not retried here (re-run the command to retry).
|
|
126
|
+
*/
|
|
127
|
+
export declare function waitForBranchDeletion(client: R5dctlClient, projectRef: string, branchId: string, options?: {
|
|
128
|
+
pollIntervalMs?: number;
|
|
129
|
+
timeoutMs?: number;
|
|
130
|
+
sleep?: (ms: number) => Promise<void>;
|
|
131
|
+
}): Promise<void>;
|
|
106
132
|
export declare function deleteBranchThroughPlatform(client: R5dctlClient, projectRef: string, branchName: string, options: {
|
|
107
133
|
confirmed: boolean;
|
|
134
|
+
noWait?: boolean;
|
|
135
|
+
pollIntervalMs?: number;
|
|
136
|
+
timeoutMs?: number;
|
|
137
|
+
sleep?: (ms: number) => Promise<void>;
|
|
108
138
|
}): Promise<R5dctlBranchDeletionOutcome>;
|
|
109
139
|
export type R5dctlBranchDeletionResult = {
|
|
110
140
|
branchName: string;
|
|
@@ -113,6 +143,13 @@ export type R5dctlBranchDeletionResult = {
|
|
|
113
143
|
} | {
|
|
114
144
|
branchName: string;
|
|
115
145
|
deleted: false;
|
|
146
|
+
accepted: true;
|
|
147
|
+
branchId: string;
|
|
148
|
+
sessionIds: string[];
|
|
149
|
+
} | {
|
|
150
|
+
branchName: string;
|
|
151
|
+
deleted: false;
|
|
152
|
+
accepted?: false;
|
|
116
153
|
error: string;
|
|
117
154
|
};
|
|
118
155
|
export type R5dctlBranchDeletionsOutcome = {
|
|
@@ -126,18 +163,29 @@ export type R5dctlBranchDeletionsOutcome = {
|
|
|
126
163
|
* Delete several branches one request at a time: the server route stays
|
|
127
164
|
* one-branch-per-request. Every name is checked before the first request, a
|
|
128
165
|
* preview describes each branch, and a confirmed run continues past a failed
|
|
129
|
-
* branch so one refused deletion does not strand the rest of the list.
|
|
166
|
+
* branch so one refused deletion does not strand the rest of the list. Each
|
|
167
|
+
* accepted deletion is awaited before the next is requested, so the worker
|
|
168
|
+
* handles them in order and a failure is reported where it happened.
|
|
130
169
|
*/
|
|
131
170
|
export declare function deleteBranchesThroughPlatform(client: R5dctlClient, projectRef: string, branchNames: readonly string[], options: {
|
|
132
171
|
confirmed: boolean;
|
|
172
|
+
noWait?: boolean;
|
|
173
|
+
pollIntervalMs?: number;
|
|
174
|
+
timeoutMs?: number;
|
|
175
|
+
sleep?: (ms: number) => Promise<void>;
|
|
133
176
|
onResult?: (result: R5dctlBranchDeletionResult) => void;
|
|
134
177
|
}): Promise<R5dctlBranchDeletionsOutcome>;
|
|
135
178
|
export declare function renderBranchDeletionResult(result: R5dctlBranchDeletionResult): string;
|
|
179
|
+
/** Operation facts of one deletion, keyed by its branch incarnation. */
|
|
180
|
+
export declare function renderBranchDeletionStatus(status: R5dctlBranchDeletionStatus): string;
|
|
136
181
|
export declare function branchDeletionsConfirmationMessage(branches: readonly R5dctlBranchDescription[]): string;
|
|
137
182
|
export declare function branchDeletionsFailureMessage(results: readonly R5dctlBranchDeletionResult[]): string;
|
|
138
183
|
export declare function renderBranchDeletionPreview(branch: R5dctlBranchDescription): string;
|
|
139
184
|
export declare function branchDeletionConfirmationMessage(branch: R5dctlBranchDescription): string;
|
|
140
|
-
export declare function renderBranchDeletion(result:
|
|
185
|
+
export declare function renderBranchDeletion(result: {
|
|
186
|
+
branchName: string;
|
|
187
|
+
deletedSessionIds: string[];
|
|
188
|
+
}): string;
|
|
141
189
|
/** Operation facts only: no commit hash, because a hash is stale as soon as the branch commits. */
|
|
142
190
|
export declare function renderBranchOperation(operation: R5dctlBranchOperation, projectRef: string): string;
|
|
143
191
|
export declare function parseSessionRunCommand(options: Pick<GlobalOptions, "project" | "branch" | "session">, args: string[], env?: Record<string, string | undefined>): R5dctlSessionRunCommand;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ricsam/r5dctl",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.122",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/cjs/cli.cjs",
|
|
6
6
|
"module": "./dist/mjs/cli.mjs",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"r5dctl": "dist/cjs/main.cjs"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@ricsam/r5d-api": "^0.0.
|
|
29
|
+
"@ricsam/r5d-api": "^0.0.122",
|
|
30
30
|
"dotenv": "^17",
|
|
31
31
|
"qrcode": "^1.5.4",
|
|
32
32
|
"ws": "^8.18.3"
|