diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..445fc4d --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,80 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + lint-and-test: + name: Lint, Typecheck & Test + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Bun + uses: oven-sh/setup-bun@v2 + with: + bun-version: latest + + - name: Install dependencies + run: | + cd tui + bun install --frozen-lockfile + + - name: Run ESLint + run: | + cd tui + bun run lint + + - name: Run TypeScript check + run: | + cd tui + bun run typecheck + + - name: Run tests + run: | + cd tui + bun test + + - name: Build + run: | + cd tui + bun run build + + # Validate plugin structure + validate-plugin: + name: Validate Plugin Structure + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Check required files exist + run: | + test -f .claude-plugin/plugin.json || (echo "Missing plugin.json" && exit 1) + test -f hooks/hooks.json || (echo "Missing hooks.json" && exit 1) + test -f scripts/session-start.sh || (echo "Missing session-start.sh" && exit 1) + test -f scripts/capture-event.sh || (echo "Missing capture-event.sh" && exit 1) + echo "All required plugin files present" + + - name: Validate plugin.json syntax + run: | + cat .claude-plugin/plugin.json | python3 -m json.tool > /dev/null + echo "plugin.json is valid JSON" + + - name: Validate hooks.json syntax + run: | + cat hooks/hooks.json | python3 -m json.tool > /dev/null + echo "hooks.json is valid JSON" + + - name: Check shell scripts are executable + run: | + test -x scripts/session-start.sh || chmod +x scripts/session-start.sh + test -x scripts/capture-event.sh || chmod +x scripts/capture-event.sh + test -x scripts/cleanup.sh || chmod +x scripts/cleanup.sh + echo "Shell scripts are executable" diff --git a/tui/src/components/AgentList.test.tsx b/tui/src/components/AgentList.test.tsx index 2948e5a..df1654d 100644 --- a/tui/src/components/AgentList.test.tsx +++ b/tui/src/components/AgentList.test.tsx @@ -126,4 +126,28 @@ describe('AgentList', () => { const { lastFrame } = render(); expect(lastFrame()).toContain('1m'); }); + + it('should handle tool with filename-only target', () => { + const tools = [createTool({ target: 'file.ts' })]; + const agents = [createAgent({ tools })]; + const { lastFrame } = render(); + expect(lastFrame()).toContain('file.ts'); + }); + + it('should truncate long tool targets', () => { + const tools = [createTool({ target: '/path/to/very-long-filename-here.ts' })]; + const agents = [createAgent({ tools })]; + const { lastFrame } = render(); + const frame = lastFrame() || ''; + expect(frame).toContain('very-long-filen'); + expect(frame).not.toContain('very-long-filename-here.ts'); + }); + + it('should handle tool with empty target', () => { + const tools = [createTool({ target: '' })]; + const agents = [createAgent({ tools })]; + const { lastFrame } = render(); + expect(lastFrame()).toContain('Grep'); + expect(lastFrame()).not.toContain(': '); + }); });