Add Featurebase issue integration#1926
Conversation
Greptile SummaryThis PR adds Featurebase as a new issue connector, following the same structural pattern used by Linear, Jira, GitLab, Forgejo, and Plain. The implementation covers the full integration surface: HTTP client, encrypted token storage, RPC controller, issue provider, renderer setup form, context wiring, and settings card.
Confidence Score: 4/5Safe to merge; no incorrect data is persisted or leaked, and all auth/token flows follow the established codebase pattern. The searchIssues function silently returns an empty success result when fetchPosts fails, so a broken token or rate-limit during search produces no visible error — unlike listIssues, which surfaces the failure. The stripHtml helper also skips " and ', so quoted text in post descriptions will render as raw entity strings. Both are limited in impact and neither affects token storage, auth, or data correctness. src/main/core/featurebase/featurebase-issue-provider.ts — search error swallowing and incomplete entity decoding.
|
| Filename | Overview |
|---|---|
| src/main/core/featurebase/featurebase-client.ts | Thin HTTP client wrapper with bearer auth and version header; clean error handling. |
| src/main/core/featurebase/featurebase-connection-service.ts | Token storage and connection validation; token caching and error message constant are duplicated in the issue provider. |
| src/main/core/featurebase/featurebase-issue-provider.ts | Maps Featurebase posts to issues; searchIssues silently swallows errors returning success:true, and stripHtml misses several common HTML entities. |
| src/renderer/features/integrations/FeaturebaseSetupForm.tsx | Simple setup form with password input and inline instructions; follows existing form patterns. |
| src/main/core/featurebase/featurebase-issue-provider.test.ts | Unit tests for list/search/empty-term/disconnected paths; good coverage of the core mapping logic. |
Sequence Diagram
sequenceDiagram
participant R as Renderer
participant RPC as RPC Router
participant CS as FeaturebaseConnectionService
participant IP as FeaturebaseIssueProvider
participant FB as Featurebase API
Note over R,FB: Connect flow
R->>RPC: featurebase.saveToken(apiKey)
RPC->>CS: saveToken(token)
CS->>FB: "GET /v2/posts?limit=1 (validate)"
FB-->>CS: 200 OK
CS->>CS: encryptedAppSecretsStore.setSecret(token)
CS-->>R: success true
Note over R,FB: Issue list / search flow
R->>IP: listIssues
IP->>CS: getClient()
CS->>CS: getStoredToken() decrypt from DB
CS-->>IP: FeaturebaseClient
IP->>FB: "GET /v2/posts?sortBy=recent&sortOrder=desc"
FB-->>IP: data FeaturebasePost array
IP-->>R: success true issues array
Note over R,FB: Disconnect flow
R->>RPC: featurebase.clearToken()
RPC->>CS: clearToken()
CS->>CS: encryptedAppSecretsStore.deleteSecret()
CS->>CS: cachedToken null client null
CS-->>R: success true
Prompt To Fix All With AI
Fix the following 4 code review issues. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 4
src/main/core/featurebase/featurebase-issue-provider.ts:35-38
Incomplete HTML entity decoding in `stripHtml`. `"` (`"`) and `'` / `'` (`'`) are common in Featurebase post content (e.g. quoted text, apostrophes in titles) and will be shown verbatim to the user as raw entity strings.
```suggestion
.replace(/ /g, ' ')
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'|'/g, "'")
```
### Issue 2 of 4
src/main/core/featurebase/featurebase-issue-provider.ts:98-103
`searchIssues` returns `{ success: true, issues: [] }` when the underlying `fetchPosts` call fails, which silently swallows auth failures, rate-limit errors, and network errors during search. `listIssues` propagates errors correctly via the same `fetchPosts`, so a broken token causes a visible error in the issue list but an invisible empty state during search.
```suggestion
const result = await fetchPosts({ limit, searchTerm: term });
if (!result.success) {
log.error('[Featurebase] searchIssues error:', result.error);
return result;
}
return result;
```
### Issue 3 of 4
src/main/core/featurebase/featurebase-issue-provider.ts:6-9
The "not configured" error string is a literal here but is also defined as the `NOT_CONFIGURED_ERROR` constant in `featurebase-connection-service.ts`. If the constant is ever updated in one place, the two messages will diverge. Exporting and importing the constant keeps them in sync.
```suggestion
import {
NOT_CONFIGURED_ERROR,
featurebaseConnectionService,
toFeaturebaseErrorMessage,
} from './featurebase-connection-service';
```
### Issue 4 of 4
src/main/core/featurebase/featurebase-connection-service.ts:6
Export `NOT_CONFIGURED_ERROR` so the issue provider can import it directly rather than duplicating the string literal.
```suggestion
export const NOT_CONFIGURED_ERROR = 'Featurebase is not configured. Connect Featurebase in settings.';
```
Reviews (1): Last reviewed commit: "Add Featurebase issue integration" | Re-trigger Greptile
0f9e15c to
13e6ee6
Compare
arnestrickmann
left a comment
There was a problem hiding this comment.
This matches the existing issue-tracker integration patterns well across provider registration, connection status, settings, and issue picker surfaces. Thank you! @maxonary
|
@maxonary nice!! I just reverted that already linked issues are disabled in the ui. we show if an issue is already linked, but do not want to prevent linking the issue again |
|
@jschwxrz thanks, that could be a cool setting for the menu |
Summary
Adds Featurebase as an Emdash issue connector.
Changes
Adds a Featurebase main-process issue provider backed by the REST posts API.
Stores and validates the Featurebase API key through the existing encrypted app secrets flow.
Registers Featurebase in shared issue provider metadata, RPC, connection status, settings, and the issue picker.
Adds focused unit tests for the Featurebase HTTP client and issue provider mapping/search behavior.
Validation
pnpm run format
pnpm run typecheck
pnpm run lint
pnpm vitest run src/main/core/featurebase/featurebase-issue-provider.test.ts src/main/core/featurebase/featurebase-connection-service.test.ts