@assistant-ui/react-ink 0.0.6 → 0.0.8

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 (66) hide show
  1. package/README.md +1 -0
  2. package/dist/index.d.ts +3 -1
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +3 -1
  5. package/dist/index.js.map +1 -1
  6. package/dist/primitives/composer/ComposerSend.js +1 -1
  7. package/dist/primitives/composer/ComposerSend.js.map +1 -1
  8. package/dist/primitives/diff/DiffContent.d.ts +22 -0
  9. package/dist/primitives/diff/DiffContent.d.ts.map +1 -0
  10. package/dist/primitives/diff/DiffContent.js +40 -0
  11. package/dist/primitives/diff/DiffContent.js.map +1 -0
  12. package/dist/primitives/diff/DiffContext.d.ts +8 -0
  13. package/dist/primitives/diff/DiffContext.d.ts.map +1 -0
  14. package/dist/primitives/diff/DiffContext.js +11 -0
  15. package/dist/primitives/diff/DiffContext.js.map +1 -0
  16. package/dist/primitives/diff/DiffHeader.d.ts +10 -0
  17. package/dist/primitives/diff/DiffHeader.d.ts.map +1 -0
  18. package/dist/primitives/diff/DiffHeader.js +18 -0
  19. package/dist/primitives/diff/DiffHeader.js.map +1 -0
  20. package/dist/primitives/diff/DiffLine.d.ts +13 -0
  21. package/dist/primitives/diff/DiffLine.d.ts.map +1 -0
  22. package/dist/primitives/diff/DiffLine.js +20 -0
  23. package/dist/primitives/diff/DiffLine.js.map +1 -0
  24. package/dist/primitives/diff/DiffRoot.d.ts +12 -0
  25. package/dist/primitives/diff/DiffRoot.d.ts.map +1 -0
  26. package/dist/primitives/diff/DiffRoot.js +8 -0
  27. package/dist/primitives/diff/DiffRoot.js.map +1 -0
  28. package/dist/primitives/diff/DiffStats.d.ts +10 -0
  29. package/dist/primitives/diff/DiffStats.d.ts.map +1 -0
  30. package/dist/primitives/diff/DiffStats.js +12 -0
  31. package/dist/primitives/diff/DiffStats.js.map +1 -0
  32. package/dist/primitives/diff/DiffView.d.ts +13 -0
  33. package/dist/primitives/diff/DiffView.d.ts.map +1 -0
  34. package/dist/primitives/diff/DiffView.js +76 -0
  35. package/dist/primitives/diff/DiffView.js.map +1 -0
  36. package/dist/primitives/diff/diff-utils.d.ts +9 -0
  37. package/dist/primitives/diff/diff-utils.d.ts.map +1 -0
  38. package/dist/primitives/diff/diff-utils.js +125 -0
  39. package/dist/primitives/diff/diff-utils.js.map +1 -0
  40. package/dist/primitives/diff/index.d.ts +7 -0
  41. package/dist/primitives/diff/index.d.ts.map +1 -0
  42. package/dist/primitives/diff/index.js +6 -0
  43. package/dist/primitives/diff/index.js.map +1 -0
  44. package/dist/primitives/diff/types.d.ts +24 -0
  45. package/dist/primitives/diff/types.d.ts.map +1 -0
  46. package/dist/primitives/diff/types.js +2 -0
  47. package/dist/primitives/diff/types.js.map +1 -0
  48. package/dist/primitives/diff.d.ts +2 -0
  49. package/dist/primitives/diff.d.ts.map +1 -0
  50. package/dist/primitives/diff.js +2 -0
  51. package/dist/primitives/diff.js.map +1 -0
  52. package/package.json +10 -8
  53. package/src/index.ts +9 -0
  54. package/src/primitives/composer/ComposerSend.tsx +1 -1
  55. package/src/primitives/diff/DiffContent.tsx +77 -0
  56. package/src/primitives/diff/DiffContext.tsx +18 -0
  57. package/src/primitives/diff/DiffHeader.tsx +38 -0
  58. package/src/primitives/diff/DiffLine.tsx +42 -0
  59. package/src/primitives/diff/DiffRoot.tsx +25 -0
  60. package/src/primitives/diff/DiffStats.tsx +22 -0
  61. package/src/primitives/diff/DiffView.test.tsx +340 -0
  62. package/src/primitives/diff/DiffView.tsx +204 -0
  63. package/src/primitives/diff/diff-utils.ts +149 -0
  64. package/src/primitives/diff/index.ts +25 -0
  65. package/src/primitives/diff/types.ts +28 -0
  66. package/src/primitives/diff.ts +1 -0
@@ -0,0 +1,6 @@
1
+ export { DiffRoot as Root } from "./DiffRoot.js";
2
+ export { DiffHeader as Header, } from "./DiffHeader.js";
3
+ export { DiffContent as Content, } from "./DiffContent.js";
4
+ export { DiffLine as Line, } from "./DiffLine.js";
5
+ export { DiffStats as Stats, } from "./DiffStats.js";
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/primitives/diff/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,IAAI,EAAmC,sBAAmB;AAC/E,OAAO,EACL,UAAU,IAAI,MAAM,GAErB,wBAAqB;AACtB,OAAO,EACL,WAAW,IAAI,OAAO,GAEvB,yBAAsB;AACvB,OAAO,EACL,QAAQ,IAAI,IAAI,GAEjB,sBAAmB;AACpB,OAAO,EACL,SAAS,IAAI,KAAK,GAEnB,uBAAoB"}
@@ -0,0 +1,24 @@
1
+ export type DiffLineType = "add" | "del" | "normal";
2
+ export interface ParsedLine {
3
+ type: DiffLineType;
4
+ content: string;
5
+ oldLineNumber?: number;
6
+ newLineNumber?: number;
7
+ }
8
+ export interface ParsedFile {
9
+ oldName?: string | undefined;
10
+ newName?: string | undefined;
11
+ lines: ParsedLine[];
12
+ additions: number;
13
+ deletions: number;
14
+ }
15
+ export interface FoldedRegion {
16
+ type: "fold";
17
+ hiddenCount: number;
18
+ }
19
+ export type DisplayLine = ParsedLine | FoldedRegion;
20
+ export interface DiffFileInput {
21
+ content: string;
22
+ name?: string | undefined;
23
+ }
24
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/primitives/diff/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAAG,KAAK,GAAG,KAAK,GAAG,QAAQ,CAAC;AAEpD,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,YAAY,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG,YAAY,CAAC;AAEpD,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3B"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/primitives/diff/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export * from "./diff/index.js";
2
+ //# sourceMappingURL=diff.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../src/primitives/diff.ts"],"names":[],"mappings":"AAAA,gCAA6B"}
@@ -0,0 +1,2 @@
1
+ export * from "./diff/index.js";
2
+ //# sourceMappingURL=diff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/primitives/diff.ts"],"names":[],"mappings":"AAAA,gCAA6B"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@assistant-ui/react-ink",
3
- "version": "0.0.6",
3
+ "version": "0.0.8",
4
4
  "description": "React Ink (terminal UI) bindings for assistant-ui",
5
5
  "keywords": [
6
6
  "assistant",
@@ -34,12 +34,14 @@
34
34
  ],
35
35
  "sideEffects": false,
36
36
  "dependencies": {
37
- "@assistant-ui/core": "^0.1.7",
38
- "@assistant-ui/store": "^0.2.3",
39
- "@assistant-ui/tap": "^0.5.3",
40
- "assistant-stream": "^0.3.6",
37
+ "@assistant-ui/core": "^0.1.9",
38
+ "@assistant-ui/store": "^0.2.5",
39
+ "@assistant-ui/tap": "^0.5.5",
40
+ "assistant-stream": "^0.3.8",
41
+ "diff": "^8.0.4",
41
42
  "ink-spinner": "^5.0.0",
42
- "zustand": "^5.0.11"
43
+ "parse-diff": "^0.11.1",
44
+ "zustand": "^5.0.12"
43
45
  },
44
46
  "peerDependencies": {
45
47
  "@types/react": "*",
@@ -55,8 +57,8 @@
55
57
  "@types/react": "^19.2.14",
56
58
  "ink": "^6.8.0",
57
59
  "ink-testing-library": "^4.0.0",
58
- "react": "^19.1.0",
59
- "vitest": "^4.1.0",
60
+ "react": "^19.2.4",
61
+ "vitest": "^4.1.1",
60
62
  "@assistant-ui/x-buildutils": "0.0.3"
61
63
  },
62
64
  "publishConfig": {
package/src/index.ts CHANGED
@@ -114,6 +114,8 @@ export * as ChainOfThoughtPrimitive from "./primitives/chainOfThought";
114
114
  export * as SuggestionPrimitive from "./primitives/suggestion";
115
115
  export * as ToolCallPrimitive from "./primitives/toolCall";
116
116
  export * as ErrorPrimitive from "./primitives/error";
117
+ export * as DiffPrimitive from "./primitives/diff";
118
+ export { DiffView, type DiffViewProps } from "./primitives/diff/DiffView";
117
119
 
118
120
  // Re-export shared providers from core/react
119
121
  export {
@@ -146,6 +148,13 @@ export {
146
148
  type ToolDefinition,
147
149
  Tools,
148
150
  DataRenderers,
151
+ Interactables,
152
+ useInteractable,
153
+ type UseInteractableConfig,
154
+ type UseInteractableMetadata,
155
+ makeInteractable,
156
+ type InteractableConfig,
157
+ type AssistantInteractable,
149
158
  } from "@assistant-ui/core/react";
150
159
  export type {
151
160
  ModelContext,
@@ -15,7 +15,7 @@ export const ComposerSend = ({
15
15
 
16
16
  return (
17
17
  <Pressable
18
- onPress={send}
18
+ onPress={() => send()}
19
19
  disabled={disabled ?? hookDisabled}
20
20
  {...pressableProps}
21
21
  >
@@ -0,0 +1,77 @@
1
+ import { type ComponentProps, type ReactNode, Fragment } from "react";
2
+ import { Box, Text } from "ink";
3
+ import { useMemo } from "react";
4
+ import { useDiffContext } from "./DiffContext";
5
+ import { DiffLine } from "./DiffLine";
6
+ import { foldContext } from "./diff-utils";
7
+ import type { ParsedLine, DisplayLine, FoldedRegion } from "./types";
8
+
9
+ export type DiffContentProps = ComponentProps<typeof Box> & {
10
+ fileIndex?: number | undefined;
11
+ showLineNumbers?: boolean | undefined;
12
+ contextLines?: number | undefined;
13
+ maxLines?: number | undefined;
14
+ renderLine?:
15
+ | ((props: { line: ParsedLine; index: number }) => ReactNode)
16
+ | undefined;
17
+ renderFold?:
18
+ | ((props: { region: FoldedRegion; index: number }) => ReactNode)
19
+ | undefined;
20
+ };
21
+
22
+ export const DiffContent = ({
23
+ fileIndex = 0,
24
+ showLineNumbers = true,
25
+ contextLines,
26
+ maxLines,
27
+ renderLine,
28
+ renderFold,
29
+ ...boxProps
30
+ }: DiffContentProps) => {
31
+ const { files } = useDiffContext();
32
+ const file = files[fileIndex];
33
+
34
+ const displayLines: DisplayLine[] = useMemo(() => {
35
+ if (!file) return [];
36
+ if (contextLines !== undefined) {
37
+ return foldContext(file.lines, contextLines);
38
+ }
39
+ return file.lines;
40
+ }, [file, contextLines]);
41
+
42
+ if (!file) return null;
43
+
44
+ const truncated = maxLines !== undefined && displayLines.length > maxLines;
45
+ const visibleLines = truncated
46
+ ? displayLines.slice(0, maxLines)
47
+ : displayLines;
48
+ const remainingCount = truncated ? displayLines.length - maxLines! : 0;
49
+
50
+ return (
51
+ <Box flexDirection="column" {...boxProps}>
52
+ {visibleLines.map((line, i) => {
53
+ if (line.type === "fold") {
54
+ if (renderFold) {
55
+ return (
56
+ <Fragment key={i}>
57
+ {renderFold({ region: line, index: i })}
58
+ </Fragment>
59
+ );
60
+ }
61
+ return (
62
+ <Text key={i}>{` --- ${line.hiddenCount} lines hidden ---`}</Text>
63
+ );
64
+ }
65
+ if (renderLine) {
66
+ return <Fragment key={i}>{renderLine({ line, index: i })}</Fragment>;
67
+ }
68
+ return (
69
+ <DiffLine key={i} line={line} showLineNumbers={showLineNumbers} />
70
+ );
71
+ })}
72
+ {truncated && <Text>{`... (${remainingCount} more lines)`}</Text>}
73
+ </Box>
74
+ );
75
+ };
76
+
77
+ DiffContent.displayName = "DiffPrimitive.Content";
@@ -0,0 +1,18 @@
1
+ import { createContext, useContext } from "react";
2
+ import type { ParsedFile } from "./types";
3
+
4
+ interface DiffContextValue {
5
+ files: ParsedFile[];
6
+ }
7
+
8
+ const DiffContext = createContext<DiffContextValue | null>(null);
9
+
10
+ export const useDiffContext = (): DiffContextValue => {
11
+ const ctx = useContext(DiffContext);
12
+ if (!ctx) {
13
+ throw new Error("useDiffContext must be used within a DiffRoot");
14
+ }
15
+ return ctx;
16
+ };
17
+
18
+ export const DiffContextProvider = DiffContext.Provider;
@@ -0,0 +1,38 @@
1
+ import type { ComponentProps } from "react";
2
+ import { Box, Text } from "ink";
3
+ import { useDiffContext } from "./DiffContext";
4
+ import { DiffStats } from "./DiffStats";
5
+
6
+ export type DiffHeaderProps = ComponentProps<typeof Box> & {
7
+ fileIndex?: number;
8
+ };
9
+
10
+ export const DiffHeader = ({ fileIndex = 0, ...boxProps }: DiffHeaderProps) => {
11
+ const { files } = useDiffContext();
12
+ const file = files[fileIndex];
13
+ if (!file) return null;
14
+
15
+ const isDevNull = (n: string | undefined) => !n || n === "/dev/null";
16
+ const renamed =
17
+ !isDevNull(file.oldName) &&
18
+ !isDevNull(file.newName) &&
19
+ file.oldName !== file.newName;
20
+ const displayName = isDevNull(file.newName) ? file.oldName : file.newName;
21
+
22
+ return (
23
+ <Box gap={1} {...boxProps}>
24
+ {renamed ? (
25
+ <>
26
+ <Text>{file.oldName}</Text>
27
+ <Text>{"->"}</Text>
28
+ <Text>{file.newName}</Text>
29
+ </>
30
+ ) : (
31
+ <Text>{displayName}</Text>
32
+ )}
33
+ <DiffStats fileIndex={fileIndex} />
34
+ </Box>
35
+ );
36
+ };
37
+
38
+ DiffHeader.displayName = "DiffPrimitive.Header";
@@ -0,0 +1,42 @@
1
+ import type { ComponentProps } from "react";
2
+ import { Box, Text } from "ink";
3
+ import type { ParsedLine } from "./types";
4
+
5
+ const INDICATOR: Record<ParsedLine["type"], string> = {
6
+ add: "+",
7
+ del: "-",
8
+ normal: " ",
9
+ };
10
+
11
+ export type DiffLineProps = ComponentProps<typeof Box> & {
12
+ line: ParsedLine;
13
+ showLineNumbers?: boolean;
14
+ lineNumberWidth?: number;
15
+ };
16
+
17
+ export const DiffLine = ({
18
+ line,
19
+ showLineNumbers = true,
20
+ lineNumberWidth = 4,
21
+ ...boxProps
22
+ }: DiffLineProps) => {
23
+ const lineNum =
24
+ line.type === "del"
25
+ ? line.oldLineNumber
26
+ : line.type === "add"
27
+ ? line.newLineNumber
28
+ : line.oldLineNumber;
29
+
30
+ const numStr = lineNum !== undefined ? String(lineNum) : "";
31
+ const padded = numStr.padStart(lineNumberWidth);
32
+ const content = `${INDICATOR[line.type]} ${line.content}`;
33
+
34
+ return (
35
+ <Box {...boxProps}>
36
+ {showLineNumbers && <Text>{padded} </Text>}
37
+ <Text>{content}</Text>
38
+ </Box>
39
+ );
40
+ };
41
+
42
+ DiffLine.displayName = "DiffPrimitive.Line";
@@ -0,0 +1,25 @@
1
+ import type { ComponentProps, ReactNode } from "react";
2
+ import { Box } from "ink";
3
+ import { DiffContextProvider } from "./DiffContext";
4
+ import type { ParsedFile } from "./types";
5
+
6
+ export type DiffRootProps = ComponentProps<typeof Box> & {
7
+ files?: ParsedFile[] | undefined;
8
+ children: ReactNode;
9
+ };
10
+
11
+ export const DiffRoot = ({
12
+ files = [],
13
+ children,
14
+ ...boxProps
15
+ }: DiffRootProps) => {
16
+ return (
17
+ <DiffContextProvider value={{ files }}>
18
+ <Box flexDirection="column" {...boxProps}>
19
+ {children}
20
+ </Box>
21
+ </DiffContextProvider>
22
+ );
23
+ };
24
+
25
+ DiffRoot.displayName = "DiffPrimitive.Root";
@@ -0,0 +1,22 @@
1
+ import type { ComponentProps } from "react";
2
+ import { Box, Text } from "ink";
3
+ import { useDiffContext } from "./DiffContext";
4
+
5
+ export type DiffStatsProps = ComponentProps<typeof Box> & {
6
+ fileIndex?: number;
7
+ };
8
+
9
+ export const DiffStats = ({ fileIndex = 0, ...boxProps }: DiffStatsProps) => {
10
+ const { files } = useDiffContext();
11
+ const file = files[fileIndex];
12
+ if (!file) return null;
13
+
14
+ return (
15
+ <Box gap={1} {...boxProps}>
16
+ <Text>+{file.additions}</Text>
17
+ <Text>-{file.deletions}</Text>
18
+ </Box>
19
+ );
20
+ };
21
+
22
+ DiffStats.displayName = "DiffPrimitive.Stats";