@windowkit/agent-chat 0.0.0-stage → 0.3.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 (164) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +147 -2
  3. package/dist/core/driver.d.ts +183 -0
  4. package/dist/core/driver.d.ts.map +1 -0
  5. package/dist/core/driver.js +12 -0
  6. package/dist/core/driver.js.map +1 -0
  7. package/dist/core/index.d.ts +8 -0
  8. package/dist/core/index.d.ts.map +1 -0
  9. package/dist/core/index.js +11 -0
  10. package/dist/core/index.js.map +1 -0
  11. package/dist/core/markdown.d.ts +7 -0
  12. package/dist/core/markdown.d.ts.map +1 -0
  13. package/dist/core/markdown.js +53 -0
  14. package/dist/core/markdown.js.map +1 -0
  15. package/dist/core/policy.d.ts +18 -0
  16. package/dist/core/policy.d.ts.map +1 -0
  17. package/dist/core/policy.js +67 -0
  18. package/dist/core/policy.js.map +1 -0
  19. package/dist/core/reducer.d.ts +61 -0
  20. package/dist/core/reducer.d.ts.map +1 -0
  21. package/dist/core/reducer.js +391 -0
  22. package/dist/core/reducer.js.map +1 -0
  23. package/dist/core/session.d.ts +105 -0
  24. package/dist/core/session.d.ts.map +1 -0
  25. package/dist/core/session.js +648 -0
  26. package/dist/core/session.js.map +1 -0
  27. package/dist/core/tools.d.ts +120 -0
  28. package/dist/core/tools.d.ts.map +1 -0
  29. package/dist/core/tools.js +120 -0
  30. package/dist/core/tools.js.map +1 -0
  31. package/dist/core/types.d.ts +295 -0
  32. package/dist/core/types.d.ts.map +1 -0
  33. package/dist/core/types.js +21 -0
  34. package/dist/core/types.js.map +1 -0
  35. package/dist/drivers/claude/index.d.ts +20 -0
  36. package/dist/drivers/claude/index.d.ts.map +1 -0
  37. package/dist/drivers/claude/index.js +727 -0
  38. package/dist/drivers/claude/index.js.map +1 -0
  39. package/dist/drivers/claude/input.d.ts +7 -0
  40. package/dist/drivers/claude/input.d.ts.map +1 -0
  41. package/dist/drivers/claude/input.js +46 -0
  42. package/dist/drivers/claude/input.js.map +1 -0
  43. package/dist/drivers/claude/peers.d.ts +16 -0
  44. package/dist/drivers/claude/peers.d.ts.map +1 -0
  45. package/dist/drivers/claude/peers.js +137 -0
  46. package/dist/drivers/claude/peers.js.map +1 -0
  47. package/dist/drivers/claude/schema.d.ts +5 -0
  48. package/dist/drivers/claude/schema.d.ts.map +1 -0
  49. package/dist/drivers/claude/schema.js +77 -0
  50. package/dist/drivers/claude/schema.js.map +1 -0
  51. package/dist/drivers/claude/sdk.d.ts +86 -0
  52. package/dist/drivers/claude/sdk.d.ts.map +1 -0
  53. package/dist/drivers/claude/sdk.js +47 -0
  54. package/dist/drivers/claude/sdk.js.map +1 -0
  55. package/dist/drivers/claude/tools.d.ts +18 -0
  56. package/dist/drivers/claude/tools.d.ts.map +1 -0
  57. package/dist/drivers/claude/tools.js +119 -0
  58. package/dist/drivers/claude/tools.js.map +1 -0
  59. package/dist/index.d.ts +8 -0
  60. package/dist/index.d.ts.map +1 -0
  61. package/dist/index.js +12 -0
  62. package/dist/index.js.map +1 -0
  63. package/dist/testing/fake.d.ts +63 -0
  64. package/dist/testing/fake.d.ts.map +1 -0
  65. package/dist/testing/fake.js +270 -0
  66. package/dist/testing/fake.js.map +1 -0
  67. package/dist/testing/index.d.ts +2 -0
  68. package/dist/testing/index.d.ts.map +1 -0
  69. package/dist/testing/index.js +4 -0
  70. package/dist/testing/index.js.map +1 -0
  71. package/dist/view/AgentChat.d.ts +53 -0
  72. package/dist/view/AgentChat.d.ts.map +1 -0
  73. package/dist/view/AgentChat.js +87 -0
  74. package/dist/view/AgentChat.js.map +1 -0
  75. package/dist/view/CodeBlock.d.ts +9 -0
  76. package/dist/view/CodeBlock.d.ts.map +1 -0
  77. package/dist/view/CodeBlock.js +67 -0
  78. package/dist/view/CodeBlock.js.map +1 -0
  79. package/dist/view/Composer.d.ts +24 -0
  80. package/dist/view/Composer.d.ts.map +1 -0
  81. package/dist/view/Composer.js +144 -0
  82. package/dist/view/Composer.js.map +1 -0
  83. package/dist/view/Header.d.ts +3 -0
  84. package/dist/view/Header.d.ts.map +1 -0
  85. package/dist/view/Header.js +30 -0
  86. package/dist/view/Header.js.map +1 -0
  87. package/dist/view/MessageList.d.ts +9 -0
  88. package/dist/view/MessageList.d.ts.map +1 -0
  89. package/dist/view/MessageList.js +111 -0
  90. package/dist/view/MessageList.js.map +1 -0
  91. package/dist/view/QuestionCard.d.ts +6 -0
  92. package/dist/view/QuestionCard.d.ts.map +1 -0
  93. package/dist/view/QuestionCard.js +39 -0
  94. package/dist/view/QuestionCard.js.map +1 -0
  95. package/dist/view/TextBlock.d.ts +9 -0
  96. package/dist/view/TextBlock.d.ts.map +1 -0
  97. package/dist/view/TextBlock.js +25 -0
  98. package/dist/view/TextBlock.js.map +1 -0
  99. package/dist/view/ToolCard.d.ts +7 -0
  100. package/dist/view/ToolCard.d.ts.map +1 -0
  101. package/dist/view/ToolCard.js +155 -0
  102. package/dist/view/ToolCard.js.map +1 -0
  103. package/dist/view/Transcript.d.ts +5 -0
  104. package/dist/view/Transcript.d.ts.map +1 -0
  105. package/dist/view/Transcript.js +56 -0
  106. package/dist/view/Transcript.js.map +1 -0
  107. package/dist/view/context.d.ts +21 -0
  108. package/dist/view/context.d.ts.map +1 -0
  109. package/dist/view/context.js +37 -0
  110. package/dist/view/context.js.map +1 -0
  111. package/dist/view/fences.d.ts +13 -0
  112. package/dist/view/fences.d.ts.map +1 -0
  113. package/dist/view/fences.js +59 -0
  114. package/dist/view/fences.js.map +1 -0
  115. package/dist/view/files.d.ts +11 -0
  116. package/dist/view/files.d.ts.map +1 -0
  117. package/dist/view/files.js +109 -0
  118. package/dist/view/files.js.map +1 -0
  119. package/dist/view/look.d.ts +25 -0
  120. package/dist/view/look.d.ts.map +1 -0
  121. package/dist/view/look.js +47 -0
  122. package/dist/view/look.js.map +1 -0
  123. package/dist/view/types.d.ts +50 -0
  124. package/dist/view/types.d.ts.map +1 -0
  125. package/dist/view/types.js +14 -0
  126. package/dist/view/types.js.map +1 -0
  127. package/dist/view/use-agent.d.ts +11 -0
  128. package/dist/view/use-agent.d.ts.map +1 -0
  129. package/dist/view/use-agent.js +33 -0
  130. package/dist/view/use-agent.js.map +1 -0
  131. package/package.json +92 -4
  132. package/src/core/driver.ts +191 -0
  133. package/src/core/index.ts +54 -0
  134. package/src/core/markdown.ts +56 -0
  135. package/src/core/policy.ts +77 -0
  136. package/src/core/reducer.ts +490 -0
  137. package/src/core/session.ts +824 -0
  138. package/src/core/tools.ts +233 -0
  139. package/src/core/types.ts +321 -0
  140. package/src/drivers/claude/index.ts +825 -0
  141. package/src/drivers/claude/input.ts +47 -0
  142. package/src/drivers/claude/peers.ts +153 -0
  143. package/src/drivers/claude/schema.ts +99 -0
  144. package/src/drivers/claude/sdk.ts +138 -0
  145. package/src/drivers/claude/tools.ts +141 -0
  146. package/src/index.ts +51 -0
  147. package/src/testing/fake.ts +374 -0
  148. package/src/testing/index.ts +11 -0
  149. package/src/view/AgentChat.tsx +204 -0
  150. package/src/view/CodeBlock.tsx +115 -0
  151. package/src/view/Composer.tsx +230 -0
  152. package/src/view/Header.tsx +73 -0
  153. package/src/view/MessageList.tsx +290 -0
  154. package/src/view/QuestionCard.tsx +107 -0
  155. package/src/view/TextBlock.tsx +61 -0
  156. package/src/view/ToolCard.tsx +283 -0
  157. package/src/view/Transcript.tsx +91 -0
  158. package/src/view/context.ts +70 -0
  159. package/src/view/dom-globals.d.ts +10 -0
  160. package/src/view/fences.ts +73 -0
  161. package/src/view/files.ts +111 -0
  162. package/src/view/look.ts +70 -0
  163. package/src/view/types.ts +71 -0
  164. package/src/view/use-agent.ts +40 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QuestionCard.js","sourceRoot":"","sources":["../../src/view/QuestionCard.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { type ReactElement } from 'react';
2
+ import type { AgentMessage } from '../core/types.js';
3
+ export interface TextBlockProps {
4
+ text: string;
5
+ streaming: boolean;
6
+ message: AgentMessage;
7
+ }
8
+ export declare const TextBlock: import("react").MemoExoticComponent<({ text, streaming, message, }: TextBlockProps) => ReactElement>;
9
+ //# sourceMappingURL=TextBlock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TextBlock.d.ts","sourceRoot":"","sources":["../../src/view/TextBlock.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAiB,KAAK,YAAY,EAAE,MAAM,OAAO,CAAC;AAGzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAMrD,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,YAAY,CAAC;CACvB;AAED,eAAO,MAAM,SAAS,sEAInB,cAAc,KAAG,YAAY,CAsC9B,CAAC"}
@@ -0,0 +1,25 @@
1
+ import { jsx as _jsx } from "react-x11/jsx-runtime";
2
+ // Assistant text: markdown, with each top-level fence drawn as a code block
3
+ // that carries actions, or by the app's renderer for its language.
4
+ import { memo, useMemo } from 'react';
5
+ import { Markdown } from '@react-x11/components/markdown';
6
+ import { CodeBlock } from './CodeBlock.js';
7
+ import { useChat } from './context.js';
8
+ import { useCodeLook } from './look.js';
9
+ import { splitFences } from './fences.js';
10
+ export const TextBlock = memo(function TextBlock({ text, streaming, message, }) {
11
+ const { fences, components, onLink, fontSize } = useChat();
12
+ // segments alternate prose and fences: the gap is the space a fence keeps
13
+ const { spacing } = useCodeLook(fontSize);
14
+ const segments = useMemo(() => splitFences(text, streaming), [text, streaming]);
15
+ const link = useMemo(() => (onLink ? (href) => onLink(href) : undefined), [onLink]);
16
+ return (_jsx("box", { style: { flexDirection: 'column', gap: spacing }, children: segments.map((s, i) => {
17
+ if (s.type === 'prose') {
18
+ return (_jsx(Markdown, { source: s.text, partial: streaming && i === segments.length - 1, ...(fences ? { fences } : {}), ...(components ? { components } : {}), ...(link ? { onLink: link } : {}), ...(fontSize ? { fontSize } : {}) }, i));
19
+ }
20
+ const fence = { lang: s.lang, text: s.text, partial: s.partial };
21
+ const custom = fences?.[s.lang];
22
+ return custom ? (_jsx("box", { children: custom(fence) }, i)) : (_jsx(CodeBlock, { fence: fence, message: message }, i));
23
+ }) }));
24
+ });
25
+ //# sourceMappingURL=TextBlock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TextBlock.js","sourceRoot":"","sources":["../../src/view/TextBlock.tsx"],"names":[],"mappings":";AAAA,4EAA4E;AAC5E,mEAAmE;AAEnE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAqB,MAAM,OAAO,CAAC;AACzD,OAAO,EAAE,QAAQ,EAAE,MAAM,gCAAgC,CAAC;AAG1D,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAQ1C,MAAM,CAAC,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,SAAS,CAAC,EAC/C,IAAI,EACJ,SAAS,EACT,OAAO,GACQ;IACf,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,EAAE,CAAC;IAC3D,0EAA0E;IAC1E,MAAM,EAAE,OAAO,EAAE,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;IAC1C,MAAM,QAAQ,GAAG,OAAO,CACtB,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,EAAE,SAAS,CAAC,EAClC,CAAC,IAAI,EAAE,SAAS,CAAC,CAClB,CAAC;IACF,MAAM,IAAI,GAAG,OAAO,CAClB,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,EAC3D,CAAC,MAAM,CAAC,CACT,CAAC;IACF,OAAO,CACL,cAAK,KAAK,EAAE,EAAE,aAAa,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,YAClD,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YACrB,IAAI,CAAC,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;gBACvB,OAAO,CACL,KAAC,QAAQ,IAEP,MAAM,EAAE,CAAC,CAAC,IAAI,EACd,OAAO,EAAE,SAAS,IAAI,CAAC,KAAK,QAAQ,CAAC,MAAM,GAAG,CAAC,KAC3C,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KAC1B,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KAClC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KAC9B,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,IAN7B,CAAC,CAON,CACH,CAAC;YACJ,CAAC;YACD,MAAM,KAAK,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;YACjE,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YAChC,OAAO,MAAM,CAAC,CAAC,CAAC,CACd,wBAAc,MAAM,CAAC,KAAK,CAAC,IAAjB,CAAC,CAAuB,CACnC,CAAC,CAAC,CAAC,CACF,KAAC,SAAS,IAAS,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,IAAjC,CAAC,CAAoC,CACtD,CAAC;QACJ,CAAC,CAAC,GACE,CACP,CAAC;AACJ,CAAC,CAAC,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { type ReactElement } from 'react';
2
+ import type { ToolPart } from '../core/types.js';
3
+ export interface ToolCardProps {
4
+ part: ToolPart;
5
+ }
6
+ export declare const ToolCard: import("react").MemoExoticComponent<({ part, }: ToolCardProps) => ReactElement>;
7
+ //# sourceMappingURL=ToolCard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToolCard.d.ts","sourceRoot":"","sources":["../../src/view/ToolCard.tsx"],"names":[],"mappings":"AAMA,OAAO,EAAkB,KAAK,YAAY,EAAkB,MAAM,OAAO,CAAC;AAM1E,OAAO,KAAK,EAAc,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAgB7D,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,QAAQ,CAAC;CAChB;AAED,eAAO,MAAM,QAAQ,kDAElB,aAAa,KAAG,YAAY,CA0H7B,CAAC"}
@@ -0,0 +1,155 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react-x11/jsx-runtime";
2
+ // One tool call: a line saying what it is and how it went, the approval row
3
+ // while it waits for the user, and its output when opened.
4
+ //
5
+ // Approval is drawn here, on the call, not in a dialog: what is being
6
+ // approved is right above the buttons.
7
+ import { memo, useState } from 'react';
8
+ import { Button, Icon } from 'react-x11';
9
+ import { Code } from '@react-x11/components/code';
10
+ import { Markdown } from '@react-x11/components/markdown';
11
+ import { TerminalOutput } from '@react-x11/components/terminal-output';
12
+ import { useChat } from './context.js';
13
+ import { clipLines, useLook } from './look.js';
14
+ import { MessageList } from './MessageList.js';
15
+ const STATE_LABEL = {
16
+ 'input-streaming': 'preparing',
17
+ pending: 'queued',
18
+ 'awaiting-approval': 'needs approval',
19
+ running: 'running',
20
+ done: '',
21
+ error: 'failed',
22
+ denied: 'denied',
23
+ cancelled: 'stopped',
24
+ };
25
+ export const ToolCard = memo(function ToolCard({ part, }) {
26
+ const { session, renderTool } = useChat();
27
+ const look = useLook();
28
+ const [open, setOpen] = useState(false);
29
+ const value = part.output.find((o) => o.type === 'value');
30
+ const render = session.tools.get(part.label)?.render ??
31
+ renderTool[part.label] ??
32
+ renderTool['*'];
33
+ const custom = render
34
+ ? render({
35
+ part,
36
+ input: part.input,
37
+ output: value?.type === 'value' ? value.value : undefined,
38
+ })
39
+ : null;
40
+ const waiting = part.state === 'awaiting-approval';
41
+ const expanded = open || waiting;
42
+ const [glyph, colour] = glyphOf(part.state, look);
43
+ return (_jsxs("box", { style: {
44
+ flexDirection: 'column',
45
+ borderWidth: 1,
46
+ borderColor: waiting ? look.warning : look.border,
47
+ borderRadius: 6,
48
+ }, children: [_jsxs("box", { style: {
49
+ flexDirection: 'row',
50
+ alignItems: 'center',
51
+ gap: 6,
52
+ paddingLeft: 8,
53
+ paddingRight: 8,
54
+ paddingTop: 4,
55
+ paddingBottom: 4,
56
+ cursor: 'pointer',
57
+ }, onClick: () => setOpen((o) => !o), children: [_jsx(Icon, { name: expanded ? 'chevronDown' : 'chevronRight', size: 12, color: look.muted }), _jsx(Icon, { name: glyph, size: 12, color: colour }), _jsx("text", { style: { color: look.text, flexGrow: 1, flexShrink: 1, maxLines: 1 }, children: part.title }), STATE_LABEL[part.state] ? (_jsx("text", { style: { color: look.muted, fontSize: 11 }, children: STATE_LABEL[part.state] })) : null] }), custom ? (_jsx("box", { style: { padding: 8, paddingTop: 0 }, children: custom })) : null, expanded && !custom ? (_jsxs("box", { style: { flexDirection: 'column', gap: 6, padding: 8, paddingTop: 0 }, children: [waiting || !part.output.length ? _jsx(InputPreview, { part: part }) : null, part.output.map((o, i) => (_jsx(Output, { output: o, look: look }, i))), part.error ? (_jsx("text", { style: { color: look.danger }, children: clipLines(part.error, 40) })) : null] })) : null, part.children?.length && expanded ? (_jsx("box", { style: {
58
+ paddingLeft: 12,
59
+ marginLeft: 8,
60
+ borderLeftWidth: 2,
61
+ borderLeftColor: look.border,
62
+ marginBottom: 8,
63
+ }, children: _jsx(MessageList, { messages: part.children }) })) : null, waiting && part.approval ? (_jsx("box", { style: {
64
+ flexDirection: 'row',
65
+ gap: 6,
66
+ padding: 8,
67
+ borderTopWidth: 1,
68
+ borderTopColor: look.border,
69
+ alignItems: 'center',
70
+ }, children: part.approval.options.map((option, i) => (_jsx(Button, { size: "small", label: option.label, primary: i === 0, variant: option.kind === 'deny' ? 'ghost' : i === 0 ? 'solid' : 'outline', onPress: () => session.respond(part.id, option.id) }, option.id))) })) : null] }));
71
+ });
72
+ function glyphOf(state, look) {
73
+ switch (state) {
74
+ case 'done':
75
+ return ['check', look.success];
76
+ case 'error':
77
+ case 'denied':
78
+ return ['close', look.danger];
79
+ case 'cancelled':
80
+ return ['dash', look.muted];
81
+ case 'awaiting-approval':
82
+ return ['dot', look.warning];
83
+ default:
84
+ return ['dot', look.accent];
85
+ }
86
+ }
87
+ /** What the call will do, for the user deciding whether it may. */
88
+ function InputPreview({ part }) {
89
+ const input = (part.input && typeof part.input === 'object' ? part.input : {});
90
+ if (part.label === 'ExitPlanMode' && typeof input.plan === 'string') {
91
+ return _jsx(Markdown, { source: input.plan, partial: false });
92
+ }
93
+ if (part.kind === 'execute' && typeof input.command === 'string') {
94
+ return _jsx(Code, { source: input.command, lang: "sh", wrap: true });
95
+ }
96
+ if (part.kind === 'edit' && typeof input.file_path === 'string') {
97
+ if (typeof input.old_string === 'string' ||
98
+ typeof input.new_string === 'string') {
99
+ return (_jsx(Diff, { output: {
100
+ type: 'diff',
101
+ path: input.file_path,
102
+ oldText: String(input.old_string ?? ''),
103
+ newText: String(input.new_string ?? ''),
104
+ } }));
105
+ }
106
+ if (typeof input.content === 'string') {
107
+ return (_jsx(Diff, { output: {
108
+ type: 'diff',
109
+ path: input.file_path,
110
+ oldText: null,
111
+ newText: input.content,
112
+ } }));
113
+ }
114
+ }
115
+ if (part.inputText === '' && part.input === undefined)
116
+ return null;
117
+ return _jsx(Code, { source: clipLines(json(part.input), 60), lang: "json", wrap: true });
118
+ }
119
+ function Output({ output, look, }) {
120
+ switch (output.type) {
121
+ case 'text':
122
+ return output.progress ? (_jsx("text", { style: { color: look.muted }, children: output.text })) : (_jsx(Code, { source: clipLines(output.text), wrap: true }));
123
+ case 'terminal':
124
+ return _jsx(TerminalOutput, { data: clipLines(output.text), mode: "flow" });
125
+ case 'diff':
126
+ return _jsx(Diff, { output: output });
127
+ case 'image':
128
+ return _jsxs("text", { style: { color: look.muted }, children: ["[image, ", output.mime, "]"] });
129
+ case 'value':
130
+ return (_jsx(Code, { source: clipLines(json(output.value), 80), lang: "json", wrap: true }));
131
+ }
132
+ }
133
+ /** A change as lines in red and green: what Claude Code's own edit shows. */
134
+ function Diff({ output, }) {
135
+ const look = useLook();
136
+ const removed = output.oldText === null ? [] : output.oldText.split('\n');
137
+ const added = output.newText.split('\n');
138
+ const lines = [
139
+ ...removed.map((l) => ['-', l]),
140
+ ...added.map((l) => ['+', l]),
141
+ ].slice(0, 300);
142
+ return (_jsxs("box", { style: { flexDirection: 'column' }, children: [_jsx("text", { style: { color: look.muted, fontSize: 11 }, children: output.path }), lines.map(([sign, line], i) => (_jsx("text", { style: {
143
+ fontFamily: look.mono,
144
+ color: sign === '-' ? look.danger : look.success,
145
+ }, children: `${sign} ${line}` }, i)))] }));
146
+ }
147
+ function json(value) {
148
+ try {
149
+ return JSON.stringify(value, null, 2) ?? '';
150
+ }
151
+ catch {
152
+ return String(value);
153
+ }
154
+ }
155
+ //# sourceMappingURL=ToolCard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToolCard.js","sourceRoot":"","sources":["../../src/view/ToolCard.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import { type ReactElement, type ReactNode } from 'react';
2
+ export declare function Transcript({ empty }: {
3
+ empty?: ReactNode;
4
+ }): ReactElement;
5
+ //# sourceMappingURL=Transcript.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Transcript.d.ts","sourceRoot":"","sources":["../../src/view/Transcript.tsx"],"names":[],"mappings":"AAMA,OAAO,EAGL,KAAK,YAAY,EACjB,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAWf,wBAAgB,UAAU,CAAC,EAAE,KAAK,EAAE,EAAE;IAAE,KAAK,CAAC,EAAE,SAAS,CAAA;CAAE,GAAG,YAAY,CA6CzE"}
@@ -0,0 +1,56 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react-x11/jsx-runtime";
2
+ // The scrolling transcript. It follows the newest message while the reader
3
+ // is at the bottom, and stops following once they scroll up to read. It
4
+ // follows content that grows after it was laid out too: a fence the app
5
+ // draws itself (a diagram compiled after mount) would otherwise push the end
6
+ // of the reply out of view.
7
+ import { useLayoutEffect, useRef, } from 'react';
8
+ import { useChat } from './context.js';
9
+ import { useLook } from './look.js';
10
+ import { MessageList } from './MessageList.js';
11
+ import { useSessionSnapshot } from './use-agent.js';
12
+ /** Within this many pixels of the end counts as at the end. */
13
+ const STICK_PX = 24;
14
+ export function Transcript({ empty }) {
15
+ const { session } = useChat();
16
+ const snap = useSessionSnapshot(session);
17
+ const look = useLook();
18
+ const pane = useRef(null);
19
+ const stick = useRef(true);
20
+ useLayoutEffect(() => {
21
+ // a layout effect: `scrollTo(Infinity)` here follows the new rows to the
22
+ // end in the frame that shows them (react-x11's ScrollableNode)
23
+ if (stick.current)
24
+ pane.current?.scrollTo(Infinity);
25
+ }, [snap.messages, snap.status]);
26
+ // fires from layout whenever the content or viewport size changes, not
27
+ // only when the snapshot does
28
+ const onViewport = () => {
29
+ if (stick.current)
30
+ pane.current?.scrollTo(Infinity);
31
+ };
32
+ const onScroll = (ev) => {
33
+ stick.current =
34
+ ev.scrollY + ev.viewportHeight >= ev.contentHeight - STICK_PX;
35
+ };
36
+ const activity = activityOf(snap.status, snap.messages);
37
+ return (_jsx("box", { ref: pane, onScroll: onScroll, onViewport: onViewport, style: { flexGrow: 1, flexShrink: 1, minHeight: 0, overflow: 'scroll' }, "data-testname": "agent-chat-transcript", children: _jsxs("box", { style: { flexDirection: 'column', gap: 14, padding: 14 }, children: [snap.messages.length ? (_jsx(MessageList, { messages: snap.messages })) : ((empty ?? null)), activity ? (_jsx("text", { style: { color: look.muted, fontSize: 12 }, children: activity })) : null] }) }));
38
+ }
39
+ function activityOf(status, messages) {
40
+ switch (status) {
41
+ case 'starting':
42
+ return 'Starting the agent…';
43
+ case 'paused':
44
+ return 'Paused. The agent stops at its next action until you resume.';
45
+ case 'waiting':
46
+ return 'Waiting for you.';
47
+ case 'running': {
48
+ const last = messages[messages.length - 1];
49
+ const streaming = last?.parts.some((p) => (p.type === 'text' || p.type === 'reasoning') && p.streaming);
50
+ return streaming ? null : 'Working…';
51
+ }
52
+ default:
53
+ return null;
54
+ }
55
+ }
56
+ //# sourceMappingURL=Transcript.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Transcript.js","sourceRoot":"","sources":["../../src/view/Transcript.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import { type ComponentType, type ReactNode } from 'react';
2
+ import type { FenceInfo } from '@react-x11/components/markdown';
3
+ import type { AgentSession } from '../core/session.js';
4
+ import type { CodeAction, ComponentEntry, FenceEntry, ToolRenderer } from './types.js';
5
+ export interface ChatContextValue {
6
+ session: AgentSession;
7
+ /** For `<Markdown fences>`: language → renderer. */
8
+ fences: Record<string, (fence: FenceInfo) => ReactNode> | undefined;
9
+ /** For `<Markdown components>`. */
10
+ components: Record<string, ComponentType<Record<string, unknown>>> | undefined;
11
+ renderTool: Readonly<Record<string, ToolRenderer>>;
12
+ codeActions: readonly CodeAction[];
13
+ onLink: ((href: string) => void) | undefined;
14
+ /** Base text size, the theme's unless the app said. */
15
+ fontSize: number | undefined;
16
+ }
17
+ export declare const ChatContext: import("react").Context<ChatContextValue | null>;
18
+ export declare function useChat(): ChatContextValue;
19
+ export declare function fenceMap(fences: Readonly<Record<string, FenceEntry>> | undefined): Record<string, (fence: FenceInfo) => ReactNode> | undefined;
20
+ export declare function componentMap(components: Readonly<Record<string, ComponentEntry>> | undefined): Record<string, ComponentType<Record<string, unknown>>> | undefined;
21
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/view/context.ts"],"names":[],"mappings":"AAOA,OAAO,EAGL,KAAK,aAAa,EAClB,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AACf,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gCAAgC,CAAC;AAEhE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EACV,UAAU,EACV,cAAc,EACd,UAAU,EACV,YAAY,EACb,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,YAAY,CAAC;IACtB,oDAAoD;IACpD,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,SAAS,CAAC,GAAG,SAAS,CAAC;IACpE,mCAAmC;IACnC,UAAU,EACR,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;IACrE,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC;IACnD,WAAW,EAAE,SAAS,UAAU,EAAE,CAAC;IACnC,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IAC7C,uDAAuD;IACvD,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;CAC9B;AAED,eAAO,MAAM,WAAW,kDAA+C,CAAC;AAExE,wBAAgB,OAAO,IAAI,gBAAgB,CAI1C;AAED,wBAAgB,QAAQ,CACtB,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,GAAG,SAAS,GACvD,MAAM,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,SAAS,CAAC,GAAG,SAAS,CAQ7D;AAED,wBAAgB,YAAY,CAC1B,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,GAAG,SAAS,GAC/D,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,SAAS,CAUpE"}
@@ -0,0 +1,37 @@
1
+ // What every part of the view reads: the session, the app's renderers and
2
+ // actions, normalized once with stable identities.
3
+ //
4
+ // Stable identities matter: `<Markdown>` keeps a block cache keyed on its
5
+ // `fences` and `components` maps, and a new map per render would re-parse
6
+ // every message on every token.
7
+ import { createContext, useContext, } from 'react';
8
+ export const ChatContext = createContext(null);
9
+ export function useChat() {
10
+ const value = useContext(ChatContext);
11
+ if (!value)
12
+ throw new Error('A chat part was rendered outside <AgentChat>.');
13
+ return value;
14
+ }
15
+ export function fenceMap(fences) {
16
+ if (!fences)
17
+ return undefined;
18
+ const out = {};
19
+ for (const [lang, entry] of Object.entries(fences)) {
20
+ out[lang.toLowerCase()] =
21
+ typeof entry === 'function' ? entry : entry.render;
22
+ }
23
+ return out;
24
+ }
25
+ export function componentMap(components) {
26
+ if (!components)
27
+ return undefined;
28
+ const out = {};
29
+ for (const [name, entry] of Object.entries(components)) {
30
+ out[name] =
31
+ typeof entry === 'object' && entry !== null && 'component' in entry
32
+ ? entry.component
33
+ : entry;
34
+ }
35
+ return out;
36
+ }
37
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/view/context.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,mDAAmD;AACnD,EAAE;AACF,0EAA0E;AAC1E,0EAA0E;AAC1E,gCAAgC;AAEhC,OAAO,EACL,aAAa,EACb,UAAU,GAGX,MAAM,OAAO,CAAC;AAyBf,MAAM,CAAC,MAAM,WAAW,GAAG,aAAa,CAA0B,IAAI,CAAC,CAAC;AAExE,MAAM,UAAU,OAAO;IACrB,MAAM,KAAK,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;IACtC,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;IAC7E,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,QAAQ,CACtB,MAAwD;IAExD,IAAI,CAAC,MAAM;QAAE,OAAO,SAAS,CAAC;IAC9B,MAAM,GAAG,GAAoD,EAAE,CAAC;IAChE,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QACnD,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACrB,OAAO,KAAK,KAAK,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC;IACvD,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,YAAY,CAC1B,UAAgE;IAEhE,IAAI,CAAC,UAAU;QAAE,OAAO,SAAS,CAAC;IAClC,MAAM,GAAG,GAA2D,EAAE,CAAC;IACvE,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;QACvD,GAAG,CAAC,IAAI,CAAC;YACP,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,WAAW,IAAI,KAAK;gBACjE,CAAC,CAAC,KAAK,CAAC,SAAS;gBACjB,CAAC,CAAE,KAAgD,CAAC;IAC1D,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,13 @@
1
+ export type Segment = {
2
+ type: 'prose';
3
+ text: string;
4
+ } | {
5
+ type: 'fence';
6
+ /** The info string's first word, lowercased: what renderers are keyed by. */
7
+ lang: string;
8
+ text: string;
9
+ /** Still streaming: the fence has not closed and more may come. */
10
+ partial: boolean;
11
+ };
12
+ export declare function splitFences(source: string, streaming: boolean): Segment[];
13
+ //# sourceMappingURL=fences.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fences.d.ts","sourceRoot":"","sources":["../../src/view/fences.ts"],"names":[],"mappings":"AASA,MAAM,MAAM,OAAO,GACf;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC/B;IACE,IAAI,EAAE,OAAO,CAAC;IACd,6EAA6E;IAC7E,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,mEAAmE;IACnE,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC;AAIN,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,GAAG,OAAO,EAAE,CAkDzE"}
@@ -0,0 +1,59 @@
1
+ // A reply split at its top-level fences, so each code block can carry a
2
+ // header of actions.
3
+ //
4
+ // `<Markdown>` draws a fence with no hook for a button on it, and adding one
5
+ // there (`codeActions`) is the right fix; until it lands, a reply is cut
6
+ // here. Only fences that start at the left margin are cut out: one indented
7
+ // under a list item stays in its list, drawn by `<Markdown>` without actions,
8
+ // rather than being pulled out of the list it belongs to.
9
+ const OPEN = /^(`{3,}|~{3,})(.*)$/;
10
+ export function splitFences(source, streaming) {
11
+ const lines = source.split('\n');
12
+ const out = [];
13
+ let prose = [];
14
+ let i = 0;
15
+ const flush = () => {
16
+ if (prose.length && prose.some((l) => l.trim())) {
17
+ out.push({ type: 'prose', text: prose.join('\n') });
18
+ }
19
+ prose = [];
20
+ };
21
+ while (i < lines.length) {
22
+ const line = lines[i];
23
+ const open = OPEN.exec(line);
24
+ // a backtick fence's info string may not hold a backtick
25
+ if (!open || (open[1][0] === '`' && open[2].includes('`'))) {
26
+ prose.push(line);
27
+ i++;
28
+ continue;
29
+ }
30
+ const marker = open[1];
31
+ const lang = (open[2].trim().split(/\s+/)[0] ?? '').toLowerCase();
32
+ const body = [];
33
+ let closed = false;
34
+ i++;
35
+ while (i < lines.length) {
36
+ const l = lines[i];
37
+ const close = /^(`{3,}|~{3,})\s*$/.exec(l);
38
+ if (close &&
39
+ close[1][0] === marker[0] &&
40
+ close[1].length >= marker.length) {
41
+ closed = true;
42
+ i++;
43
+ break;
44
+ }
45
+ body.push(l);
46
+ i++;
47
+ }
48
+ flush();
49
+ out.push({
50
+ type: 'fence',
51
+ lang,
52
+ text: body.join('\n'),
53
+ partial: !closed && streaming,
54
+ });
55
+ }
56
+ flush();
57
+ return out;
58
+ }
59
+ //# sourceMappingURL=fences.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fences.js","sourceRoot":"","sources":["../../src/view/fences.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,qBAAqB;AACrB,EAAE;AACF,6EAA6E;AAC7E,yEAAyE;AACzE,4EAA4E;AAC5E,8EAA8E;AAC9E,0DAA0D;AAa1D,MAAM,IAAI,GAAG,qBAAqB,CAAC;AAEnC,MAAM,UAAU,WAAW,CAAC,MAAc,EAAE,SAAkB;IAC5D,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACjC,MAAM,GAAG,GAAc,EAAE,CAAC;IAC1B,IAAI,KAAK,GAAa,EAAE,CAAC;IACzB,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,MAAM,KAAK,GAAG,GAAG,EAAE;QACjB,IAAI,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;YAChD,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACtD,CAAC;QACD,KAAK,GAAG,EAAE,CAAC;IACb,CAAC,CAAC;IACF,OAAO,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;QACxB,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC;QACvB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7B,yDAAyD;QACzD,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,IAAI,CAAC,CAAC,CAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YAC7D,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACjB,CAAC,EAAE,CAAC;YACJ,SAAS;QACX,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,CAAC,CAAE,CAAC;QACxB,MAAM,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,CAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;QACnE,MAAM,IAAI,GAAa,EAAE,CAAC;QAC1B,IAAI,MAAM,GAAG,KAAK,CAAC;QACnB,CAAC,EAAE,CAAC;QACJ,OAAO,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;YACxB,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC;YACpB,MAAM,KAAK,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAC3C,IACE,KAAK;gBACL,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC;gBAC1B,KAAK,CAAC,CAAC,CAAE,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,EACjC,CAAC;gBACD,MAAM,GAAG,IAAI,CAAC;gBACd,CAAC,EAAE,CAAC;gBACJ,MAAM;YACR,CAAC;YACD,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACb,CAAC,EAAE,CAAC;QACN,CAAC;QACD,KAAK,EAAE,CAAC;QACR,GAAG,CAAC,IAAI,CAAC;YACP,IAAI,EAAE,OAAO;YACb,IAAI;YACJ,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;YACrB,OAAO,EAAE,CAAC,MAAM,IAAI,SAAS;SAC9B,CAAC,CAAC;IACL,CAAC;IACD,KAAK,EAAE,CAAC;IACR,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,11 @@
1
+ /** How many paths a walk collects before it stops. */
2
+ export declare const FILE_LIMIT = 5000;
3
+ /** Paths under `root`, relative and `/`-separated, files only. */
4
+ export declare function listFiles(root: string): Promise<string[]>;
5
+ /**
6
+ * The paths a query names, best first: a file whose name starts with the
7
+ * query, then one whose name holds it, then one whose path holds it, then
8
+ * one whose path holds its characters in order. Case does not matter.
9
+ */
10
+ export declare function matchFiles(files: readonly string[], query: string, max?: number): string[];
11
+ //# sourceMappingURL=files.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../../src/view/files.ts"],"names":[],"mappings":"AA0BA,sDAAsD;AACtD,eAAO,MAAM,UAAU,OAAO,CAAC;AAK/B,kEAAkE;AAClE,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAMzD;AAgCD;;;;GAIG;AACH,wBAAgB,UAAU,CACxB,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,KAAK,EAAE,MAAM,EACb,GAAG,SAAK,GACP,MAAM,EAAE,CAoBV"}
@@ -0,0 +1,109 @@
1
+ // The files under the agent's working directory, for the composer's `@`
2
+ // list. A walk of the tree, kept for a few seconds so a burst of keystrokes
3
+ // reads it once, bounded so a home directory does not hang the list, and
4
+ // blind to what nobody mentions: dependencies, build output, VCS data.
5
+ import { readdir } from 'node:fs/promises';
6
+ import path from 'node:path';
7
+ const SKIPPED = new Set([
8
+ 'node_modules',
9
+ '.git',
10
+ '.hg',
11
+ '.svn',
12
+ 'dist',
13
+ 'build',
14
+ 'out',
15
+ 'target',
16
+ 'coverage',
17
+ '.next',
18
+ '.turbo',
19
+ '.cache',
20
+ '.venv',
21
+ 'venv',
22
+ '__pycache__',
23
+ ]);
24
+ /** How many paths a walk collects before it stops. */
25
+ export const FILE_LIMIT = 5000;
26
+ const KEEP_MS = 10_000;
27
+ const walks = new Map();
28
+ /** Paths under `root`, relative and `/`-separated, files only. */
29
+ export function listFiles(root) {
30
+ const kept = walks.get(root);
31
+ if (kept && Date.now() - kept.at < KEEP_MS)
32
+ return kept.files;
33
+ const files = walk(root).catch(() => []);
34
+ walks.set(root, { at: Date.now(), files });
35
+ return files;
36
+ }
37
+ async function walk(root) {
38
+ const out = [];
39
+ // breadth first, so the files nearest the root are the ones kept
40
+ let level = [''];
41
+ while (level.length && out.length < FILE_LIMIT) {
42
+ const next = [];
43
+ for (const dir of level) {
44
+ let entries;
45
+ try {
46
+ entries = await readdir(path.join(root, dir), { withFileTypes: true });
47
+ }
48
+ catch {
49
+ continue;
50
+ }
51
+ entries.sort((a, b) => a.name.localeCompare(b.name));
52
+ for (const e of entries) {
53
+ const rel = dir ? `${dir}/${e.name}` : e.name;
54
+ if (e.isDirectory()) {
55
+ if (!SKIPPED.has(e.name))
56
+ next.push(rel);
57
+ }
58
+ else if (e.isFile()) {
59
+ out.push(rel);
60
+ if (out.length >= FILE_LIMIT)
61
+ break;
62
+ }
63
+ }
64
+ if (out.length >= FILE_LIMIT)
65
+ break;
66
+ }
67
+ level = next;
68
+ }
69
+ return out;
70
+ }
71
+ /**
72
+ * The paths a query names, best first: a file whose name starts with the
73
+ * query, then one whose name holds it, then one whose path holds it, then
74
+ * one whose path holds its characters in order. Case does not matter.
75
+ */
76
+ export function matchFiles(files, query, max = 20) {
77
+ const q = query.toLowerCase();
78
+ if (!q)
79
+ return files.slice(0, max);
80
+ const scored = [];
81
+ for (const f of files) {
82
+ const p = f.toLowerCase();
83
+ const name = p.slice(p.lastIndexOf('/') + 1);
84
+ const score = name.startsWith(q)
85
+ ? 0
86
+ : name.includes(q)
87
+ ? 1
88
+ : p.includes(q)
89
+ ? 2
90
+ : inOrder(p, q)
91
+ ? 3
92
+ : -1;
93
+ if (score >= 0)
94
+ scored.push([score * 10_000 + p.length, f]);
95
+ }
96
+ scored.sort((a, b) => a[0] - b[0]);
97
+ return scored.slice(0, max).map(([, f]) => f);
98
+ }
99
+ function inOrder(text, query) {
100
+ let at = 0;
101
+ for (const ch of query) {
102
+ at = text.indexOf(ch, at);
103
+ if (at < 0)
104
+ return false;
105
+ at++;
106
+ }
107
+ return true;
108
+ }
109
+ //# sourceMappingURL=files.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"files.js","sourceRoot":"","sources":["../../src/view/files.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import { type CodeBlockLook } from '@react-x11/components/codeblock';
2
+ export interface ChatLook {
3
+ text: string;
4
+ muted: string;
5
+ border: string;
6
+ surface: string;
7
+ background: string;
8
+ accent: string;
9
+ danger: string;
10
+ success: string;
11
+ warning: string;
12
+ mono: string;
13
+ /** The user's bubble: the text colour, faintly, so it shows on any ground. */
14
+ bubble: string;
15
+ }
16
+ export declare function useLook(): ChatLook;
17
+ /**
18
+ * What a block of code looks like here: what `<Markdown>` draws a fence
19
+ * with, at the chat's text size, so a fence the chat draws itself (to carry
20
+ * its actions) has the fill, radius, inset and spacing of one it does not.
21
+ */
22
+ export declare function useCodeLook(fontSize: number | undefined): CodeBlockLook;
23
+ /** At most `max` lines: the first and last halves, and how many were cut. */
24
+ export declare function clipLines(text: string, max?: number): string;
25
+ //# sourceMappingURL=look.d.ts.map