@cellarnode/ui 0.195.1 → 0.196.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 (104) hide show
  1. package/dist/agent/activity-ledger.d.ts +28 -0
  2. package/dist/agent/activity-ledger.d.ts.map +1 -0
  3. package/dist/agent/activity-ledger.js +50 -0
  4. package/dist/agent/activity-ledger.js.map +1 -0
  5. package/dist/agent/approval-ledger.d.ts +27 -0
  6. package/dist/agent/approval-ledger.d.ts.map +1 -0
  7. package/dist/agent/approval-ledger.js +39 -0
  8. package/dist/agent/approval-ledger.js.map +1 -0
  9. package/dist/agent/composer.d.ts +27 -0
  10. package/dist/agent/composer.d.ts.map +1 -0
  11. package/dist/agent/composer.js +50 -0
  12. package/dist/agent/composer.js.map +1 -0
  13. package/dist/agent/confirm-card.d.ts +58 -0
  14. package/dist/agent/confirm-card.d.ts.map +1 -0
  15. package/dist/agent/confirm-card.js +127 -0
  16. package/dist/agent/confirm-card.js.map +1 -0
  17. package/dist/agent/confirm-guards.d.ts +36 -0
  18. package/dist/agent/confirm-guards.d.ts.map +1 -0
  19. package/dist/agent/confirm-guards.js +44 -0
  20. package/dist/agent/confirm-guards.js.map +1 -0
  21. package/dist/agent/conversation.d.ts +41 -0
  22. package/dist/agent/conversation.d.ts.map +1 -0
  23. package/dist/agent/conversation.js +77 -0
  24. package/dist/agent/conversation.js.map +1 -0
  25. package/dist/agent/copy.d.ts +5 -0
  26. package/dist/agent/copy.d.ts.map +1 -0
  27. package/dist/agent/copy.js +10 -0
  28. package/dist/agent/copy.js.map +1 -0
  29. package/dist/agent/fixtures.d.ts +20 -0
  30. package/dist/agent/fixtures.d.ts.map +1 -0
  31. package/dist/agent/fixtures.js +197 -0
  32. package/dist/agent/fixtures.js.map +1 -0
  33. package/dist/agent/index.d.ts +24 -0
  34. package/dist/agent/index.d.ts.map +1 -0
  35. package/dist/agent/index.js +24 -0
  36. package/dist/agent/index.js.map +1 -0
  37. package/dist/agent/masked-value.d.ts +20 -0
  38. package/dist/agent/masked-value.d.ts.map +1 -0
  39. package/dist/agent/masked-value.js +19 -0
  40. package/dist/agent/masked-value.js.map +1 -0
  41. package/dist/agent/message.d.ts +32 -0
  42. package/dist/agent/message.d.ts.map +1 -0
  43. package/dist/agent/message.js +47 -0
  44. package/dist/agent/message.js.map +1 -0
  45. package/dist/agent/panel-frame.d.ts +23 -0
  46. package/dist/agent/panel-frame.d.ts.map +1 -0
  47. package/dist/agent/panel-frame.js +17 -0
  48. package/dist/agent/panel-frame.js.map +1 -0
  49. package/dist/agent/readiness-checklist.d.ts +49 -0
  50. package/dist/agent/readiness-checklist.d.ts.map +1 -0
  51. package/dist/agent/readiness-checklist.js +104 -0
  52. package/dist/agent/readiness-checklist.js.map +1 -0
  53. package/dist/agent/schema.d.ts +418 -0
  54. package/dist/agent/schema.d.ts.map +1 -0
  55. package/dist/agent/schema.js +137 -0
  56. package/dist/agent/schema.js.map +1 -0
  57. package/dist/agent/states.d.ts +44 -0
  58. package/dist/agent/states.d.ts.map +1 -0
  59. package/dist/agent/states.js +70 -0
  60. package/dist/agent/states.js.map +1 -0
  61. package/dist/agent/thinking.d.ts +14 -0
  62. package/dist/agent/thinking.d.ts.map +1 -0
  63. package/dist/agent/thinking.js +12 -0
  64. package/dist/agent/thinking.js.map +1 -0
  65. package/dist/agent/thread-list.d.ts +25 -0
  66. package/dist/agent/thread-list.d.ts.map +1 -0
  67. package/dist/agent/thread-list.js +39 -0
  68. package/dist/agent/thread-list.js.map +1 -0
  69. package/dist/agent/tool-call-card.d.ts +24 -0
  70. package/dist/agent/tool-call-card.d.ts.map +1 -0
  71. package/dist/agent/tool-call-card.js +36 -0
  72. package/dist/agent/tool-call-card.js.map +1 -0
  73. package/dist/agent/ui.d.ts +13 -0
  74. package/dist/agent/ui.d.ts.map +1 -0
  75. package/dist/agent/ui.js +22 -0
  76. package/dist/agent/ui.js.map +1 -0
  77. package/dist/components/button.js +1 -1
  78. package/dist/components/button.js.map +1 -1
  79. package/dist/mcp-connect/brand-marks.d.ts +18 -0
  80. package/dist/mcp-connect/brand-marks.d.ts.map +1 -0
  81. package/dist/mcp-connect/brand-marks.js +15 -0
  82. package/dist/mcp-connect/brand-marks.js.map +1 -0
  83. package/dist/mcp-connect/clients.d.ts +18 -0
  84. package/dist/mcp-connect/clients.d.ts.map +1 -0
  85. package/dist/mcp-connect/clients.js +15 -0
  86. package/dist/mcp-connect/clients.js.map +1 -0
  87. package/dist/mcp-connect/index.d.ts +7 -0
  88. package/dist/mcp-connect/index.d.ts.map +1 -0
  89. package/dist/mcp-connect/index.js +4 -0
  90. package/dist/mcp-connect/index.js.map +1 -0
  91. package/dist/mcp-connect/mcp-connect-panel.d.ts +87 -0
  92. package/dist/mcp-connect/mcp-connect-panel.d.ts.map +1 -0
  93. package/dist/mcp-connect/mcp-connect-panel.js +145 -0
  94. package/dist/mcp-connect/mcp-connect-panel.js.map +1 -0
  95. package/dist/portfolio-import/session/import-job.d.ts.map +1 -1
  96. package/dist/portfolio-import/session/import-job.js +2 -1
  97. package/dist/portfolio-import/session/import-job.js.map +1 -1
  98. package/dist/portfolio-import/session/list-all-confirmations.d.ts +8 -0
  99. package/dist/portfolio-import/session/list-all-confirmations.d.ts.map +1 -0
  100. package/dist/portfolio-import/session/list-all-confirmations.js +30 -0
  101. package/dist/portfolio-import/session/list-all-confirmations.js.map +1 -0
  102. package/dist/realtime/job-status/schemas.d.ts +2 -2
  103. package/package.json +9 -1
  104. package/src/theme/tokens.css +10 -0
@@ -0,0 +1,28 @@
1
+ import type { AgentStep } from "./schema.js";
2
+ export interface AgentActivityLedgerCopy {
3
+ heading: string;
4
+ running: string;
5
+ done: string;
6
+ partial: string;
7
+ expand: string;
8
+ collapse: string;
9
+ kind_candidates: string;
10
+ kind_decision: string;
11
+ kind_toolCall: string;
12
+ kind_note: string;
13
+ }
14
+ export interface AgentActivityLedgerProps {
15
+ steps: readonly AgentStep[];
16
+ /** Controlled collapsed state. Uncontrolled default: collapsed once no step is running. */
17
+ collapsed?: boolean;
18
+ onCollapsedChange?: (collapsed: boolean) => void;
19
+ copy?: Partial<AgentActivityLedgerCopy>;
20
+ className?: string;
21
+ }
22
+ /**
23
+ * @internal A run is a ledger of steps (options considered, the choice, tool
24
+ * calls). It stays open while running and folds to one summary row when done.
25
+ * Static: no per-step animation.
26
+ */
27
+ export declare function AgentActivityLedger({ steps, collapsed, onCollapsedChange, copy, className, }: AgentActivityLedgerProps): import("react/jsx-runtime").JSX.Element;
28
+ //# sourceMappingURL=activity-ledger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activity-ledger.d.ts","sourceRoot":"","sources":["../../src/agent/activity-ledger.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAG1C,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;CACnB;AAoBD,MAAM,WAAW,wBAAwB;IACvC,KAAK,EAAE,SAAS,SAAS,EAAE,CAAC;IAC5B,2FAA2F;IAC3F,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,KAAK,IAAI,CAAC;IACjD,IAAI,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,CAAC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,KAAK,EACL,SAAS,EACT,iBAAiB,EACjB,IAAI,EACJ,SAAS,GACV,EAAE,wBAAwB,2CAuF1B"}
@@ -0,0 +1,50 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from "react";
3
+ import { AlertCircle, CheckCircle2, ChevronRight, Loader2 } from "lucide-react";
4
+ import { cn } from "../lib/utils.js";
5
+ import { fmt, useCopy } from "./copy.js";
6
+ import { focusRing, toneChip } from "./ui.js";
7
+ const DEFAULT_COPY = {
8
+ heading: "Activity",
9
+ running: "Working, {count} steps so far",
10
+ done: "Finished in {count} steps",
11
+ partial: "Finished with {failed} failed of {count} steps",
12
+ expand: "Show steps",
13
+ collapse: "Hide steps",
14
+ kind_candidates: "Options considered",
15
+ kind_decision: "Choice",
16
+ kind_toolCall: "Tool call",
17
+ kind_note: "Note",
18
+ };
19
+ const STATUS = {
20
+ running: { tone: "info", icon: Loader2, spin: true },
21
+ done: { tone: "success", icon: CheckCircle2 },
22
+ failed: { tone: "danger", icon: AlertCircle },
23
+ };
24
+ /**
25
+ * @internal A run is a ledger of steps (options considered, the choice, tool
26
+ * calls). It stays open while running and folds to one summary row when done.
27
+ * Static: no per-step animation.
28
+ */
29
+ export function AgentActivityLedger({ steps, collapsed, onCollapsedChange, copy, className, }) {
30
+ const c = useCopy(DEFAULT_COPY, copy);
31
+ const running = steps.some((s) => s.status === "running");
32
+ const failed = steps.filter((s) => s.status === "failed").length;
33
+ const [userCollapsed, setUserCollapsed] = useState(null);
34
+ const isCollapsed = collapsed ?? userCollapsed ?? !running;
35
+ const summary = running
36
+ ? fmt(c.running, { count: steps.length })
37
+ : failed > 0
38
+ ? fmt(c.partial, { failed, count: steps.length })
39
+ : fmt(c.done, { count: steps.length });
40
+ function toggle() {
41
+ const next = !isCollapsed;
42
+ setUserCollapsed(next);
43
+ onCollapsedChange?.(next);
44
+ }
45
+ return (_jsxs("div", { "data-collapsed": isCollapsed, className: cn("rounded-xl bg-card text-sm/5 ring-1 ring-border/60", className), children: [_jsxs("button", { type: "button", "aria-expanded": !isCollapsed, "aria-label": `${c.heading}: ${summary}. ${isCollapsed ? c.expand : c.collapse}`, onClick: toggle, className: cn("flex min-h-10 w-full items-center gap-2 rounded-xl px-3 text-left", focusRing), children: [_jsx(ChevronRight, { "aria-hidden": true, className: cn("size-3.5 shrink-0 text-muted-foreground transition-transform duration-[var(--duration-micro)] motion-reduce:transition-none", !isCollapsed && "rotate-90") }), _jsx("span", { "aria-hidden": true, className: "text-xs/4 font-medium uppercase tracking-wider text-muted-foreground", children: c.heading }), _jsx("span", { "aria-hidden": true, className: cn("min-w-0 flex-1 truncate", failed > 0 && !running ? "text-[var(--tone-warning-fg)]" : "text-foreground"), children: summary })] }), !isCollapsed && (_jsx("ol", { className: "border-t border-border/60 px-3 py-2", children: steps.map((step) => {
46
+ const s = STATUS[step.status];
47
+ return (_jsxs("li", { "data-status": step.status, className: "flex items-start gap-2 py-1.5", children: [_jsx("span", { className: cn("mt-0.5 inline-flex size-5 shrink-0 items-center justify-center rounded-full", toneChip[s.tone]), children: _jsx(s.icon, { "aria-hidden": true, className: cn("size-3", s.spin && "animate-spin motion-reduce:animate-none") }) }), _jsxs("div", { className: "min-w-0", children: [_jsx("p", { className: "text-xs/4 text-muted-foreground", children: c[`kind_${step.kind}`] }), _jsx("p", { className: "text-foreground", children: step.title }), step.detail && _jsx("p", { className: "text-muted-foreground", children: step.detail })] })] }, step.id));
48
+ }) }))] }));
49
+ }
50
+ //# sourceMappingURL=activity-ledger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activity-ledger.js","sourceRoot":"","sources":["../../src/agent/activity-ledger.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import type { AgentApproval } from "./schema.js";
2
+ export interface AgentApprovalLedgerCopy {
3
+ heading: string;
4
+ empty: string;
5
+ tool: string;
6
+ status: string;
7
+ when: string;
8
+ s_pending: string;
9
+ s_confirming: string;
10
+ s_approved_running: string;
11
+ s_succeeded: string;
12
+ s_failed: string;
13
+ s_rejected: string;
14
+ s_expired: string;
15
+ s_superseded: string;
16
+ s_cap_reached: string;
17
+ }
18
+ export interface AgentApprovalLedgerProps {
19
+ approvals: readonly Pick<AgentApproval, "approvalId" | "tool" | "intent" | "status" | "decidedAt" | "expiresAt">[];
20
+ /** Locale-aware time formatter supplied by the host. Defaults to the ISO string. */
21
+ formatTime?: (iso: string) => string;
22
+ copy?: Partial<AgentApprovalLedgerCopy>;
23
+ className?: string;
24
+ }
25
+ /** @internal The thread's past approvals as a table. */
26
+ export declare function AgentApprovalLedger({ approvals, formatTime, copy, className, }: AgentApprovalLedgerProps): import("react/jsx-runtime").JSX.Element;
27
+ //# sourceMappingURL=approval-ledger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"approval-ledger.d.ts","sourceRoot":"","sources":["../../src/agent/approval-ledger.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAuB,MAAM,UAAU,CAAC;AAGnE,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;CACvB;AA6BD,MAAM,WAAW,wBAAwB;IACvC,SAAS,EAAE,SAAS,IAAI,CACtB,aAAa,EACb,YAAY,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,WAAW,GAAG,WAAW,CACxE,EAAE,CAAC;IACJ,oFAAoF;IACpF,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;IACrC,IAAI,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,CAAC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wDAAwD;AACxD,wBAAgB,mBAAmB,CAAC,EAClC,SAAS,EACT,UAAqB,EACrB,IAAI,EACJ,SAAS,GACV,EAAE,wBAAwB,2CAyC1B"}
@@ -0,0 +1,39 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cn } from "../lib/utils.js";
3
+ import { useCopy } from "./copy.js";
4
+ import { toneChip } from "./ui.js";
5
+ const DEFAULT_COPY = {
6
+ heading: "Approvals in this conversation",
7
+ empty: "No approvals yet.",
8
+ tool: "Action",
9
+ status: "Outcome",
10
+ when: "When",
11
+ s_pending: "Waiting",
12
+ s_confirming: "Confirming",
13
+ s_approved_running: "Running",
14
+ s_succeeded: "Done",
15
+ s_failed: "Failed",
16
+ s_rejected: "Rejected",
17
+ s_expired: "Expired",
18
+ s_superseded: "Replaced",
19
+ s_cap_reached: "Cap reached",
20
+ };
21
+ const TONE = {
22
+ pending: "warning",
23
+ confirming: "info",
24
+ approved_running: "info",
25
+ succeeded: "success",
26
+ failed: "danger",
27
+ rejected: "neutral",
28
+ expired: "warning",
29
+ superseded: "neutral",
30
+ cap_reached: "warning",
31
+ };
32
+ /** @internal The thread's past approvals as a table. */
33
+ export function AgentApprovalLedger({ approvals, formatTime = (s) => s, copy, className, }) {
34
+ const c = useCopy(DEFAULT_COPY, copy);
35
+ if (approvals.length === 0)
36
+ return _jsx("p", { className: cn("text-sm/5 text-muted-foreground", className), children: c.empty });
37
+ return (_jsxs("table", { className: cn("w-full text-left text-sm/5", className), children: [_jsx("caption", { className: "pb-2 text-left text-xs/4 font-medium uppercase tracking-wider text-muted-foreground", children: c.heading }), _jsx("thead", { className: "sr-only", children: _jsxs("tr", { children: [_jsx("th", { scope: "col", children: c.tool }), _jsx("th", { scope: "col", children: c.status }), _jsx("th", { scope: "col", children: c.when })] }) }), _jsx("tbody", { className: "divide-y divide-border/60", children: approvals.map((a) => (_jsxs("tr", { children: [_jsxs("td", { className: "py-2 pr-3", children: [_jsx("span", { className: "block font-mono text-xs/5 text-foreground", children: a.tool }), _jsx("span", { className: "block text-muted-foreground", children: a.intent })] }), _jsx("td", { className: "py-2 pr-3", children: _jsx("span", { className: cn("rounded-full px-2 py-0.5 text-xs/4 font-medium", toneChip[TONE[a.status]]), children: c[`s_${a.status}`] }) }), _jsx("td", { className: "py-2 text-xs/5 tabular-nums text-muted-foreground", children: formatTime(a.decidedAt ?? a.expiresAt) })] }, a.approvalId))) })] }));
38
+ }
39
+ //# sourceMappingURL=approval-ledger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"approval-ledger.js","sourceRoot":"","sources":["../../src/agent/approval-ledger.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEjC,OAAO,EAAE,QAAQ,EAAa,MAAM,MAAM,CAAC;AAkB3C,MAAM,YAAY,GAA4B;IAC5C,OAAO,EAAE,gCAAgC;IACzC,KAAK,EAAE,mBAAmB;IAC1B,IAAI,EAAE,QAAQ;IACd,MAAM,EAAE,SAAS;IACjB,IAAI,EAAE,MAAM;IACZ,SAAS,EAAE,SAAS;IACpB,YAAY,EAAE,YAAY;IAC1B,kBAAkB,EAAE,SAAS;IAC7B,WAAW,EAAE,MAAM;IACnB,QAAQ,EAAE,QAAQ;IAClB,UAAU,EAAE,UAAU;IACtB,SAAS,EAAE,SAAS;IACpB,YAAY,EAAE,UAAU;IACxB,aAAa,EAAE,aAAa;CAC7B,CAAC;AACF,MAAM,IAAI,GAAsC;IAC9C,OAAO,EAAE,SAAS;IAClB,UAAU,EAAE,MAAM;IAClB,gBAAgB,EAAE,MAAM;IACxB,SAAS,EAAE,SAAS;IACpB,MAAM,EAAE,QAAQ;IAChB,QAAQ,EAAE,SAAS;IACnB,OAAO,EAAE,SAAS;IAClB,UAAU,EAAE,SAAS;IACrB,WAAW,EAAE,SAAS;CACvB,CAAC;AAaF,wDAAwD;AACxD,MAAM,UAAU,mBAAmB,CAAC,EAClC,SAAS,EACT,UAAU,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EACrB,IAAI,EACJ,SAAS,GACgB;IACzB,MAAM,CAAC,GAAG,OAAO,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;IACtC,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;QACxB,OAAO,YAAG,SAAS,EAAE,EAAE,CAAC,iCAAiC,EAAE,SAAS,CAAC,YAAG,CAAC,CAAC,KAAK,GAAK,CAAC;IACvF,OAAO,CACL,iBAAO,SAAS,EAAE,EAAE,CAAC,4BAA4B,EAAE,SAAS,CAAC,aAC3D,kBAAS,SAAS,EAAC,qFAAqF,YACrG,CAAC,CAAC,OAAO,GACF,EACV,gBAAO,SAAS,EAAC,SAAS,YACxB,yBACE,aAAI,KAAK,EAAC,KAAK,YAAE,CAAC,CAAC,IAAI,GAAM,EAC7B,aAAI,KAAK,EAAC,KAAK,YAAE,CAAC,CAAC,MAAM,GAAM,EAC/B,aAAI,KAAK,EAAC,KAAK,YAAE,CAAC,CAAC,IAAI,GAAM,IAC1B,GACC,EACR,gBAAO,SAAS,EAAC,2BAA2B,YACzC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CACpB,yBACE,cAAI,SAAS,EAAC,WAAW,aACvB,eAAM,SAAS,EAAC,2CAA2C,YAAE,CAAC,CAAC,IAAI,GAAQ,EAC3E,eAAM,SAAS,EAAC,6BAA6B,YAAE,CAAC,CAAC,MAAM,GAAQ,IAC5D,EACL,aAAI,SAAS,EAAC,WAAW,YACvB,eACE,SAAS,EAAE,EAAE,CACX,gDAAgD,EAChD,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CACzB,YAEA,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,EAAmC,CAAC,GAC/C,GACJ,EACL,aAAI,SAAS,EAAC,mDAAmD,YAC9D,UAAU,CAAC,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,SAAS,CAAC,GACpC,KAjBE,CAAC,CAAC,UAAU,CAkBhB,CACN,CAAC,GACI,IACF,CACT,CAAC;AACJ,CAAC"}
@@ -0,0 +1,27 @@
1
+ export interface AgentComposerCopy {
2
+ label: string;
3
+ placeholder: string;
4
+ send: string;
5
+ stop: string;
6
+ disabledRun: string;
7
+ disabledApproval: string;
8
+ tooLong: string;
9
+ counter: string;
10
+ suggestions: string;
11
+ }
12
+ export interface AgentComposerProps {
13
+ onSubmit: (text: string) => void;
14
+ onStop?: () => void;
15
+ /** A run is in flight: sending is blocked, Stop is offered. */
16
+ running?: boolean;
17
+ /** An approval is pending: sending is blocked until it is decided. */
18
+ approvalPending?: boolean;
19
+ disabled?: boolean;
20
+ maxLength?: number;
21
+ suggestions?: readonly string[];
22
+ copy?: Partial<AgentComposerCopy>;
23
+ className?: string;
24
+ }
25
+ /** @internal Composer. Enter sends, Shift+Enter newline, Esc stops a running run. */
26
+ export declare function AgentComposer({ onSubmit, onStop, running, approvalPending, disabled, maxLength, suggestions, copy, className, }: AgentComposerProps): import("react/jsx-runtime").JSX.Element;
27
+ //# sourceMappingURL=composer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"composer.d.ts","sourceRoot":"","sources":["../../src/agent/composer.tsx"],"names":[],"mappings":"AAMA,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;CACrB;AAaD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,+DAA+D;IAC/D,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,sEAAsE;IACtE,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,IAAI,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,qFAAqF;AACrF,wBAAgB,aAAa,CAAC,EAC5B,QAAQ,EACR,MAAM,EACN,OAAe,EACf,eAAuB,EACvB,QAAgB,EAChB,SAAgB,EAChB,WAAW,EACX,IAAI,EACJ,SAAS,GACV,EAAE,kBAAkB,2CAoGpB"}
@@ -0,0 +1,50 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useId, useRef, useState } from "react";
3
+ import { SendHorizontal, Square } from "lucide-react";
4
+ import { cn } from "../lib/utils.js";
5
+ import { fmt, useCopy } from "./copy.js";
6
+ import { agentButton, focusRing } from "./ui.js";
7
+ const DEFAULT_COPY = {
8
+ label: "Message the agent",
9
+ placeholder: "Ask a question. Enter to send, Shift+Enter for a new line.",
10
+ send: "Send",
11
+ stop: "Stop",
12
+ disabledRun: "The agent is working. You can stop it.",
13
+ disabledApproval: "Decide on the pending approval first.",
14
+ tooLong: "Message is {over} characters over the limit.",
15
+ counter: "{used} of {max}",
16
+ suggestions: "Suggestions",
17
+ };
18
+ /** @internal Composer. Enter sends, Shift+Enter newline, Esc stops a running run. */
19
+ export function AgentComposer({ onSubmit, onStop, running = false, approvalPending = false, disabled = false, maxLength = 4000, suggestions, copy, className, }) {
20
+ const c = useCopy(DEFAULT_COPY, copy);
21
+ const [value, setValue] = useState("");
22
+ const taRef = useRef(null);
23
+ const id = useId();
24
+ const over = value.length - maxLength;
25
+ const blocked = disabled || running || approvalPending;
26
+ const canSend = !blocked && value.trim().length > 0 && over <= 0;
27
+ const reason = running ? c.disabledRun : approvalPending ? c.disabledApproval : undefined;
28
+ function submit() {
29
+ if (!canSend)
30
+ return;
31
+ onSubmit(value.trim());
32
+ setValue("");
33
+ }
34
+ return (_jsxs("form", { className: cn("flex flex-col gap-2", className), onSubmit: (e) => {
35
+ e.preventDefault();
36
+ submit();
37
+ }, children: [suggestions && suggestions.length > 0 && value === "" && !blocked && (_jsx("div", { role: "group", "aria-label": c.suggestions, className: "flex flex-wrap gap-2", children: suggestions.map((s) => (_jsx("button", { type: "button", className: cn("rounded-full bg-muted px-3 py-1 text-xs/5 text-foreground hover:bg-muted/70", focusRing), onClick: () => {
38
+ setValue(s);
39
+ taRef.current?.focus();
40
+ }, children: s }, s))) })), _jsxs("div", { className: "rounded-2xl bg-card p-1.5 ring-1 ring-border focus-within:ring-2 focus-within:ring-ring", children: [_jsx("label", { htmlFor: id, className: "sr-only", children: c.label }), _jsx("textarea", { id: id, ref: taRef, rows: 2, value: value, disabled: disabled, placeholder: c.placeholder, "aria-describedby": reason || over > 0 ? `${id}-note` : undefined, "aria-invalid": over > 0 || undefined, onChange: (e) => setValue(e.target.value), onKeyDown: (e) => {
41
+ if (e.key === "Enter" && !e.shiftKey && !e.nativeEvent.isComposing) {
42
+ e.preventDefault();
43
+ submit();
44
+ }
45
+ else if (e.key === "Escape" && running) {
46
+ onStop?.();
47
+ }
48
+ }, className: "block max-h-40 min-h-12 w-full resize-none bg-transparent px-2 py-1.5 text-sm/5 text-foreground outline-hidden placeholder:text-muted-foreground disabled:cursor-not-allowed" }), _jsxs("div", { className: "flex items-center justify-between gap-2 px-1 pt-1", children: [_jsx("p", { id: `${id}-note`, className: cn("min-w-0 text-xs/4", over > 0 ? "text-[var(--tone-danger-fg)]" : "text-muted-foreground"), children: over > 0 ? fmt(c.tooLong, { over }) : reason }), _jsxs("div", { className: "flex items-center gap-2", children: [value.length > maxLength * 0.8 && (_jsx("span", { className: "text-xs/4 tabular-nums text-muted-foreground", children: fmt(c.counter, { used: value.length, max: maxLength }) })), running ? (_jsxs("button", { type: "button", className: agentButton.quiet, onClick: onStop, children: [_jsx(Square, { "aria-hidden": true, className: "size-3.5" }), c.stop] })) : (_jsxs("button", { type: "submit", className: agentButton.primary, disabled: !canSend, children: [_jsx(SendHorizontal, { "aria-hidden": true, className: "size-3.5" }), c.send] }))] })] })] })] }));
49
+ }
50
+ //# sourceMappingURL=composer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"composer.js","sourceRoot":"","sources":["../../src/agent/composer.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ import type { AgentApproval } from "./schema.js";
2
+ export interface AgentConfirmCardCopy {
3
+ needsApproval: string;
4
+ confirm: string;
5
+ expiresSeconds: string;
6
+ was: string;
7
+ now: string;
8
+ emptyValue: string;
9
+ exactRequest: string;
10
+ confirmRun: string;
11
+ reject: string;
12
+ showRequest: string;
13
+ hideRequest: string;
14
+ riskRead: string;
15
+ riskReversible: string;
16
+ riskDestructive: string;
17
+ riskCostly: string;
18
+ taint: string;
19
+ expiresIn: string;
20
+ expiresSoon: string;
21
+ confirming: string;
22
+ approvedRunning: string;
23
+ succeeded: string;
24
+ failed: string;
25
+ failedHint: string;
26
+ rejected: string;
27
+ expired: string;
28
+ expiredHint: string;
29
+ superseded: string;
30
+ capReached: string;
31
+ noChanges: string;
32
+ changesHeading: string;
33
+ typeToConfirmTitle: string;
34
+ typeToConfirmBody: string;
35
+ typeToConfirmLabel: string;
36
+ cancel: string;
37
+ capRemaining: string;
38
+ }
39
+ export declare const DEFAULT_CONFIRM_CARD_COPY: AgentConfirmCardCopy;
40
+ export interface AgentConfirmCardProps {
41
+ approval: AgentApproval;
42
+ /** `typed` is set only for approvals that carry a `confirmPhrase`. */
43
+ onDecision: (decision: "approve" | "reject", typed?: string) => void;
44
+ /** Clock override (ms since epoch). Defaults to a 1 s ticking clock while the approval is pending. */
45
+ nowMs?: number;
46
+ copy?: Partial<AgentConfirmCardCopy>;
47
+ className?: string;
48
+ }
49
+ /**
50
+ * @internal The receipt-before-button confirmation card. Shows the persisted
51
+ * request (never a regenerated one), what changes, the taint and cost lines and
52
+ * the expiry. Guards (see `evaluateConfirmGuards`): Confirm is disabled until the
53
+ * typed phrase matches exactly, a decision fires once per approval (inert after
54
+ * the click until the server answers), and a superseded, expired, failed or
55
+ * decided card is read-only and can never be re-submitted.
56
+ */
57
+ export declare function AgentConfirmCard({ approval, onDecision, nowMs, copy, className, }: AgentConfirmCardProps): import("react/jsx-runtime").JSX.Element;
58
+ //# sourceMappingURL=confirm-card.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"confirm-card.d.ts","sourceRoot":"","sources":["../../src/agent/confirm-card.tsx"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,aAAa,EAAkC,MAAM,UAAU,CAAC;AAG9E,MAAM,WAAW,oBAAoB;IACnC,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,eAAO,MAAM,yBAAyB,EAAE,oBAsCvC,CAAC;AAsBF,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,aAAa,CAAC;IACxB,sEAAsE;IACtE,UAAU,EAAE,CAAC,QAAQ,EAAE,SAAS,GAAG,QAAQ,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACrE,sGAAsG;IACtG,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAYD;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,QAAQ,EACR,UAAU,EACV,KAAK,EACL,IAAI,EACJ,SAAS,GACV,EAAE,qBAAqB,2CAiSvB"}
@@ -0,0 +1,127 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useId, useRef, useState } from "react";
3
+ import { ArrowRight, Ban, CheckCircle2, ChevronRight, CircleAlert, Clock, Loader2, ShieldAlert, Replace, } from "lucide-react";
4
+ import { Dialog, DialogActions, DialogBody, DialogDescription, DialogTitle, } from "../components/dialog.js";
5
+ import { cn } from "../lib/utils.js";
6
+ import { evaluateConfirmGuards } from "./confirm-guards.js";
7
+ import { fmt, useCopy } from "./copy.js";
8
+ import { MaskedValue } from "./masked-value.js";
9
+ import { agentButton, bezel, focusRing, toneChip } from "./ui.js";
10
+ export const DEFAULT_CONFIRM_CARD_COPY = {
11
+ needsApproval: "Needs your approval",
12
+ confirm: "Review and confirm",
13
+ expiresSeconds: "Expires in {seconds} s",
14
+ was: "was",
15
+ now: "now",
16
+ emptyValue: "(empty)",
17
+ exactRequest: "Exact request that will run",
18
+ confirmRun: "Confirm and run",
19
+ reject: "Reject",
20
+ showRequest: "Show exact request",
21
+ hideRequest: "Hide request",
22
+ riskRead: "Read only",
23
+ riskReversible: "Reversible change",
24
+ riskDestructive: "Cannot be undone",
25
+ riskCostly: "Paid action",
26
+ taint: "Influenced by untrusted content from: {sources}. Do not confirm unless you recognise these sources.",
27
+ expiresIn: "Expires in {minutes} min",
28
+ expiresSoon: "Expires in under a minute",
29
+ confirming: "Waiting for the server to confirm",
30
+ approvedRunning: "Approved, running",
31
+ succeeded: "Done",
32
+ failed: "Failed",
33
+ failedHint: "This approval cannot be retried. Ask the agent to propose the change again.",
34
+ rejected: "Rejected, nothing was changed",
35
+ expired: "Expired, nothing was changed",
36
+ expiredHint: "Ask the agent to propose the change again.",
37
+ superseded: "Replaced by a newer proposal",
38
+ capReached: "Daily cap reached, this action cannot run today",
39
+ noChanges: "No field-level preview was provided. Open the exact request below to see what will run.",
40
+ changesHeading: "What changes",
41
+ typeToConfirmTitle: "Confirm this action",
42
+ typeToConfirmBody: "Type the text below exactly to enable Confirm. Case and spaces count.",
43
+ typeToConfirmLabel: "Confirmation text",
44
+ cancel: "Cancel",
45
+ capRemaining: "Cap remaining: {remaining}",
46
+ };
47
+ const RISK = {
48
+ read: { tone: "neutral", key: "riskRead" },
49
+ reversible: { tone: "info", key: "riskReversible" },
50
+ destructive: { tone: "danger", key: "riskDestructive" },
51
+ costly: { tone: "warning", key: "riskCostly" },
52
+ };
53
+ const TERMINAL_ICON = {
54
+ succeeded: { icon: CheckCircle2, tone: "success" },
55
+ failed: { icon: CircleAlert, tone: "danger" },
56
+ rejected: { icon: Ban, tone: "neutral" },
57
+ expired: { icon: Clock, tone: "warning" },
58
+ superseded: { icon: Replace, tone: "neutral" },
59
+ cap_reached: { icon: CircleAlert, tone: "warning" },
60
+ confirming: { icon: Loader2, tone: "info" },
61
+ approved_running: { icon: Loader2, tone: "info" },
62
+ };
63
+ const rowKey = (label, i) => `${label}:${i}`;
64
+ function useNowMs(override, active) {
65
+ const [now, setNow] = useState(() => Date.now());
66
+ useEffect(() => {
67
+ if (override !== undefined || !active)
68
+ return;
69
+ const id = window.setInterval(() => setNow(Date.now()), 1000);
70
+ return () => window.clearInterval(id);
71
+ }, [override, active]);
72
+ return override ?? now;
73
+ }
74
+ /**
75
+ * @internal The receipt-before-button confirmation card. Shows the persisted
76
+ * request (never a regenerated one), what changes, the taint and cost lines and
77
+ * the expiry. Guards (see `evaluateConfirmGuards`): Confirm is disabled until the
78
+ * typed phrase matches exactly, a decision fires once per approval (inert after
79
+ * the click until the server answers), and a superseded, expired, failed or
80
+ * decided card is read-only and can never be re-submitted.
81
+ */
82
+ export function AgentConfirmCard({ approval, onDecision, nowMs, copy, className, }) {
83
+ const c = useCopy(DEFAULT_CONFIRM_CARD_COPY, copy);
84
+ const titleId = useId();
85
+ const phraseHintId = useId();
86
+ const [typed, setTyped] = useState("");
87
+ const [dialogOpen, setDialogOpen] = useState(false);
88
+ const [showBody, setShowBody] = useState(false);
89
+ // Single-shot: remembered per approvalId, in a ref so two clicks in one tick cannot both fire.
90
+ const firedRef = useRef(null);
91
+ const [firedId, setFiredId] = useState(null);
92
+ const now = useNowMs(nowMs, approval.status === "pending");
93
+ const fired = firedId === approval.approvalId;
94
+ const g = evaluateConfirmGuards({ approval, typed, nowMs: now, fired });
95
+ function decide(decision) {
96
+ // Re-evaluate at click time against the freshest clock, never trust a stale render.
97
+ const live = evaluateConfirmGuards({
98
+ approval,
99
+ typed,
100
+ nowMs: nowMs ?? Date.now(),
101
+ fired: firedRef.current === approval.approvalId,
102
+ });
103
+ if (decision === "approve" ? !live.canConfirm : !live.canReject)
104
+ return;
105
+ firedRef.current = approval.approvalId;
106
+ setFiredId(approval.approvalId);
107
+ setDialogOpen(false);
108
+ onDecision(decision, decision === "approve" && live.phraseRequired ? typed : undefined);
109
+ }
110
+ const live = g.status === "pending";
111
+ // A decision just fired but the host has not moved the status yet: show it as confirming, never as an idle card.
112
+ const inFlight = live && fired;
113
+ const risk = RISK[approval.risk];
114
+ const secondsLeft = Math.max(0, Math.floor((Date.parse(approval.expiresAt) - now) / 1000));
115
+ const minutes = Math.floor(secondsLeft / 60);
116
+ const shown = inFlight ? "confirming" : g.status;
117
+ const terminal = shown !== "pending" ? TERMINAL_ICON[shown] : undefined;
118
+ const hasChanges = (approval.changes?.length ?? 0) > 0;
119
+ const bodyText = approval.body === undefined ? undefined : JSON.stringify(approval.body, null, 2);
120
+ return (_jsxs("section", { id: `agent-approval-${approval.approvalId}`, tabIndex: -1, role: "group", "aria-labelledby": titleId, "data-status": g.status, className: cn(bezel, "p-1 text-sm/5", className), children: [_jsxs("div", { className: "rounded-xl bg-background p-3", children: [_jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [_jsxs("span", { className: cn("inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-xs/4 font-medium", toneChip[risk.tone]), children: [_jsx(ShieldAlert, { "aria-hidden": true, className: "size-3" }), c[risk.key]] }), live && !inFlight && (_jsxs("span", { className: "text-xs/4 text-muted-foreground", children: [_jsx(Clock, { "aria-hidden": true, className: "mr-1 inline size-3 align-[-1px]" }), _jsx("time", { dateTime: approval.expiresAt, children: minutes < 2
121
+ ? fmt(c.expiresSeconds, { seconds: secondsLeft })
122
+ : fmt(c.expiresIn, { minutes }) })] }))] }), approval.taint && (_jsx("p", { className: cn("mt-2 rounded-lg font-medium px-2.5 py-1.5 text-xs/4", toneChip.warning), "data-testid": "taint-strip", children: fmt(c.taint, { sources: approval.taint.sources.join(", ") }) })), _jsx("p", { id: titleId, className: "mt-2 text-base/6 font-medium text-foreground", children: approval.intent }), _jsxs("p", { className: "mt-1 break-all font-mono text-xs/4 text-foreground", children: [_jsx("span", { className: "font-semibold", children: approval.method }), " ", approval.routeTemplate] }), hasChanges ? (_jsx("dl", { "aria-label": c.changesHeading, tabIndex: 0, className: cn("mt-3 max-h-56 divide-y divide-border/60 overflow-y-auto rounded-lg ring-1 ring-border/60", focusRing), children: approval.changes.map((row, i) => (_jsxs("div", { className: "grid grid-cols-[minmax(0,9rem)_1fr] gap-x-3 px-3 py-1.5", children: [_jsx("dt", { className: "break-words text-xs/5 text-muted-foreground", title: row.label, children: row.label }), _jsxs("dd", { className: "flex min-w-0 flex-wrap items-center gap-1.5 text-sm/5", children: [row.before !== undefined && (_jsxs("span", { className: "text-muted-foreground line-through decoration-muted-foreground/60", children: [_jsxs("span", { className: "sr-only", children: [c.was, ": "] }), _jsx(MaskedValue, { value: row.before, empty: c.emptyValue })] })), row.before !== undefined && row.after !== undefined && (_jsx(ArrowRight, { "aria-hidden": true, className: "size-3 shrink-0 text-muted-foreground" })), row.after !== undefined && (_jsxs("span", { className: "font-medium text-foreground", children: [_jsxs("span", { className: "sr-only", children: [c.now, ": "] }), _jsx(MaskedValue, { value: row.after, empty: c.emptyValue })] }))] })] }, rowKey(row.label, i)))) })) : (bodyText !== undefined && (_jsx("p", { className: "mt-3 text-xs/5 text-muted-foreground", children: c.noChanges }))), approval.cost && (_jsxs("p", { className: "mt-2 text-xs/4 text-muted-foreground", children: [approval.cost.label, approval.cost.capRemaining
123
+ ? ` · ${fmt(c.capRemaining, { remaining: approval.cost.capRemaining })}`
124
+ : ""] })), bodyText !== undefined && (_jsxs("div", { className: "mt-2", children: [_jsxs("button", { type: "button", "aria-expanded": showBody, onClick: () => setShowBody((v) => !v), className: cn("inline-flex min-h-6 items-center gap-1 rounded-md text-xs/4 text-muted-foreground hover:text-foreground", focusRing), children: [_jsx(ChevronRight, { "aria-hidden": true, className: cn("size-3.5 transition-transform duration-[var(--duration-micro)] motion-reduce:transition-none", showBody && "rotate-90") }), showBody ? c.hideRequest : c.showRequest] }), showBody && (_jsx("pre", { tabIndex: 0, "aria-label": c.exactRequest, className: cn("mt-1 max-h-40 overflow-auto rounded-lg bg-muted p-2.5 font-mono text-xs/5 text-foreground", focusRing), children: bodyText }))] }))] }), _jsx("div", { className: "px-3 py-2", children: g.status === "pending" && !inFlight ? (_jsxs("div", { className: "flex flex-wrap items-center justify-end gap-2", children: [_jsx("button", { type: "button", className: agentButton.quiet, disabled: !g.canReject, onClick: () => decide("reject"), children: c.reject }), _jsx("button", { type: "button", className: approval.risk === "destructive" ? agentButton.danger : agentButton.primary, disabled: g.phraseRequired ? !g.open : !g.canConfirm, onClick: () => (g.phraseRequired ? setDialogOpen(true) : decide("approve")), children: g.phraseRequired ? c.confirm : c.confirmRun })] })) : (_jsxs("div", { role: "status", className: "flex items-start gap-2", children: [terminal && (_jsx("span", { className: cn("mt-0.5 inline-flex size-5 shrink-0 items-center justify-center rounded-full", toneChip[terminal.tone]), children: _jsx(terminal.icon, { "aria-hidden": true, className: cn("size-3", (shown === "confirming" || shown === "approved_running") &&
125
+ "animate-spin motion-reduce:animate-none") }) })), _jsxs("div", { className: "min-w-0 text-sm/5", children: [_jsxs("p", { className: "font-medium text-foreground", children: [shown === "confirming" && c.confirming, g.status === "approved_running" && c.approvedRunning, g.status === "succeeded" && (approval.resultSummary ?? c.succeeded), g.status === "failed" && (approval.error ?? c.failed), g.status === "rejected" && c.rejected, g.status === "expired" && c.expired, g.status === "superseded" && c.superseded, g.status === "cap_reached" && c.capReached] }), g.status === "failed" && _jsx("p", { className: "text-muted-foreground", children: c.failedHint }), g.status === "expired" && _jsx("p", { className: "text-muted-foreground", children: c.expiredHint })] })] })) }), g.phraseRequired && (_jsxs(Dialog, { open: dialogOpen && g.open, onClose: () => setDialogOpen(false), size: "md", children: [_jsx(DialogTitle, { children: c.typeToConfirmTitle }), _jsx(DialogDescription, { id: phraseHintId, children: approval.intent }), _jsxs("p", { className: "mt-2 break-all font-mono text-xs/4 text-foreground", children: [_jsx("span", { className: "font-semibold", children: approval.method }), " ", approval.routeTemplate] }), _jsxs(DialogBody, { children: [_jsx("label", { className: "block text-sm/5 font-medium text-foreground", htmlFor: `${phraseHintId}-input`, children: c.typeToConfirmLabel }), _jsx("p", { className: "mt-1 text-sm/5 text-muted-foreground", id: `${phraseHintId}-hint`, children: c.typeToConfirmBody }), _jsx("code", { className: "mt-2 block break-all rounded-lg border border-border bg-muted px-3 py-2 font-mono text-sm/5 text-foreground", children: approval.confirmPhrase }), _jsx("input", { id: `${phraseHintId}-input`, value: typed, onChange: (e) => setTyped(e.target.value), "aria-describedby": `${phraseHintId}-hint`, autoComplete: "off", spellCheck: false, className: cn("mt-2 w-full rounded-lg border border-input bg-background px-3 py-2 font-mono text-sm/5", focusRing) })] }), _jsxs(DialogActions, { children: [_jsx("button", { type: "button", className: agentButton.quiet, onClick: () => setDialogOpen(false), children: c.cancel }), _jsx("button", { type: "button", className: approval.risk === "destructive" ? agentButton.danger : agentButton.primary, disabled: !g.canConfirm, onClick: () => decide("approve"), children: c.confirmRun })] })] }))] }));
126
+ }
127
+ //# sourceMappingURL=confirm-card.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"confirm-card.js","sourceRoot":"","sources":["../../src/agent/confirm-card.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ import type { AgentApproval } from "./schema.js";
2
+ /**
3
+ * @internal The confirm-card guards, as a pure function so they can be tested
4
+ * (and mutation-proven) without a DOM. Component and tests both go through here.
5
+ */
6
+ export interface ConfirmGuardInput {
7
+ approval: Pick<AgentApproval, "status" | "confirmPhrase" | "expiresAt">;
8
+ typed: string;
9
+ nowMs: number;
10
+ /** True once this card has already emitted a decision for this approvalId. */
11
+ fired: boolean;
12
+ }
13
+ export interface ConfirmGuardResult {
14
+ /** The card can still accept a decision at all (pending, not expired, not already fired). */
15
+ open: boolean;
16
+ /** Effective status after local expiry. */
17
+ status: AgentApproval["status"];
18
+ phraseRequired: boolean;
19
+ phraseMatches: boolean;
20
+ canConfirm: boolean;
21
+ canReject: boolean;
22
+ }
23
+ export declare function evaluateConfirmGuards({ approval, typed, nowMs, fired, }: ConfirmGuardInput): ConfirmGuardResult;
24
+ /**
25
+ * At most one approval is live per thread: the pending approval with the newest
26
+ * `createdAt` is live, every other pending one renders as superseded
27
+ * (read-only), mirroring the server's rule. Ordering uses `createdAt`, never
28
+ * array position, so caller order cannot make a stale approval live. A pending
29
+ * approval whose `createdAt` cannot be parsed is never live.
30
+ */
31
+ export declare function supersedeStale<T extends {
32
+ approvalId: string;
33
+ status: AgentApproval["status"];
34
+ createdAt: string;
35
+ }>(approvals: readonly T[]): Map<string, AgentApproval["status"]>;
36
+ //# sourceMappingURL=confirm-guards.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"confirm-guards.d.ts","sourceRoot":"","sources":["../../src/agent/confirm-guards.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,IAAI,CAAC,aAAa,EAAE,QAAQ,GAAG,eAAe,GAAG,WAAW,CAAC,CAAC;IACxE,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,8EAA8E;IAC9E,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC,6FAA6F;IAC7F,IAAI,EAAE,OAAO,CAAC;IACd,2CAA2C;IAC3C,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;IAChC,cAAc,EAAE,OAAO,CAAC;IACxB,aAAa,EAAE,OAAO,CAAC;IACvB,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,qBAAqB,CAAC,EACpC,QAAQ,EACR,KAAK,EACL,KAAK,EACL,KAAK,GACN,EAAE,iBAAiB,GAAG,kBAAkB,CAkBxC;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,CAAC,SAAS;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,EACpF,SAAS,EAAE,SAAS,CAAC,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC,CAkB/D"}
@@ -0,0 +1,44 @@
1
+ export function evaluateConfirmGuards({ approval, typed, nowMs, fired, }) {
2
+ // Fail closed: an unparseable expiry (NaN) counts as expired.
3
+ const expired = !(Date.parse(approval.expiresAt) > nowMs);
4
+ const status = approval.status === "pending" && expired ? "expired" : approval.status;
5
+ const open = status === "pending" && !fired;
6
+ const phraseRequired = approval.confirmPhrase !== undefined;
7
+ // Exact, case-sensitive, untrimmed: the statement the admin makes is the statement we check.
8
+ // An empty phrase would silently mean "no phrase": it can never match, so it fails closed.
9
+ const phraseMatches = !phraseRequired || (approval.confirmPhrase !== "" && typed === approval.confirmPhrase);
10
+ return {
11
+ open,
12
+ status,
13
+ phraseRequired,
14
+ phraseMatches,
15
+ canConfirm: open && phraseMatches,
16
+ canReject: open,
17
+ };
18
+ }
19
+ /**
20
+ * At most one approval is live per thread: the pending approval with the newest
21
+ * `createdAt` is live, every other pending one renders as superseded
22
+ * (read-only), mirroring the server's rule. Ordering uses `createdAt`, never
23
+ * array position, so caller order cannot make a stale approval live. A pending
24
+ * approval whose `createdAt` cannot be parsed is never live.
25
+ */
26
+ export function supersedeStale(approvals) {
27
+ let live;
28
+ let liveAt = Number.NEGATIVE_INFINITY;
29
+ for (const a of approvals) {
30
+ if (a.status !== "pending")
31
+ continue;
32
+ const at = Date.parse(a.createdAt);
33
+ // NaN (unparseable) compares false, so such an approval can never become live.
34
+ if (at >= liveAt) {
35
+ live = a.approvalId;
36
+ liveAt = at;
37
+ }
38
+ }
39
+ return new Map(approvals.map((a) => [
40
+ a.approvalId,
41
+ a.status === "pending" && a.approvalId !== live ? "superseded" : a.status,
42
+ ]));
43
+ }
44
+ //# sourceMappingURL=confirm-guards.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"confirm-guards.js","sourceRoot":"","sources":["../../src/agent/confirm-guards.ts"],"names":[],"mappings":"AAyBA,MAAM,UAAU,qBAAqB,CAAC,EACpC,QAAQ,EACR,KAAK,EACL,KAAK,EACL,KAAK,GACa;IAClB,8DAA8D;IAC9D,MAAM,OAAO,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,GAAG,KAAK,CAAC,CAAC;IAC1D,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,KAAK,SAAS,IAAI,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC;IACtF,MAAM,IAAI,GAAG,MAAM,KAAK,SAAS,IAAI,CAAC,KAAK,CAAC;IAC5C,MAAM,cAAc,GAAG,QAAQ,CAAC,aAAa,KAAK,SAAS,CAAC;IAC5D,6FAA6F;IAC7F,2FAA2F;IAC3F,MAAM,aAAa,GACjB,CAAC,cAAc,IAAI,CAAC,QAAQ,CAAC,aAAa,KAAK,EAAE,IAAI,KAAK,KAAK,QAAQ,CAAC,aAAa,CAAC,CAAC;IACzF,OAAO;QACL,IAAI;QACJ,MAAM;QACN,cAAc;QACd,aAAa;QACb,UAAU,EAAE,IAAI,IAAI,aAAa;QACjC,SAAS,EAAE,IAAI;KAChB,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAE5B,SAAuB;IACvB,IAAI,IAAwB,CAAC;IAC7B,IAAI,MAAM,GAAG,MAAM,CAAC,iBAAiB,CAAC;IACtC,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;QAC1B,IAAI,CAAC,CAAC,MAAM,KAAK,SAAS;YAAE,SAAS;QACrC,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QACnC,+EAA+E;QAC/E,IAAI,EAAE,IAAI,MAAM,EAAE,CAAC;YACjB,IAAI,GAAG,CAAC,CAAC,UAAU,CAAC;YACpB,MAAM,GAAG,EAAE,CAAC;QACd,CAAC;IACH,CAAC;IACD,OAAO,IAAI,GAAG,CACZ,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QACnB,CAAC,CAAC,UAAU;QACZ,CAAC,CAAC,MAAM,KAAK,SAAS,IAAI,CAAC,CAAC,UAAU,KAAK,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM;KAC1E,CAAC,CACH,CAAC;AACJ,CAAC"}