@agimon-ai/po-git 0.0.0-alpha.78 → 0.0.0-alpha.79
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/dist/apiContracts.cjs +30 -0
- package/dist/apiContracts.cjs.map +1 -1
- package/dist/apiContracts.mjs +30 -0
- package/dist/apiContracts.mjs.map +1 -1
- package/dist/extensions/native.mjs +10 -0
- package/dist/extensions/native.mjs.map +1 -1
- package/dist/extensions/server.cjs +222 -161
- package/dist/extensions/server.cjs.map +1 -1
- package/dist/extensions/server.mjs +222 -161
- package/dist/extensions/server.mjs.map +1 -1
- package/dist/extensions/web.mjs +134 -30
- package/dist/extensions/web.mjs.map +1 -1
- package/package.json +8 -8
package/dist/extensions/web.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createApiClient, defineActivityGroup, defineChannelFile, defineFill, defineGlobalStore, defineLeaderBinding, defineRepositorySettingsPanel, defineSessionStore, defineToolRenderer, defineWebLifecycle, defineWebPlugin, sessionApiAddress } from "@agimon-ai/po-core/web";
|
|
2
|
-
import { ArrowRightIcon, BranchIcon, Button, CheckIcon, ChevronDownIcon, ChevronUpIcon, CodeBlock, Dialog, DialogContent, DialogTitle, DiffView, Dot, DropdownMenuItem, EmptyState, Input, MessageIcon, MessageItem, MessageItemBody, ReviewCommentDraft, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, SettingsActions, SettingsCard, SettingsNote, SettingsRow, SettingsRowDescription, SettingsRowText, SettingsRowTitle, SettingsSection, SettingsSectionDescription, SettingsSectionHeader, SettingsSectionTitle, ShieldIcon, Spinner, StatusBadge, Tabs, TabsContent, TabsList, TabsTrigger, buildReviewPrompt } from "@agimon-ai/po-web-components";
|
|
2
|
+
import { ArrowRightIcon, BranchIcon, Button, CheckIcon, ChevronDownIcon, ChevronUpIcon, CodeBlock, Dialog, DialogContent, DialogTitle, DiffView, Dot, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger, EmptyState, FolderIcon, Input, KebabIcon, MessageIcon, MessageItem, MessageItemBody, ReviewCommentDraft, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, SettingsActions, SettingsCard, SettingsNote, SettingsRow, SettingsRowDescription, SettingsRowText, SettingsRowTitle, SettingsSection, SettingsSectionDescription, SettingsSectionHeader, SettingsSectionTitle, ShieldIcon, Spinner, StatusBadge, Tabs, TabsContent, TabsList, TabsTrigger, TrashIcon, buildReviewPrompt } from "@agimon-ai/po-web-components";
|
|
3
3
|
import { createElement, useCallback, useEffect, useEffectEvent, useId, useRef, useState } from "react";
|
|
4
4
|
import { browserTransport } from "@agimon-ai/po-web-security/browser";
|
|
5
5
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -11,6 +11,16 @@ const api = createApiClient({
|
|
|
11
11
|
path: "/branches",
|
|
12
12
|
response: void 0
|
|
13
13
|
},
|
|
14
|
+
deleteBranch: {
|
|
15
|
+
method: "DELETE",
|
|
16
|
+
path: "/branches",
|
|
17
|
+
response: void 0
|
|
18
|
+
},
|
|
19
|
+
openBranchFolder: {
|
|
20
|
+
method: "POST",
|
|
21
|
+
path: "/branches/open",
|
|
22
|
+
response: void 0
|
|
23
|
+
},
|
|
14
24
|
/** Workspace: a top-level worktree session on an existing or new branch. */
|
|
15
25
|
createSession: {
|
|
16
26
|
method: "POST",
|
|
@@ -124,7 +134,7 @@ function Field$1({ label, children }) {
|
|
|
124
134
|
});
|
|
125
135
|
}
|
|
126
136
|
/** Inline presentation also lets story capture inspect content, rather than a portal-only root. */
|
|
127
|
-
function GitNewSessionDialogView({ workspaceRoot, branches, loadError = "", initialForm, busy = false, error = "", riftMissing = false, onClose, onCreate }) {
|
|
137
|
+
function GitNewSessionDialogView({ workspaceRoot, branches, loadError = "", initialForm, busy = false, error = "", riftMissing = false, onClose, onCreate, onDeleteBranch, onOpenBranchFolder }) {
|
|
128
138
|
const [form, setForm] = useState({
|
|
129
139
|
mode: "existing",
|
|
130
140
|
newBranch: "",
|
|
@@ -133,6 +143,7 @@ function GitNewSessionDialogView({ workspaceRoot, branches, loadError = "", init
|
|
|
133
143
|
...initialForm
|
|
134
144
|
});
|
|
135
145
|
const [query, setQuery] = useState("");
|
|
146
|
+
const [deleting, setDeleting] = useState();
|
|
136
147
|
const ready = branches?.repository === true && loadError === "";
|
|
137
148
|
const loading = branches === null && loadError === "";
|
|
138
149
|
const mode = ready || loading ? form.mode : "plain";
|
|
@@ -149,7 +160,7 @@ function GitNewSessionDialogView({ workspaceRoot, branches, loadError = "", init
|
|
|
149
160
|
const options = branches === null ? [] : branchOptions(branches, query);
|
|
150
161
|
const bases = branches === null ? [] : baseOptions(branches);
|
|
151
162
|
const submit = () => {
|
|
152
|
-
if (!busy && !loading && problem === void 0) onCreate(state);
|
|
163
|
+
if (!busy && !loading && deleting === void 0 && problem === void 0) onCreate(state);
|
|
153
164
|
};
|
|
154
165
|
return /* @__PURE__ */ jsxs("section", {
|
|
155
166
|
"data-testid": "new-session-dialog",
|
|
@@ -230,32 +241,94 @@ function GitNewSessionDialogView({ workspaceRoot, branches, loadError = "", init
|
|
|
230
241
|
}) : null, options.map((branch, index) => /* @__PURE__ */ jsxs("div", { children: [branch.remote !== void 0 && (index === 0 || options[index - 1]?.remote === void 0) ? /* @__PURE__ */ jsx("p", {
|
|
231
242
|
className: "mt-1 border-t border-po-border-soft px-3 pt-2 text-sm text-po-dim",
|
|
232
243
|
children: "Remote branches"
|
|
233
|
-
}) : null, /* @__PURE__ */ jsxs("
|
|
234
|
-
|
|
235
|
-
"
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
className:
|
|
243
|
-
children: [/* @__PURE__ */
|
|
244
|
-
className: "
|
|
245
|
-
children:
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
className: "
|
|
251
|
-
children:
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
244
|
+
}) : null, /* @__PURE__ */ jsxs("div", {
|
|
245
|
+
className: "flex min-w-0 items-start gap-1",
|
|
246
|
+
children: [/* @__PURE__ */ jsxs("button", {
|
|
247
|
+
"data-testid": "git-new-session-branch-option",
|
|
248
|
+
"data-branch": branch.name,
|
|
249
|
+
"data-remote": branch.remote,
|
|
250
|
+
"aria-pressed": form.selected?.key === branch.key,
|
|
251
|
+
disabled: branch.busyAt !== void 0 || busy,
|
|
252
|
+
onClick: () => update({ selected: branch }),
|
|
253
|
+
className: `flex min-w-0 flex-1 flex-col gap-1 rounded px-3 py-2 text-left text-base ${form.selected?.key === branch.key ? "bg-po-tint-green text-po-green" : "text-po-text"}`,
|
|
254
|
+
children: [/* @__PURE__ */ jsxs("span", {
|
|
255
|
+
className: "flex items-center justify-between gap-2",
|
|
256
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
257
|
+
className: "font-mono break-all",
|
|
258
|
+
children: branch.remote === void 0 ? branch.name : `${branch.remote}/${branch.name}`
|
|
259
|
+
}), form.selected?.key === branch.key ? /* @__PURE__ */ jsx(CheckIcon, { className: "size-4 shrink-0" }) : null]
|
|
260
|
+
}), branch.busyAt !== void 0 ? /* @__PURE__ */ jsxs("span", {
|
|
261
|
+
className: "text-sm text-po-dim",
|
|
262
|
+
children: ["Checked out in ", /* @__PURE__ */ jsx("span", {
|
|
263
|
+
className: "font-mono break-all",
|
|
264
|
+
children: branch.busyAt
|
|
265
|
+
})]
|
|
266
|
+
}) : branch.current ? /* @__PURE__ */ jsx("span", {
|
|
267
|
+
className: "text-sm text-po-dim",
|
|
268
|
+
children: "Current"
|
|
269
|
+
}) : null]
|
|
270
|
+
}), /* @__PURE__ */ jsxs(DropdownMenu, { children: [/* @__PURE__ */ jsx(DropdownMenuTrigger, {
|
|
271
|
+
asChild: true,
|
|
272
|
+
children: /* @__PURE__ */ jsx(Button, {
|
|
273
|
+
variant: "ghost",
|
|
274
|
+
size: "icon-md",
|
|
275
|
+
className: "mt-1",
|
|
276
|
+
"aria-label": `Actions for ${branch.remote === void 0 ? branch.name : `${branch.remote}/${branch.name}`}`,
|
|
277
|
+
disabled: busy,
|
|
278
|
+
children: /* @__PURE__ */ jsx(KebabIcon, { className: "size-4" })
|
|
279
|
+
})
|
|
280
|
+
}), /* @__PURE__ */ jsxs(DropdownMenuContent, { children: [
|
|
281
|
+
/* @__PURE__ */ jsxs(DropdownMenuItem, {
|
|
282
|
+
disabled: branch.busyAt === void 0 || onOpenBranchFolder === void 0,
|
|
283
|
+
title: branch.busyAt === void 0 ? "This branch has no checked-out folder." : branch.busyAt,
|
|
284
|
+
onSelect: () => onOpenBranchFolder?.(branch.name),
|
|
285
|
+
children: [/* @__PURE__ */ jsx(FolderIcon, { className: "size-4" }), "Open in Finder"]
|
|
286
|
+
}),
|
|
287
|
+
/* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
|
|
288
|
+
/* @__PURE__ */ jsxs(DropdownMenuItem, {
|
|
289
|
+
variant: "destructive",
|
|
290
|
+
disabled: branch.remote !== void 0 || branch.busyAt !== void 0 || branch.current || onDeleteBranch === void 0,
|
|
291
|
+
title: branch.remote !== void 0 ? "Only local branches can be deleted here." : branch.busyAt !== void 0 || branch.current ? "Close this branch’s worktree before deleting it." : void 0,
|
|
292
|
+
onSelect: () => setDeleting(branch),
|
|
293
|
+
children: [/* @__PURE__ */ jsx(TrashIcon, { className: "size-4" }), "Delete branch"]
|
|
294
|
+
})
|
|
295
|
+
] })] })]
|
|
257
296
|
})] }, branch.key))]
|
|
258
|
-
})
|
|
297
|
+
}),
|
|
298
|
+
deleting !== void 0 ? /* @__PURE__ */ jsxs("fieldset", {
|
|
299
|
+
"aria-label": "Confirm branch deletion",
|
|
300
|
+
className: "flex flex-col gap-3 rounded-md border border-po-edge-red bg-po-tint-red p-3",
|
|
301
|
+
children: [/* @__PURE__ */ jsxs("p", {
|
|
302
|
+
className: "text-sm text-po-text",
|
|
303
|
+
children: [
|
|
304
|
+
"Delete local branch ",
|
|
305
|
+
/* @__PURE__ */ jsx("span", {
|
|
306
|
+
className: "font-mono break-all",
|
|
307
|
+
children: deleting.name
|
|
308
|
+
}),
|
|
309
|
+
"? Git will refuse if it contains unmerged commits. No worktree or remote branch will be removed."
|
|
310
|
+
]
|
|
311
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
312
|
+
className: "flex justify-end gap-2",
|
|
313
|
+
children: [/* @__PURE__ */ jsx(Button, {
|
|
314
|
+
variant: "ghost",
|
|
315
|
+
disabled: busy,
|
|
316
|
+
onClick: () => setDeleting(void 0),
|
|
317
|
+
children: "Cancel deletion"
|
|
318
|
+
}), /* @__PURE__ */ jsx(Button, {
|
|
319
|
+
variant: "danger-outline",
|
|
320
|
+
disabled: busy,
|
|
321
|
+
onClick: async () => {
|
|
322
|
+
if (busy || onDeleteBranch === void 0) return;
|
|
323
|
+
if (await onDeleteBranch(deleting.name)) {
|
|
324
|
+
if (form.selected?.key === deleting.key) update({ selected: void 0 });
|
|
325
|
+
setDeleting(void 0);
|
|
326
|
+
}
|
|
327
|
+
},
|
|
328
|
+
children: "Delete branch"
|
|
329
|
+
})]
|
|
330
|
+
})]
|
|
331
|
+
}) : null
|
|
259
332
|
]
|
|
260
333
|
}),
|
|
261
334
|
/* @__PURE__ */ jsxs(TabsContent, {
|
|
@@ -353,7 +426,7 @@ rift init`,
|
|
|
353
426
|
"data-testid": "new-session-create",
|
|
354
427
|
variant: "primary",
|
|
355
428
|
title: problem,
|
|
356
|
-
disabled: busy || loading || problem !== void 0,
|
|
429
|
+
disabled: busy || loading || deleting !== void 0 || problem !== void 0,
|
|
357
430
|
onClick: submit,
|
|
358
431
|
children: busy ? mode === "plain" ? "Creating session..." : "Creating worktree..." : riftMissing ? "Try again" : "Create session"
|
|
359
432
|
})]
|
|
@@ -423,6 +496,35 @@ function GitNewSessionDialog({ newSession }) {
|
|
|
423
496
|
setError(failure);
|
|
424
497
|
setBusy(false);
|
|
425
498
|
};
|
|
499
|
+
const branchAction = async (branch, action) => {
|
|
500
|
+
if (busy) return false;
|
|
501
|
+
setBusy(true);
|
|
502
|
+
setError("");
|
|
503
|
+
setRiftMissing(false);
|
|
504
|
+
try {
|
|
505
|
+
const workspace = api.workspace(newSession.workspaceId);
|
|
506
|
+
const response = await newSession.requestWithStepUp(action === "delete" ? workspace.deleteBranch.url() : workspace.openBranchFolder.url(), {
|
|
507
|
+
method: action === "delete" ? "DELETE" : "POST",
|
|
508
|
+
headers: { "Content-Type": "application/json" },
|
|
509
|
+
body: JSON.stringify({ branch })
|
|
510
|
+
});
|
|
511
|
+
const body = await response.json().catch(() => void 0);
|
|
512
|
+
if (!response.ok) {
|
|
513
|
+
setError(errorOf$1(body, response.status));
|
|
514
|
+
return false;
|
|
515
|
+
}
|
|
516
|
+
if (action === "delete") setBranches((current) => current === null ? null : {
|
|
517
|
+
...current,
|
|
518
|
+
local: current.local.filter((item) => item.name !== branch)
|
|
519
|
+
});
|
|
520
|
+
return true;
|
|
521
|
+
} catch {
|
|
522
|
+
setError("The cockpit is unreachable.");
|
|
523
|
+
return false;
|
|
524
|
+
} finally {
|
|
525
|
+
setBusy(false);
|
|
526
|
+
}
|
|
527
|
+
};
|
|
426
528
|
return /* @__PURE__ */ jsx(Dialog, {
|
|
427
529
|
open: true,
|
|
428
530
|
onOpenChange: (next) => {
|
|
@@ -443,7 +545,9 @@ function GitNewSessionDialog({ newSession }) {
|
|
|
443
545
|
error,
|
|
444
546
|
riftMissing,
|
|
445
547
|
onClose: newSession.close,
|
|
446
|
-
onCreate: (state) => void submit(state)
|
|
548
|
+
onCreate: (state) => void submit(state),
|
|
549
|
+
onDeleteBranch: (branch) => branchAction(branch, "delete"),
|
|
550
|
+
onOpenBranchFolder: (branch) => void branchAction(branch, "open")
|
|
447
551
|
})]
|
|
448
552
|
})
|
|
449
553
|
});
|