bazilion 0.18.0 → 0.19.0
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/cli.js +607 -96
- package/dist/cli.js.map +1 -1
- package/dist/daemon.js +3225 -739
- package/dist/daemon.js.map +1 -1
- package/dist/migrations/0001_init.sql +142 -3
- package/dist/web/client/assets/{ChatPane-CAYS_fIQ.js → ChatPane-DCyGcqdh.js} +1 -1
- package/dist/web/client/assets/ConfirmDialog-C908TxS5.js +1 -0
- package/dist/web/client/assets/{FieldRow-W_54rw5c.js → FieldRow-CELqI-1V.js} +1 -1
- package/dist/web/client/assets/{ProductionTeamPolicyEditor-DNXVX8Lz.js → ProductionTeamPolicyEditor-DnTcWhG8.js} +1 -1
- package/dist/web/client/assets/{ProfileCommunicationEditor-DN0fOzqn.js → ProfileCommunicationEditor-BVIEaW3s.js} +1 -1
- package/dist/web/client/assets/{ResultSourceConversation-DoU4tOWc.js → ResultSourceConversation-4gbZCh_s.js} +1 -1
- package/dist/web/client/assets/{TeamTabs-BmTZRI4T.js → TeamTabs-V17b45X5.js} +1 -1
- package/dist/web/client/assets/{TemplatesTabs-Bs_OXKwx.js → TemplatesTabs-BMK3Qok_.js} +1 -1
- package/dist/web/client/assets/{UnsavedChangesGuard-CPRtFReU.js → UnsavedChangesGuard-BaE-UzyS.js} +1 -1
- package/dist/web/client/assets/{_id-Dbmei5tg.js → _id-BU1l9gP7.js} +1 -1
- package/dist/web/client/assets/{_id-DL4tJFQB.js → _id-BVANQm00.js} +1 -1
- package/dist/web/client/assets/{_id-DR9eFC17.js → _id-Bvh5LyUv.js} +1 -1
- package/dist/web/client/assets/{_id-ybF-pqmr.js → _id-CArZR-IO.js} +1 -1
- package/dist/web/client/assets/{_id-CxAB4TDr.js → _id-tUkSe5li.js} +1 -1
- package/dist/web/client/assets/{activity-oUyy77jD.js → activity-CWCnqjqj.js} +1 -1
- package/dist/web/client/assets/{agents-DkjJp7JP.js → agents-CX4STmGK.js} +1 -1
- package/dist/web/client/assets/{agents-D_TrEqAg.js → agents-CdCnhH06.js} +1 -1
- package/dist/web/client/assets/{approvals-DhOerWdt.js → approvals-CnNpwG78.js} +1 -1
- package/dist/web/client/assets/{attention-DGwiF-Jy.js → attention-CEE-wWrx.js} +1 -1
- package/dist/web/client/assets/chevron-right-CvCEwfSl.js +1 -0
- package/dist/web/client/assets/{config-BJ2ZzHPR.js → config-CSEtI-dq.js} +1 -1
- package/dist/web/client/assets/{inbox-BUElnGep.js → inbox-MYnBtPdF.js} +1 -1
- package/dist/web/client/assets/index-Ct31TjS-.js +52 -0
- package/dist/web/client/assets/{learning-BiTHNwB3.js → learning-BIR5FTgQ.js} +1 -1
- package/dist/web/client/assets/{login-BmcZvAH2.js → login-DIeceuOs.js} +1 -1
- package/dist/web/client/assets/{mcp-Cwk9V82W.js → mcp-CX3kJpGu.js} +1 -1
- package/dist/web/client/assets/{members-CHDNabFh.js → members-DlhSjye1.js} +1 -1
- package/dist/web/client/assets/{memory-Cx_Fpd4e.js → memory-CsDd6b2l.js} +1 -1
- package/dist/web/client/assets/{policy-C0nMdwcG.js → policy-DkWDhG0x.js} +1 -1
- package/dist/web/client/assets/{results-Bz3jASs-.js → results-BHdhNHJJ.js} +1 -1
- package/dist/web/client/assets/review-Dyw47eM1.js +1 -0
- package/dist/web/client/assets/{routes-DsMY_6oy.js → routes-DtYD4WJL.js} +1 -1
- package/dist/web/client/assets/{services-DItA6fJ7.js → services-WUlW7oEo.js} +1 -1
- package/dist/web/client/assets/{skills-DbNV2vgL.js → skills-jNoUfUSZ.js} +1 -1
- package/dist/web/client/assets/styles-DCX6QTqJ.css +2 -0
- package/dist/web/client/assets/{teams-D83scDxw.js → teams-C1kYRrtP.js} +1 -1
- package/dist/web/client/assets/{teams-DAny1ypN.js → teams-D3FaSKE7.js} +1 -1
- package/dist/web/client/assets/{telegram-BOmf9vUh.js → telegram-D86AO6V9.js} +1 -1
- package/dist/web/client/assets/{tokens-DBGH6Bw5.js → tokens-B42KDisP.js} +1 -1
- package/dist/web/client/assets/{triggers-D1_pseI3.js → triggers-yEfWnQ_K.js} +1 -1
- package/dist/web/client/assets/{verifications-CBTo-FyV.js → verifications-DrHQEQFx.js} +2 -2
- package/dist/web/client/assets/{welcome-DAfPOm15.js → welcome-D8IbF_P0.js} +1 -1
- package/dist/web/client/assets/{x-CWY-gUaM.js → x-CXKABZ7C.js} +1 -1
- package/dist/web/server/assets/{_id--zoh1vv7.js → _id-D2bDA1iV.js} +1 -1
- package/dist/web/server/assets/{_id-6p-mDmI8.js → _id-DL-SnSnK.js} +1 -1
- package/dist/web/server/assets/{_id-dUnXL-My2.js → _id-Dab2CVtO2.js} +1 -1
- package/dist/web/server/assets/{_id-DptBl3X8.js → _id-bVispdh-.js} +1 -1
- package/dist/web/server/assets/{_tanstack-start-manifest_v-B3M-dfRO.js → _tanstack-start-manifest_v-BcTOb0oj.js} +84 -85
- package/dist/web/server/assets/{activity-C5jpoEQI.js → activity-CLDAy6rk.js} +1 -1
- package/dist/web/server/assets/{agents-RE6aYOb-.js → agents-CdB2kuNN.js} +1 -1
- package/dist/web/server/assets/{agents-nAOx_H7s.js → agents-DfHcb2H2.js} +1 -1
- package/dist/web/server/assets/{approvals-DhHxIDrL.js → approvals-Bq846WaP.js} +1 -1
- package/dist/web/server/assets/{attention-CBWzWRni.js → attention-Sm-U7s_0.js} +1 -1
- package/dist/web/server/assets/{auth-tB3i6cFd.js → auth-PB5dVyvX.js} +1 -1
- package/dist/web/server/assets/{config-D1k_tTAw.js → config-BNGTBu80.js} +1 -1
- package/dist/web/server/assets/{daemon-client-C7qjQ2iO.js → daemon-client-CWQvck6B.js} +35 -0
- package/dist/web/server/assets/{git-review-Bf5ABFJg.js → git-review-C_h_tezf.js} +1 -1
- package/dist/web/server/assets/{inbox-Dw4pTevh.js → inbox-DJoU-bla.js} +1 -1
- package/dist/web/server/assets/{learning-CF8ZzFVD.js → learning-DVb0I_3Z.js} +1 -1
- package/dist/web/server/assets/{mcp-D5dmBT82.js → mcp-CeZqOiDG.js} +1 -1
- package/dist/web/server/assets/{members-CvwEN9pm.js → members-CcYjuqxB.js} +1 -1
- package/dist/web/server/assets/{memory-CcPK7um7.js → memory-CH2yNT89.js} +1 -1
- package/dist/web/server/assets/{policy-Dh6wd2wN.js → policy-DrRKinMr.js} +1 -1
- package/dist/web/server/assets/{results-BWnu3gXP.js → results-fT2zyiJx.js} +1 -1
- package/dist/web/server/assets/review-CvUPk4HA.js +38 -0
- package/dist/web/server/assets/review-DYcYdUTv.js +859 -0
- package/dist/web/server/assets/review-packets-e36PsTSX.js +172 -0
- package/dist/web/server/assets/{router-Deq94UJQ.js → router-NYhuYQCd.js} +4 -4
- package/dist/web/server/assets/{routes-CVKkvFVv.js → routes-RdppWPiW.js} +1 -1
- package/dist/web/server/assets/{services-CEr61xb5.js → services-Dgu7dcTC.js} +1 -1
- package/dist/web/server/assets/{skills-BImC3LTO.js → skills-DL7UIWa8.js} +1 -1
- package/dist/web/server/assets/{teams-8zEIo08E.js → teams-Cmn7mdx9.js} +1 -1
- package/dist/web/server/assets/{teams-D-yaAWLV.js → teams-DiC-MBg4.js} +1 -1
- package/dist/web/server/assets/{telegram-CGl_LFtJ.js → telegram-CLOFnLjF.js} +1 -1
- package/dist/web/server/assets/{tokens-cB-uf7qm.js → tokens-BVva7GHu.js} +1 -1
- package/dist/web/server/assets/{triggers-CtSj79L0.js → triggers-D4orksJq.js} +1 -1
- package/dist/web/server/assets/{verification-B5QjcpIo.js → verification-C1SHMTX8.js} +1 -1
- package/dist/web/server/assets/{verifications-CUq_6ZqL.js → verifications-C_ycXrPK.js} +1 -1
- package/dist/web/server/assets/{verifications-BfQsfwSE.js → verifications-Ci49n2Km.js} +14 -1
- package/dist/web/server/server.js +75 -39
- package/dist/worker.js +528 -111
- package/dist/worker.js.map +1 -1
- package/package.json +3 -3
- package/dist/web/client/assets/ConfirmDialog-BzIiABOP.js +0 -1
- package/dist/web/client/assets/chevron-right-DSa4xPTs.js +0 -1
- package/dist/web/client/assets/createServerFn-Dzfjt7mA.js +0 -3
- package/dist/web/client/assets/index-Bi-HxcPG.js +0 -50
- package/dist/web/client/assets/review-AK9WGmpv.js +0 -1
- package/dist/web/client/assets/styles-C6br2xxl.css +0 -2
- package/dist/web/server/assets/review-DUe3vHPU.js +0 -393
- package/dist/web/server/assets/review-c_-cFi7H.js +0 -14
|
@@ -0,0 +1,859 @@
|
|
|
1
|
+
import { a as fetchReviewFileLink, c as recordReviewConclusion, i as fetchReviewExport, l as resolveReviewFinding, n as addReviewFinding, o as fetchReviewPacket, r as createReviewPacket, s as recordReportedState, t as Route } from "./review-CvUPk4HA.js";
|
|
2
|
+
import { a as fetchTeamSnapshot, i as fetchTeamReview, n as fetchFileDiff, o as prepareReviewFeedback, s as sendReviewFeedback, t as captureTeamSnapshot } from "./git-review-BB3M9nYg.js";
|
|
3
|
+
import { r as PageShell } from "./Page-Bz-ydB8j.js";
|
|
4
|
+
import { t as Button } from "./Button-Dsnw22OF.js";
|
|
5
|
+
import { a as referenceLabel, i as changeSummary, o as snapshotLabel, r as baseLabel, s as unavailableMessage } from "./git-review-presentation-TJiHJhen.js";
|
|
6
|
+
import { t as TeamTabs } from "./TeamTabs-Dg4v6x0-.js";
|
|
7
|
+
import { useState } from "react";
|
|
8
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
9
|
+
//#region src/components/ReviewPacketPanel.tsx
|
|
10
|
+
var SEVERITIES = [
|
|
11
|
+
"blocker",
|
|
12
|
+
"major",
|
|
13
|
+
"minor",
|
|
14
|
+
"info"
|
|
15
|
+
];
|
|
16
|
+
var CONCLUSIONS = [
|
|
17
|
+
"changes_requested",
|
|
18
|
+
"commented",
|
|
19
|
+
"recommended"
|
|
20
|
+
];
|
|
21
|
+
/**
|
|
22
|
+
* The completion facts, in the order they happen. Each is shown with the state it actually has: a review
|
|
23
|
+
* conclusion is not acceptance, and a reported state is what the operator said rather than something the
|
|
24
|
+
* daemon checked.
|
|
25
|
+
*/
|
|
26
|
+
var REPORTED_STATES = [
|
|
27
|
+
"committed",
|
|
28
|
+
"pushed",
|
|
29
|
+
"pullRequest",
|
|
30
|
+
"merged",
|
|
31
|
+
"deployed",
|
|
32
|
+
"productionAccepted"
|
|
33
|
+
];
|
|
34
|
+
function applicabilityLabel(comparison) {
|
|
35
|
+
return comparison === "identical" ? "unchanged since capture" : comparison === "changed" ? "changed since capture (never a pass)" : "not checked";
|
|
36
|
+
}
|
|
37
|
+
function ReviewPacketPanel({ teamId, view }) {
|
|
38
|
+
const [reports, setReports] = useState({});
|
|
39
|
+
const [busy, setBusy] = useState(false);
|
|
40
|
+
const [error, setError] = useState(null);
|
|
41
|
+
const [snapshotId, setSnapshotId] = useState(view.snapshots[0]?.id ?? "");
|
|
42
|
+
const [reviewer, setReviewer] = useState(view.members[0]?.id ?? "");
|
|
43
|
+
const [finding, setFinding] = useState({
|
|
44
|
+
path: "",
|
|
45
|
+
severity: "major",
|
|
46
|
+
note: ""
|
|
47
|
+
});
|
|
48
|
+
const [handoff, setHandoff] = useState(null);
|
|
49
|
+
const [link, setLink] = useState(null);
|
|
50
|
+
const [reference, setReference] = useState("");
|
|
51
|
+
const [reportedState, setReportedState] = useState("committed");
|
|
52
|
+
const [linkPath, setLinkPath] = useState("");
|
|
53
|
+
const run = async (action) => {
|
|
54
|
+
setBusy(true);
|
|
55
|
+
setError(null);
|
|
56
|
+
try {
|
|
57
|
+
const result = await action();
|
|
58
|
+
if ("report" in result && result.report) setReports((current) => ({
|
|
59
|
+
...current,
|
|
60
|
+
[result.report.packet.id]: result.report
|
|
61
|
+
}));
|
|
62
|
+
else if ("message" in result) setError(result);
|
|
63
|
+
} finally {
|
|
64
|
+
setBusy(false);
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
const create = () => run(() => createReviewPacket({ data: {
|
|
68
|
+
id: teamId,
|
|
69
|
+
snapshotId,
|
|
70
|
+
reviewerAgentId: reviewer || null
|
|
71
|
+
} }));
|
|
72
|
+
const load = (packetId) => run(() => fetchReviewPacket({ data: {
|
|
73
|
+
id: teamId,
|
|
74
|
+
packetId
|
|
75
|
+
} }));
|
|
76
|
+
const reportFor = (packetId) => reports[packetId];
|
|
77
|
+
return /* @__PURE__ */ jsxs("section", {
|
|
78
|
+
className: "space-y-3",
|
|
79
|
+
"aria-label": "Review packets",
|
|
80
|
+
children: [
|
|
81
|
+
/* @__PURE__ */ jsxs("div", {
|
|
82
|
+
className: "flex items-baseline justify-between gap-2",
|
|
83
|
+
children: [/* @__PURE__ */ jsx("h3", { children: "Review packets" }), /* @__PURE__ */ jsx("span", {
|
|
84
|
+
className: "muted",
|
|
85
|
+
children: "A packet binds one captured revision. Findings are recorded against it; resolving one needs an explicit decision or a named later revision."
|
|
86
|
+
})]
|
|
87
|
+
}),
|
|
88
|
+
/* @__PURE__ */ jsxs("div", {
|
|
89
|
+
className: "flex flex-wrap items-end gap-2",
|
|
90
|
+
children: [
|
|
91
|
+
/* @__PURE__ */ jsxs("label", {
|
|
92
|
+
className: "flex flex-col text-sm",
|
|
93
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
94
|
+
className: "muted",
|
|
95
|
+
children: "Revision"
|
|
96
|
+
}), /* @__PURE__ */ jsxs("select", {
|
|
97
|
+
value: snapshotId,
|
|
98
|
+
onChange: (event) => setSnapshotId(event.target.value),
|
|
99
|
+
className: "unstyled",
|
|
100
|
+
children: [view.snapshots.length === 0 ? /* @__PURE__ */ jsx("option", {
|
|
101
|
+
value: "",
|
|
102
|
+
children: "(none captured)"
|
|
103
|
+
}) : null, view.snapshots.map((snapshot) => /* @__PURE__ */ jsxs("option", {
|
|
104
|
+
value: snapshot.id,
|
|
105
|
+
children: [snapshot.id.slice(0, 12), snapshot.complete ? "" : " — INCOMPLETE"]
|
|
106
|
+
}, snapshot.id))]
|
|
107
|
+
})]
|
|
108
|
+
}),
|
|
109
|
+
/* @__PURE__ */ jsxs("label", {
|
|
110
|
+
className: "flex flex-col text-sm",
|
|
111
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
112
|
+
className: "muted",
|
|
113
|
+
children: "Reviewer (optional)"
|
|
114
|
+
}), /* @__PURE__ */ jsxs("select", {
|
|
115
|
+
value: reviewer,
|
|
116
|
+
onChange: (event) => setReviewer(event.target.value),
|
|
117
|
+
className: "unstyled",
|
|
118
|
+
children: [/* @__PURE__ */ jsx("option", {
|
|
119
|
+
value: "",
|
|
120
|
+
children: "none — nothing delegated"
|
|
121
|
+
}), view.members.map((member) => /* @__PURE__ */ jsx("option", {
|
|
122
|
+
value: member.id,
|
|
123
|
+
children: member.name
|
|
124
|
+
}, member.id))]
|
|
125
|
+
})]
|
|
126
|
+
}),
|
|
127
|
+
/* @__PURE__ */ jsx(Button, {
|
|
128
|
+
variant: "primary",
|
|
129
|
+
disabled: busy || !snapshotId,
|
|
130
|
+
onClick: create,
|
|
131
|
+
children: "Open packet"
|
|
132
|
+
})
|
|
133
|
+
]
|
|
134
|
+
}),
|
|
135
|
+
error ? /* @__PURE__ */ jsx("p", {
|
|
136
|
+
role: "alert",
|
|
137
|
+
className: "rounded-sm border border-fawn p-2 text-sm",
|
|
138
|
+
children: error.message
|
|
139
|
+
}) : null,
|
|
140
|
+
view.packets.length === 0 ? /* @__PURE__ */ jsx("p", {
|
|
141
|
+
className: "muted",
|
|
142
|
+
children: "No review packets yet."
|
|
143
|
+
}) : /* @__PURE__ */ jsx("ul", {
|
|
144
|
+
className: "list",
|
|
145
|
+
children: view.packets.map((entry) => {
|
|
146
|
+
const report = reportFor(entry.packet.id);
|
|
147
|
+
return /* @__PURE__ */ jsxs("li", {
|
|
148
|
+
className: "card space-y-2",
|
|
149
|
+
children: [
|
|
150
|
+
/* @__PURE__ */ jsxs("div", {
|
|
151
|
+
className: "flex flex-wrap items-baseline justify-between gap-2",
|
|
152
|
+
children: [/* @__PURE__ */ jsxs("div", { children: [
|
|
153
|
+
/* @__PURE__ */ jsx("strong", { children: entry.packet.state }),
|
|
154
|
+
" ",
|
|
155
|
+
/* @__PURE__ */ jsxs("span", {
|
|
156
|
+
className: "muted",
|
|
157
|
+
children: [
|
|
158
|
+
entry.packet.reviewerAgentId ?? "no reviewer",
|
|
159
|
+
" ·",
|
|
160
|
+
" ",
|
|
161
|
+
entry.packet.snapshot.id.slice(0, 12)
|
|
162
|
+
]
|
|
163
|
+
})
|
|
164
|
+
] }), /* @__PURE__ */ jsxs("div", {
|
|
165
|
+
className: "flex gap-2",
|
|
166
|
+
children: [/* @__PURE__ */ jsx(Button, {
|
|
167
|
+
variant: "ghost",
|
|
168
|
+
disabled: busy,
|
|
169
|
+
onClick: () => load(entry.packet.id),
|
|
170
|
+
children: "Details"
|
|
171
|
+
}), /* @__PURE__ */ jsx(Button, {
|
|
172
|
+
variant: "ghost",
|
|
173
|
+
disabled: busy,
|
|
174
|
+
onClick: async () => {
|
|
175
|
+
setBusy(true);
|
|
176
|
+
const result = await fetchReviewExport({ data: {
|
|
177
|
+
id: teamId,
|
|
178
|
+
packetId: entry.packet.id
|
|
179
|
+
} });
|
|
180
|
+
setBusy(false);
|
|
181
|
+
if ("handoff" in result) setHandoff({
|
|
182
|
+
packetId: entry.packet.id,
|
|
183
|
+
patch: result.patch,
|
|
184
|
+
text: result.handoff
|
|
185
|
+
});
|
|
186
|
+
else if ("message" in result) setError(result);
|
|
187
|
+
},
|
|
188
|
+
children: "Handoff"
|
|
189
|
+
})]
|
|
190
|
+
})]
|
|
191
|
+
}),
|
|
192
|
+
/* @__PURE__ */ jsxs("p", {
|
|
193
|
+
className: "muted",
|
|
194
|
+
children: [
|
|
195
|
+
entry.counts.findings,
|
|
196
|
+
" finding(s), ",
|
|
197
|
+
entry.counts.unresolved,
|
|
198
|
+
" unresolved",
|
|
199
|
+
entry.counts.blockers > 0 ? `, ${entry.counts.blockers} blocker(s)` : "",
|
|
200
|
+
" ·",
|
|
201
|
+
" ",
|
|
202
|
+
entry.conclusion ?? "no conclusion yet"
|
|
203
|
+
]
|
|
204
|
+
}),
|
|
205
|
+
handoff?.packetId === entry.packet.id ? /* @__PURE__ */ jsxs("div", {
|
|
206
|
+
className: "space-y-1",
|
|
207
|
+
children: [
|
|
208
|
+
/* @__PURE__ */ jsx("h4", { children: "Handoff" }),
|
|
209
|
+
/* @__PURE__ */ jsx("pre", {
|
|
210
|
+
className: "overflow-x-auto rounded-sm border border-fawn p-2 text-xs",
|
|
211
|
+
children: handoff.text
|
|
212
|
+
}),
|
|
213
|
+
handoff.patch ? /* @__PURE__ */ jsx("pre", {
|
|
214
|
+
className: "overflow-x-auto rounded-sm border border-fawn p-2 text-xs",
|
|
215
|
+
children: handoff.patch
|
|
216
|
+
}) : null,
|
|
217
|
+
/* @__PURE__ */ jsx(Button, {
|
|
218
|
+
variant: "ghost",
|
|
219
|
+
onClick: () => {
|
|
220
|
+
navigator.clipboard?.writeText(handoff.patch || handoff.text);
|
|
221
|
+
},
|
|
222
|
+
children: "Copy"
|
|
223
|
+
})
|
|
224
|
+
]
|
|
225
|
+
}) : null,
|
|
226
|
+
report ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
227
|
+
/* @__PURE__ */ jsxs("p", {
|
|
228
|
+
className: "muted",
|
|
229
|
+
children: ["applicability: ", applicabilityLabel(report.applicability.comparison)]
|
|
230
|
+
}),
|
|
231
|
+
/* @__PURE__ */ jsx("ul", { children: report.findings.map((item) => /* @__PURE__ */ jsxs("li", { children: [
|
|
232
|
+
/* @__PURE__ */ jsxs("span", {
|
|
233
|
+
className: "muted",
|
|
234
|
+
children: [
|
|
235
|
+
"[",
|
|
236
|
+
item.severity,
|
|
237
|
+
"]"
|
|
238
|
+
]
|
|
239
|
+
}),
|
|
240
|
+
" ",
|
|
241
|
+
/* @__PURE__ */ jsxs("code", { children: [item.path, item.lineStart === null ? "" : `:${item.lineStart}${item.lineEnd && item.lineEnd !== item.lineStart ? `-${item.lineEnd}` : ""}`] }),
|
|
242
|
+
" ",
|
|
243
|
+
"— ",
|
|
244
|
+
item.note,
|
|
245
|
+
item.resolution ? /* @__PURE__ */ jsxs("span", {
|
|
246
|
+
className: "muted",
|
|
247
|
+
children: [
|
|
248
|
+
" ",
|
|
249
|
+
"· resolved (",
|
|
250
|
+
item.resolution.kind,
|
|
251
|
+
") by ",
|
|
252
|
+
item.resolution.by.kind
|
|
253
|
+
]
|
|
254
|
+
}) : item.state === "unverified" ? /* @__PURE__ */ jsx("span", {
|
|
255
|
+
className: "muted",
|
|
256
|
+
children: " · UNVERIFIED — not correlated to this revision"
|
|
257
|
+
}) : /* @__PURE__ */ jsx(Button, {
|
|
258
|
+
variant: "ghost",
|
|
259
|
+
disabled: busy,
|
|
260
|
+
onClick: () => run(() => resolveReviewFinding({ data: {
|
|
261
|
+
id: teamId,
|
|
262
|
+
packetId: entry.packet.id,
|
|
263
|
+
findingId: item.id,
|
|
264
|
+
resolutionKind: "explicit",
|
|
265
|
+
resolutionNote: "resolved by the operator"
|
|
266
|
+
} })),
|
|
267
|
+
children: "Resolve explicitly"
|
|
268
|
+
})
|
|
269
|
+
] }, item.id)) }),
|
|
270
|
+
/* @__PURE__ */ jsxs("div", {
|
|
271
|
+
className: "flex flex-wrap items-end gap-2",
|
|
272
|
+
children: [
|
|
273
|
+
/* @__PURE__ */ jsxs("label", {
|
|
274
|
+
className: "flex flex-col text-sm",
|
|
275
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
276
|
+
className: "muted",
|
|
277
|
+
children: "Finding path"
|
|
278
|
+
}), /* @__PURE__ */ jsx("input", {
|
|
279
|
+
value: finding.path,
|
|
280
|
+
onChange: (event) => setFinding({
|
|
281
|
+
...finding,
|
|
282
|
+
path: event.target.value
|
|
283
|
+
})
|
|
284
|
+
})]
|
|
285
|
+
}),
|
|
286
|
+
/* @__PURE__ */ jsxs("label", {
|
|
287
|
+
className: "flex flex-col text-sm",
|
|
288
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
289
|
+
className: "muted",
|
|
290
|
+
children: "Severity"
|
|
291
|
+
}), /* @__PURE__ */ jsx("select", {
|
|
292
|
+
value: finding.severity,
|
|
293
|
+
onChange: (event) => setFinding({
|
|
294
|
+
...finding,
|
|
295
|
+
severity: event.target.value
|
|
296
|
+
}),
|
|
297
|
+
children: SEVERITIES.map((severity) => /* @__PURE__ */ jsx("option", {
|
|
298
|
+
value: severity,
|
|
299
|
+
children: severity
|
|
300
|
+
}, severity))
|
|
301
|
+
})]
|
|
302
|
+
}),
|
|
303
|
+
/* @__PURE__ */ jsxs("label", {
|
|
304
|
+
className: "flex flex-col grow text-sm",
|
|
305
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
306
|
+
className: "muted",
|
|
307
|
+
children: "Note"
|
|
308
|
+
}), /* @__PURE__ */ jsx("input", {
|
|
309
|
+
value: finding.note,
|
|
310
|
+
onChange: (event) => setFinding({
|
|
311
|
+
...finding,
|
|
312
|
+
note: event.target.value
|
|
313
|
+
})
|
|
314
|
+
})]
|
|
315
|
+
}),
|
|
316
|
+
/* @__PURE__ */ jsx(Button, {
|
|
317
|
+
variant: "ghost",
|
|
318
|
+
disabled: busy || !finding.path || !finding.note,
|
|
319
|
+
onClick: () => run(() => addReviewFinding({ data: {
|
|
320
|
+
id: teamId,
|
|
321
|
+
packetId: entry.packet.id,
|
|
322
|
+
path: finding.path,
|
|
323
|
+
severity: finding.severity,
|
|
324
|
+
note: finding.note
|
|
325
|
+
} })),
|
|
326
|
+
children: "Add finding"
|
|
327
|
+
})
|
|
328
|
+
]
|
|
329
|
+
}),
|
|
330
|
+
/* @__PURE__ */ jsxs("div", {
|
|
331
|
+
className: "flex flex-wrap items-center gap-2",
|
|
332
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
333
|
+
className: "muted",
|
|
334
|
+
children: "Conclusion:"
|
|
335
|
+
}), CONCLUSIONS.map((conclusion) => /* @__PURE__ */ jsx(Button, {
|
|
336
|
+
variant: "ghost",
|
|
337
|
+
disabled: busy,
|
|
338
|
+
onClick: () => run(() => recordReviewConclusion({ data: {
|
|
339
|
+
id: teamId,
|
|
340
|
+
packetId: entry.packet.id,
|
|
341
|
+
conclusion
|
|
342
|
+
} })),
|
|
343
|
+
children: conclusion
|
|
344
|
+
}, conclusion))]
|
|
345
|
+
}),
|
|
346
|
+
/* @__PURE__ */ jsxs("div", {
|
|
347
|
+
className: "space-y-1",
|
|
348
|
+
children: [
|
|
349
|
+
/* @__PURE__ */ jsx("span", {
|
|
350
|
+
className: "muted",
|
|
351
|
+
children: "Where a file link points. The workspace belongs to the machine running the daemon, so this says which host it names and whether it is the reviewed revision."
|
|
352
|
+
}),
|
|
353
|
+
/* @__PURE__ */ jsxs("div", {
|
|
354
|
+
className: "flex flex-wrap items-center gap-2",
|
|
355
|
+
children: [
|
|
356
|
+
/* @__PURE__ */ jsx("input", {
|
|
357
|
+
placeholder: "changed path",
|
|
358
|
+
value: linkPath,
|
|
359
|
+
onChange: (event) => setLinkPath(event.target.value)
|
|
360
|
+
}),
|
|
361
|
+
/* @__PURE__ */ jsx(Button, {
|
|
362
|
+
variant: "ghost",
|
|
363
|
+
disabled: busy || !linkPath,
|
|
364
|
+
onClick: async () => {
|
|
365
|
+
const result = await fetchReviewFileLink({ data: {
|
|
366
|
+
id: teamId,
|
|
367
|
+
packetId: entry.packet.id,
|
|
368
|
+
path: linkPath
|
|
369
|
+
} });
|
|
370
|
+
if ("link" in result) setLink({
|
|
371
|
+
packetId: entry.packet.id,
|
|
372
|
+
link: result.link
|
|
373
|
+
});
|
|
374
|
+
else if ("message" in result) setError(result);
|
|
375
|
+
},
|
|
376
|
+
children: "Resolve location"
|
|
377
|
+
}),
|
|
378
|
+
link?.packetId === entry.packet.id ? /* @__PURE__ */ jsx(Button, {
|
|
379
|
+
variant: "ghost",
|
|
380
|
+
onClick: () => void navigator.clipboard?.writeText(link.link.copyTarget),
|
|
381
|
+
children: "Copy location"
|
|
382
|
+
}) : null
|
|
383
|
+
]
|
|
384
|
+
}),
|
|
385
|
+
link?.packetId === entry.packet.id ? /* @__PURE__ */ jsxs("p", {
|
|
386
|
+
className: "muted",
|
|
387
|
+
children: [
|
|
388
|
+
/* @__PURE__ */ jsx("code", { children: link.link.copyTarget }),
|
|
389
|
+
" · on",
|
|
390
|
+
" ",
|
|
391
|
+
link.link.host.daemon ?? "the daemon host",
|
|
392
|
+
" ·",
|
|
393
|
+
" ",
|
|
394
|
+
link.link.mode === "live" ? "the reviewed revision" : link.link.mode === "stale" ? "the CURRENT file, not the reviewed revision" : "unknown",
|
|
395
|
+
" ",
|
|
396
|
+
"·",
|
|
397
|
+
" ",
|
|
398
|
+
link.link.canOpen ? `an editor is configured on the daemon host (${link.link.command})` : "no editor configured, so nothing can be opened here"
|
|
399
|
+
]
|
|
400
|
+
}) : null
|
|
401
|
+
]
|
|
402
|
+
}),
|
|
403
|
+
/* @__PURE__ */ jsxs("p", {
|
|
404
|
+
className: "muted",
|
|
405
|
+
children: [
|
|
406
|
+
"completed: change prepared=",
|
|
407
|
+
String(report.facts.changePrepared),
|
|
408
|
+
" checks current=",
|
|
409
|
+
String(report.facts.checksCurrent),
|
|
410
|
+
" reviewed=",
|
|
411
|
+
String(report.facts.reviewed),
|
|
412
|
+
" — a conclusion is not acceptance, and nothing here commits, pushes, merges or deploys."
|
|
413
|
+
]
|
|
414
|
+
}),
|
|
415
|
+
/* @__PURE__ */ jsxs("div", {
|
|
416
|
+
className: "space-y-1",
|
|
417
|
+
children: [
|
|
418
|
+
/* @__PURE__ */ jsx("span", {
|
|
419
|
+
className: "muted",
|
|
420
|
+
children: "Beyond this point nothing is verified: Bazilion has no code-host integration, so these are whatever you report."
|
|
421
|
+
}),
|
|
422
|
+
/* @__PURE__ */ jsxs("div", {
|
|
423
|
+
className: "flex flex-wrap items-center gap-2",
|
|
424
|
+
children: [
|
|
425
|
+
/* @__PURE__ */ jsx("select", {
|
|
426
|
+
className: "unstyled",
|
|
427
|
+
value: reportedState,
|
|
428
|
+
onChange: (event) => setReportedState(event.target.value),
|
|
429
|
+
children: REPORTED_STATES.map((state) => /* @__PURE__ */ jsx("option", {
|
|
430
|
+
value: state,
|
|
431
|
+
children: state
|
|
432
|
+
}, state))
|
|
433
|
+
}),
|
|
434
|
+
/* @__PURE__ */ jsx("input", {
|
|
435
|
+
placeholder: "commit id, URL, release name…",
|
|
436
|
+
value: reference,
|
|
437
|
+
onChange: (event) => setReference(event.target.value)
|
|
438
|
+
}),
|
|
439
|
+
/* @__PURE__ */ jsx(Button, {
|
|
440
|
+
variant: "ghost",
|
|
441
|
+
disabled: busy,
|
|
442
|
+
onClick: () => run(() => recordReportedState({ data: {
|
|
443
|
+
id: teamId,
|
|
444
|
+
packetId: entry.packet.id,
|
|
445
|
+
state: reportedState,
|
|
446
|
+
reference: reference || null
|
|
447
|
+
} })),
|
|
448
|
+
children: "Report"
|
|
449
|
+
})
|
|
450
|
+
]
|
|
451
|
+
}),
|
|
452
|
+
/* @__PURE__ */ jsxs("p", {
|
|
453
|
+
className: "muted",
|
|
454
|
+
children: [
|
|
455
|
+
"reported (reported, not verified):",
|
|
456
|
+
" ",
|
|
457
|
+
Object.entries(report.packet.reported).filter(([, value]) => value !== null).map(([key, value]) => `${key}=${value}`).join(" ") || "nothing yet"
|
|
458
|
+
]
|
|
459
|
+
})
|
|
460
|
+
]
|
|
461
|
+
})
|
|
462
|
+
] }) : null
|
|
463
|
+
]
|
|
464
|
+
}, entry.packet.id);
|
|
465
|
+
})
|
|
466
|
+
})
|
|
467
|
+
]
|
|
468
|
+
});
|
|
469
|
+
}
|
|
470
|
+
//#endregion
|
|
471
|
+
//#region src/routes/teams/$id/review.tsx?tsr-split=component
|
|
472
|
+
function ReviewPage() {
|
|
473
|
+
const loaded = Route.useLoaderData();
|
|
474
|
+
const teamId = loaded.team.id;
|
|
475
|
+
const [base, setBase] = useState("");
|
|
476
|
+
const [appliedBase, setAppliedBase] = useState("");
|
|
477
|
+
const [review, setReview] = useState(loaded.review);
|
|
478
|
+
const [unavailable, setUnavailable] = useState(loaded.unavailable);
|
|
479
|
+
const [snapshots, setSnapshots] = useState(loaded.snapshots);
|
|
480
|
+
const [selected, setSelected] = useState(null);
|
|
481
|
+
const [diff, setDiff] = useState(null);
|
|
482
|
+
const [snapshot, setSnapshot] = useState(null);
|
|
483
|
+
const [latestSnapshotId, setLatestSnapshotId] = useState(() => loaded.snapshots[0]?.snapshotId ?? null);
|
|
484
|
+
const [note, setNote] = useState("");
|
|
485
|
+
const [agentId, setAgentId] = useState(() => loaded.members[0]?.id ?? "");
|
|
486
|
+
const [composed, setComposed] = useState(null);
|
|
487
|
+
const [status, setStatus] = useState(null);
|
|
488
|
+
const [busy, setBusy] = useState(false);
|
|
489
|
+
async function load(nextBase = appliedBase) {
|
|
490
|
+
setBusy(true);
|
|
491
|
+
setStatus({
|
|
492
|
+
kind: "info",
|
|
493
|
+
message: "Loading changes…"
|
|
494
|
+
});
|
|
495
|
+
try {
|
|
496
|
+
const data = await fetchTeamReview({ data: {
|
|
497
|
+
id: teamId,
|
|
498
|
+
...nextBase ? { base: nextBase } : {}
|
|
499
|
+
} });
|
|
500
|
+
if (!data) return;
|
|
501
|
+
setReview(data.review);
|
|
502
|
+
setUnavailable(data.unavailable);
|
|
503
|
+
setSnapshots(data.snapshots);
|
|
504
|
+
setAppliedBase(nextBase);
|
|
505
|
+
setSelected(null);
|
|
506
|
+
setDiff(null);
|
|
507
|
+
setStatus(null);
|
|
508
|
+
} finally {
|
|
509
|
+
setBusy(false);
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
async function openDiff(path) {
|
|
513
|
+
setSelected(path);
|
|
514
|
+
setDiff(null);
|
|
515
|
+
setStatus({
|
|
516
|
+
kind: "info",
|
|
517
|
+
message: "Loading diff…"
|
|
518
|
+
});
|
|
519
|
+
setDiff(await fetchFileDiff({ data: {
|
|
520
|
+
id: teamId,
|
|
521
|
+
path,
|
|
522
|
+
...appliedBase ? { base: appliedBase } : {}
|
|
523
|
+
} }));
|
|
524
|
+
setStatus(null);
|
|
525
|
+
}
|
|
526
|
+
async function capture() {
|
|
527
|
+
setBusy(true);
|
|
528
|
+
setStatus({
|
|
529
|
+
kind: "info",
|
|
530
|
+
message: "Capturing a source snapshot…"
|
|
531
|
+
});
|
|
532
|
+
const result = await captureTeamSnapshot({ data: { id: teamId } });
|
|
533
|
+
if ("reference" in result) {
|
|
534
|
+
setStatus({
|
|
535
|
+
kind: "info",
|
|
536
|
+
message: `Captured ${referenceLabel(result.reference)}`
|
|
537
|
+
});
|
|
538
|
+
await load();
|
|
539
|
+
} else setStatus({
|
|
540
|
+
kind: "error",
|
|
541
|
+
message: unavailableMessage(result.code, result.message)
|
|
542
|
+
});
|
|
543
|
+
setBusy(false);
|
|
544
|
+
}
|
|
545
|
+
async function prepare() {
|
|
546
|
+
if (!selected) return;
|
|
547
|
+
setBusy(true);
|
|
548
|
+
setStatus({
|
|
549
|
+
kind: "info",
|
|
550
|
+
message: "Preparing feedback…"
|
|
551
|
+
});
|
|
552
|
+
const result = await prepareReviewFeedback({ data: {
|
|
553
|
+
id: teamId,
|
|
554
|
+
path: selected,
|
|
555
|
+
...latestSnapshotId ? { snapshotId: latestSnapshotId } : {},
|
|
556
|
+
...note.trim() ? { note } : {}
|
|
557
|
+
} });
|
|
558
|
+
if ("message" in result && "reference" in result) {
|
|
559
|
+
setComposed(result);
|
|
560
|
+
setStatus(null);
|
|
561
|
+
} else setStatus({
|
|
562
|
+
kind: "error",
|
|
563
|
+
message: unavailableMessage(result.code, result.message)
|
|
564
|
+
});
|
|
565
|
+
setBusy(false);
|
|
566
|
+
}
|
|
567
|
+
async function send() {
|
|
568
|
+
if (!composed || !agentId) return;
|
|
569
|
+
setBusy(true);
|
|
570
|
+
const result = await sendReviewFeedback({ data: {
|
|
571
|
+
agentId,
|
|
572
|
+
message: composed.message
|
|
573
|
+
} });
|
|
574
|
+
setStatus("queued" in result ? {
|
|
575
|
+
kind: "info",
|
|
576
|
+
message: "Feedback queued for the Agent. It runs as the next turn."
|
|
577
|
+
} : {
|
|
578
|
+
kind: "error",
|
|
579
|
+
message: unavailableMessage(result.code, result.message)
|
|
580
|
+
});
|
|
581
|
+
if ("queued" in result) setComposed(null);
|
|
582
|
+
setBusy(false);
|
|
583
|
+
}
|
|
584
|
+
async function openSnapshot(snapshotId) {
|
|
585
|
+
setStatus({
|
|
586
|
+
kind: "info",
|
|
587
|
+
message: "Loading snapshot…"
|
|
588
|
+
});
|
|
589
|
+
const loadedSnapshot = await fetchTeamSnapshot({ data: {
|
|
590
|
+
id: teamId,
|
|
591
|
+
snapshotId
|
|
592
|
+
} });
|
|
593
|
+
setSnapshot(loadedSnapshot);
|
|
594
|
+
setStatus(loadedSnapshot ? null : {
|
|
595
|
+
kind: "error",
|
|
596
|
+
message: "That snapshot is no longer retained."
|
|
597
|
+
});
|
|
598
|
+
}
|
|
599
|
+
const changes = review?.changes;
|
|
600
|
+
return /* @__PURE__ */ jsxs(PageShell, { children: [
|
|
601
|
+
/* @__PURE__ */ jsxs("header", { children: [/* @__PURE__ */ jsxs("h1", { children: [loaded.team.name || loaded.team.id, " review"] }), /* @__PURE__ */ jsx("p", { children: "Changes since a pinned baseline, and the source snapshots taken for them. Inspection is read-only — nothing here stages, commits or reverts anything." })] }),
|
|
602
|
+
/* @__PURE__ */ jsx(TeamTabs, { teamId }),
|
|
603
|
+
/* @__PURE__ */ jsxs("section", {
|
|
604
|
+
className: "space-y-2",
|
|
605
|
+
"aria-label": "Comparison base",
|
|
606
|
+
children: [
|
|
607
|
+
/* @__PURE__ */ jsxs("div", {
|
|
608
|
+
className: "flex flex-col gap-2 sm:flex-row sm:items-end",
|
|
609
|
+
children: [/* @__PURE__ */ jsxs("label", {
|
|
610
|
+
className: "flex min-w-0 flex-1 flex-col gap-1",
|
|
611
|
+
children: [/* @__PURE__ */ jsx("span", { children: "Comparison base" }), /* @__PURE__ */ jsx("input", {
|
|
612
|
+
className: "input",
|
|
613
|
+
value: base,
|
|
614
|
+
placeholder: "HEAD",
|
|
615
|
+
onChange: (event) => setBase(event.target.value),
|
|
616
|
+
onKeyDown: (event) => {
|
|
617
|
+
if (event.key === "Enter") load(base);
|
|
618
|
+
}
|
|
619
|
+
})]
|
|
620
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
621
|
+
className: "flex gap-2",
|
|
622
|
+
children: [/* @__PURE__ */ jsx(Button, {
|
|
623
|
+
variant: "ghost",
|
|
624
|
+
disabled: busy,
|
|
625
|
+
onClick: () => void load(base),
|
|
626
|
+
children: "Apply base"
|
|
627
|
+
}), /* @__PURE__ */ jsx(Button, {
|
|
628
|
+
variant: "primary",
|
|
629
|
+
disabled: busy,
|
|
630
|
+
onClick: () => void load(),
|
|
631
|
+
children: "Refresh"
|
|
632
|
+
})]
|
|
633
|
+
})]
|
|
634
|
+
}),
|
|
635
|
+
changes && /* @__PURE__ */ jsx("p", {
|
|
636
|
+
className: "text-sm opacity-80",
|
|
637
|
+
children: baseLabel(changes.identity, changes)
|
|
638
|
+
}),
|
|
639
|
+
/* @__PURE__ */ jsx("p", {
|
|
640
|
+
className: "text-xs opacity-70",
|
|
641
|
+
children: "A branch name is resolved to a concrete commit when the review loads, so a moving tip cannot rewrite what you are looking at."
|
|
642
|
+
})
|
|
643
|
+
]
|
|
644
|
+
}),
|
|
645
|
+
status && /* @__PURE__ */ jsx("p", {
|
|
646
|
+
role: status.kind === "error" ? "alert" : "status",
|
|
647
|
+
className: "text-sm",
|
|
648
|
+
children: status.message
|
|
649
|
+
}),
|
|
650
|
+
unavailable && /* @__PURE__ */ jsxs("section", {
|
|
651
|
+
className: "rounded-sm border border-fawn bg-ivory p-3",
|
|
652
|
+
"aria-label": "Review unavailable",
|
|
653
|
+
children: [/* @__PURE__ */ jsx("p", {
|
|
654
|
+
role: "alert",
|
|
655
|
+
children: unavailableMessage(unavailable.code, unavailable.message)
|
|
656
|
+
}), unavailable.code && /* @__PURE__ */ jsxs("p", {
|
|
657
|
+
className: "text-xs opacity-70",
|
|
658
|
+
children: ["code: ", unavailable.code]
|
|
659
|
+
})]
|
|
660
|
+
}),
|
|
661
|
+
changes && /* @__PURE__ */ jsxs("section", {
|
|
662
|
+
className: "space-y-2",
|
|
663
|
+
"aria-label": "Changes since baseline",
|
|
664
|
+
children: [
|
|
665
|
+
/* @__PURE__ */ jsx("h2", { children: "Changes since baseline" }),
|
|
666
|
+
changes.changes.length === 0 && /* @__PURE__ */ jsx("p", { children: "No changes since this baseline." }),
|
|
667
|
+
changes.changes.length > 0 && /* @__PURE__ */ jsx("ul", {
|
|
668
|
+
className: "divide-y divide-fawn rounded-sm border border-fawn",
|
|
669
|
+
children: changes.changes.map((change) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs("button", {
|
|
670
|
+
type: "button",
|
|
671
|
+
"aria-current": selected === change.path ? "true" : void 0,
|
|
672
|
+
onClick: () => void openDiff(change.path),
|
|
673
|
+
className: "flex w-full flex-col gap-1 px-3 py-2 text-left hover:bg-sapphire-glow focus:bg-sapphire-glow",
|
|
674
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
675
|
+
className: "break-all font-mono text-sm",
|
|
676
|
+
children: change.previousPath ? `${change.previousPath} → ${change.path}` : change.path
|
|
677
|
+
}), /* @__PURE__ */ jsxs("span", {
|
|
678
|
+
className: "text-xs opacity-80",
|
|
679
|
+
children: [changeSummary(change), change.patchTruncated ? " · diff truncated" : ""]
|
|
680
|
+
})]
|
|
681
|
+
}) }, `${change.status}:${change.path}`))
|
|
682
|
+
}),
|
|
683
|
+
changes.truncated && /* @__PURE__ */ jsx("p", {
|
|
684
|
+
className: "text-sm",
|
|
685
|
+
children: "This list is incomplete: more files changed than the review limit allows."
|
|
686
|
+
}),
|
|
687
|
+
(changes.withheld.excluded > 0 || changes.withheld.untracked > 0) && /* @__PURE__ */ jsxs("p", {
|
|
688
|
+
className: "text-xs opacity-80",
|
|
689
|
+
children: [
|
|
690
|
+
changes.withheld.excluded,
|
|
691
|
+
" excluded and ",
|
|
692
|
+
changes.withheld.untracked,
|
|
693
|
+
" untracked path(s) withheld by scope policy."
|
|
694
|
+
]
|
|
695
|
+
}),
|
|
696
|
+
changes.issues.map((issue) => /* @__PURE__ */ jsxs("p", {
|
|
697
|
+
className: "text-xs opacity-80",
|
|
698
|
+
children: [
|
|
699
|
+
"note: ",
|
|
700
|
+
issue.code,
|
|
701
|
+
": ",
|
|
702
|
+
issue.message
|
|
703
|
+
]
|
|
704
|
+
}, `${issue.code}:${issue.message}`))
|
|
705
|
+
]
|
|
706
|
+
}),
|
|
707
|
+
selected && /* @__PURE__ */ jsxs("section", {
|
|
708
|
+
className: "space-y-2",
|
|
709
|
+
"aria-label": "Selected file diff",
|
|
710
|
+
children: [
|
|
711
|
+
/* @__PURE__ */ jsx("h2", {
|
|
712
|
+
className: "break-all font-mono text-base",
|
|
713
|
+
children: selected
|
|
714
|
+
}),
|
|
715
|
+
diff === null ? /* @__PURE__ */ jsx("p", {
|
|
716
|
+
className: "text-sm",
|
|
717
|
+
children: "Loading…"
|
|
718
|
+
}) : diff.patch === null ? /* @__PURE__ */ jsxs("p", {
|
|
719
|
+
className: "text-sm",
|
|
720
|
+
children: [
|
|
721
|
+
"No diff text for this file",
|
|
722
|
+
diff.omitted ? ` (${diff.omitted.replaceAll("_", " ")})` : "",
|
|
723
|
+
"."
|
|
724
|
+
]
|
|
725
|
+
}) : /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("pre", {
|
|
726
|
+
className: "max-h-96 overflow-auto whitespace-pre-wrap break-words rounded-sm bg-[rgba(42,31,22,0.04)] p-3 font-mono text-xs",
|
|
727
|
+
children: diff.patch
|
|
728
|
+
}), diff.truncated && /* @__PURE__ */ jsx("p", {
|
|
729
|
+
className: "text-xs",
|
|
730
|
+
children: "This diff was truncated at the patch limit."
|
|
731
|
+
})] }),
|
|
732
|
+
/* @__PURE__ */ jsxs("div", {
|
|
733
|
+
className: "space-y-2 rounded-sm border border-fawn p-3",
|
|
734
|
+
children: [
|
|
735
|
+
/* @__PURE__ */ jsx("h3", { children: "Send feedback about this file" }),
|
|
736
|
+
/* @__PURE__ */ jsxs("label", {
|
|
737
|
+
className: "flex flex-col gap-1",
|
|
738
|
+
children: [/* @__PURE__ */ jsx("span", { children: "Note (optional)" }), /* @__PURE__ */ jsx("textarea", {
|
|
739
|
+
className: "input",
|
|
740
|
+
rows: 2,
|
|
741
|
+
value: note,
|
|
742
|
+
onChange: (event) => setNote(event.target.value)
|
|
743
|
+
})]
|
|
744
|
+
}),
|
|
745
|
+
/* @__PURE__ */ jsxs("label", {
|
|
746
|
+
className: "flex flex-col gap-1",
|
|
747
|
+
children: [/* @__PURE__ */ jsx("span", { children: "Agent" }), /* @__PURE__ */ jsx("select", {
|
|
748
|
+
className: "input",
|
|
749
|
+
value: agentId,
|
|
750
|
+
onChange: (event) => setAgentId(event.target.value),
|
|
751
|
+
children: loaded.members.map((member) => /* @__PURE__ */ jsx("option", {
|
|
752
|
+
value: member.id,
|
|
753
|
+
children: member.name
|
|
754
|
+
}, member.id))
|
|
755
|
+
})]
|
|
756
|
+
}),
|
|
757
|
+
/* @__PURE__ */ jsxs("div", {
|
|
758
|
+
className: "flex flex-wrap gap-2",
|
|
759
|
+
children: [/* @__PURE__ */ jsx(Button, {
|
|
760
|
+
variant: "ghost",
|
|
761
|
+
disabled: busy,
|
|
762
|
+
onClick: () => void prepare(),
|
|
763
|
+
children: "Preview message"
|
|
764
|
+
}), /* @__PURE__ */ jsx(Button, {
|
|
765
|
+
variant: "primary",
|
|
766
|
+
disabled: busy || !composed || !agentId,
|
|
767
|
+
onClick: () => void send(),
|
|
768
|
+
children: "Queue for Agent"
|
|
769
|
+
})]
|
|
770
|
+
}),
|
|
771
|
+
latestSnapshotId ? /* @__PURE__ */ jsxs("p", {
|
|
772
|
+
className: "text-xs opacity-70",
|
|
773
|
+
children: [
|
|
774
|
+
"Referenced snapshot: ",
|
|
775
|
+
latestSnapshotId.slice(0, 12),
|
|
776
|
+
". It is rechecked now, and the verdict is stated in the message."
|
|
777
|
+
]
|
|
778
|
+
}) : /* @__PURE__ */ jsx("p", {
|
|
779
|
+
className: "text-xs opacity-70",
|
|
780
|
+
children: "No snapshot captured for this Team yet, so the feedback will say its source identity is unknown rather than implying the lines still match."
|
|
781
|
+
}),
|
|
782
|
+
composed && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("p", {
|
|
783
|
+
className: "text-sm",
|
|
784
|
+
children: composed.applicability === "current" ? "This file is unchanged since the snapshot." : composed.applicability === "stale" ? "This file changed since the snapshot — the selected lines may have moved." : `Source identity unknown (${composed.applicabilityReason}).`
|
|
785
|
+
}), /* @__PURE__ */ jsx("pre", {
|
|
786
|
+
className: "max-h-64 overflow-auto whitespace-pre-wrap break-words rounded-sm bg-[rgba(42,31,22,0.04)] p-3 font-mono text-xs",
|
|
787
|
+
children: composed.message
|
|
788
|
+
})] })
|
|
789
|
+
]
|
|
790
|
+
})
|
|
791
|
+
]
|
|
792
|
+
}),
|
|
793
|
+
/* @__PURE__ */ jsxs("section", {
|
|
794
|
+
className: "space-y-2",
|
|
795
|
+
"aria-label": "Source snapshots",
|
|
796
|
+
children: [
|
|
797
|
+
/* @__PURE__ */ jsxs("div", {
|
|
798
|
+
className: "flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between",
|
|
799
|
+
children: [/* @__PURE__ */ jsx("h2", { children: "Source snapshots" }), /* @__PURE__ */ jsx(Button, {
|
|
800
|
+
variant: "ghost",
|
|
801
|
+
disabled: busy,
|
|
802
|
+
onClick: () => void capture(),
|
|
803
|
+
children: "Capture snapshot"
|
|
804
|
+
})]
|
|
805
|
+
}),
|
|
806
|
+
/* @__PURE__ */ jsx("p", {
|
|
807
|
+
className: "text-xs opacity-70",
|
|
808
|
+
children: "A snapshot records HEAD, the index and digests of changed files — never file content. Untracked content is only included when a path is named explicitly."
|
|
809
|
+
}),
|
|
810
|
+
snapshots.length === 0 && /* @__PURE__ */ jsx("p", { children: "No retained snapshots for this Team." }),
|
|
811
|
+
snapshots.length > 0 && /* @__PURE__ */ jsx("ul", {
|
|
812
|
+
className: "divide-y divide-fawn rounded-sm border border-fawn",
|
|
813
|
+
children: snapshots.map((entry) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx("button", {
|
|
814
|
+
type: "button",
|
|
815
|
+
onClick: () => void openSnapshot(entry.snapshotId),
|
|
816
|
+
className: "w-full px-3 py-2 text-left font-mono text-xs hover:bg-sapphire-glow focus:bg-sapphire-glow",
|
|
817
|
+
children: snapshotLabel(entry)
|
|
818
|
+
}) }, entry.snapshotId))
|
|
819
|
+
}),
|
|
820
|
+
snapshot && /* @__PURE__ */ jsxs("div", {
|
|
821
|
+
className: "space-y-1",
|
|
822
|
+
children: [
|
|
823
|
+
/* @__PURE__ */ jsxs("p", {
|
|
824
|
+
className: "text-sm",
|
|
825
|
+
children: [
|
|
826
|
+
snapshot.id.slice(0, 12),
|
|
827
|
+
" · ",
|
|
828
|
+
snapshot.complete ? "complete" : "incomplete — applicability unknown",
|
|
829
|
+
" · head ",
|
|
830
|
+
snapshot.head?.slice(0, 12) ?? "(unborn)"
|
|
831
|
+
]
|
|
832
|
+
}),
|
|
833
|
+
snapshot.entries.length > 0 && /* @__PURE__ */ jsx("ul", {
|
|
834
|
+
className: "space-y-1 font-mono text-xs",
|
|
835
|
+
children: snapshot.entries.map((entry) => /* @__PURE__ */ jsxs("li", { children: [
|
|
836
|
+
entry.layer,
|
|
837
|
+
" · ",
|
|
838
|
+
entry.kind,
|
|
839
|
+
" · ",
|
|
840
|
+
entry.path,
|
|
841
|
+
entry.bytes === null ? "" : ` · ${entry.bytes}B`
|
|
842
|
+
] }, `${entry.layer}:${entry.path}`))
|
|
843
|
+
}),
|
|
844
|
+
snapshot.exclusions.length > 0 && /* @__PURE__ */ jsxs("p", {
|
|
845
|
+
className: "text-xs opacity-80",
|
|
846
|
+
children: ["withheld: ", snapshot.exclusions.map((item) => `${item.path} (${item.reason})`).join(", ")]
|
|
847
|
+
})
|
|
848
|
+
]
|
|
849
|
+
})
|
|
850
|
+
]
|
|
851
|
+
}),
|
|
852
|
+
loaded.packets ? /* @__PURE__ */ jsx(ReviewPacketPanel, {
|
|
853
|
+
teamId,
|
|
854
|
+
view: loaded.packets
|
|
855
|
+
}) : null
|
|
856
|
+
] });
|
|
857
|
+
}
|
|
858
|
+
//#endregion
|
|
859
|
+
export { ReviewPage as component };
|