dsh-auto-review 0.4.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.
Files changed (84) hide show
  1. package/CHANGELOG.md +91 -0
  2. package/LICENSE +201 -0
  3. package/README.es.md +226 -0
  4. package/README.hi.md +226 -0
  5. package/README.md +226 -0
  6. package/README.pt.md +226 -0
  7. package/README.zh.md +226 -0
  8. package/cordis.patch.yml +27 -0
  9. package/lib/client.js +494 -0
  10. package/lib/client.js.map +1 -0
  11. package/lib/events-CFl6CHZi.js +344 -0
  12. package/lib/index.js +5305 -0
  13. package/lib/invariant.js +223 -0
  14. package/lib/types/client/ReviewPanel.d.ts +29 -0
  15. package/lib/types/client/ReviewPanel.d.ts.map +1 -0
  16. package/lib/types/client/ReviewPanel.js +63 -0
  17. package/lib/types/client/ReviewPanel.js.map +1 -0
  18. package/lib/types/client/index.d.ts +31 -0
  19. package/lib/types/client/index.d.ts.map +1 -0
  20. package/lib/types/client/index.js +51 -0
  21. package/lib/types/client/index.js.map +1 -0
  22. package/lib/types/client/locales.d.ts +49 -0
  23. package/lib/types/client/locales.d.ts.map +1 -0
  24. package/lib/types/client/locales.js +82 -0
  25. package/lib/types/client/locales.js.map +1 -0
  26. package/lib/types/client/present.d.ts +25 -0
  27. package/lib/types/client/present.d.ts.map +1 -0
  28. package/lib/types/client/present.js +36 -0
  29. package/lib/types/client/present.js.map +1 -0
  30. package/lib/types/client/styles.d.ts +9 -0
  31. package/lib/types/client/styles.d.ts.map +1 -0
  32. package/lib/types/client/styles.js +130 -0
  33. package/lib/types/client/styles.js.map +1 -0
  34. package/lib/types/config.d.ts +200 -0
  35. package/lib/types/config.d.ts.map +1 -0
  36. package/lib/types/config.js +154 -0
  37. package/lib/types/config.js.map +1 -0
  38. package/lib/types/events.d.ts +347 -0
  39. package/lib/types/events.d.ts.map +1 -0
  40. package/lib/types/events.js +369 -0
  41. package/lib/types/events.js.map +1 -0
  42. package/lib/types/index.d.ts +26 -0
  43. package/lib/types/index.d.ts.map +1 -0
  44. package/lib/types/index.js +26 -0
  45. package/lib/types/index.js.map +1 -0
  46. package/lib/types/invariant.d.ts +28 -0
  47. package/lib/types/invariant.d.ts.map +1 -0
  48. package/lib/types/invariant.js +306 -0
  49. package/lib/types/invariant.js.map +1 -0
  50. package/lib/types/messages.d.ts +38 -0
  51. package/lib/types/messages.d.ts.map +1 -0
  52. package/lib/types/messages.js +65 -0
  53. package/lib/types/messages.js.map +1 -0
  54. package/lib/types/projection-types.d.ts +61 -0
  55. package/lib/types/projection-types.d.ts.map +1 -0
  56. package/lib/types/projection-types.js +8 -0
  57. package/lib/types/projection-types.js.map +1 -0
  58. package/lib/types/projection.d.ts +93 -0
  59. package/lib/types/projection.d.ts.map +1 -0
  60. package/lib/types/projection.js +197 -0
  61. package/lib/types/projection.js.map +1 -0
  62. package/lib/types/review.d.ts +141 -0
  63. package/lib/types/review.d.ts.map +1 -0
  64. package/lib/types/review.js +389 -0
  65. package/lib/types/review.js.map +1 -0
  66. package/lib/types/runtime.d.ts +160 -0
  67. package/lib/types/runtime.d.ts.map +1 -0
  68. package/lib/types/runtime.js +486 -0
  69. package/lib/types/runtime.js.map +1 -0
  70. package/package.json +132 -0
  71. package/src/client/ReviewPanel.tsx +164 -0
  72. package/src/client/index.ts +72 -0
  73. package/src/client/locales.ts +87 -0
  74. package/src/client/present.ts +58 -0
  75. package/src/client/styles.ts +131 -0
  76. package/src/config.ts +346 -0
  77. package/src/events.ts +553 -0
  78. package/src/index.ts +28 -0
  79. package/src/invariant.ts +326 -0
  80. package/src/messages.ts +91 -0
  81. package/src/projection-types.ts +61 -0
  82. package/src/projection.ts +224 -0
  83. package/src/review.ts +428 -0
  84. package/src/runtime.ts +562 -0
@@ -0,0 +1,223 @@
1
+ import { c as DENY_MARKER_PATTERN, f as NEVER_MARKER_PATTERN, o as CIRCUIT_MARKER_PATTERN, t as AUTO_REVIEW_FALLBACKS, u as FALLBACK_MARKER_PATTERN } from "./events-CFl6CHZi.js";
2
+ //#region src/invariant.ts
3
+ const PACKAGE_NAME = "dsh-auto-review";
4
+ /** Cordis companion plugin name. */
5
+ const name = "auto-review-invariant";
6
+ /** Service required before the companion can reserve package ownership. */
7
+ const inject = ["invariants"];
8
+ const DECISIONS = ["allow", "deny"];
9
+ const RISK_LEVELS = [
10
+ "low",
11
+ "medium",
12
+ "high"
13
+ ];
14
+ const OUTCOMES = [
15
+ "allowed-once",
16
+ "rejected",
17
+ "cancelled",
18
+ "unavailable"
19
+ ];
20
+ const TRIP_KINDS = ["consecutive", "window"];
21
+ const CIRCUIT_ACTIONS = [
22
+ "delegate",
23
+ "reject",
24
+ "abort-turn"
25
+ ];
26
+ /** Install verdict-chain and deny-marker validation over loaded logs and newly appended events. */
27
+ const install = Object.assign((ctx, fail) => {
28
+ const askedIds = /* @__PURE__ */ new WeakMap();
29
+ const verdicts = /* @__PURE__ */ new WeakMap();
30
+ const verdictByApproval = /* @__PURE__ */ new WeakMap();
31
+ const circuits = /* @__PURE__ */ new WeakMap();
32
+ const rejections = /* @__PURE__ */ new WeakMap();
33
+ const validateEvent = (session, event) => {
34
+ if (event.type === "approval/asked") {
35
+ let ids = askedIds.get(session);
36
+ if (ids === void 0) {
37
+ ids = /* @__PURE__ */ new Map();
38
+ askedIds.set(session, ids);
39
+ }
40
+ ids.set(event.data.id, (ids.get(event.data.id) ?? 0) + 1);
41
+ return;
42
+ }
43
+ if (event.type === "autoReview/verdict") {
44
+ const data = event.data;
45
+ const fallback = data.fallback;
46
+ if (fallback === void 0) {
47
+ if (data.decision === void 0 || !DECISIONS.includes(data.decision)) fail(`autoReview/verdict ${JSON.stringify(data.reviewId)} has invalid decision ${JSON.stringify(data.decision)}`);
48
+ if (typeof data.reason !== "string" || data.reason.length === 0) fail(`autoReview/verdict ${JSON.stringify(data.reviewId)} has no reviewer reason`);
49
+ if (data.riskLevel !== void 0 && !RISK_LEVELS.includes(data.riskLevel)) fail(`autoReview/verdict ${JSON.stringify(data.reviewId)} has invalid riskLevel ${JSON.stringify(data.riskLevel)}`);
50
+ } else {
51
+ if (!AUTO_REVIEW_FALLBACKS.includes(fallback)) fail(`autoReview/verdict ${JSON.stringify(data.reviewId)} has invalid fallback ${JSON.stringify(fallback)}`);
52
+ if (data.decision !== void 0 || data.reason !== void 0 || data.riskLevel !== void 0) fail(`autoReview/verdict ${JSON.stringify(data.reviewId)} carries verdict fields alongside fallback ${JSON.stringify(fallback)}`);
53
+ }
54
+ if (data.outcome !== void 0 && !OUTCOMES.includes(data.outcome)) fail(`autoReview/verdict ${JSON.stringify(data.reviewId)} has invalid outcome ${JSON.stringify(data.outcome)}`);
55
+ if (data.escalation !== void 0) {
56
+ if (data.escalation !== "risk-policy") fail(`autoReview/verdict ${JSON.stringify(data.reviewId)} has invalid escalation ${JSON.stringify(data.escalation)}`);
57
+ if (data.decision !== "allow") fail(`autoReview/verdict ${JSON.stringify(data.reviewId)} escalates a non-allow verdict`);
58
+ if (data.outcome === "allowed-once") fail(`autoReview/verdict ${JSON.stringify(data.reviewId)} escalates yet settles allowed-once`);
59
+ }
60
+ if (!Number.isSafeInteger(data.durationMs) || data.durationMs < 0) fail(`autoReview/verdict ${JSON.stringify(data.reviewId)} has invalid durationMs ${String(data.durationMs)}`);
61
+ if ((askedIds.get(session)?.get(data.approvalId) ?? 0) < 1) fail(`autoReview/verdict ${JSON.stringify(data.reviewId)} references no prior approval/asked ${JSON.stringify(data.approvalId)}`);
62
+ let verdictsForSession = verdicts.get(session);
63
+ if (verdictsForSession === void 0) {
64
+ verdictsForSession = /* @__PURE__ */ new Map();
65
+ verdicts.set(session, verdictsForSession);
66
+ }
67
+ if (verdictsForSession.has(data.reviewId)) fail(`autoReview/verdict repeats reviewId ${JSON.stringify(data.reviewId)}`);
68
+ const record = {
69
+ callId: data.callId,
70
+ decision: data.decision,
71
+ outcome: data.outcome,
72
+ fallback: data.fallback,
73
+ escalation: data.escalation
74
+ };
75
+ verdictsForSession.set(data.reviewId, record);
76
+ let byApproval = verdictByApproval.get(session);
77
+ if (byApproval === void 0) {
78
+ byApproval = /* @__PURE__ */ new Map();
79
+ verdictByApproval.set(session, byApproval);
80
+ }
81
+ if (byApproval.has(data.approvalId)) fail(`autoReview/verdict ${JSON.stringify(data.reviewId)} is the second verdict for approval/asked ${JSON.stringify(data.approvalId)}`);
82
+ byApproval.set(data.approvalId, record);
83
+ return;
84
+ }
85
+ if (event.type === "autoReview/circuit") {
86
+ const data = event.data;
87
+ if (!TRIP_KINDS.includes(data.trip.kind)) fail(`autoReview/circuit ${JSON.stringify(data.circuitId)} has invalid trip kind ${JSON.stringify(data.trip.kind)}`);
88
+ if (!CIRCUIT_ACTIONS.includes(data.action)) fail(`autoReview/circuit ${JSON.stringify(data.circuitId)} has invalid action ${JSON.stringify(data.action)}`);
89
+ if (!Number.isSafeInteger(data.trip.count) || data.trip.count < 1) fail(`autoReview/circuit ${JSON.stringify(data.circuitId)} has invalid trip count ${String(data.trip.count)}`);
90
+ let circuitIds = circuits.get(session);
91
+ if (circuitIds === void 0) {
92
+ circuitIds = /* @__PURE__ */ new Map();
93
+ circuits.set(session, circuitIds);
94
+ }
95
+ if (circuitIds.has(data.circuitId)) fail(`autoReview/circuit repeats circuitId ${JSON.stringify(data.circuitId)}`);
96
+ circuitIds.set(data.circuitId, data.action);
97
+ return;
98
+ }
99
+ if (event.type === "autoReview/override") {
100
+ const verdict = verdicts.get(session)?.get(event.data.reviewId);
101
+ if (verdict === void 0 || verdict.decision !== "deny" && verdict.escalation !== "risk-policy") fail(`autoReview/override references reviewId ${JSON.stringify(event.data.reviewId)} without a prior denial verdict`);
102
+ return;
103
+ }
104
+ if (event.type === "autoReview/rejection") {
105
+ const data = event.data;
106
+ if (typeof data.reason !== "string" || data.reason.length === 0) fail(`autoReview/rejection ${JSON.stringify(data.rejectionId)} has no hard-disable reason`);
107
+ if (data.outcome !== "rejected") fail(`autoReview/rejection ${JSON.stringify(data.rejectionId)} has invalid outcome ${JSON.stringify(data.outcome)}`);
108
+ if (data.approvalId !== void 0) {
109
+ if ((askedIds.get(session)?.get(data.approvalId) ?? 0) < 1) fail(`autoReview/rejection ${JSON.stringify(data.rejectionId)} references no prior approval/asked ${JSON.stringify(data.approvalId)}`);
110
+ let byApproval = verdictByApproval.get(session);
111
+ if (byApproval === void 0) {
112
+ byApproval = /* @__PURE__ */ new Map();
113
+ verdictByApproval.set(session, byApproval);
114
+ }
115
+ if (byApproval.has(data.approvalId)) fail(`autoReview/rejection ${JSON.stringify(data.rejectionId)} is the second decision for approval/asked ${JSON.stringify(data.approvalId)}`);
116
+ byApproval.set(data.approvalId, {
117
+ callId: data.callId,
118
+ decision: void 0,
119
+ outcome: data.outcome,
120
+ fallback: void 0,
121
+ escalation: void 0
122
+ });
123
+ }
124
+ let rejectionIds = rejections.get(session);
125
+ if (rejectionIds === void 0) {
126
+ rejectionIds = /* @__PURE__ */ new Map();
127
+ rejections.set(session, rejectionIds);
128
+ }
129
+ if (rejectionIds.has(data.rejectionId)) fail(`autoReview/rejection repeats rejectionId ${JSON.stringify(data.rejectionId)}`);
130
+ rejectionIds.set(data.rejectionId, {
131
+ callId: data.callId,
132
+ outcome: data.outcome
133
+ });
134
+ return;
135
+ }
136
+ if (event.type === "approval/decided") {
137
+ const claimed = verdictByApproval.get(session)?.get(event.data.id);
138
+ if (claimed?.outcome !== void 0 && claimed.outcome !== event.data.outcome) fail(`approval/decided ${JSON.stringify(event.data.id)} outcome ${JSON.stringify(event.data.outcome)} contradicts the autoReview/verdict outcome ${JSON.stringify(claimed.outcome)}`);
139
+ return;
140
+ }
141
+ if (event.type === "tool/result") {
142
+ const block = event.data.message.content[0];
143
+ if (block === void 0 || block.type !== "tool-result") return;
144
+ const text = block.content.filter((item) => item.type === "text").map((item) => item.text).join("\n");
145
+ const denyMatch = DENY_MARKER_PATTERN.exec(text);
146
+ if (denyMatch !== null) {
147
+ const reviewId = denyMatch[1];
148
+ if (reviewId === void 0) {
149
+ fail(`tool/result carries an unparseable deny marker: ${JSON.stringify(denyMatch[0])}`);
150
+ return;
151
+ }
152
+ const verdict = verdicts.get(session)?.get(reviewId);
153
+ if (verdict === void 0) {
154
+ fail(`tool/result deny marker references unknown reviewId ${JSON.stringify(reviewId)}`);
155
+ return;
156
+ }
157
+ if (verdict.decision !== "deny" && !(verdict.escalation === "risk-policy" && verdict.outcome === "rejected")) fail(`tool/result deny marker references a non-deny verdict ${JSON.stringify(reviewId)}`);
158
+ if (verdict.callId !== void 0 && verdict.callId !== block.toolCallId) fail(`tool/result deny marker for review ${JSON.stringify(reviewId)} has call id ${JSON.stringify(block.toolCallId)}, expected ${JSON.stringify(verdict.callId)}`);
159
+ return;
160
+ }
161
+ const fallbackMatch = FALLBACK_MARKER_PATTERN.exec(text);
162
+ if (fallbackMatch !== null) {
163
+ const reviewId = fallbackMatch[1];
164
+ if (reviewId === void 0) {
165
+ fail(`tool/result carries an unparseable fallback marker: ${JSON.stringify(fallbackMatch[0])}`);
166
+ return;
167
+ }
168
+ const verdict = verdicts.get(session)?.get(reviewId);
169
+ if (verdict === void 0) {
170
+ fail(`tool/result fallback marker references unknown reviewId ${JSON.stringify(reviewId)}`);
171
+ return;
172
+ }
173
+ if (verdict.fallback === void 0 || verdict.outcome !== "rejected") fail(`tool/result fallback marker references a verdict that was not rejected by fallback ${JSON.stringify(reviewId)}`);
174
+ if (verdict.callId !== void 0 && verdict.callId !== block.toolCallId) fail(`tool/result fallback marker for review ${JSON.stringify(reviewId)} has call id ${JSON.stringify(block.toolCallId)}, expected ${JSON.stringify(verdict.callId)}`);
175
+ return;
176
+ }
177
+ const circuitMatch = CIRCUIT_MARKER_PATTERN.exec(text);
178
+ if (circuitMatch !== null) {
179
+ const circuitId = circuitMatch[1];
180
+ const toolName = circuitMatch[2];
181
+ if (circuitId === void 0 || toolName === void 0) {
182
+ fail(`tool/result carries an unparseable circuit marker: ${JSON.stringify(circuitMatch[0])}`);
183
+ return;
184
+ }
185
+ const action = circuits.get(session)?.get(circuitId);
186
+ if (action === void 0) {
187
+ fail(`tool/result circuit marker references unknown circuitId ${JSON.stringify(circuitId)}`);
188
+ return;
189
+ }
190
+ if (action === "delegate") fail(`tool/result circuit marker references a delegate-action circuit ${JSON.stringify(circuitId)}`);
191
+ return;
192
+ }
193
+ const neverMatch = NEVER_MARKER_PATTERN.exec(text);
194
+ if (neverMatch === null) return;
195
+ const rejectionId = neverMatch[1];
196
+ if (rejectionId === void 0) {
197
+ fail(`tool/result carries an unparseable never marker: ${JSON.stringify(neverMatch[0])}`);
198
+ return;
199
+ }
200
+ const rejection = rejections.get(session)?.get(rejectionId);
201
+ if (rejection === void 0) {
202
+ fail(`tool/result never marker references unknown rejectionId ${JSON.stringify(rejectionId)}`);
203
+ return;
204
+ }
205
+ if (rejection.outcome !== "rejected") fail(`tool/result never marker references a rejection that did not settle rejected ${JSON.stringify(rejectionId)}`);
206
+ if (rejection.callId !== void 0 && rejection.callId !== block.toolCallId) fail(`tool/result never marker for rejection ${JSON.stringify(rejectionId)} has call id ${JSON.stringify(block.toolCallId)}, expected ${JSON.stringify(rejection.callId)}`);
207
+ }
208
+ };
209
+ for (const session of ctx.sessions.list()) for (const event of session.events) validateEvent(session, event);
210
+ ctx.on("internal/dispatch", (_mode, eventName, args) => {
211
+ if (eventName !== "session/event") return;
212
+ const [session, event] = args;
213
+ validateEvent(session, event);
214
+ }, { global: true });
215
+ }, { inject: ["sessions"] });
216
+ /**
217
+ * Register this package's invariant companion.
218
+ * @param ctx - Cordis context carrying the invariant service.
219
+ * @returns the installed registration's disposer after setup succeeds.
220
+ */
221
+ const apply = (ctx) => Promise.resolve(ctx.invariants.register(PACKAGE_NAME, install));
222
+ //#endregion
223
+ export { apply, inject, name };
@@ -0,0 +1,29 @@
1
+ /**
2
+ * The session-header review panel: a button in the conversation header that
3
+ * opens a popover with this session's auto-review state — the on/off switch,
4
+ * budgets, cumulative statistics (including hard-disable rejections), the
5
+ * circuit trip, recent verdicts, and one-shot approve buttons for recent
6
+ * denials. Data arrives through the `autoReview` session projection;
7
+ * switches and approves execute the `/auto-review` command through the
8
+ * commands Remote.
9
+ * @module dsh-auto-review/client/ReviewPanel
10
+ */
11
+ import { type ReactNode } from 'react';
12
+ import type { InjectFace, PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
13
+ import { NS } from './locales.ts';
14
+ /** Registration-side injected face: the approve action for one recent denial. */
15
+ export interface ReviewPanelInjected {
16
+ /** Approve the n-th most recent denial (1 = most recent); resolves with the command result text. */
17
+ approve: (n: number) => Promise<string>;
18
+ /** Switch the session's auto-review on/off (`/auto-review on|off`); resolves with the command result text. */
19
+ setEnabled: (enabled: boolean) => Promise<string>;
20
+ }
21
+ /** Full component props assembled by the session-header slot renderer. */
22
+ export type ReviewPanelProps = PropsRuntime<'conversation.session.header.actions'> & PropsLocale<typeof NS> & InjectFace<ReviewPanelInjected>;
23
+ /**
24
+ * Render the review panel action.
25
+ * @param props - framework kit (sessionId, useProjection), locale, and the approve face.
26
+ * @returns the header button with its popover.
27
+ */
28
+ export declare function ReviewPanel({ useProjection, approve, setEnabled, t }: ReviewPanelProps): ReactNode;
29
+ //# sourceMappingURL=ReviewPanel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ReviewPanel.d.ts","sourceRoot":"","sources":["../../../src/client/ReviewPanel.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAoB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAA;AAG7F,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAA;AAEjC,iFAAiF;AACjF,MAAM,WAAW,mBAAmB;IAClC,oGAAoG;IACpG,OAAO,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;IACvC,8GAA8G;IAC9G,UAAU,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;CAClD;AAED,0EAA0E;AAC1E,MAAM,MAAM,gBAAgB,GAC1B,YAAY,CAAC,qCAAqC,CAAC,GACjD,WAAW,CAAC,OAAO,EAAE,CAAC,GACtB,UAAU,CAAC,mBAAmB,CAAC,CAAA;AAwBnC;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,EAAE,aAAa,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,EAAE,EAAE,gBAAgB,GAAG,SAAS,CAyGlG"}
@@ -0,0 +1,63 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * The session-header review panel: a button in the conversation header that
4
+ * opens a popover with this session's auto-review state — the on/off switch,
5
+ * budgets, cumulative statistics (including hard-disable rejections), the
6
+ * circuit trip, recent verdicts, and one-shot approve buttons for recent
7
+ * denials. Data arrives through the `autoReview` session projection;
8
+ * switches and approves execute the `/auto-review` command through the
9
+ * commands Remote.
10
+ * @module dsh-auto-review/client/ReviewPanel
11
+ */
12
+ import { useRef, useState } from 'react';
13
+ import { presentVerdict } from "./present.js";
14
+ /** Compact verdict-row badge label for the panel. */
15
+ function verdictBadge(value, t) {
16
+ if (value === undefined)
17
+ return t('unavailable');
18
+ const fallback = (kind) => t('fallbackLabel').replace('{kind}', kind);
19
+ const labels = {
20
+ allow: t('decisionAllow'),
21
+ deny: t('decisionDeny'),
22
+ fallback,
23
+ escalation: t('escalationLabel'),
24
+ };
25
+ return value.recent.map(verdict => presentVerdict(verdict, labels)).map(row => (_jsxs("div", { "data-dsh-auto-review-verdict": true, children: [_jsx("span", { "data-dsh-auto-review-muted": true, children: row.toolName }), _jsx("span", { "data-dsh-auto-review": `tone-${row.tone}`, children: row.label }), _jsx("span", { "data-dsh-auto-review-muted": true, children: row.detail })] }, row.reviewId)));
26
+ }
27
+ /**
28
+ * Render the review panel action.
29
+ * @param props - framework kit (sessionId, useProjection), locale, and the approve face.
30
+ * @returns the header button with its popover.
31
+ */
32
+ export function ReviewPanel({ useProjection, approve, setEnabled, t }) {
33
+ const value = useProjection('autoReview');
34
+ const [open, setOpen] = useState(false);
35
+ const [notice, setNotice] = useState(null);
36
+ const anchor = useRef(null);
37
+ const toggle = () => setOpen(previous => !previous);
38
+ const runApprove = async (n) => {
39
+ try {
40
+ const text = await approve(n);
41
+ setNotice(t('approveResult').replace('{text}', text));
42
+ }
43
+ catch (error) {
44
+ setNotice(t('approveFailed').replace('{text}', error instanceof Error ? error.message : String(error)));
45
+ }
46
+ };
47
+ const runSwitch = async (enabled) => {
48
+ try {
49
+ const text = await setEnabled(enabled);
50
+ setNotice(t('switchedResult').replace('{text}', text));
51
+ }
52
+ catch (error) {
53
+ setNotice(t('switchFailed').replace('{text}', error instanceof Error ? error.message : String(error)));
54
+ }
55
+ };
56
+ return (_jsxs("div", { "data-dsh-auto-review": true, ref: anchor, children: [_jsx("button", { type: "button", "data-dsh-auto-review-button": true, onClick: toggle, children: t('label') }), open && (_jsxs("div", { "data-dsh-auto-review-panel": true, children: [_jsx("div", { "data-dsh-auto-review-title": true, children: t('title') }), value === undefined
57
+ ? _jsx("div", { "data-dsh-auto-review-muted": true, children: t('unavailable') })
58
+ : (_jsxs("div", { children: [_jsxs("div", { "data-dsh-auto-review-row": true, children: [_jsx("span", { children: t('state') }), _jsx("span", { children: value.enabled ? t('stateOn') : t('stateOff') })] }), _jsxs("div", { "data-dsh-auto-review-row": true, children: [_jsxs("span", { children: [t('enable'), " / ", t('disable')] }), _jsxs("span", { children: [_jsx("button", { type: "button", "data-dsh-auto-review-switch": true, disabled: value.enabled, onClick: () => void runSwitch(true), children: t('enable') }), _jsx("button", { type: "button", "data-dsh-auto-review-switch": true, disabled: !value.enabled, onClick: () => void runSwitch(false), children: t('disable') })] })] }), _jsxs("div", { "data-dsh-auto-review-row": true, children: [_jsx("span", { children: t('verdicts') }), _jsx("span", { children: value.verdictsUsed })] }), _jsxs("div", { "data-dsh-auto-review-row": true, children: [_jsx("span", { children: t('failures') }), _jsx("span", { children: value.failuresUsed })] }), _jsxs("div", { "data-dsh-auto-review-row": true, children: [_jsx("span", { children: t('allTime') }), _jsxs("span", { children: [value.allows, " ", t('allows'), " \u00B7 ", value.denies, " ", t('denies'), " \u00B7 ", value.fallbacks, " ", t('fallbacks'), " \u00B7 ", value.neverRejects, " ", t('neverRejects'), " \u00B7 ", t('avg'), " ", value.avgDurationMs, " ", t('ms')] })] }), value.circuit !== null && (_jsxs("div", { "data-dsh-auto-review-circuit": true, children: [t('circuit'), " \u2014 ", t('circuitDetail')
59
+ .replace('{kind}', value.circuit.trip.kind)
60
+ .replace('{count}', String(value.circuit.trip.count))
61
+ .replace('{action}', value.circuit.action)] })), value.recentDenies.length > 0 && (_jsxs("div", { "data-dsh-auto-review-section": true, children: [_jsx("div", { "data-dsh-auto-review-title": true, children: t('denyList') }), value.recentDenies.map((deny, index) => (_jsxs("div", { "data-dsh-auto-review-row": true, children: [_jsx("span", { "data-dsh-auto-review-muted": true, children: deny.toolName }), _jsxs("button", { type: "button", "data-dsh-auto-review-approve": true, onClick: () => void runApprove(index + 1), children: [t('approve'), " #", index + 1] })] }, deny.reviewId)))] })), _jsxs("div", { "data-dsh-auto-review-section": true, children: [_jsx("div", { "data-dsh-auto-review-title": true, children: t('recent') }), value.recent.length === 0 ? _jsx("div", { "data-dsh-auto-review-muted": true, children: t('empty') }) : verdictBadge(value, t)] })] })), notice !== null && _jsx("div", { "data-dsh-auto-review-muted": true, children: notice })] }))] }));
62
+ }
63
+ //# sourceMappingURL=ReviewPanel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ReviewPanel.js","sourceRoot":"","sources":["../../../src/client/ReviewPanel.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * `dsh-auto-review`, browser half: registers the locale dictionaries, the
3
+ * scoped stylesheet, and the session-header review panel action. All data
4
+ * arrives through the `autoReview` session projection; the approve buttons
5
+ * execute the `/auto-review approve [n]` command through the commands
6
+ * Remote namespace.
7
+ *
8
+ * @module dsh-auto-review/client
9
+ */
10
+ import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client';
11
+ import { type ReviewPanelLocaleKey } from './locales.ts';
12
+ declare module '@deepseek-ai/dsh-client-ui-slots' {
13
+ interface LocaleNamespaceMap {
14
+ /** Review panel copy. */
15
+ 'autoReviewPanel': ReviewPanelLocaleKey;
16
+ }
17
+ }
18
+ export type { ReviewPanelProps, ReviewPanelInjected } from './ReviewPanel.tsx';
19
+ export type { ReviewPanelLocaleKey } from './locales.ts';
20
+ export { presentVerdict, type PresentedVerdict, type VerdictTone } from './present.ts';
21
+ /** Plugin name: matches the package name, the graph row id, and the bundle id. */
22
+ export declare const name = "dsh-auto-review";
23
+ /** Services the panel reads; `remote.commands` is mounted by the api-remotes client. */
24
+ export declare const inject: string[];
25
+ /**
26
+ * Browser plugin body: dictionaries, the scoped stylesheet, and the
27
+ * session-header action registration.
28
+ * @param ctx - client root context.
29
+ */
30
+ export declare function apply(ctx: ClientContext): void;
31
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAa,MAAM,wCAAwC,CAAA;AAStF,OAAO,EAAc,KAAK,oBAAoB,EAAE,MAAM,cAAc,CAAA;AAGpE,OAAO,QAAQ,kCAAkC,CAAC;IAChD,UAAU,kBAAkB;QAC1B,yBAAyB;QACzB,iBAAiB,EAAE,oBAAoB,CAAA;KACxC;CACF;AAED,YAAY,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AAC9E,YAAY,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAA;AACxD,OAAO,EAAE,cAAc,EAAE,KAAK,gBAAgB,EAAE,KAAK,WAAW,EAAE,MAAM,cAAc,CAAA;AAEtF,kFAAkF;AAClF,eAAO,MAAM,IAAI,oBAAoB,CAAA;AAErC,wFAAwF;AACxF,eAAO,MAAM,MAAM,UAAmD,CAAA;AAEtE;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI,CA2B9C"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * `dsh-auto-review`, browser half: registers the locale dictionaries, the
3
+ * scoped stylesheet, and the session-header review panel action. All data
4
+ * arrives through the `autoReview` session projection; the approve buttons
5
+ * execute the `/auto-review approve [n]` command through the commands
6
+ * Remote namespace.
7
+ *
8
+ * @module dsh-auto-review/client
9
+ */
10
+ import { ReviewPanel } from "./ReviewPanel.js";
11
+ import { en, NS, zh } from "./locales.js";
12
+ import { installPanelStyles } from "./styles.js";
13
+ export { presentVerdict } from "./present.js";
14
+ /** Plugin name: matches the package name, the graph row id, and the bundle id. */
15
+ export const name = 'dsh-auto-review';
16
+ /** Services the panel reads; `remote.commands` is mounted by the api-remotes client. */
17
+ export const inject = ['slots', 'locale', 'remote', 'remote.commands'];
18
+ /**
19
+ * Browser plugin body: dictionaries, the scoped stylesheet, and the
20
+ * session-header action registration.
21
+ * @param ctx - client root context.
22
+ */
23
+ export function apply(ctx) {
24
+ ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'dsh-auto-review: dictionaries');
25
+ ctx.effect(() => installPanelStyles(), 'dsh-auto-review: stylesheet');
26
+ ctx.slots.inject('conversation.session.header.actions', () => ctx.slots.register({
27
+ name: 'conversation.session.header.actions',
28
+ id: 'auto-review',
29
+ order: 40,
30
+ locale: NS,
31
+ inject: (sessionId) => {
32
+ const executeCommand = async (line) => {
33
+ const result = await ctx.remote.commands.execute(sessionId, line);
34
+ if (!result.ok)
35
+ throw new Error(`${result.error.code}: ${result.error.message}`);
36
+ if (result.value === undefined)
37
+ throw new Error('unknown command: /auto-review');
38
+ const command = result.value.result;
39
+ if (command === undefined)
40
+ throw new Error('/auto-review produced no command result');
41
+ const text = command.text ?? '';
42
+ return command.kind === 'success' ? text : `${command.kind}: ${text}`;
43
+ };
44
+ return {
45
+ approve: async (n) => executeCommand(`/auto-review approve ${n}`),
46
+ setEnabled: async (enabled) => executeCommand(`/auto-review ${enabled ? 'on' : 'off'}`),
47
+ };
48
+ },
49
+ }, ReviewPanel));
50
+ }
51
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAUH,OAAO,EAAE,WAAW,EAA4B,MAAM,kBAAmB,CAAA;AACzE,OAAO,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAA6B,MAAM,cAAc,CAAA;AACpE,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAWhD,OAAO,EAAE,cAAc,EAA2C,MAAM,cAAc,CAAA;AAEtF,kFAAkF;AAClF,MAAM,CAAC,MAAM,IAAI,GAAG,iBAAiB,CAAA;AAErC,wFAAwF;AACxF,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,iBAAiB,CAAC,CAAA;AAEtE;;;;GAIG;AACH,MAAM,UAAU,KAAK,CAAC,GAAkB;IACtC,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,+BAA+B,CAAC,CAAA;IACtF,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,kBAAkB,EAAE,EAAE,6BAA6B,CAAC,CAAA;IACrE,GAAG,CAAC,KAAK,CAAC,MAAM,CACd,qCAAqC,EACrC,GAAG,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC;QACvB,IAAI,EAAE,qCAAqC;QAC3C,EAAE,EAAE,aAAa;QACjB,KAAK,EAAE,EAAE;QACT,MAAM,EAAE,EAAE;QACV,MAAM,EAAE,CAAC,SAAoB,EAAuB,EAAE;YACpD,MAAM,cAAc,GAAG,KAAK,EAAE,IAAY,EAAmB,EAAE;gBAC7D,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,CAAA;gBACjE,IAAI,CAAC,MAAM,CAAC,EAAE;oBAAE,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,KAAK,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;gBAChF,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS;oBAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAA;gBAChF,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAA;gBACnC,IAAI,OAAO,KAAK,SAAS;oBAAE,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAA;gBACrF,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,EAAE,CAAA;gBAC/B,OAAO,OAAO,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,KAAK,IAAI,EAAE,CAAA;YACvE,CAAC,CAAA;YACD,OAAO;gBACL,OAAO,EAAE,KAAK,EAAE,CAAS,EAAmB,EAAE,CAAC,cAAc,CAAC,wBAAwB,CAAC,EAAE,CAAC;gBAC1F,UAAU,EAAE,KAAK,EAAE,OAAgB,EAAmB,EAAE,CAAC,cAAc,CAAC,gBAAgB,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC;aAClH,CAAA;QACH,CAAC;KACF,EAAE,WAAW,CAAC,CAChB,CAAA;AACH,CAAC"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Copy dictionaries for the auto-review session-header panel (en/zh — the
3
+ * harness locale registry accepts these two UI language codes today).
4
+ * @module dsh-auto-review/client/locales
5
+ */
6
+ /** Simplified Chinese dictionary and key source of truth. */
7
+ export declare const zh: {
8
+ label: string;
9
+ title: string;
10
+ state: string;
11
+ stateOn: string;
12
+ stateOff: string;
13
+ enable: string;
14
+ disable: string;
15
+ verdicts: string;
16
+ failures: string;
17
+ allTime: string;
18
+ allows: string;
19
+ denies: string;
20
+ fallbacks: string;
21
+ neverRejects: string;
22
+ avg: string;
23
+ circuit: string;
24
+ circuitDetail: string;
25
+ empty: string;
26
+ recent: string;
27
+ denyList: string;
28
+ approve: string;
29
+ approveResult: string;
30
+ approveFailed: string;
31
+ switchedResult: string;
32
+ switchFailed: string;
33
+ unavailable: string;
34
+ decisionAllow: string;
35
+ decisionDeny: string;
36
+ fallbackLabel: string;
37
+ escalationLabel: string;
38
+ riskLow: string;
39
+ riskMedium: string;
40
+ riskHigh: string;
41
+ ms: string;
42
+ };
43
+ /** Auto-review panel locale key union. */
44
+ export type ReviewPanelLocaleKey = keyof typeof zh;
45
+ /** English dictionary checked against the Chinese key set. */
46
+ export declare const en: Record<ReviewPanelLocaleKey, string>;
47
+ /** Dictionary namespace owned by this plugin. */
48
+ export declare const NS = "autoReviewPanel";
49
+ //# sourceMappingURL=locales.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"locales.d.ts","sourceRoot":"","sources":["../../../src/client/locales.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,6DAA6D;AAC7D,eAAO,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmCmB,CAAA;AAElC,0CAA0C;AAC1C,MAAM,MAAM,oBAAoB,GAAG,MAAM,OAAO,EAAE,CAAA;AAElD,8DAA8D;AAC9D,eAAO,MAAM,EAAE,EAAE,MAAM,CAAC,oBAAoB,EAAE,MAAM,CAmCnD,CAAA;AAED,iDAAiD;AACjD,eAAO,MAAM,EAAE,oBAAoB,CAAA"}
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Copy dictionaries for the auto-review session-header panel (en/zh — the
3
+ * harness locale registry accepts these two UI language codes today).
4
+ * @module dsh-auto-review/client/locales
5
+ */
6
+ /** Simplified Chinese dictionary and key source of truth. */
7
+ export const zh = {
8
+ label: 'AI 审查',
9
+ title: 'AI 自动审查',
10
+ state: '状态',
11
+ stateOn: '已开启',
12
+ stateOff: '已关闭',
13
+ enable: '开启',
14
+ disable: '关闭',
15
+ verdicts: '本回合 AI 裁决',
16
+ failures: '本回合失败',
17
+ allTime: '累计',
18
+ allows: '放行',
19
+ denies: '拒绝',
20
+ fallbacks: '失败',
21
+ neverRejects: '硬禁用拒绝',
22
+ avg: '平均耗时',
23
+ circuit: '拒绝熔断器已触发',
24
+ circuitDetail: '触发类型:{kind},计数 {count},动作 {action}',
25
+ empty: '本会话暂无 AI 审查裁决。',
26
+ recent: '最近裁决',
27
+ denyList: '可批准的重试',
28
+ approve: '批准重试',
29
+ approveResult: '已授权:{text}',
30
+ approveFailed: '批准失败:{text}',
31
+ switchedResult: '已切换:{text}',
32
+ switchFailed: '切换失败:{text}',
33
+ unavailable: '审查面板不可用(宿主未提供会话投影能力)。',
34
+ decisionAllow: '放行',
35
+ decisionDeny: '拒绝',
36
+ fallbackLabel: '失败({kind})',
37
+ escalationLabel: '风险策略升级',
38
+ riskLow: '低风险',
39
+ riskMedium: '中风险',
40
+ riskHigh: '高风险',
41
+ ms: 'ms',
42
+ };
43
+ /** English dictionary checked against the Chinese key set. */
44
+ export const en = {
45
+ label: 'AI Review',
46
+ title: 'AI Auto-Review',
47
+ state: 'State',
48
+ stateOn: 'ON',
49
+ stateOff: 'OFF',
50
+ enable: 'Enable',
51
+ disable: 'Disable',
52
+ verdicts: 'AI verdicts this turn',
53
+ failures: 'Failures this turn',
54
+ allTime: 'All-time',
55
+ allows: 'allows',
56
+ denies: 'denies',
57
+ fallbacks: 'fallbacks',
58
+ neverRejects: 'never rejects',
59
+ avg: 'avg',
60
+ circuit: 'Rejection circuit breaker tripped',
61
+ circuitDetail: '{kind}: {count} denials, action {action}',
62
+ empty: 'No AI review verdicts in this session yet.',
63
+ recent: 'Recent verdicts',
64
+ denyList: 'Approvable retries',
65
+ approve: 'Approve retry',
66
+ approveResult: 'Authorized: {text}',
67
+ approveFailed: 'Approve failed: {text}',
68
+ switchedResult: 'Switched: {text}',
69
+ switchFailed: 'Switch failed: {text}',
70
+ unavailable: 'The review panel is unavailable (the host does not provide the session-projection capability).',
71
+ decisionAllow: 'allow',
72
+ decisionDeny: 'deny',
73
+ fallbackLabel: 'fallback ({kind})',
74
+ escalationLabel: 'risk-policy escalation',
75
+ riskLow: 'low risk',
76
+ riskMedium: 'medium risk',
77
+ riskHigh: 'high risk',
78
+ ms: 'ms',
79
+ };
80
+ /** Dictionary namespace owned by this plugin. */
81
+ export const NS = 'autoReviewPanel';
82
+ //# sourceMappingURL=locales.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"locales.js","sourceRoot":"","sources":["../../../src/client/locales.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,6DAA6D;AAC7D,MAAM,CAAC,MAAM,EAAE,GAAG;IAChB,KAAK,EAAE,OAAO;IACd,KAAK,EAAE,SAAS;IAChB,KAAK,EAAE,IAAI;IACX,OAAO,EAAE,KAAK;IACd,QAAQ,EAAE,KAAK;IACf,MAAM,EAAE,IAAI;IACZ,OAAO,EAAE,IAAI;IACb,QAAQ,EAAE,WAAW;IACrB,QAAQ,EAAE,OAAO;IACjB,OAAO,EAAE,IAAI;IACb,MAAM,EAAE,IAAI;IACZ,MAAM,EAAE,IAAI;IACZ,SAAS,EAAE,IAAI;IACf,YAAY,EAAE,OAAO;IACrB,GAAG,EAAE,MAAM;IACX,OAAO,EAAE,UAAU;IACnB,aAAa,EAAE,oCAAoC;IACnD,KAAK,EAAE,gBAAgB;IACvB,MAAM,EAAE,MAAM;IACd,QAAQ,EAAE,QAAQ;IAClB,OAAO,EAAE,MAAM;IACf,aAAa,EAAE,YAAY;IAC3B,aAAa,EAAE,aAAa;IAC5B,cAAc,EAAE,YAAY;IAC5B,YAAY,EAAE,aAAa;IAC3B,WAAW,EAAE,uBAAuB;IACpC,aAAa,EAAE,IAAI;IACnB,YAAY,EAAE,IAAI;IAClB,aAAa,EAAE,YAAY;IAC3B,eAAe,EAAE,QAAQ;IACzB,OAAO,EAAE,KAAK;IACd,UAAU,EAAE,KAAK;IACjB,QAAQ,EAAE,KAAK;IACf,EAAE,EAAE,IAAI;CACwB,CAAA;AAKlC,8DAA8D;AAC9D,MAAM,CAAC,MAAM,EAAE,GAAyC;IACtD,KAAK,EAAE,WAAW;IAClB,KAAK,EAAE,gBAAgB;IACvB,KAAK,EAAE,OAAO;IACd,OAAO,EAAE,IAAI;IACb,QAAQ,EAAE,KAAK;IACf,MAAM,EAAE,QAAQ;IAChB,OAAO,EAAE,SAAS;IAClB,QAAQ,EAAE,uBAAuB;IACjC,QAAQ,EAAE,oBAAoB;IAC9B,OAAO,EAAE,UAAU;IACnB,MAAM,EAAE,QAAQ;IAChB,MAAM,EAAE,QAAQ;IAChB,SAAS,EAAE,WAAW;IACtB,YAAY,EAAE,eAAe;IAC7B,GAAG,EAAE,KAAK;IACV,OAAO,EAAE,mCAAmC;IAC5C,aAAa,EAAE,0CAA0C;IACzD,KAAK,EAAE,4CAA4C;IACnD,MAAM,EAAE,iBAAiB;IACzB,QAAQ,EAAE,oBAAoB;IAC9B,OAAO,EAAE,eAAe;IACxB,aAAa,EAAE,oBAAoB;IACnC,aAAa,EAAE,wBAAwB;IACvC,cAAc,EAAE,kBAAkB;IAClC,YAAY,EAAE,uBAAuB;IACrC,WAAW,EAAE,gGAAgG;IAC7G,aAAa,EAAE,OAAO;IACtB,YAAY,EAAE,MAAM;IACpB,aAAa,EAAE,mBAAmB;IAClC,eAAe,EAAE,wBAAwB;IACzC,OAAO,EAAE,UAAU;IACnB,UAAU,EAAE,aAAa;IACzB,QAAQ,EAAE,WAAW;IACrB,EAAE,EAAE,IAAI;CACT,CAAA;AAED,iDAAiD;AACjD,MAAM,CAAC,MAAM,EAAE,GAAG,iBAAiB,CAAA"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Pure presentation for the review panel: verdict rows and badges as plain
3
+ * strings and tone codes — no I/O, clock, or randomness. The component
4
+ * owns layout and interaction; this module owns the text.
5
+ * @module dsh-auto-review/client/present
6
+ */
7
+ import type { AutoReviewVerdictView } from '../projection-types.ts';
8
+ /** Badge tones the component maps to scoped styles. */
9
+ export type VerdictTone = 'allow' | 'deny' | 'fallback' | 'escalation';
10
+ /** One presented verdict row. */
11
+ export interface PresentedVerdict {
12
+ readonly reviewId: string;
13
+ readonly toolName: string;
14
+ readonly label: string;
15
+ readonly detail: string;
16
+ readonly tone: VerdictTone;
17
+ }
18
+ /** Present one verdict row (the component supplies the localized label texts). */
19
+ export declare function presentVerdict(verdict: AutoReviewVerdictView, labels: {
20
+ readonly allow: string;
21
+ readonly deny: string;
22
+ readonly fallback: (kind: string) => string;
23
+ readonly escalation: string;
24
+ }): PresentedVerdict;
25
+ //# sourceMappingURL=present.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"present.d.ts","sourceRoot":"","sources":["../../../src/client/present.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAA;AAEnE,uDAAuD;AACvD,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,MAAM,GAAG,UAAU,GAAG,YAAY,CAAA;AAEtE,iCAAiC;AACjC,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAA;CAC3B;AAED,kFAAkF;AAClF,wBAAgB,cAAc,CAC5B,OAAO,EAAE,qBAAqB,EAC9B,MAAM,EAAE;IACN,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAA;IAC3C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAC5B,GACA,gBAAgB,CA2BlB"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Pure presentation for the review panel: verdict rows and badges as plain
3
+ * strings and tone codes — no I/O, clock, or randomness. The component
4
+ * owns layout and interaction; this module owns the text.
5
+ * @module dsh-auto-review/client/present
6
+ */
7
+ /** Present one verdict row (the component supplies the localized label texts). */
8
+ export function presentVerdict(verdict, labels) {
9
+ if (verdict.fallback !== undefined) {
10
+ return {
11
+ reviewId: verdict.reviewId,
12
+ toolName: verdict.toolName,
13
+ label: labels.fallback(verdict.fallback),
14
+ detail: `${verdict.durationMs} ms`,
15
+ tone: 'fallback',
16
+ };
17
+ }
18
+ if (verdict.escalation === 'risk-policy') {
19
+ return {
20
+ reviewId: verdict.reviewId,
21
+ toolName: verdict.toolName,
22
+ label: labels.escalation,
23
+ detail: verdict.reason ?? '',
24
+ tone: 'escalation',
25
+ };
26
+ }
27
+ const label = verdict.decision === 'deny' ? labels.deny : labels.allow;
28
+ return {
29
+ reviewId: verdict.reviewId,
30
+ toolName: verdict.toolName,
31
+ label,
32
+ detail: verdict.reason ?? `${verdict.durationMs} ms`,
33
+ tone: verdict.decision === 'deny' ? 'deny' : 'allow',
34
+ };
35
+ }
36
+ //# sourceMappingURL=present.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"present.js","sourceRoot":"","sources":["../../../src/client/present.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAgBH,kFAAkF;AAClF,MAAM,UAAU,cAAc,CAC5B,OAA8B,EAC9B,MAKC;IAED,IAAI,OAAO,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QACnC,OAAO;YACL,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC;YACxC,MAAM,EAAE,GAAG,OAAO,CAAC,UAAU,KAAK;YAClC,IAAI,EAAE,UAAU;SACjB,CAAA;IACH,CAAC;IACD,IAAI,OAAO,CAAC,UAAU,KAAK,aAAa,EAAE,CAAC;QACzC,OAAO;YACL,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,KAAK,EAAE,MAAM,CAAC,UAAU;YACxB,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,EAAE;YAC5B,IAAI,EAAE,YAAY;SACnB,CAAA;IACH,CAAC;IACD,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAA;IACtE,OAAO;QACL,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,KAAK;QACL,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,GAAG,OAAO,CAAC,UAAU,KAAK;QACpD,IAAI,EAAE,OAAO,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO;KACrD,CAAA;AACH,CAAC"}