@agent-native/core 0.34.0 → 0.35.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 (130) hide show
  1. package/dist/agent/context-xray/actions/context-evict.d.ts +3 -0
  2. package/dist/agent/context-xray/actions/context-evict.d.ts.map +1 -0
  3. package/dist/agent/context-xray/actions/context-evict.js +35 -0
  4. package/dist/agent/context-xray/actions/context-evict.js.map +1 -0
  5. package/dist/agent/context-xray/actions/context-manifest-get.d.ts +3 -0
  6. package/dist/agent/context-xray/actions/context-manifest-get.d.ts.map +1 -0
  7. package/dist/agent/context-xray/actions/context-manifest-get.js +67 -0
  8. package/dist/agent/context-xray/actions/context-manifest-get.js.map +1 -0
  9. package/dist/agent/context-xray/actions/context-pin.d.ts +3 -0
  10. package/dist/agent/context-xray/actions/context-pin.d.ts.map +1 -0
  11. package/dist/agent/context-xray/actions/context-pin.js +35 -0
  12. package/dist/agent/context-xray/actions/context-pin.js.map +1 -0
  13. package/dist/agent/context-xray/actions/context-report.d.ts +3 -0
  14. package/dist/agent/context-xray/actions/context-report.d.ts.map +1 -0
  15. package/dist/agent/context-xray/actions/context-report.js +59 -0
  16. package/dist/agent/context-xray/actions/context-report.js.map +1 -0
  17. package/dist/agent/context-xray/actions/context-restore.d.ts +3 -0
  18. package/dist/agent/context-xray/actions/context-restore.d.ts.map +1 -0
  19. package/dist/agent/context-xray/actions/context-restore.js +33 -0
  20. package/dist/agent/context-xray/actions/context-restore.js.map +1 -0
  21. package/dist/agent/context-xray/actions/errors.d.ts +7 -0
  22. package/dist/agent/context-xray/actions/errors.d.ts.map +1 -0
  23. package/dist/agent/context-xray/actions/errors.js +15 -0
  24. package/dist/agent/context-xray/actions/errors.js.map +1 -0
  25. package/dist/agent/context-xray/apply-directives.d.ts +10 -0
  26. package/dist/agent/context-xray/apply-directives.d.ts.map +1 -0
  27. package/dist/agent/context-xray/apply-directives.js +100 -0
  28. package/dist/agent/context-xray/apply-directives.js.map +1 -0
  29. package/dist/agent/context-xray/directives-store.d.ts +26 -0
  30. package/dist/agent/context-xray/directives-store.d.ts.map +1 -0
  31. package/dist/agent/context-xray/directives-store.js +131 -0
  32. package/dist/agent/context-xray/directives-store.js.map +1 -0
  33. package/dist/agent/context-xray/identity.d.ts +5 -0
  34. package/dist/agent/context-xray/identity.d.ts.map +1 -0
  35. package/dist/agent/context-xray/identity.js +33 -0
  36. package/dist/agent/context-xray/identity.js.map +1 -0
  37. package/dist/agent/context-xray/manifest.d.ts +19 -0
  38. package/dist/agent/context-xray/manifest.d.ts.map +1 -0
  39. package/dist/agent/context-xray/manifest.js +115 -0
  40. package/dist/agent/context-xray/manifest.js.map +1 -0
  41. package/dist/agent/context-xray/migrations.d.ts +3 -0
  42. package/dist/agent/context-xray/migrations.d.ts.map +1 -0
  43. package/dist/agent/context-xray/migrations.js +31 -0
  44. package/dist/agent/context-xray/migrations.js.map +1 -0
  45. package/dist/agent/context-xray/plugin.d.ts +5 -0
  46. package/dist/agent/context-xray/plugin.d.ts.map +1 -0
  47. package/dist/agent/context-xray/plugin.js +15 -0
  48. package/dist/agent/context-xray/plugin.js.map +1 -0
  49. package/dist/agent/context-xray/schema.d.ts +249 -0
  50. package/dist/agent/context-xray/schema.d.ts.map +1 -0
  51. package/dist/agent/context-xray/schema.js +17 -0
  52. package/dist/agent/context-xray/schema.js.map +1 -0
  53. package/dist/agent/context-xray/segments.d.ts +19 -0
  54. package/dist/agent/context-xray/segments.d.ts.map +1 -0
  55. package/dist/agent/context-xray/segments.js +154 -0
  56. package/dist/agent/context-xray/segments.js.map +1 -0
  57. package/dist/agent/context-xray/tokenize.d.ts +10 -0
  58. package/dist/agent/context-xray/tokenize.d.ts.map +1 -0
  59. package/dist/agent/context-xray/tokenize.js +70 -0
  60. package/dist/agent/context-xray/tokenize.js.map +1 -0
  61. package/dist/agent/production-agent.d.ts +2 -0
  62. package/dist/agent/production-agent.d.ts.map +1 -1
  63. package/dist/agent/production-agent.js +45 -5
  64. package/dist/agent/production-agent.js.map +1 -1
  65. package/dist/cli/context-xray-local.d.ts +16 -0
  66. package/dist/cli/context-xray-local.d.ts.map +1 -0
  67. package/dist/cli/context-xray-local.js +738 -0
  68. package/dist/cli/context-xray-local.js.map +1 -0
  69. package/dist/cli/skills.d.ts +3 -0
  70. package/dist/cli/skills.d.ts.map +1 -1
  71. package/dist/cli/skills.js +200 -73
  72. package/dist/cli/skills.js.map +1 -1
  73. package/dist/cli/templates-meta.js +5 -5
  74. package/dist/cli/templates-meta.js.map +1 -1
  75. package/dist/client/AssistantChat.d.ts.map +1 -1
  76. package/dist/client/AssistantChat.js +2 -1
  77. package/dist/client/AssistantChat.js.map +1 -1
  78. package/dist/client/components/ui/sheet.d.ts +16 -0
  79. package/dist/client/components/ui/sheet.d.ts.map +1 -0
  80. package/dist/client/components/ui/sheet.js +23 -0
  81. package/dist/client/components/ui/sheet.js.map +1 -0
  82. package/dist/client/context-xray/ContextMeter.d.ts +4 -0
  83. package/dist/client/context-xray/ContextMeter.d.ts.map +1 -0
  84. package/dist/client/context-xray/ContextMeter.js +76 -0
  85. package/dist/client/context-xray/ContextMeter.js.map +1 -0
  86. package/dist/client/context-xray/ContextSegmentRow.d.ts +9 -0
  87. package/dist/client/context-xray/ContextSegmentRow.d.ts.map +1 -0
  88. package/dist/client/context-xray/ContextSegmentRow.js +22 -0
  89. package/dist/client/context-xray/ContextSegmentRow.js.map +1 -0
  90. package/dist/client/context-xray/ContextTreemap.d.ts +6 -0
  91. package/dist/client/context-xray/ContextTreemap.d.ts.map +1 -0
  92. package/dist/client/context-xray/ContextTreemap.js +49 -0
  93. package/dist/client/context-xray/ContextTreemap.js.map +1 -0
  94. package/dist/client/context-xray/ContextXRayPanel.d.ts +11 -0
  95. package/dist/client/context-xray/ContextXRayPanel.d.ts.map +1 -0
  96. package/dist/client/context-xray/ContextXRayPanel.js +87 -0
  97. package/dist/client/context-xray/ContextXRayPanel.js.map +1 -0
  98. package/dist/client/context-xray/SegmentProvenancePopover.d.ts +7 -0
  99. package/dist/client/context-xray/SegmentProvenancePopover.d.ts.map +1 -0
  100. package/dist/client/context-xray/SegmentProvenancePopover.js +7 -0
  101. package/dist/client/context-xray/SegmentProvenancePopover.js.map +1 -0
  102. package/dist/client/context-xray/format.d.ts +7 -0
  103. package/dist/client/context-xray/format.d.ts.map +1 -0
  104. package/dist/client/context-xray/format.js +47 -0
  105. package/dist/client/context-xray/format.js.map +1 -0
  106. package/dist/deploy/route-discovery.d.ts.map +1 -1
  107. package/dist/deploy/route-discovery.js +1 -0
  108. package/dist/deploy/route-discovery.js.map +1 -1
  109. package/dist/deploy/workspace-core.d.ts +1 -1
  110. package/dist/deploy/workspace-core.d.ts.map +1 -1
  111. package/dist/deploy/workspace-core.js +1 -0
  112. package/dist/deploy/workspace-core.js.map +1 -1
  113. package/dist/server/action-discovery.d.ts.map +1 -1
  114. package/dist/server/action-discovery.js +20 -0
  115. package/dist/server/action-discovery.js.map +1 -1
  116. package/dist/server/framework-request-handler.d.ts.map +1 -1
  117. package/dist/server/framework-request-handler.js +2 -0
  118. package/dist/server/framework-request-handler.js.map +1 -1
  119. package/dist/server/index.d.ts +1 -0
  120. package/dist/server/index.d.ts.map +1 -1
  121. package/dist/server/index.js +1 -0
  122. package/dist/server/index.js.map +1 -1
  123. package/dist/shared/context-xray.d.ts +58 -0
  124. package/dist/shared/context-xray.d.ts.map +1 -0
  125. package/dist/shared/context-xray.js +17 -0
  126. package/dist/shared/context-xray.js.map +1 -0
  127. package/dist/vite/action-types-plugin.d.ts.map +1 -1
  128. package/dist/vite/action-types-plugin.js +20 -0
  129. package/dist/vite/action-types-plugin.js.map +1 -1
  130. package/package.json +9 -1
@@ -0,0 +1,16 @@
1
+ import * as React from "react";
2
+ import * as SheetPrimitive from "@radix-ui/react-dialog";
3
+ declare const Sheet: React.FC<SheetPrimitive.DialogProps>;
4
+ declare const SheetTrigger: React.ForwardRefExoticComponent<SheetPrimitive.DialogTriggerProps & React.RefAttributes<HTMLButtonElement>>;
5
+ declare const SheetClose: React.ForwardRefExoticComponent<SheetPrimitive.DialogCloseProps & React.RefAttributes<HTMLButtonElement>>;
6
+ declare const SheetContent: React.ForwardRefExoticComponent<Omit<SheetPrimitive.DialogContentProps & React.RefAttributes<HTMLDivElement>, "ref"> & {
7
+ side?: "right" | "left";
8
+ } & React.RefAttributes<HTMLDivElement>>;
9
+ declare const SheetHeader: {
10
+ ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>): import("react/jsx-runtime").JSX.Element;
11
+ displayName: string;
12
+ };
13
+ declare const SheetTitle: React.ForwardRefExoticComponent<Omit<SheetPrimitive.DialogTitleProps & React.RefAttributes<HTMLHeadingElement>, "ref"> & React.RefAttributes<HTMLHeadingElement>>;
14
+ declare const SheetDescription: React.ForwardRefExoticComponent<Omit<SheetPrimitive.DialogDescriptionProps & React.RefAttributes<HTMLParagraphElement>, "ref"> & React.RefAttributes<HTMLParagraphElement>>;
15
+ export { Sheet, SheetTrigger, SheetClose, SheetContent, SheetHeader, SheetTitle, SheetDescription, };
16
+ //# sourceMappingURL=sheet.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sheet.d.ts","sourceRoot":"","sources":["../../../../src/client/components/ui/sheet.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,cAAc,MAAM,wBAAwB,CAAC;AAKzD,QAAA,MAAM,KAAK,sCAAsB,CAAC;AAClC,QAAA,MAAM,YAAY,6GAAyB,CAAC;AAC5C,QAAA,MAAM,UAAU,2GAAuB,CAAC;AAkBxC,QAAA,MAAM,YAAY;WAGP,OAAO,GAAG,MAAM;wCAuBzB,CAAC;AAGH,QAAA,MAAM,WAAW;8BAGd,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;;CAEtC,CAAC;AAGF,QAAA,MAAM,UAAU,mKASd,CAAC;AAGH,QAAA,MAAM,gBAAgB,6KASpB,CAAC;AAGH,OAAO,EACL,KAAK,EACL,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,WAAW,EACX,UAAU,EACV,gBAAgB,GACjB,CAAC"}
@@ -0,0 +1,23 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import * as React from "react";
3
+ import * as SheetPrimitive from "@radix-ui/react-dialog";
4
+ import { IconX } from "@tabler/icons-react";
5
+ import { cn } from "../../utils.js";
6
+ const Sheet = SheetPrimitive.Root;
7
+ const SheetTrigger = SheetPrimitive.Trigger;
8
+ const SheetClose = SheetPrimitive.Close;
9
+ const SheetPortal = SheetPrimitive.Portal;
10
+ const SheetOverlay = React.forwardRef(({ className, ...props }, ref) => (_jsx(SheetPrimitive.Overlay, { ref: ref, className: cn("fixed inset-0 z-[220] bg-background/35 backdrop-blur-[1px] data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0", className), ...props })));
11
+ SheetOverlay.displayName = SheetPrimitive.Overlay.displayName;
12
+ const SheetContent = React.forwardRef(({ side = "right", className, children, ...props }, ref) => (_jsxs(SheetPortal, { children: [_jsx(SheetOverlay, {}), _jsxs(SheetPrimitive.Content, { ref: ref, className: cn("fixed top-0 z-[230] flex h-full w-full max-w-[440px] flex-col border-border bg-background text-foreground shadow-lg outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-150 data-[state=open]:duration-200", side === "right"
13
+ ? "right-0 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right"
14
+ : "left-0 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left", className), ...props, children: [children, _jsxs(SheetPrimitive.Close, { className: "absolute right-3 top-3 flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring", children: [_jsx(IconX, { className: "h-4 w-4" }), _jsx("span", { className: "sr-only", children: "Close" })] })] })] })));
15
+ SheetContent.displayName = SheetPrimitive.Content.displayName;
16
+ const SheetHeader = ({ className, ...props }) => (_jsx("div", { className: cn("grid gap-1.5 px-4 py-4", className), ...props }));
17
+ SheetHeader.displayName = "SheetHeader";
18
+ const SheetTitle = React.forwardRef(({ className, ...props }, ref) => (_jsx(SheetPrimitive.Title, { ref: ref, className: cn("text-sm font-semibold text-foreground", className), ...props })));
19
+ SheetTitle.displayName = SheetPrimitive.Title.displayName;
20
+ const SheetDescription = React.forwardRef(({ className, ...props }, ref) => (_jsx(SheetPrimitive.Description, { ref: ref, className: cn("text-xs text-muted-foreground", className), ...props })));
21
+ SheetDescription.displayName = SheetPrimitive.Description.displayName;
22
+ export { Sheet, SheetTrigger, SheetClose, SheetContent, SheetHeader, SheetTitle, SheetDescription, };
23
+ //# sourceMappingURL=sheet.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sheet.js","sourceRoot":"","sources":["../../../../src/client/components/ui/sheet.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from \"react\";\nimport * as SheetPrimitive from \"@radix-ui/react-dialog\";\nimport { IconX } from \"@tabler/icons-react\";\n\nimport { cn } from \"../../utils.js\";\n\nconst Sheet = SheetPrimitive.Root;\nconst SheetTrigger = SheetPrimitive.Trigger;\nconst SheetClose = SheetPrimitive.Close;\nconst SheetPortal = SheetPrimitive.Portal;\n\nconst SheetOverlay = React.forwardRef<\n React.ElementRef<typeof SheetPrimitive.Overlay>,\n React.ComponentPropsWithoutRef<typeof SheetPrimitive.Overlay>\n>(({ className, ...props }, ref) => (\n <SheetPrimitive.Overlay\n ref={ref}\n className={cn(\n \"fixed inset-0 z-[220] bg-background/35 backdrop-blur-[1px] data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\",\n className,\n )}\n {...props}\n />\n));\nSheetOverlay.displayName = SheetPrimitive.Overlay.displayName;\n\nconst SheetContent = React.forwardRef<\n React.ElementRef<typeof SheetPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content> & {\n side?: \"right\" | \"left\";\n }\n>(({ side = \"right\", className, children, ...props }, ref) => (\n <SheetPortal>\n <SheetOverlay />\n <SheetPrimitive.Content\n ref={ref}\n className={cn(\n \"fixed top-0 z-[230] flex h-full w-full max-w-[440px] flex-col border-border bg-background text-foreground shadow-lg outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-150 data-[state=open]:duration-200\",\n side === \"right\"\n ? \"right-0 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right\"\n : \"left-0 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left\",\n className,\n )}\n {...props}\n >\n {children}\n <SheetPrimitive.Close className=\"absolute right-3 top-3 flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\">\n <IconX className=\"h-4 w-4\" />\n <span className=\"sr-only\">Close</span>\n </SheetPrimitive.Close>\n </SheetPrimitive.Content>\n </SheetPortal>\n));\nSheetContent.displayName = SheetPrimitive.Content.displayName;\n\nconst SheetHeader = ({\n className,\n ...props\n}: React.HTMLAttributes<HTMLDivElement>) => (\n <div className={cn(\"grid gap-1.5 px-4 py-4\", className)} {...props} />\n);\nSheetHeader.displayName = \"SheetHeader\";\n\nconst SheetTitle = React.forwardRef<\n React.ElementRef<typeof SheetPrimitive.Title>,\n React.ComponentPropsWithoutRef<typeof SheetPrimitive.Title>\n>(({ className, ...props }, ref) => (\n <SheetPrimitive.Title\n ref={ref}\n className={cn(\"text-sm font-semibold text-foreground\", className)}\n {...props}\n />\n));\nSheetTitle.displayName = SheetPrimitive.Title.displayName;\n\nconst SheetDescription = React.forwardRef<\n React.ElementRef<typeof SheetPrimitive.Description>,\n React.ComponentPropsWithoutRef<typeof SheetPrimitive.Description>\n>(({ className, ...props }, ref) => (\n <SheetPrimitive.Description\n ref={ref}\n className={cn(\"text-xs text-muted-foreground\", className)}\n {...props}\n />\n));\nSheetDescription.displayName = SheetPrimitive.Description.displayName;\n\nexport {\n Sheet,\n SheetTrigger,\n SheetClose,\n SheetContent,\n SheetHeader,\n SheetTitle,\n SheetDescription,\n};\n"]}
@@ -0,0 +1,4 @@
1
+ export declare function ContextMeter({ threadId }: {
2
+ threadId?: string | null;
3
+ }): import("react/jsx-runtime").JSX.Element;
4
+ //# sourceMappingURL=ContextMeter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ContextMeter.d.ts","sourceRoot":"","sources":["../../../src/client/context-xray/ContextMeter.tsx"],"names":[],"mappings":"AAqBA,wBAAgB,YAAY,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,2CA6HtE"}
@@ -0,0 +1,76 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { IconExternalLink, IconGauge } from "@tabler/icons-react";
3
+ import { useEffect, useMemo, useRef, useState } from "react";
4
+ import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from "../components/ui/tooltip.js";
5
+ import { useActionMutation, useActionQuery } from "../use-action.js";
6
+ import { cn } from "../utils.js";
7
+ import { ContextXRayPanel } from "./ContextXRayPanel.js";
8
+ import { CONTEXT_XRAY_MODEL_LIMIT, formatTokens, groupColor, } from "./format.js";
9
+ export function ContextMeter({ threadId }) {
10
+ const [open, setOpen] = useState(false);
11
+ const [optimistic, setOptimistic] = useState(new Map());
12
+ const currentThreadId = useRef(threadId);
13
+ const query = useActionQuery("context-manifest-get", threadId ? { threadId } : undefined, {
14
+ enabled: Boolean(threadId),
15
+ staleTime: 1000,
16
+ });
17
+ const pin = useActionMutation("context-pin");
18
+ const evict = useActionMutation("context-evict");
19
+ const restore = useActionMutation("context-restore");
20
+ useEffect(() => {
21
+ currentThreadId.current = threadId;
22
+ setOptimistic(new Map());
23
+ }, [threadId]);
24
+ useEffect(() => {
25
+ if (!threadId || typeof window === "undefined")
26
+ return;
27
+ const params = new URLSearchParams(window.location.search);
28
+ const wantsXray = params.get("contextXray") === "1";
29
+ const targetThread = params.get("threadId");
30
+ if (wantsXray && (!targetThread || targetThread === threadId)) {
31
+ setOpen(true);
32
+ }
33
+ }, [threadId]);
34
+ const manifest = query.data;
35
+ const segments = manifest?.segments ?? [];
36
+ const pct = manifest
37
+ ? Math.min(100, Math.round((manifest.totalTokens / CONTEXT_XRAY_MODEL_LIMIT) * 100))
38
+ : 0;
39
+ const visibleGroups = useMemo(() => {
40
+ const totals = new Map();
41
+ for (const segment of segments) {
42
+ if (segment.status === "evicted")
43
+ continue;
44
+ const group = segment.status === "pinned" ? "Pinned" : segment.group;
45
+ totals.set(group, (totals.get(group) ?? 0) + segment.tokenCount);
46
+ }
47
+ const total = [...totals.values()].reduce((sum, n) => sum + n, 0);
48
+ return [...totals.entries()].map(([group, tokens]) => ({
49
+ group,
50
+ tokens,
51
+ pct: total > 0 ? (tokens / total) * 100 : 0,
52
+ }));
53
+ }, [segments]);
54
+ if (!threadId || !manifest || manifest.rawTokens <= 0)
55
+ return null;
56
+ const mutateStatus = (segmentId, status, action) => {
57
+ const previous = new Map(optimistic);
58
+ setOptimistic((prev) => new Map(prev).set(segmentId, status));
59
+ const params = { threadId, segmentId };
60
+ const options = {
61
+ onError: () => {
62
+ if (currentThreadId.current === threadId) {
63
+ setOptimistic(previous);
64
+ }
65
+ },
66
+ };
67
+ if (action === "pin")
68
+ pin.mutate(params, options);
69
+ if (action === "evict")
70
+ evict.mutate(params, options);
71
+ if (action === "restore")
72
+ restore.mutate(params, options);
73
+ };
74
+ return (_jsxs(TooltipProvider, { delayDuration: 200, children: [_jsx("div", { className: "shrink-0 px-3 pb-1", children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsxs("button", { type: "button", onClick: () => setOpen(true), className: "flex w-full items-center gap-2 rounded-md border border-border bg-background px-2.5 py-1.5 text-left hover:bg-accent/40", children: [_jsx(IconGauge, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "flex items-center justify-between gap-2 text-[11px] text-muted-foreground", children: [_jsxs("span", { children: ["Context ", pct, "% \u00B7 ", formatTokens(manifest.totalTokens)] }), _jsxs("span", { className: "flex items-center gap-1", children: [!manifest.enforceable && "Advisory", _jsx(IconExternalLink, { className: "h-3 w-3" })] })] }), _jsx("div", { className: "mt-1 flex h-1.5 overflow-hidden rounded-full bg-muted", children: visibleGroups.map((group) => (_jsx("span", { className: cn("h-full", groupColor(group.group)), style: { width: `${group.pct}%` } }, group.group))) })] })] }) }), _jsx(TooltipContent, { children: "Open Context X-Ray" })] }) }), _jsx(ContextXRayPanel, { open: open, onOpenChange: setOpen, manifest: manifest, optimistic: optimistic, onPin: (segmentId) => mutateStatus(segmentId, "pinned", "pin"), onEvict: (segmentId) => mutateStatus(segmentId, "evicted", "evict"), onRestore: (segmentId) => mutateStatus(segmentId, "active", "restore") })] }));
75
+ }
76
+ //# sourceMappingURL=ContextMeter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ContextMeter.js","sourceRoot":"","sources":["../../../src/client/context-xray/ContextMeter.tsx"],"names":[],"mappings":"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","sourcesContent":["import { IconExternalLink, IconGauge } from \"@tabler/icons-react\";\nimport { useEffect, useMemo, useRef, useState } from \"react\";\nimport type {\n ContextManifest,\n ContextSegmentStatus,\n} from \"../../shared/context-xray.js\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from \"../components/ui/tooltip.js\";\nimport { useActionMutation, useActionQuery } from \"../use-action.js\";\nimport { cn } from \"../utils.js\";\nimport { ContextXRayPanel } from \"./ContextXRayPanel.js\";\nimport {\n CONTEXT_XRAY_MODEL_LIMIT,\n formatTokens,\n groupColor,\n} from \"./format.js\";\n\nexport function ContextMeter({ threadId }: { threadId?: string | null }) {\n const [open, setOpen] = useState(false);\n const [optimistic, setOptimistic] = useState<\n Map<string, ContextSegmentStatus>\n >(new Map());\n const currentThreadId = useRef(threadId);\n const query = useActionQuery(\n \"context-manifest-get\",\n threadId ? { threadId } : undefined,\n {\n enabled: Boolean(threadId),\n staleTime: 1000,\n },\n ) as { data?: ContextManifest };\n const pin = useActionMutation(\"context-pin\");\n const evict = useActionMutation(\"context-evict\");\n const restore = useActionMutation(\"context-restore\");\n\n useEffect(() => {\n currentThreadId.current = threadId;\n setOptimistic(new Map());\n }, [threadId]);\n\n useEffect(() => {\n if (!threadId || typeof window === \"undefined\") return;\n const params = new URLSearchParams(window.location.search);\n const wantsXray = params.get(\"contextXray\") === \"1\";\n const targetThread = params.get(\"threadId\");\n if (wantsXray && (!targetThread || targetThread === threadId)) {\n setOpen(true);\n }\n }, [threadId]);\n\n const manifest = query.data;\n const segments = manifest?.segments ?? [];\n const pct = manifest\n ? Math.min(\n 100,\n Math.round((manifest.totalTokens / CONTEXT_XRAY_MODEL_LIMIT) * 100),\n )\n : 0;\n const visibleGroups = useMemo(() => {\n const totals = new Map<string, number>();\n for (const segment of segments) {\n if (segment.status === \"evicted\") continue;\n const group = segment.status === \"pinned\" ? \"Pinned\" : segment.group;\n totals.set(group, (totals.get(group) ?? 0) + segment.tokenCount);\n }\n const total = [...totals.values()].reduce((sum, n) => sum + n, 0);\n return [...totals.entries()].map(([group, tokens]) => ({\n group,\n tokens,\n pct: total > 0 ? (tokens / total) * 100 : 0,\n }));\n }, [segments]);\n\n if (!threadId || !manifest || manifest.rawTokens <= 0) return null;\n\n const mutateStatus = (\n segmentId: string,\n status: ContextSegmentStatus,\n action: \"pin\" | \"evict\" | \"restore\",\n ) => {\n const previous = new Map(optimistic);\n setOptimistic((prev) => new Map(prev).set(segmentId, status));\n const params = { threadId, segmentId };\n const options = {\n onError: () => {\n if (currentThreadId.current === threadId) {\n setOptimistic(previous);\n }\n },\n };\n if (action === \"pin\") pin.mutate(params, options);\n if (action === \"evict\") evict.mutate(params, options);\n if (action === \"restore\") restore.mutate(params, options);\n };\n\n return (\n <TooltipProvider delayDuration={200}>\n <div className=\"shrink-0 px-3 pb-1\">\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n onClick={() => setOpen(true)}\n className=\"flex w-full items-center gap-2 rounded-md border border-border bg-background px-2.5 py-1.5 text-left hover:bg-accent/40\"\n >\n <IconGauge className=\"h-3.5 w-3.5 shrink-0 text-muted-foreground\" />\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center justify-between gap-2 text-[11px] text-muted-foreground\">\n <span>\n Context {pct}% · {formatTokens(manifest.totalTokens)}\n </span>\n <span className=\"flex items-center gap-1\">\n {!manifest.enforceable && \"Advisory\"}\n <IconExternalLink className=\"h-3 w-3\" />\n </span>\n </div>\n <div className=\"mt-1 flex h-1.5 overflow-hidden rounded-full bg-muted\">\n {visibleGroups.map((group) => (\n <span\n key={group.group}\n className={cn(\"h-full\", groupColor(group.group))}\n style={{ width: `${group.pct}%` }}\n />\n ))}\n </div>\n </div>\n </button>\n </TooltipTrigger>\n <TooltipContent>Open Context X-Ray</TooltipContent>\n </Tooltip>\n </div>\n <ContextXRayPanel\n open={open}\n onOpenChange={setOpen}\n manifest={manifest}\n optimistic={optimistic}\n onPin={(segmentId) => mutateStatus(segmentId, \"pinned\", \"pin\")}\n onEvict={(segmentId) => mutateStatus(segmentId, \"evicted\", \"evict\")}\n onRestore={(segmentId) => mutateStatus(segmentId, \"active\", \"restore\")}\n />\n </TooltipProvider>\n );\n}\n"]}
@@ -0,0 +1,9 @@
1
+ import type { ContextManifestSegment } from "../../shared/context-xray.js";
2
+ export declare function ContextSegmentRow({ segment, advisory, onPin, onEvict, onRestore, }: {
3
+ segment: ContextManifestSegment;
4
+ advisory: boolean;
5
+ onPin: () => void;
6
+ onEvict: () => void;
7
+ onRestore: () => void;
8
+ }): import("react/jsx-runtime").JSX.Element;
9
+ //# sourceMappingURL=ContextSegmentRow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ContextSegmentRow.d.ts","sourceRoot":"","sources":["../../../src/client/context-xray/ContextSegmentRow.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAU3E,wBAAgB,iBAAiB,CAAC,EAChC,OAAO,EACP,QAAQ,EACR,KAAK,EACL,OAAO,EACP,SAAS,GACV,EAAE;IACD,OAAO,EAAE,sBAAsB,CAAC;IAChC,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,SAAS,EAAE,MAAM,IAAI,CAAC;CACvB,2CAsHA"}
@@ -0,0 +1,22 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { IconArrowsMinimize, IconLock, IconPin, IconRotate2, IconX, } from "@tabler/icons-react";
3
+ import { Tooltip, TooltipContent, TooltipTrigger, } from "../components/ui/tooltip.js";
4
+ import { cn } from "../utils.js";
5
+ import { formatTokens, statusLabel } from "./format.js";
6
+ import { SegmentProvenancePopover } from "./SegmentProvenancePopover.js";
7
+ export function ContextSegmentRow({ segment, advisory, onPin, onEvict, onRestore, }) {
8
+ const disabled = segment.protected || segment.status === "evicted";
9
+ return (_jsxs("div", { tabIndex: 0, onKeyDown: (event) => {
10
+ if (event.key === "p")
11
+ onPin();
12
+ if (event.key === "e" && !disabled)
13
+ onEvict();
14
+ if (event.key === "u" && segment.status !== "active")
15
+ onRestore();
16
+ }, className: cn("group flex min-h-12 items-center gap-2 rounded-md border border-transparent px-2 py-1.5 outline-none hover:border-border hover:bg-accent/35 focus-visible:border-ring", segment.status === "evicted" && "opacity-60"), children: [_jsx(SegmentProvenancePopover, { segment: segment, children: _jsxs("button", { type: "button", className: "min-w-0 flex-1 text-left", "aria-label": `Inspect ${segment.label}`, children: [_jsx("div", { className: cn("truncate text-xs font-medium text-foreground", segment.status === "evicted" && "line-through"), children: segment.label }), _jsxs("div", { className: "mt-0.5 flex items-center gap-1.5 text-[11px] text-muted-foreground", children: [_jsx("span", { children: formatTokens(segment.tokenCount) }), segment.tokenMethod === "estimate" && _jsx("span", { children: "~" }), _jsx("span", { children: "\u00B7" }), _jsx("span", { children: statusLabel(segment) }), advisory && _jsx("span", { children: "\u00B7 advisory" })] })] }) }), _jsx("div", { className: "flex shrink-0 items-center gap-1 opacity-100 sm:opacity-0 sm:group-hover:opacity-100 sm:group-focus-within:opacity-100", children: segment.protected ? (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("span", { className: "flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground", children: _jsx(IconLock, { className: "h-3.5 w-3.5" }) }) }), _jsx(TooltipContent, { children: "Protected during active turn" })] })) : segment.status === "evicted" ||
17
+ segment.status === "summarized" ||
18
+ segment.status === "pinned" ? (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", onClick: onRestore, className: "flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground hover:bg-background hover:text-foreground", "aria-label": segment.status === "pinned"
19
+ ? "Unpin segment"
20
+ : "Restore segment", children: _jsx(IconRotate2, { className: "h-3.5 w-3.5" }) }) }), _jsx(TooltipContent, { children: segment.status === "pinned" ? "Unpin" : "Restore" })] })) : (_jsxs(_Fragment, { children: [_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", onClick: onPin, className: "flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground hover:bg-background hover:text-foreground", "aria-label": "Pin segment", children: _jsx(IconPin, { className: "h-3.5 w-3.5" }) }) }), _jsx(TooltipContent, { children: "Pin" })] }), _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", disabled: true, className: "flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground/50", "aria-label": "Compress segment", children: _jsx(IconArrowsMinimize, { className: "h-3.5 w-3.5" }) }) }), _jsx(TooltipContent, { children: "Compress is coming soon" })] }), _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", onClick: onEvict, className: "flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground hover:bg-background hover:text-destructive", "aria-label": "Evict segment", children: _jsx(IconX, { className: "h-3.5 w-3.5" }) }) }), _jsx(TooltipContent, { children: advisory ? "Record eviction intent" : "Evict" })] })] })) })] }));
21
+ }
22
+ //# sourceMappingURL=ContextSegmentRow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ContextSegmentRow.js","sourceRoot":"","sources":["../../../src/client/context-xray/ContextSegmentRow.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n IconArrowsMinimize,\n IconLock,\n IconPin,\n IconRotate2,\n IconX,\n} from \"@tabler/icons-react\";\nimport type { ContextManifestSegment } from \"../../shared/context-xray.js\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"../components/ui/tooltip.js\";\nimport { cn } from \"../utils.js\";\nimport { formatTokens, statusLabel } from \"./format.js\";\nimport { SegmentProvenancePopover } from \"./SegmentProvenancePopover.js\";\n\nexport function ContextSegmentRow({\n segment,\n advisory,\n onPin,\n onEvict,\n onRestore,\n}: {\n segment: ContextManifestSegment;\n advisory: boolean;\n onPin: () => void;\n onEvict: () => void;\n onRestore: () => void;\n}) {\n const disabled = segment.protected || segment.status === \"evicted\";\n return (\n <div\n tabIndex={0}\n onKeyDown={(event) => {\n if (event.key === \"p\") onPin();\n if (event.key === \"e\" && !disabled) onEvict();\n if (event.key === \"u\" && segment.status !== \"active\") onRestore();\n }}\n className={cn(\n \"group flex min-h-12 items-center gap-2 rounded-md border border-transparent px-2 py-1.5 outline-none hover:border-border hover:bg-accent/35 focus-visible:border-ring\",\n segment.status === \"evicted\" && \"opacity-60\",\n )}\n >\n <SegmentProvenancePopover segment={segment}>\n <button\n type=\"button\"\n className=\"min-w-0 flex-1 text-left\"\n aria-label={`Inspect ${segment.label}`}\n >\n <div\n className={cn(\n \"truncate text-xs font-medium text-foreground\",\n segment.status === \"evicted\" && \"line-through\",\n )}\n >\n {segment.label}\n </div>\n <div className=\"mt-0.5 flex items-center gap-1.5 text-[11px] text-muted-foreground\">\n <span>{formatTokens(segment.tokenCount)}</span>\n {segment.tokenMethod === \"estimate\" && <span>~</span>}\n <span>·</span>\n <span>{statusLabel(segment)}</span>\n {advisory && <span>· advisory</span>}\n </div>\n </button>\n </SegmentProvenancePopover>\n <div className=\"flex shrink-0 items-center gap-1 opacity-100 sm:opacity-0 sm:group-hover:opacity-100 sm:group-focus-within:opacity-100\">\n {segment.protected ? (\n <Tooltip>\n <TooltipTrigger asChild>\n <span className=\"flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground\">\n <IconLock className=\"h-3.5 w-3.5\" />\n </span>\n </TooltipTrigger>\n <TooltipContent>Protected during active turn</TooltipContent>\n </Tooltip>\n ) : segment.status === \"evicted\" ||\n segment.status === \"summarized\" ||\n segment.status === \"pinned\" ? (\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n onClick={onRestore}\n className=\"flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground hover:bg-background hover:text-foreground\"\n aria-label={\n segment.status === \"pinned\"\n ? \"Unpin segment\"\n : \"Restore segment\"\n }\n >\n <IconRotate2 className=\"h-3.5 w-3.5\" />\n </button>\n </TooltipTrigger>\n <TooltipContent>\n {segment.status === \"pinned\" ? \"Unpin\" : \"Restore\"}\n </TooltipContent>\n </Tooltip>\n ) : (\n <>\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n onClick={onPin}\n className=\"flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground hover:bg-background hover:text-foreground\"\n aria-label=\"Pin segment\"\n >\n <IconPin className=\"h-3.5 w-3.5\" />\n </button>\n </TooltipTrigger>\n <TooltipContent>Pin</TooltipContent>\n </Tooltip>\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n disabled\n className=\"flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground/50\"\n aria-label=\"Compress segment\"\n >\n <IconArrowsMinimize className=\"h-3.5 w-3.5\" />\n </button>\n </TooltipTrigger>\n <TooltipContent>Compress is coming soon</TooltipContent>\n </Tooltip>\n <Tooltip>\n <TooltipTrigger asChild>\n <button\n type=\"button\"\n onClick={onEvict}\n className=\"flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground hover:bg-background hover:text-destructive\"\n aria-label=\"Evict segment\"\n >\n <IconX className=\"h-3.5 w-3.5\" />\n </button>\n </TooltipTrigger>\n <TooltipContent>\n {advisory ? \"Record eviction intent\" : \"Evict\"}\n </TooltipContent>\n </Tooltip>\n </>\n )}\n </div>\n </div>\n );\n}\n"]}
@@ -0,0 +1,6 @@
1
+ import type { ContextManifestSegment } from "../../shared/context-xray.js";
2
+ export declare function ContextTreemap({ segments, onSelect, }: {
3
+ segments: ContextManifestSegment[];
4
+ onSelect?: (segmentId: string) => void;
5
+ }): import("react/jsx-runtime").JSX.Element;
6
+ //# sourceMappingURL=ContextTreemap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ContextTreemap.d.ts","sourceRoot":"","sources":["../../../src/client/context-xray/ContextTreemap.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AA4C3E,wBAAgB,cAAc,CAAC,EAC7B,QAAQ,EACR,QAAQ,GACT,EAAE;IACD,QAAQ,EAAE,sBAAsB,EAAE,CAAC;IACnC,QAAQ,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CACxC,2CA+DA"}
@@ -0,0 +1,49 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useRef, useState } from "react";
3
+ import { Treemap } from "recharts";
4
+ import { formatTokens, groupFill } from "./format.js";
5
+ function TreemapContent(props) {
6
+ const { x, y, width, height, name, group, size } = props;
7
+ if (width < 8 || height < 8)
8
+ return null;
9
+ const showLabel = width > 90 && height > 42;
10
+ return (_jsxs("g", { children: [_jsx("rect", { x: x, y: y, width: width, height: height, rx: 3, ry: 3, fill: groupFill(group), stroke: "var(--background)", strokeWidth: 2 }), showLabel && (_jsx("foreignObject", { x: x + 6, y: y + 6, width: width - 12, height: height - 12, children: _jsxs("div", { className: "flex h-full flex-col justify-between overflow-hidden text-[11px] leading-tight text-white", children: [_jsx("div", { className: "truncate font-medium", children: name }), _jsx("div", { className: "text-white/85", children: formatTokens(size) })] }) }))] }));
11
+ }
12
+ export function ContextTreemap({ segments, onSelect, }) {
13
+ const containerRef = useRef(null);
14
+ const [chartWidth, setChartWidth] = useState(0);
15
+ const data = segments
16
+ .filter((segment) => segment.status !== "evicted" && segment.tokenCount > 0)
17
+ .map((segment) => ({
18
+ name: segment.label,
19
+ size: segment.tokenCount,
20
+ group: segment.group,
21
+ segmentId: segment.segmentId,
22
+ }));
23
+ useEffect(() => {
24
+ const element = containerRef.current;
25
+ if (!element)
26
+ return;
27
+ const updateWidth = () => {
28
+ setChartWidth(Math.max(0, Math.floor(element.clientWidth - 8)));
29
+ };
30
+ updateWidth();
31
+ const observer = typeof ResizeObserver !== "undefined"
32
+ ? new ResizeObserver(updateWidth)
33
+ : null;
34
+ observer?.observe(element);
35
+ window.addEventListener("resize", updateWidth);
36
+ return () => {
37
+ observer?.disconnect();
38
+ window.removeEventListener("resize", updateWidth);
39
+ };
40
+ }, []);
41
+ if (data.length === 0) {
42
+ return (_jsx("div", { className: "flex h-56 items-center justify-center rounded-md border border-dashed border-border text-xs text-muted-foreground", children: "No active segments" }));
43
+ }
44
+ return (_jsx("div", { ref: containerRef, className: "h-64 min-w-0 rounded-md border border-border bg-muted/20 p-1", children: chartWidth > 0 && (_jsx(Treemap, { width: chartWidth, height: 248, data: data, dataKey: "size", nameKey: "name", aspectRatio: 4 / 3, isAnimationActive: false, content: _jsx(TreemapContent, {}), onClick: (datum) => {
45
+ if (datum?.segmentId)
46
+ onSelect?.(datum.segmentId);
47
+ } })) }));
48
+ }
49
+ //# sourceMappingURL=ContextTreemap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ContextTreemap.js","sourceRoot":"","sources":["../../../src/client/context-xray/ContextTreemap.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useRef, useState } from \"react\";\nimport { Treemap } from \"recharts\";\nimport type { ContextManifestSegment } from \"../../shared/context-xray.js\";\nimport { formatTokens, groupFill } from \"./format.js\";\n\ninterface TreemapDatum {\n name: string;\n size: number;\n group: string;\n segmentId: string;\n}\n\nfunction TreemapContent(props: any) {\n const { x, y, width, height, name, group, size } = props;\n if (width < 8 || height < 8) return null;\n const showLabel = width > 90 && height > 42;\n return (\n <g>\n <rect\n x={x}\n y={y}\n width={width}\n height={height}\n rx={3}\n ry={3}\n fill={groupFill(group)}\n stroke=\"var(--background)\"\n strokeWidth={2}\n />\n {showLabel && (\n <foreignObject\n x={x + 6}\n y={y + 6}\n width={width - 12}\n height={height - 12}\n >\n <div className=\"flex h-full flex-col justify-between overflow-hidden text-[11px] leading-tight text-white\">\n <div className=\"truncate font-medium\">{name}</div>\n <div className=\"text-white/85\">{formatTokens(size)}</div>\n </div>\n </foreignObject>\n )}\n </g>\n );\n}\n\nexport function ContextTreemap({\n segments,\n onSelect,\n}: {\n segments: ContextManifestSegment[];\n onSelect?: (segmentId: string) => void;\n}) {\n const containerRef = useRef<HTMLDivElement>(null);\n const [chartWidth, setChartWidth] = useState(0);\n const data: TreemapDatum[] = segments\n .filter((segment) => segment.status !== \"evicted\" && segment.tokenCount > 0)\n .map((segment) => ({\n name: segment.label,\n size: segment.tokenCount,\n group: segment.group,\n segmentId: segment.segmentId,\n }));\n\n useEffect(() => {\n const element = containerRef.current;\n if (!element) return;\n\n const updateWidth = () => {\n setChartWidth(Math.max(0, Math.floor(element.clientWidth - 8)));\n };\n updateWidth();\n\n const observer =\n typeof ResizeObserver !== \"undefined\"\n ? new ResizeObserver(updateWidth)\n : null;\n observer?.observe(element);\n window.addEventListener(\"resize\", updateWidth);\n return () => {\n observer?.disconnect();\n window.removeEventListener(\"resize\", updateWidth);\n };\n }, []);\n\n if (data.length === 0) {\n return (\n <div className=\"flex h-56 items-center justify-center rounded-md border border-dashed border-border text-xs text-muted-foreground\">\n No active segments\n </div>\n );\n }\n\n return (\n <div\n ref={containerRef}\n className=\"h-64 min-w-0 rounded-md border border-border bg-muted/20 p-1\"\n >\n {chartWidth > 0 && (\n <Treemap\n width={chartWidth}\n height={248}\n data={data as any}\n dataKey=\"size\"\n nameKey=\"name\"\n aspectRatio={4 / 3}\n isAnimationActive={false}\n content={<TreemapContent />}\n onClick={(datum: any) => {\n if (datum?.segmentId) onSelect?.(datum.segmentId);\n }}\n />\n )}\n </div>\n );\n}\n"]}
@@ -0,0 +1,11 @@
1
+ import type { ContextManifest, ContextSegmentStatus } from "../../shared/context-xray.js";
2
+ export declare function ContextXRayPanel({ open, onOpenChange, manifest, optimistic, onPin, onEvict, onRestore, }: {
3
+ open: boolean;
4
+ onOpenChange: (open: boolean) => void;
5
+ manifest: ContextManifest;
6
+ optimistic: Map<string, ContextSegmentStatus>;
7
+ onPin: (segmentId: string) => void;
8
+ onEvict: (segmentId: string) => void;
9
+ onRestore: (segmentId: string) => void;
10
+ }): import("react/jsx-runtime").JSX.Element;
11
+ //# sourceMappingURL=ContextXRayPanel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ContextXRayPanel.d.ts","sourceRoot":"","sources":["../../../src/client/context-xray/ContextXRayPanel.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EACV,eAAe,EAEf,oBAAoB,EACrB,MAAM,8BAA8B,CAAC;AAsGtC,wBAAgB,gBAAgB,CAAC,EAC/B,IAAI,EACJ,YAAY,EACZ,QAAQ,EACR,UAAU,EACV,KAAK,EACL,OAAO,EACP,SAAS,GACV,EAAE;IACD,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,QAAQ,EAAE,eAAe,CAAC;IAC1B,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;IAC9C,KAAK,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,OAAO,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,SAAS,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CACxC,2CAuKA"}
@@ -0,0 +1,87 @@
1
+ import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { IconAdjustmentsHorizontal, IconChartTreemap, IconChevronDown, IconChevronRight, IconListDetails, IconPin, } from "@tabler/icons-react";
3
+ import { useMemo, useState } from "react";
4
+ import { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle, } from "../components/ui/sheet.js";
5
+ import { Tooltip, TooltipContent, TooltipTrigger, } from "../components/ui/tooltip.js";
6
+ import { cn } from "../utils.js";
7
+ import { ContextSegmentRow } from "./ContextSegmentRow.js";
8
+ import { ContextTreemap } from "./ContextTreemap.js";
9
+ import { CONTEXT_XRAY_MODEL_LIMIT, formatTokens, groupColor, } from "./format.js";
10
+ function applyOptimisticStatus(segments, optimistic) {
11
+ if (optimistic.size === 0)
12
+ return segments;
13
+ return segments.map((segment) => {
14
+ const status = optimistic.get(segment.segmentId);
15
+ return status ? { ...segment, status } : segment;
16
+ });
17
+ }
18
+ function groupedSegments(segments) {
19
+ const map = new Map();
20
+ for (const segment of segments) {
21
+ const groupName = segment.status === "pinned"
22
+ ? "Pinned"
23
+ : segment.status === "evicted"
24
+ ? "Evicted"
25
+ : segment.group;
26
+ const group = map.get(groupName) ?? {
27
+ name: groupName,
28
+ tokens: 0,
29
+ segments: [],
30
+ };
31
+ group.tokens += segment.tokenCount;
32
+ group.segments.push(segment);
33
+ map.set(groupName, group);
34
+ }
35
+ const order = [
36
+ "Pinned",
37
+ "Tool results",
38
+ "Files read",
39
+ "Conversation",
40
+ "Thinking",
41
+ "Evicted",
42
+ ];
43
+ return [...map.values()].sort((a, b) => {
44
+ const ai = order.indexOf(a.name);
45
+ const bi = order.indexOf(b.name);
46
+ if (ai >= 0 || bi >= 0)
47
+ return (ai < 0 ? 99 : ai) - (bi < 0 ? 99 : bi);
48
+ return b.tokens - a.tokens;
49
+ });
50
+ }
51
+ function StatusLine({ manifest }) {
52
+ const pinned = manifest.segments.filter((s) => s.status === "pinned").length;
53
+ const evicted = manifest.segments.filter((s) => s.status === "evicted").length;
54
+ const estimate = manifest.tokenCountMethod === "estimate";
55
+ return (_jsxs("div", { className: "flex flex-wrap items-center gap-2 text-[11px] text-muted-foreground", children: [_jsxs("span", { children: ["Pinned ", pinned] }), _jsx("span", { children: "\u00B7" }), _jsxs("span", { children: ["Evicted ", evicted] }), estimate && (_jsxs(_Fragment, { children: [_jsx("span", { children: "\u00B7" }), _jsx("span", { children: "token counts estimated" })] })), !manifest.enforceable && (_jsxs(_Fragment, { children: [_jsx("span", { children: "\u00B7" }), _jsx("span", { className: "rounded-sm border border-amber-500/30 bg-amber-500/10 px-1.5 py-0.5 text-amber-700 dark:text-amber-300", children: "Advisory" })] }))] }));
56
+ }
57
+ export function ContextXRayPanel({ open, onOpenChange, manifest, optimistic, onPin, onEvict, onRestore, }) {
58
+ const [mode, setMode] = useState("list");
59
+ const [collapsed, setCollapsed] = useState(new Set());
60
+ const segments = useMemo(() => applyOptimisticStatus(manifest.segments, optimistic), [manifest.segments, optimistic]);
61
+ const groups = useMemo(() => groupedSegments(segments), [segments]);
62
+ const pct = Math.min(100, Math.round((manifest.totalTokens / CONTEXT_XRAY_MODEL_LIMIT) * 100));
63
+ const headroom = Math.max(0, CONTEXT_XRAY_MODEL_LIMIT - manifest.totalTokens);
64
+ return (_jsx(Sheet, { open: open, onOpenChange: onOpenChange, children: _jsxs(SheetContent, { className: "max-w-[460px]", children: [_jsxs(SheetHeader, { className: "border-b border-border pr-12", children: [_jsxs(SheetTitle, { className: "flex items-center gap-2", children: [_jsx(IconAdjustmentsHorizontal, { className: "h-4 w-4" }), "Context X-Ray"] }), _jsx(SheetDescription, { children: manifest.enforceable
65
+ ? "Pinned items survive compaction. Evicted items are excluded, not deleted."
66
+ : "Advisory mode records intent for an external host." })] }), _jsxs("div", { className: "space-y-4 px-4 py-4", children: [_jsxs("div", { className: "space-y-2", children: [_jsxs("div", { className: "flex items-end justify-between gap-3", children: [_jsxs("div", { children: [_jsxs("div", { className: "text-xl font-semibold text-foreground", children: [formatTokens(manifest.totalTokens), " /", " ", formatTokens(CONTEXT_XRAY_MODEL_LIMIT)] }), _jsxs("div", { className: "text-xs text-muted-foreground", children: [pct, "% \u00B7 ", formatTokens(headroom), " headroom"] })] }), manifest.reclaimedTokens > 0 && (_jsxs("div", { className: "rounded-md border border-emerald-500/30 bg-emerald-500/10 px-2 py-1 text-xs font-medium text-emerald-700 dark:text-emerald-300", children: ["-", formatTokens(manifest.reclaimedTokens)] }))] }), _jsx("div", { className: "h-2 overflow-hidden rounded-full bg-muted", children: _jsx("div", { className: "h-full rounded-full bg-foreground transition-[width] duration-300", style: { width: `${pct}%` } }) }), _jsx(StatusLine, { manifest: manifest })] }), _jsxs("div", { className: "flex items-center justify-between gap-2", children: [_jsxs("div", { className: "inline-flex rounded-md border border-border bg-muted/30 p-0.5", children: [_jsxs("button", { type: "button", onClick: () => setMode("list"), className: cn("flex h-7 items-center gap-1 rounded px-2 text-xs", mode === "list" && "bg-background shadow-sm"), children: [_jsx(IconListDetails, { className: "h-3.5 w-3.5" }), "List"] }), _jsxs("button", { type: "button", onClick: () => setMode("map"), className: cn("flex h-7 items-center gap-1 rounded px-2 text-xs", mode === "map" && "bg-background shadow-sm"), children: [_jsx(IconChartTreemap, { className: "h-3.5 w-3.5" }), "Map"] })] }), _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsxs("div", { className: "flex items-center gap-1 text-[11px] text-muted-foreground", children: [_jsx(IconPin, { className: "h-3.5 w-3.5" }), "survives compaction"] }) }), _jsx(TooltipContent, { children: "Pinned segments stay in future context" })] })] }), mode === "map" ? (_jsx(ContextTreemap, { segments: segments, onSelect: (segmentId) => {
67
+ const segment = segments.find((s) => s.segmentId === segmentId);
68
+ if (segment)
69
+ setCollapsed(new Set());
70
+ } })) : (_jsx("div", { className: "space-y-2", children: groups.map((group) => {
71
+ const isCollapsed = collapsed.has(group.name);
72
+ return (_jsxs("div", { className: "rounded-md border border-border", children: [_jsxs("button", { type: "button", onClick: () => {
73
+ setCollapsed((prev) => {
74
+ const next = new Set(prev);
75
+ if (next.has(group.name))
76
+ next.delete(group.name);
77
+ else
78
+ next.add(group.name);
79
+ return next;
80
+ });
81
+ }, className: "flex w-full items-center gap-2 px-2.5 py-2 text-left", children: [isCollapsed ? (_jsx(IconChevronRight, { className: "h-3.5 w-3.5 text-muted-foreground" })) : (_jsx(IconChevronDown, { className: "h-3.5 w-3.5 text-muted-foreground" })), _jsx("span", { className: cn("h-2 w-2 rounded-full", groupColor(group.name)) }), _jsx("span", { className: "min-w-0 flex-1 truncate text-xs font-medium", children: group.name }), _jsx("span", { className: "text-[11px] text-muted-foreground", children: formatTokens(group.tokens) })] }), !isCollapsed && (_jsx("div", { className: "border-t border-border py-1", children: group.segments
82
+ .slice()
83
+ .sort((a, b) => b.tokenCount - a.tokenCount)
84
+ .map((segment) => (_jsx(ContextSegmentRow, { segment: segment, advisory: !manifest.enforceable, onPin: () => onPin(segment.segmentId), onEvict: () => onEvict(segment.segmentId), onRestore: () => onRestore(segment.segmentId) }, segment.segmentId))) }))] }, group.name));
85
+ }) }))] })] }) }));
86
+ }
87
+ //# sourceMappingURL=ContextXRayPanel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ContextXRayPanel.js","sourceRoot":"","sources":["../../../src/client/context-xray/ContextXRayPanel.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n IconAdjustmentsHorizontal,\n IconChartTreemap,\n IconChevronDown,\n IconChevronRight,\n IconListDetails,\n IconPin,\n} from \"@tabler/icons-react\";\nimport { useMemo, useState } from \"react\";\nimport type {\n ContextManifest,\n ContextManifestSegment,\n ContextSegmentStatus,\n} from \"../../shared/context-xray.js\";\nimport {\n Sheet,\n SheetContent,\n SheetDescription,\n SheetHeader,\n SheetTitle,\n} from \"../components/ui/sheet.js\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"../components/ui/tooltip.js\";\nimport { cn } from \"../utils.js\";\nimport { ContextSegmentRow } from \"./ContextSegmentRow.js\";\nimport { ContextTreemap } from \"./ContextTreemap.js\";\nimport {\n CONTEXT_XRAY_MODEL_LIMIT,\n formatTokens,\n groupColor,\n} from \"./format.js\";\n\ninterface Group {\n name: string;\n tokens: number;\n segments: ContextManifestSegment[];\n}\n\nfunction applyOptimisticStatus(\n segments: ContextManifestSegment[],\n optimistic: Map<string, ContextSegmentStatus>,\n): ContextManifestSegment[] {\n if (optimistic.size === 0) return segments;\n return segments.map((segment) => {\n const status = optimistic.get(segment.segmentId);\n return status ? { ...segment, status } : segment;\n });\n}\n\nfunction groupedSegments(segments: ContextManifestSegment[]): Group[] {\n const map = new Map<string, Group>();\n for (const segment of segments) {\n const groupName =\n segment.status === \"pinned\"\n ? \"Pinned\"\n : segment.status === \"evicted\"\n ? \"Evicted\"\n : segment.group;\n const group = map.get(groupName) ?? {\n name: groupName,\n tokens: 0,\n segments: [],\n };\n group.tokens += segment.tokenCount;\n group.segments.push(segment);\n map.set(groupName, group);\n }\n const order = [\n \"Pinned\",\n \"Tool results\",\n \"Files read\",\n \"Conversation\",\n \"Thinking\",\n \"Evicted\",\n ];\n return [...map.values()].sort((a, b) => {\n const ai = order.indexOf(a.name);\n const bi = order.indexOf(b.name);\n if (ai >= 0 || bi >= 0) return (ai < 0 ? 99 : ai) - (bi < 0 ? 99 : bi);\n return b.tokens - a.tokens;\n });\n}\n\nfunction StatusLine({ manifest }: { manifest: ContextManifest }) {\n const pinned = manifest.segments.filter((s) => s.status === \"pinned\").length;\n const evicted = manifest.segments.filter(\n (s) => s.status === \"evicted\",\n ).length;\n const estimate = manifest.tokenCountMethod === \"estimate\";\n return (\n <div className=\"flex flex-wrap items-center gap-2 text-[11px] text-muted-foreground\">\n <span>Pinned {pinned}</span>\n <span>·</span>\n <span>Evicted {evicted}</span>\n {estimate && (\n <>\n <span>·</span>\n <span>token counts estimated</span>\n </>\n )}\n {!manifest.enforceable && (\n <>\n <span>·</span>\n <span className=\"rounded-sm border border-amber-500/30 bg-amber-500/10 px-1.5 py-0.5 text-amber-700 dark:text-amber-300\">\n Advisory\n </span>\n </>\n )}\n </div>\n );\n}\n\nexport function ContextXRayPanel({\n open,\n onOpenChange,\n manifest,\n optimistic,\n onPin,\n onEvict,\n onRestore,\n}: {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n manifest: ContextManifest;\n optimistic: Map<string, ContextSegmentStatus>;\n onPin: (segmentId: string) => void;\n onEvict: (segmentId: string) => void;\n onRestore: (segmentId: string) => void;\n}) {\n const [mode, setMode] = useState<\"list\" | \"map\">(\"list\");\n const [collapsed, setCollapsed] = useState<Set<string>>(new Set());\n const segments = useMemo(\n () => applyOptimisticStatus(manifest.segments, optimistic),\n [manifest.segments, optimistic],\n );\n const groups = useMemo(() => groupedSegments(segments), [segments]);\n const pct = Math.min(\n 100,\n Math.round((manifest.totalTokens / CONTEXT_XRAY_MODEL_LIMIT) * 100),\n );\n const headroom = Math.max(0, CONTEXT_XRAY_MODEL_LIMIT - manifest.totalTokens);\n\n return (\n <Sheet open={open} onOpenChange={onOpenChange}>\n <SheetContent className=\"max-w-[460px]\">\n <SheetHeader className=\"border-b border-border pr-12\">\n <SheetTitle className=\"flex items-center gap-2\">\n <IconAdjustmentsHorizontal className=\"h-4 w-4\" />\n Context X-Ray\n </SheetTitle>\n <SheetDescription>\n {manifest.enforceable\n ? \"Pinned items survive compaction. Evicted items are excluded, not deleted.\"\n : \"Advisory mode records intent for an external host.\"}\n </SheetDescription>\n </SheetHeader>\n\n <div className=\"space-y-4 px-4 py-4\">\n <div className=\"space-y-2\">\n <div className=\"flex items-end justify-between gap-3\">\n <div>\n <div className=\"text-xl font-semibold text-foreground\">\n {formatTokens(manifest.totalTokens)} /{\" \"}\n {formatTokens(CONTEXT_XRAY_MODEL_LIMIT)}\n </div>\n <div className=\"text-xs text-muted-foreground\">\n {pct}% · {formatTokens(headroom)} headroom\n </div>\n </div>\n {manifest.reclaimedTokens > 0 && (\n <div className=\"rounded-md border border-emerald-500/30 bg-emerald-500/10 px-2 py-1 text-xs font-medium text-emerald-700 dark:text-emerald-300\">\n -{formatTokens(manifest.reclaimedTokens)}\n </div>\n )}\n </div>\n <div className=\"h-2 overflow-hidden rounded-full bg-muted\">\n <div\n className=\"h-full rounded-full bg-foreground transition-[width] duration-300\"\n style={{ width: `${pct}%` }}\n />\n </div>\n <StatusLine manifest={manifest} />\n </div>\n\n <div className=\"flex items-center justify-between gap-2\">\n <div className=\"inline-flex rounded-md border border-border bg-muted/30 p-0.5\">\n <button\n type=\"button\"\n onClick={() => setMode(\"list\")}\n className={cn(\n \"flex h-7 items-center gap-1 rounded px-2 text-xs\",\n mode === \"list\" && \"bg-background shadow-sm\",\n )}\n >\n <IconListDetails className=\"h-3.5 w-3.5\" />\n List\n </button>\n <button\n type=\"button\"\n onClick={() => setMode(\"map\")}\n className={cn(\n \"flex h-7 items-center gap-1 rounded px-2 text-xs\",\n mode === \"map\" && \"bg-background shadow-sm\",\n )}\n >\n <IconChartTreemap className=\"h-3.5 w-3.5\" />\n Map\n </button>\n </div>\n <Tooltip>\n <TooltipTrigger asChild>\n <div className=\"flex items-center gap-1 text-[11px] text-muted-foreground\">\n <IconPin className=\"h-3.5 w-3.5\" />\n survives compaction\n </div>\n </TooltipTrigger>\n <TooltipContent>\n Pinned segments stay in future context\n </TooltipContent>\n </Tooltip>\n </div>\n\n {mode === \"map\" ? (\n <ContextTreemap\n segments={segments}\n onSelect={(segmentId) => {\n const segment = segments.find((s) => s.segmentId === segmentId);\n if (segment) setCollapsed(new Set());\n }}\n />\n ) : (\n <div className=\"space-y-2\">\n {groups.map((group) => {\n const isCollapsed = collapsed.has(group.name);\n return (\n <div\n key={group.name}\n className=\"rounded-md border border-border\"\n >\n <button\n type=\"button\"\n onClick={() => {\n setCollapsed((prev) => {\n const next = new Set(prev);\n if (next.has(group.name)) next.delete(group.name);\n else next.add(group.name);\n return next;\n });\n }}\n className=\"flex w-full items-center gap-2 px-2.5 py-2 text-left\"\n >\n {isCollapsed ? (\n <IconChevronRight className=\"h-3.5 w-3.5 text-muted-foreground\" />\n ) : (\n <IconChevronDown className=\"h-3.5 w-3.5 text-muted-foreground\" />\n )}\n <span\n className={cn(\n \"h-2 w-2 rounded-full\",\n groupColor(group.name),\n )}\n />\n <span className=\"min-w-0 flex-1 truncate text-xs font-medium\">\n {group.name}\n </span>\n <span className=\"text-[11px] text-muted-foreground\">\n {formatTokens(group.tokens)}\n </span>\n </button>\n {!isCollapsed && (\n <div className=\"border-t border-border py-1\">\n {group.segments\n .slice()\n .sort((a, b) => b.tokenCount - a.tokenCount)\n .map((segment) => (\n <ContextSegmentRow\n key={segment.segmentId}\n segment={segment}\n advisory={!manifest.enforceable}\n onPin={() => onPin(segment.segmentId)}\n onEvict={() => onEvict(segment.segmentId)}\n onRestore={() => onRestore(segment.segmentId)}\n />\n ))}\n </div>\n )}\n </div>\n );\n })}\n </div>\n )}\n </div>\n </SheetContent>\n </Sheet>\n );\n}\n"]}
@@ -0,0 +1,7 @@
1
+ import type React from "react";
2
+ import type { ContextManifestSegment } from "../../shared/context-xray.js";
3
+ export declare function SegmentProvenancePopover({ segment, children, }: {
4
+ segment: ContextManifestSegment;
5
+ children: React.ReactNode;
6
+ }): import("react/jsx-runtime").JSX.Element;
7
+ //# sourceMappingURL=SegmentProvenancePopover.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SegmentProvenancePopover.d.ts","sourceRoot":"","sources":["../../../src/client/context-xray/SegmentProvenancePopover.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAQ3E,wBAAgB,wBAAwB,CAAC,EACvC,OAAO,EACP,QAAQ,GACT,EAAE;IACD,OAAO,EAAE,sBAAsB,CAAC;IAChC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,2CAiDA"}
@@ -0,0 +1,7 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Popover, PopoverContent, PopoverTrigger, } from "../components/ui/popover.js";
3
+ import { formatTokens, statusLabel } from "./format.js";
4
+ export function SegmentProvenancePopover({ segment, children, }) {
5
+ return (_jsxs(Popover, { children: [_jsx(PopoverTrigger, { asChild: true, children: children }), _jsx(PopoverContent, { align: "start", className: "w-80 p-3", children: _jsxs("div", { className: "space-y-2", children: [_jsxs("div", { children: [_jsx("div", { className: "text-[11px] font-medium uppercase text-muted-foreground", children: "Segment" }), _jsx("div", { className: "mt-0.5 break-words text-xs text-foreground", children: segment.label })] }), _jsxs("div", { className: "grid grid-cols-2 gap-2 text-[11px] text-muted-foreground", children: [_jsxs("div", { children: [_jsx("span", { className: "block font-medium text-foreground", children: formatTokens(segment.tokenCount) }), "tokens", segment.tokenMethod === "estimate" ? " estimated" : ""] }), _jsxs("div", { children: [_jsx("span", { className: "block font-medium text-foreground", children: statusLabel(segment) }), "current status"] }), _jsxs("div", { children: [_jsx("span", { className: "block font-medium text-foreground", children: segment.msgIndex ?? "-" }), "message index"] }), _jsxs("div", { children: [_jsx("span", { className: "block font-medium text-foreground", children: segment.partIndex ?? "-" }), "part index"] })] }), segment.protected && (_jsx("div", { className: "rounded-md border border-border bg-muted/40 px-2 py-1.5 text-[11px] text-muted-foreground", children: "This segment is part of the active turn and cannot be evicted yet." }))] }) })] }));
6
+ }
7
+ //# sourceMappingURL=SegmentProvenancePopover.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SegmentProvenancePopover.js","sourceRoot":"","sources":["../../../src/client/context-xray/SegmentProvenancePopover.tsx"],"names":[],"mappings":";AAEA,OAAO,EACL,OAAO,EACP,cAAc,EACd,cAAc,GACf,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAExD,MAAM,UAAU,wBAAwB,CAAC,EACvC,OAAO,EACP,QAAQ,GAIT;IACC,OAAO,CACL,MAAC,OAAO,eACN,KAAC,cAAc,IAAC,OAAO,kBAAE,QAAQ,GAAkB,EACnD,KAAC,cAAc,IAAC,KAAK,EAAC,OAAO,EAAC,SAAS,EAAC,UAAU,YAChD,eAAK,SAAS,EAAC,WAAW,aACxB,0BACE,cAAK,SAAS,EAAC,yDAAyD,wBAElE,EACN,cAAK,SAAS,EAAC,4CAA4C,YACxD,OAAO,CAAC,KAAK,GACV,IACF,EACN,eAAK,SAAS,EAAC,0DAA0D,aACvE,0BACE,eAAM,SAAS,EAAC,mCAAmC,YAChD,YAAY,CAAC,OAAO,CAAC,UAAU,CAAC,GAC5B,YACA,OAAO,CAAC,WAAW,KAAK,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,IACzD,EACN,0BACE,eAAM,SAAS,EAAC,mCAAmC,YAChD,WAAW,CAAC,OAAO,CAAC,GAChB,sBAEH,EACN,0BACE,eAAM,SAAS,EAAC,mCAAmC,YAChD,OAAO,CAAC,QAAQ,IAAI,GAAG,GACnB,qBAEH,EACN,0BACE,eAAM,SAAS,EAAC,mCAAmC,YAChD,OAAO,CAAC,SAAS,IAAI,GAAG,GACpB,kBAEH,IACF,EACL,OAAO,CAAC,SAAS,IAAI,CACpB,cAAK,SAAS,EAAC,2FAA2F,mFAEpG,CACP,IACG,GACS,IACT,CACX,CAAC;AACJ,CAAC","sourcesContent":["import type React from \"react\";\nimport type { ContextManifestSegment } from \"../../shared/context-xray.js\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"../components/ui/popover.js\";\nimport { formatTokens, statusLabel } from \"./format.js\";\n\nexport function SegmentProvenancePopover({\n segment,\n children,\n}: {\n segment: ContextManifestSegment;\n children: React.ReactNode;\n}) {\n return (\n <Popover>\n <PopoverTrigger asChild>{children}</PopoverTrigger>\n <PopoverContent align=\"start\" className=\"w-80 p-3\">\n <div className=\"space-y-2\">\n <div>\n <div className=\"text-[11px] font-medium uppercase text-muted-foreground\">\n Segment\n </div>\n <div className=\"mt-0.5 break-words text-xs text-foreground\">\n {segment.label}\n </div>\n </div>\n <div className=\"grid grid-cols-2 gap-2 text-[11px] text-muted-foreground\">\n <div>\n <span className=\"block font-medium text-foreground\">\n {formatTokens(segment.tokenCount)}\n </span>\n tokens{segment.tokenMethod === \"estimate\" ? \" estimated\" : \"\"}\n </div>\n <div>\n <span className=\"block font-medium text-foreground\">\n {statusLabel(segment)}\n </span>\n current status\n </div>\n <div>\n <span className=\"block font-medium text-foreground\">\n {segment.msgIndex ?? \"-\"}\n </span>\n message index\n </div>\n <div>\n <span className=\"block font-medium text-foreground\">\n {segment.partIndex ?? \"-\"}\n </span>\n part index\n </div>\n </div>\n {segment.protected && (\n <div className=\"rounded-md border border-border bg-muted/40 px-2 py-1.5 text-[11px] text-muted-foreground\">\n This segment is part of the active turn and cannot be evicted yet.\n </div>\n )}\n </div>\n </PopoverContent>\n </Popover>\n );\n}\n"]}
@@ -0,0 +1,7 @@
1
+ import type { ContextManifestSegment } from "../../shared/context-xray.js";
2
+ export declare const CONTEXT_XRAY_MODEL_LIMIT = 200000;
3
+ export declare function formatTokens(tokens: number | undefined): string;
4
+ export declare function statusLabel(segment: ContextManifestSegment): string;
5
+ export declare function groupColor(group: string): string;
6
+ export declare function groupFill(group: string): string;
7
+ //# sourceMappingURL=format.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../../src/client/context-xray/format.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAE3E,eAAO,MAAM,wBAAwB,SAAU,CAAC;AAEhD,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAO/D;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,sBAAsB,GAAG,MAAM,CAMnE;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAOhD;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAO/C"}
@@ -0,0 +1,47 @@
1
+ export const CONTEXT_XRAY_MODEL_LIMIT = 200_000;
2
+ export function formatTokens(tokens) {
3
+ const value = Math.max(0, Math.round(tokens ?? 0));
4
+ if (value >= 1000) {
5
+ const compact = value / 1000;
6
+ return `${compact >= 100 ? compact.toFixed(0) : compact.toFixed(1)}k`;
7
+ }
8
+ return String(value);
9
+ }
10
+ export function statusLabel(segment) {
11
+ if (segment.protected)
12
+ return "Protected";
13
+ if (segment.status === "pinned")
14
+ return "Pinned";
15
+ if (segment.status === "evicted")
16
+ return "Evicted";
17
+ if (segment.status === "summarized")
18
+ return "Summarized";
19
+ return "Active";
20
+ }
21
+ export function groupColor(group) {
22
+ if (group === "Pinned")
23
+ return "bg-emerald-500";
24
+ if (group === "Tool results")
25
+ return "bg-amber-500";
26
+ if (group === "Files read")
27
+ return "bg-sky-500";
28
+ if (group === "Thinking")
29
+ return "bg-violet-500";
30
+ if (group === "Task & instructions")
31
+ return "bg-rose-500";
32
+ return "bg-slate-400";
33
+ }
34
+ export function groupFill(group) {
35
+ if (group === "Pinned")
36
+ return "#10b981";
37
+ if (group === "Tool results")
38
+ return "#f59e0b";
39
+ if (group === "Files read")
40
+ return "#0ea5e9";
41
+ if (group === "Thinking")
42
+ return "#8b5cf6";
43
+ if (group === "Task & instructions")
44
+ return "#f43f5e";
45
+ return "#94a3b8";
46
+ }
47
+ //# sourceMappingURL=format.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.js","sourceRoot":"","sources":["../../../src/client/context-xray/format.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,wBAAwB,GAAG,OAAO,CAAC;AAEhD,MAAM,UAAU,YAAY,CAAC,MAA0B;IACrD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC;IACnD,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;QAClB,MAAM,OAAO,GAAG,KAAK,GAAG,IAAI,CAAC;QAC7B,OAAO,GAAG,OAAO,IAAI,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;IACxE,CAAC;IACD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,OAA+B;IACzD,IAAI,OAAO,CAAC,SAAS;QAAE,OAAO,WAAW,CAAC;IAC1C,IAAI,OAAO,CAAC,MAAM,KAAK,QAAQ;QAAE,OAAO,QAAQ,CAAC;IACjD,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IACnD,IAAI,OAAO,CAAC,MAAM,KAAK,YAAY;QAAE,OAAO,YAAY,CAAC;IACzD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAa;IACtC,IAAI,KAAK,KAAK,QAAQ;QAAE,OAAO,gBAAgB,CAAC;IAChD,IAAI,KAAK,KAAK,cAAc;QAAE,OAAO,cAAc,CAAC;IACpD,IAAI,KAAK,KAAK,YAAY;QAAE,OAAO,YAAY,CAAC;IAChD,IAAI,KAAK,KAAK,UAAU;QAAE,OAAO,eAAe,CAAC;IACjD,IAAI,KAAK,KAAK,qBAAqB;QAAE,OAAO,aAAa,CAAC;IAC1D,OAAO,cAAc,CAAC;AACxB,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,KAAa;IACrC,IAAI,KAAK,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IACzC,IAAI,KAAK,KAAK,cAAc;QAAE,OAAO,SAAS,CAAC;IAC/C,IAAI,KAAK,KAAK,YAAY;QAAE,OAAO,SAAS,CAAC;IAC7C,IAAI,KAAK,KAAK,UAAU;QAAE,OAAO,SAAS,CAAC;IAC3C,IAAI,KAAK,KAAK,qBAAqB;QAAE,OAAO,SAAS,CAAC;IACtD,OAAO,SAAS,CAAC;AACnB,CAAC","sourcesContent":["import type { ContextManifestSegment } from \"../../shared/context-xray.js\";\n\nexport const CONTEXT_XRAY_MODEL_LIMIT = 200_000;\n\nexport function formatTokens(tokens: number | undefined): string {\n const value = Math.max(0, Math.round(tokens ?? 0));\n if (value >= 1000) {\n const compact = value / 1000;\n return `${compact >= 100 ? compact.toFixed(0) : compact.toFixed(1)}k`;\n }\n return String(value);\n}\n\nexport function statusLabel(segment: ContextManifestSegment): string {\n if (segment.protected) return \"Protected\";\n if (segment.status === \"pinned\") return \"Pinned\";\n if (segment.status === \"evicted\") return \"Evicted\";\n if (segment.status === \"summarized\") return \"Summarized\";\n return \"Active\";\n}\n\nexport function groupColor(group: string): string {\n if (group === \"Pinned\") return \"bg-emerald-500\";\n if (group === \"Tool results\") return \"bg-amber-500\";\n if (group === \"Files read\") return \"bg-sky-500\";\n if (group === \"Thinking\") return \"bg-violet-500\";\n if (group === \"Task & instructions\") return \"bg-rose-500\";\n return \"bg-slate-400\";\n}\n\nexport function groupFill(group: string): string {\n if (group === \"Pinned\") return \"#10b981\";\n if (group === \"Tool results\") return \"#f59e0b\";\n if (group === \"Files read\") return \"#0ea5e9\";\n if (group === \"Thinking\") return \"#8b5cf6\";\n if (group === \"Task & instructions\") return \"#f43f5e\";\n return \"#94a3b8\";\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"route-discovery.d.ts","sourceRoot":"","sources":["../../src/deploy/route-discovery.ts"],"names":[],"mappings":"AAYA;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG;IAC/C,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf,GAAG,IAAI,CA2BP;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,GAAG,EAAE,MAAM,EACX,MAAM,SAAK,GACV,OAAO,CAAC,MAAM,EAAE,CAAC,CAkBnB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,wCAAwC;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,4BAA4B;IAC5B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,eAAe,EAAE,CAAC,CAoB5B;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAapE;AASD;;;GAGG;AACH,eAAO,MAAM,uBAAuB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAU1D,CAAC;AAWF,MAAM,WAAW,gBAAgB;IAC/B,+CAA+C;IAC/C,IAAI,EAAE,MAAM,CAAC;IACb,uCAAuC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,kEAAkE;IAClE,MAAM,EAAE,MAAM,CAAC;CAChB;AAgDD;;;;;;;;GAQG;AACH,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAoB7B;AAED;;GAEG;AACH,wBAAsB,wBAAwB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAmB7E"}
1
+ {"version":3,"file":"route-discovery.d.ts","sourceRoot":"","sources":["../../src/deploy/route-discovery.ts"],"names":[],"mappings":"AAYA;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG;IAC/C,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf,GAAG,IAAI,CA2BP;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,GAAG,EAAE,MAAM,EACX,MAAM,SAAK,GACV,OAAO,CAAC,MAAM,EAAE,CAAC,CAkBnB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,wCAAwC;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,4BAA4B;IAC5B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,eAAe,EAAE,CAAC,CAoB5B;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAapE;AASD;;;GAGG;AACH,eAAO,MAAM,uBAAuB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAW1D,CAAC;AAWF,MAAM,WAAW,gBAAgB;IAC/B,+CAA+C;IAC/C,IAAI,EAAE,MAAM,CAAC;IACb,uCAAuC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,kEAAkE;IAClE,MAAM,EAAE,MAAM,CAAC;CAChB;AAgDD;;;;;;;;GAQG;AACH,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAoB7B;AAED;;GAEG;AACH,wBAAsB,wBAAwB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAmB7E"}