Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .claude/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,22 @@ npm run test:e2e:docker # Docker E2E (real backend)

Stack: Vitest browser mode + MSW (`msw/browser`) + axe-core + Testing Library. CI: `ci-ui.yml` (path-filtered) + `ci-docker.yml` (always runs).

## Formatting & Linting

```bash
cd ui
npm run format # Prettier — format all files
npm run format:check # Prettier — check without writing (used in CI)
npm run lint # ESLint — check for errors
npm run lint:fix # ESLint — auto-fix what's possible
```

- **Prettier**: tabs, single quotes, semicolons, Tailwind class sorting
- **ESLint 9** (flat config): TypeScript, React Hooks, import ordering, unused imports, jsx-a11y accessibility, `button-has-type`, `consistent-type-imports`
- **Husky + lint-staged**: pre-commit hook formats and lints staged files automatically
- **`@/` imports**: all cross-directory imports use `@/` (maps to `src/`). Enforced via `no-restricted-imports` rule.
- Config files: `ui/eslint.config.js`, `ui/prettier.config.js`, `ui/.editorconfig`

## Data directory (all gitignored)
- `data/jentic-mini.db` — SQLite database
- `data/vault.key` — Fernet encryption key (auto-generated)
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/ci-ui.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ jobs:
if: steps.cache-playwright.outputs.cache-hit == 'true'
run: npx playwright install-deps chromium

- name: Lint & format check
run: npm run lint

- name: TypeScript check
run: npx tsc --noEmit

Expand Down
1 change: 1 addition & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
cd ui && npx lint-staged
17 changes: 17 additions & 0 deletions ui/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# EditorConfig — https://editorconfig.org
root = true

[*]
indent_style = tab
indent_size = 4
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[*.md]
trim_trailing_whitespace = false

[*.{yml,yaml}]
indent_style = space
indent_size = 2
6 changes: 6 additions & 0 deletions ui/.prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
node_modules/
dist/
coverage/
playwright-report/
.vitest-attachments/
src/api/generated/
167 changes: 94 additions & 73 deletions ui/BUILD_REPORT.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,87 +5,96 @@
### 1. **New Pages Built** ✅

#### SearchPage (`/search`)

- Full-text search with BM25 over local operations, workflows, and public catalog
- Debounced search input (400ms)
- Result cards with:
- Type badge (operation/workflow)
- Source badge (local/catalog) with icons
- HTTP method badge (for operations)
- Relevance score (percentage)
- Capability ID with copy button
- Type badge (operation/workflow)
- Source badge (local/catalog) with icons
- HTTP method badge (for operations)
- Relevance score (percentage)
- Capability ID with copy button
- Expandable inline detail panel per result:
- Full parameter schema (name, type, required, description)
- Authentication requirements
- Links to API docs and trace history
- Full parameter schema (name, type, required, description)
- Authentication requirements
- Links to API docs and trace history
- Example query chips for empty state
- Load more pagination (10/20/50 results)
- Clean empty state with link to catalog

#### CatalogPage (`/catalog`)

**Two tabs:**

1. **Your APIs (registered)**:
- Lists all locally registered APIs
- Expandable operation list per API (first 50, with truncation notice)
- Operation cards show method badge, summary, path
- Link to search for each API
- Pagination (20 per page)
- Filter by name/ID
- Lists all locally registered APIs
- Expandable operation list per API (first 50, with truncation notice)
- Operation cards show method badge, summary, path
- Link to search for each API
- Pagination (20 per page)
- Filter by name/ID

2. **Public Catalog**:
- Browse Jentic public API catalog (jentic/jentic-public-apis)
- Filter: All | Registered | Unregistered
- Import button for unregistered APIs (routes to credential form)
- Refresh button (pulls fresh manifest from GitHub)
- Manifest age display
- Empty state with sync button
- GitHub links for each entry
- Browse Jentic public API catalog (jentic/jentic-public-apis)
- Filter: All | Registered | Unregistered
- Import button for unregistered APIs (routes to credential form)
- Refresh button (pulls fresh manifest from GitHub)
- Manifest age display
- Empty state with sync button
- GitHub links for each entry

#### WorkflowDetailPage (`/workflows/:slug`)

- Workflow name, description, slug
- Badge for step count
- Involved APIs as badges
- Inputs section: name, type, required, description
- Steps section: ordered list with:
- Step number badge
- Step ID, description
- Operation ID or nested workflow ID
- Parameters display (first 5)
- Arrow between steps
- Step number badge
- Step ID, description
- Operation ID or nested workflow ID
- Parameters display (first 5)
- Arrow between steps
- Fallback to raw JSON if structure missing

---

### 2. **Major Page Fixes** ✅

#### ToolkitDetailPage — Comprehensive Rebuild

**Fixed:**

- **Keys query bug** — `toolkit.keys` doesn't come from `GET /toolkits/{id}`; now fetches separately from `GET /toolkits/{id}/keys`
- **Keys count** — now uses actual keys array length from separate query (was always 0)
- **Credential count** — already correct (credentials DO come from detail endpoint)

**Added:**

- **Permission management per credential**:
- Expandable editor for each bound credential
- Uses `PermissionRuleEditor` component
- Loads agent rules (filters out system safety rules for display)
- Save button → `setPermissions` API call
- Rule count display on each credential card
- Expandable editor for each bound credential
- Uses `PermissionRuleEditor` component
- Loads agent rules (filters out system safety rules for display)
- Save button → `setPermissions` API call
- Rule count display on each credential card
- **Unbind credential button**:
- `ConfirmInline` wrapper for safety
- Calls `api.unbindCredential(toolkitId, credentialId)`
- `ConfirmInline` wrapper for safety
- Calls `api.unbindCredential(toolkitId, credentialId)`
- **Request Access dialog**:
- Button at top: "Request Access"
- Modal with:
- Request type selector (grant | modify_permissions)
- Credential dropdown (from `/credentials`)
- Permission rule editor
- Reason textarea
- Submit → creates access request via `api.createAccessRequest`
- Alert with `approve_url` on success
- Button at top: "Request Access"
- Modal with:
- Request type selector (grant | modify_permissions)
- Credential dropdown (from `/credentials`)
- Permission rule editor
- Reason textarea
- Submit → creates access request via `api.createAccessRequest`
- Alert with `approve_url` on success
- **Fixed pending requests display** — now shows type badge (grant vs modify)

#### ToolkitsPage

**Fixed:**

- **Pending count** — now uses `usePendingRequests()` hook, groups by `toolkit_id`
- **Credential count** — improved fallback logic (`credential_count` || `credentials.length` || '—')
- **Key count** — shows `key_count` or '—' (list endpoint doesn't return this)
Expand All @@ -95,6 +104,7 @@
### 3. **Routes Added** ✅

Added to `App.tsx`:

```
/credentials/new → CredentialFormPage
/credentials/:id/edit → CredentialFormPage
Expand All @@ -110,6 +120,7 @@ All imports added correctly.
### 4. **API Client Methods Added** ✅

Added to `api/client.ts`:

```
createAccessRequest(toolkitId, body) // POST /toolkits/{id}/access-requests
patchKey(toolkitId, keyId, body) // PATCH /toolkits/{id}/keys/{key_id}
Expand All @@ -125,21 +136,22 @@ Import for `InspectService` added.
**Three entry points:**

1. **From toolkit detail page** (`/toolkits/:id`):
- "Request Access" button at top-right
- Opens modal dialog
- Submit → creates request → shows alert with approval URL
- "Request Access" button at top-right
- Opens modal dialog
- Submit → creates request → shows alert with approval URL

2. **Pending requests banner** (DashboardPage + ToolkitDetailPage):
- Shows pending count with warning styling
- "Review" button → navigates to `/approve/:toolkit_id/:req_id`
- Shows pending count with warning styling
- "Review" button → navigates to `/approve/:toolkit_id/:req_id`

3. **Direct approval URL** (`/approve/:toolkit_id/:req_id`):
- Standalone page (outside main Layout chrome)
- Shows request details: type, reason, rules
- Approve/Deny buttons
- Success → redirects to `/toolkits` after 2.5s
- Standalone page (outside main Layout chrome)
- Shows request details: type, reason, rules
- Approve/Deny buttons
- Success → redirects to `/toolkits` after 2.5s

**URL pattern:** `/approve/:toolkit_id/:req_id`

- Clean, shareable
- Backend generates as full URL in `approve_url` field
- Easy to copy/paste for human approval
Expand All @@ -149,6 +161,7 @@ Import for `InspectService` added.
## 🔍 Code Audit Results

### Static vs Dynamic Text — All Fixed ✅

- **DashboardPage**: All counts dynamic (`total`, `length`, etc.)
- **CredentialsPage**: All dynamic (count, dates, labels)
- **WorkflowsPage**: All dynamic (step count, involved APIs)
Expand All @@ -157,6 +170,7 @@ Import for `InspectService` added.
- **ToolkitsPage**: Pending count fixed ✅, credential count improved ✅

### Missing Functionality — All Added ✅

- ✅ Search results → inspect panel
- ✅ Catalog → import flow
- ✅ Workflows → detail page
Expand All @@ -175,14 +189,18 @@ Import for `InspectService` added.
✓ Vite build succeeded
✓ TailwindCSS 4 via @tailwindcss/vite plugin (no PostCSS)
✓ Zero hardcoded colors, zero emoji icons
✓ Prettier: all files formatted (tabs, single quotes, Tailwind class sorting)
✓ ESLint 9: 0 errors (143 warnings — no-explicit-any, non-blocking)
✓ Husky + lint-staged: pre-commit hook auto-formats and lints staged files
✓ 143 unit + integration tests passing (Vitest browser mode, 19 test files)
✓ 35 Playwright mocked E2E specs
✓ 3 Docker E2E specs (true end-to-end against real backend)
✓ Automated a11y checks via axe-core on all pages
✓ CI: ci-ui.yml (path-filtered) + ci-docker.yml (always runs, Docker layer caching)
✓ CI: ci-ui.yml (format + lint + tsc + tests) + ci-docker.yml (Docker E2E)
```

**Fixed issues:**

- React Query v5 `onSuccess` → `useEffect` pattern
- Credentials query `queryFn` call signature
- TailwindCSS 3 → 4 migration: `outline-none` → `outline-hidden` (10 files)
Expand All @@ -193,6 +211,7 @@ Import for `InspectService` added.
## 📋 UI Coverage vs API

### Fully Covered ✅

- Search (`/search`)
- Catalog browsing (`/catalog` + `/catalog/{api_id}`)
- Workflows list + detail (`/workflows`, `/workflows/:slug`)
Expand All @@ -204,6 +223,7 @@ Import for `InspectService` added.
- Access request approval flow

### Gaps (if any)

- **Overlays** (`/apis/{id}/overlays`) — no UI page yet (low priority, admin feature)
- **Notes** (`/notes`) — no UI page yet (low priority, internal metadata)
- **OAuth brokers** — no UI (intentional, handled server-side)
Expand All @@ -215,46 +235,47 @@ Both gaps are expected — overlays and notes are advanced admin features, not c
## 🎨 UI/UX Highlights

1. **Design token system** (TailwindCSS 4):
- Single-file theme architecture (`src/index.css`) using shadcn/TW4-native pattern
- `@theme inline` maps CSS custom properties to Tailwind utility classes
- Full HSL color palette in `:root` matching `@jentic/frontend-theme`
- Semantic token names throughout: `bg-primary`, `text-foreground`, `border-border`, etc.
- Zero hardcoded Tailwind default colors (no `red-500`, `gray-300`, etc.)
- No separate `tailwind.config.js` or `styles.css` — everything in `index.css`
- Single-file theme architecture (`src/index.css`) using shadcn/TW4-native pattern
- `@theme inline` maps CSS custom properties to Tailwind utility classes
- Full HSL color palette in `:root` matching `@jentic/frontend-theme`
- Semantic token names throughout: `bg-primary`, `text-foreground`, `border-border`, etc.
- Zero hardcoded Tailwind default colors (no `red-500`, `gray-300`, etc.)
- No separate `tailwind.config.js` or `styles.css` — everything in `index.css`

2. **Lucide React icons**:
- All icons are SVG components from `lucide-react`
- Zero emoji characters used as icons anywhere in the codebase
- All icons are SVG components from `lucide-react`
- Zero emoji characters used as icons anywhere in the codebase

3. **Consistent design language**:
- Badge variants for status (success/warning/danger)
- Method badges (GET/POST/etc.) with color coding
- Source badges (local/catalog) with icons
- ConfirmInline for destructive actions
- Badge variants for status (success/warning/danger)
- Method badges (GET/POST/etc.) with color coding
- Source badges (local/catalog) with icons
- ConfirmInline for destructive actions

4. **Smart loading states**:
- Skeleton text ("Loading...")
- Empty states with helpful CTAs
- Inline spinners for mutations
- Skeleton text ("Loading...")
- Empty states with helpful CTAs
- Inline spinners for mutations

5. **Search & filter**:
- Debounced search inputs
- Filter chips with clear buttons
- Pagination controls
- Debounced search inputs
- Filter chips with clear buttons
- Pagination controls

6. **Keyboard-friendly**:
- Autofocus on search inputs
- Enter to submit forms
- Autofocus on search inputs
- Enter to submit forms

7. **Mobile-responsive**:
- Grid layouts adapt (1/2/4 columns)
- Overflow-x-auto on tables
- Grid layouts adapt (1/2/4 columns)
- Overflow-x-auto on tables

---

## 🚀 Ready for Review

All requested features complete:

- ✅ SearchPage and CatalogPage fully built
- ✅ All static → dynamic text issues fixed
- ✅ Permission request dialogs working with easy URLs
Expand Down
Loading
Loading