Skip to content

Commit 84e142c

Browse files
build(package): render TUI with Ink and React
1 parent f98b126 commit 84e142c

9 files changed

Lines changed: 478 additions & 18 deletions

File tree

package-lock.json

Lines changed: 437 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
},
1111
"scripts": {
1212
"build": "tsc --project tsconfig.build.json && chmod +x dist/cli.js",
13-
"start": "tsx src/cli.ts",
13+
"start": "tsx --tsconfig tsconfig.test.json src/cli.tsx",
1414
"clean": "rm -rf coverage dist docs",
1515
"lint": "eslint .",
1616
"lint:fix": "npm run lint -- --fix",
@@ -39,20 +39,24 @@
3939
"ai"
4040
],
4141
"dependencies": {
42-
"cac": "7.0.0"
42+
"cac": "7.0.0",
43+
"ink": "7.0.1",
44+
"react": "19.2.5"
4345
},
4446
"devDependencies": {
4547
"@commitlint/cli": "20.5.3",
4648
"@commitlint/config-conventional": "20.5.3",
4749
"@eslint/compat": "2.0.5",
4850
"@eslint/js": "10.0.1",
4951
"@types/node": "25.6.0",
52+
"@types/react": "19.2.14",
5053
"@vitest/coverage-v8": "4.1.5",
5154
"eslint": "10.3.0",
5255
"eslint-plugin-prettier": "5.5.5",
5356
"eslint-plugin-simple-import-sort": "13.0.0",
5457
"globals": "17.6.0",
5558
"husky": "9.1.7",
59+
"ink-testing-library": "4.0.0",
5660
"lint-staged": "16.4.0",
5761
"prettier": "3.8.3",
5862
"publint": "0.3.18",

src/App.test.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { render } from 'ink-testing-library';
2+
3+
import App from './App';
4+
5+
describe('App', () => {
6+
it('renders', () => {
7+
const { lastFrame } = render(<App />);
8+
expect(lastFrame()).toContain('code-ollama');
9+
});
10+
});

src/App.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { Box, Text } from 'ink';
2+
3+
export default function App() {
4+
return (
5+
<Box>
6+
<Text>🦙 code-ollama</Text>
7+
</Box>
8+
);
9+
}

src/cli.test.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
import { type MockInstance, vi } from 'vitest';
22

3-
const { outputHelp, parse } = vi.hoisted(() => ({
3+
const { outputHelp, parse, render } = vi.hoisted(() => ({
44
outputHelp: vi.fn(),
55
parse: vi.fn(),
6+
render: vi.fn(),
67
}));
78

9+
vi.mock('ink', () => ({ render }));
10+
811
vi.mock('cac', () => ({
912
default: () => ({
1013
version: vi.fn(),
@@ -30,9 +33,9 @@ describe('cli', () => {
3033
stdoutSpy.mockRestore();
3134
});
3235

33-
it('calls outputHelp with no args', () => {
36+
it('renders TUI with no args', () => {
3437
main([]);
35-
expect(outputHelp).toHaveBeenCalledOnce();
38+
expect(render).toHaveBeenCalledOnce();
3639
expect(parse).not.toHaveBeenCalled();
3740
});
3841

src/cli.ts renamed to src/cli.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
#!/usr/bin/env node
22

33
import cac from 'cac';
4+
import { render } from 'ink';
45

56
import pkg from '../package.json' with { type: 'json' };
7+
import App from './App.js';
68

79
const cli = cac('code-ollama');
810

@@ -11,7 +13,7 @@ cli.help();
1113

1214
export function main(args: string[] = process.argv.slice(2)): void {
1315
if (!args.length) {
14-
cli.outputHelp();
16+
render(<App />);
1517
return;
1618
}
1719

tsconfig.build.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"extends": "./tsconfig.test.json",
33
"compilerOptions": {
44
"composite": false,
5+
"allowImportingTsExtensions": false,
56
"module": "nodenext",
67
"moduleResolution": "nodenext",
78
"rewriteRelativeImportExtensions": true,
@@ -13,5 +14,5 @@
1314
"types": ["node"]
1415
},
1516
"include": ["src"],
16-
"exclude": ["src/**/*.test.ts"]
17+
"exclude": ["src/**/*.test.ts", "src/**/*.test.tsx"]
1718
}

tsconfig.test.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,11 @@
1111
"sourceMap": true,
1212
"strict": true,
1313
"types": ["vitest/globals"],
14+
"allowImportingTsExtensions": true,
1415
"noEmit": true,
1516
"resolveJsonModule": true,
17+
"jsx": "react-jsx",
18+
"jsxImportSource": "react",
1619
"skipLibCheck": true
1720
},
1821
"include": ["src", "vitest.config.mts", "eslint.config.mts", "*.mjs", "*.ts"]

vitest.config.mts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ import { defineConfig } from 'vitest/config';
33
export default defineConfig({
44
test: {
55
globals: true,
6+
exclude: ['dist/**', 'node_modules/**'],
67
coverage: {
78
include: ['src'],
8-
exclude: ['src/**/*.test.ts'],
9+
exclude: ['src/**/*.test.ts', 'src/**/*.test.tsx'],
910
thresholds: {
1011
100: true,
1112
},

0 commit comments

Comments
 (0)