uidex 0.2.4 → 0.4.0

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 (65) hide show
  1. package/README.md +253 -353
  2. package/dist/cli/cli.cjs +3324 -0
  3. package/dist/cli/cli.cjs.map +1 -0
  4. package/dist/cloud/index.cjs +169 -0
  5. package/dist/cloud/index.cjs.map +1 -0
  6. package/dist/cloud/index.js +140 -0
  7. package/dist/cloud/index.js.map +1 -0
  8. package/dist/headless/index.cjs +4143 -0
  9. package/dist/headless/index.cjs.map +1 -0
  10. package/dist/headless/index.d.cts +220 -0
  11. package/dist/headless/index.d.ts +220 -0
  12. package/dist/headless/index.js +4130 -0
  13. package/dist/headless/index.js.map +1 -0
  14. package/dist/index.cjs +8704 -9883
  15. package/dist/index.cjs.map +1 -1
  16. package/dist/index.d.cts +968 -146
  17. package/dist/index.d.ts +968 -146
  18. package/dist/index.js +8327 -9492
  19. package/dist/index.js.map +1 -1
  20. package/dist/playwright/index.cjs +164 -24
  21. package/dist/playwright/index.cjs.map +1 -1
  22. package/dist/playwright/index.d.cts +30 -53
  23. package/dist/playwright/index.d.ts +30 -53
  24. package/dist/playwright/index.js +148 -21
  25. package/dist/playwright/index.js.map +1 -1
  26. package/dist/playwright/reporter.cjs +62 -28
  27. package/dist/playwright/reporter.cjs.map +1 -1
  28. package/dist/playwright/reporter.d.cts +24 -12
  29. package/dist/playwright/reporter.d.ts +24 -12
  30. package/dist/playwright/reporter.js +62 -28
  31. package/dist/playwright/reporter.js.map +1 -1
  32. package/dist/react/index.cjs +8706 -9883
  33. package/dist/react/index.cjs.map +1 -1
  34. package/dist/react/index.d.cts +720 -146
  35. package/dist/react/index.d.ts +720 -146
  36. package/dist/react/index.js +8518 -9629
  37. package/dist/react/index.js.map +1 -1
  38. package/dist/scan/index.cjs +3360 -0
  39. package/dist/scan/index.cjs.map +1 -0
  40. package/dist/scan/index.d.cts +378 -0
  41. package/dist/scan/index.d.ts +378 -0
  42. package/dist/scan/index.js +3303 -0
  43. package/dist/scan/index.js.map +1 -0
  44. package/package.json +67 -60
  45. package/templates/claude/audit.md +43 -0
  46. package/templates/claude/rules.md +227 -0
  47. package/claude/audit-command.md +0 -46
  48. package/claude/rules.md +0 -167
  49. package/dist/api/index.cjs +0 -254
  50. package/dist/api/index.cjs.map +0 -1
  51. package/dist/api/index.d.cts +0 -236
  52. package/dist/api/index.d.ts +0 -236
  53. package/dist/api/index.js +0 -226
  54. package/dist/api/index.js.map +0 -1
  55. package/dist/core/index.cjs +0 -11045
  56. package/dist/core/index.cjs.map +0 -1
  57. package/dist/core/index.d.cts +0 -424
  58. package/dist/core/index.d.ts +0 -424
  59. package/dist/core/index.global.js +0 -66516
  60. package/dist/core/index.global.js.map +0 -1
  61. package/dist/core/index.js +0 -10995
  62. package/dist/core/index.js.map +0 -1
  63. package/dist/core/style.css +0 -1529
  64. package/dist/scripts/cli.cjs +0 -3904
  65. package/uidex.schema.json +0 -93
package/claude/rules.md DELETED
@@ -1,167 +0,0 @@
1
- # uidex conventions
2
-
3
- This project uses [uidex](https://github.com/soel/uidex) for UI element tracking and documentation.
4
-
5
- ## Annotations
6
-
7
- uidex uses three annotation types:
8
-
9
- ### `data-uidex` — interactive elements
10
-
11
- Every user-facing interactive element MUST have a `data-uidex="kebab-id"` attribute.
12
-
13
- - IDs should be descriptive and kebab-cased: `data-uidex="submit-btn"`, `data-uidex="user-avatar"`.
14
- - When creating new components with interactive elements, always add `data-uidex` attributes.
15
- - When modifying components, preserve existing `data-uidex` attributes. If you rename or remove an element, update or remove its attribute accordingly.
16
-
17
- ### `data-uidex-block` — structural regions
18
-
19
- Structural UI regions (pages, sections, panels, toolbars) use `data-uidex-block="kebab-id"`.
20
-
21
- - Add `data-uidex-block` to the root wrapper of each page/component.
22
- - Add `data-uidex-block` to meaningful sections within a page (forms, tables, sidebars, etc.).
23
- - Blocks do NOT need JSDoc comments — they are spatial context, not documented behavior.
24
-
25
- ```tsx
26
- <div data-uidex-block="settings-page">
27
- <form data-uidex-block="settings-form">
28
- /** @uidex save-btn - Saves current settings */
29
- <button data-uidex="save-btn">Save</button>
30
- </form>
31
- </div>
32
- ```
33
-
34
- ### `data-uidex-primitive` — reusable UI component definitions
35
-
36
- Reusable, presentational components (buttons, inputs, cards, etc.) use `data-uidex-primitive="kebab-name"` on the root element inside the component definition.
37
-
38
- - Place the attribute on the root element of the component's **definition**, not at call sites.
39
- - IDs should be descriptive and kebab-cased: `data-uidex-primitive="button"`, `data-uidex-primitive="sign-in-card"`.
40
- - A single element can carry both `data-uidex-primitive` and `data-uidex` without conflict.
41
- - Files containing `data-uidex-primitive` are exempt from missing-annotation lint checks.
42
- - Primitives do NOT need JSDoc comments — they are tracked by the scanner automatically.
43
-
44
- ```tsx
45
- // Button.tsx — component definition
46
- export function Button({ children, ...props }) {
47
- return <button data-uidex-primitive="button" {...props}>{children}</button>;
48
- }
49
- ```
50
-
51
- ### When to use which annotation
52
-
53
- | Annotation | Use for | Placed on |
54
- |---|---|---|
55
- | `data-uidex` | Interactive elements (buttons, inputs, links) | Usage sites in consumer components |
56
- | `data-uidex-block` | Structural regions (pages, forms, sections) | Wrapper elements in consumer components |
57
- | `data-uidex-primitive` | Reusable UI component definitions | Root element inside the component definition file |
58
-
59
- ## @uidex JSDoc comments
60
-
61
- Add JSDoc comments above `data-uidex` (interactive) elements to enrich documentation. Do NOT add JSDoc to `data-uidex-block` elements.
62
-
63
- ```tsx
64
- /** @uidex submit-btn - Primary action button for form submission */
65
- <button data-uidex="submit-btn">Submit</button>
66
- ```
67
-
68
- Multi-line format for longer descriptions:
69
-
70
- ```tsx
71
- /**
72
- * @uidex user-profile-card
73
- * Displays user avatar, name, and role.
74
- * Shown in the sidebar and team directory.
75
- */
76
- <div data-uidex="user-profile-card">...</div>
77
- ```
78
-
79
- ## UIDEX_PAGE.md files
80
-
81
- Page docs describe a **route** (a URL the user can visit). Components in the directory are automatically associated.
82
-
83
- - Place `UIDEX_PAGE.md` only in **route directories** (e.g., `app/settings/`, `app/dashboard/`, `app/(auth)/login/`).
84
- - Do NOT place `UIDEX_PAGE.md` in non-route directories like `contexts/`, `hooks/`, `lib/`, `utils/`, or shared `components/`.
85
- - Each route directory should have a `UIDEX_PAGE.md` with acceptance criteria.
86
- - The description MUST be a `>` blockquote immediately after the `# Title` heading.
87
- - Acceptance criteria MUST use `- [ ]` checkbox syntax.
88
- - When adding components to a route directory that lacks a `UIDEX_PAGE.md`, create one.
89
- - When removing all components from a route directory, remove its `UIDEX_PAGE.md`.
90
-
91
- ```markdown
92
- # Page Name
93
-
94
- > Brief description of what this page does and its purpose.
95
-
96
- ## Acceptance
97
- - [ ] User can do X
98
- - [ ] Y is displayed when Z
99
- ```
100
-
101
- ## UIDEX_FEATURE.md files
102
-
103
- Feature docs describe a cross-cutting feature that spans multiple pages. Components are explicitly listed via frontmatter.
104
-
105
- - Place feature docs in a `features/` directory inside the scanner root (e.g., `app/features/auth/UIDEX_FEATURE.md`).
106
- - Use one subdirectory per feature: `features/auth/`, `features/billing/`, `features/notifications/`, etc.
107
- - List associated component IDs in the `components:` frontmatter.
108
- - The description MUST be a `>` blockquote immediately after the `# Title` heading.
109
- - When a component participates in a cross-cutting concern (auth, billing, search, etc.) and isn't fully described by its page alone, add it to a feature.
110
-
111
- ```
112
- features/
113
- auth/
114
- UIDEX_FEATURE.md
115
- billing/
116
- UIDEX_FEATURE.md
117
- ```
118
-
119
- ```markdown
120
- ---
121
- components:
122
- - login-form
123
- - signup-btn
124
- ---
125
- # Feature Name
126
-
127
- > Brief description of the feature and its scope.
128
- ```
129
-
130
- ## Component registry
131
-
132
- For a project-wide view of all components, pages, and features, read the generated registry file (default: `src/uidex.gen.ts`). This file is kept up to date by the scanner.
133
-
134
- ## Scanner
135
-
136
- After adding, removing, or renaming `data-uidex`, `data-uidex-block`, or `data-uidex-primitive` attributes, run:
137
-
138
- ```bash
139
- npx uidex scan
140
- ```
141
-
142
- To validate coverage and check for missing annotations:
143
-
144
- ```bash
145
- npx uidex scan --audit
146
- ```
147
-
148
- ## Setup & Administration
149
-
150
- Manage authentication, project linking, and integrations via the CLI. These commands run in the user's terminal — use `! uidex <command>` to execute them from Claude Code.
151
-
152
- ```bash
153
- # Auth & context
154
- ! uidex login # Authenticate with uidex server
155
- ! uidex status # Show auth and link state
156
- ! uidex link # Link current directory to org/project
157
-
158
- # Integrations
159
- ! uidex integrations list # List configured integrations
160
- ! uidex integrations add jira # Add Jira (interactive prompts)
161
- ! uidex integrations add github # Add GitHub (browser flow)
162
- ! uidex integrations test <id> # Test integration connection
163
- ! uidex integrations remove <id> # Remove integration (with confirmation)
164
- ! uidex integrations targets <id> # List available targets (repos, projects)
165
- ```
166
-
167
- The prerequisite flow is: `login` → `link` → `integrations`. Adding/removing integrations requires org owner role.
@@ -1,254 +0,0 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
-
20
- // src/api/index.ts
21
- var index_exports = {};
22
- __export(index_exports, {
23
- ApiError: () => ApiError,
24
- createClient: () => createClient
25
- });
26
- module.exports = __toCommonJS(index_exports);
27
-
28
- // src/api/feedback.ts
29
- function buildQuery(params) {
30
- const parts = [];
31
- for (const [key, value] of Object.entries(params)) {
32
- if (value === void 0 || value === null) continue;
33
- if (Array.isArray(value)) {
34
- for (const v of value) {
35
- parts.push(`${encodeURIComponent(key)}=${encodeURIComponent(v)}`);
36
- }
37
- } else {
38
- parts.push(
39
- `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`
40
- );
41
- }
42
- }
43
- return parts.length > 0 ? `?${parts.join("&")}` : "";
44
- }
45
- function createFeedbackAPI(fetcher) {
46
- return {
47
- async list(orgId, projectId, params = {}) {
48
- const query = buildQuery(params);
49
- return fetcher(
50
- `/api/organizations/${orgId}/projects/${projectId}/feedback${query}`
51
- );
52
- },
53
- async get(orgId, projectId, feedbackId) {
54
- return fetcher(
55
- `/api/organizations/${orgId}/projects/${projectId}/feedback/${feedbackId}`
56
- );
57
- },
58
- async update(orgId, projectId, feedbackId, params) {
59
- return fetcher(
60
- `/api/organizations/${orgId}/projects/${projectId}/feedback/${feedbackId}`,
61
- {
62
- method: "PATCH",
63
- body: JSON.stringify(params)
64
- }
65
- );
66
- },
67
- async delete(orgId, projectId, feedbackId) {
68
- await fetcher(
69
- `/api/organizations/${orgId}/projects/${projectId}/feedback/${feedbackId}`,
70
- { method: "DELETE" }
71
- );
72
- }
73
- };
74
- }
75
-
76
- // src/api/triage.ts
77
- function createTriageAPI(fetcher) {
78
- return {
79
- async run(orgId, projectId) {
80
- return fetcher(
81
- `/api/organizations/${orgId}/projects/${projectId}/triage`,
82
- { method: "POST" }
83
- );
84
- }
85
- };
86
- }
87
-
88
- // src/api/drafts.ts
89
- function createDraftsAPI(fetcher) {
90
- return {
91
- async list(orgId, projectId, params = {}) {
92
- const query = new URLSearchParams();
93
- query.set("projectId", projectId);
94
- if (params.status) query.set("status", params.status);
95
- if (params.composed_by) query.set("composed_by", params.composed_by);
96
- return fetcher(
97
- `/api/organizations/${orgId}/issue-drafts?${query.toString()}`
98
- );
99
- },
100
- async get(orgId, draftId) {
101
- return fetcher(
102
- `/api/organizations/${orgId}/issue-drafts/${draftId}`
103
- );
104
- },
105
- async update(orgId, draftId, params) {
106
- return fetcher(
107
- `/api/organizations/${orgId}/issue-drafts/${draftId}`,
108
- {
109
- method: "PATCH",
110
- body: JSON.stringify(params)
111
- }
112
- );
113
- },
114
- async submit(orgId, draftId) {
115
- return fetcher(
116
- `/api/organizations/${orgId}/issue-drafts/${draftId}/submit`,
117
- { method: "POST" }
118
- );
119
- }
120
- };
121
- }
122
-
123
- // src/api/projects.ts
124
- function createProjectsAPI(fetcher) {
125
- return {
126
- async list(orgId) {
127
- return fetcher(`/api/organizations/${orgId}/projects`);
128
- }
129
- };
130
- }
131
-
132
- // src/api/orgs.ts
133
- function createOrgsAPI(fetcher) {
134
- return {
135
- async list() {
136
- return fetcher("/api/organizations");
137
- }
138
- };
139
- }
140
-
141
- // src/api/tokens.ts
142
- function createUserAPI(fetcher) {
143
- return {
144
- async createToken(label, expiresAt) {
145
- return fetcher("/api/user/tokens", {
146
- method: "POST",
147
- body: JSON.stringify({
148
- label,
149
- expires_at: expiresAt ?? null
150
- })
151
- });
152
- },
153
- async listTokens() {
154
- return fetcher("/api/user/tokens");
155
- },
156
- async revokeToken(tokenId) {
157
- await fetcher(`/api/user/tokens/${tokenId}`, {
158
- method: "DELETE"
159
- });
160
- }
161
- };
162
- }
163
-
164
- // src/api/integrations.ts
165
- function createIntegrationsAPI(fetcher) {
166
- return {
167
- async list(orgId) {
168
- return fetcher(
169
- `/api/organizations/${orgId}/integrations`
170
- );
171
- },
172
- async create(orgId, params) {
173
- return fetcher(
174
- `/api/organizations/${orgId}/integrations`,
175
- {
176
- method: "POST",
177
- body: JSON.stringify(params)
178
- }
179
- );
180
- },
181
- async get(orgId, integrationId) {
182
- return fetcher(
183
- `/api/organizations/${orgId}/integrations/${integrationId}`
184
- );
185
- },
186
- async delete(orgId, integrationId) {
187
- await fetcher(
188
- `/api/organizations/${orgId}/integrations/${integrationId}`,
189
- { method: "DELETE" }
190
- );
191
- },
192
- async test(orgId, integrationId) {
193
- return fetcher(
194
- `/api/organizations/${orgId}/integrations/${integrationId}/test`,
195
- { method: "POST" }
196
- );
197
- },
198
- async listTargets(orgId, integrationId, parentId) {
199
- const query = parentId ? `?parentId=${encodeURIComponent(parentId)}` : "";
200
- return fetcher(
201
- `/api/organizations/${orgId}/integrations/${integrationId}/targets${query}`
202
- );
203
- }
204
- };
205
- }
206
-
207
- // src/api/client.ts
208
- var ApiError = class extends Error {
209
- status;
210
- constructor(status, message) {
211
- super(message);
212
- this.name = "ApiError";
213
- this.status = status;
214
- }
215
- };
216
- function createFetcher(config) {
217
- return async (path, init) => {
218
- const res = await fetch(`${config.endpoint}${path}`, {
219
- ...init,
220
- headers: {
221
- "Content-Type": "application/json",
222
- Authorization: `Bearer ${config.token}`,
223
- ...init?.headers
224
- }
225
- });
226
- if (!res.ok) {
227
- const body = await res.json().catch(() => ({}));
228
- throw new ApiError(
229
- res.status,
230
- body.error || res.statusText
231
- );
232
- }
233
- if (res.status === 204) return null;
234
- return res.json();
235
- };
236
- }
237
- function createClient(config) {
238
- const fetcher = createFetcher(config);
239
- return {
240
- feedback: createFeedbackAPI(fetcher),
241
- triage: createTriageAPI(fetcher),
242
- drafts: createDraftsAPI(fetcher),
243
- projects: createProjectsAPI(fetcher),
244
- orgs: createOrgsAPI(fetcher),
245
- user: createUserAPI(fetcher),
246
- integrations: createIntegrationsAPI(fetcher)
247
- };
248
- }
249
- // Annotate the CommonJS export names for ESM import in node:
250
- 0 && (module.exports = {
251
- ApiError,
252
- createClient
253
- });
254
- //# sourceMappingURL=index.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/api/index.ts","../../src/api/feedback.ts","../../src/api/triage.ts","../../src/api/drafts.ts","../../src/api/projects.ts","../../src/api/orgs.ts","../../src/api/tokens.ts","../../src/api/integrations.ts","../../src/api/client.ts"],"sourcesContent":["export { createClient, ApiError } from './client';\nexport type { ClientConfig, UidexClient, Fetcher } from './client';\nexport type {\n FeedbackRow,\n FeedbackType,\n FeedbackSeverity,\n FeedbackStatus,\n FeedbackPriority,\n FeedbackResolution,\n FeedbackListParams,\n FeedbackUpdateParams,\n IssueDraftRow,\n IssueDraftStatus,\n TriageResult,\n DraftUpdateParams,\n ProjectRow,\n OrganizationRow,\n TokenRow,\n PaginatedResponse,\n IntegrationRow,\n CreateIntegrationParams,\n TestConnectionResult,\n TargetOption,\n} from './types';\n","import type { Fetcher } from './client';\nimport type {\n FeedbackRow,\n FeedbackListParams,\n FeedbackUpdateParams,\n PaginatedResponse,\n} from './types';\n\nfunction buildQuery(params: FeedbackListParams): string {\n const parts: string[] = [];\n for (const [key, value] of Object.entries(params)) {\n if (value === undefined || value === null) continue;\n if (Array.isArray(value)) {\n for (const v of value) {\n parts.push(`${encodeURIComponent(key)}=${encodeURIComponent(v)}`);\n }\n } else {\n parts.push(\n `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`\n );\n }\n }\n return parts.length > 0 ? `?${parts.join('&')}` : '';\n}\n\nexport function createFeedbackAPI(fetcher: Fetcher) {\n return {\n async list(\n orgId: string,\n projectId: string,\n params: FeedbackListParams = {}\n ): Promise<PaginatedResponse<FeedbackRow>> {\n const query = buildQuery(params);\n return fetcher<PaginatedResponse<FeedbackRow>>(\n `/api/organizations/${orgId}/projects/${projectId}/feedback${query}`\n );\n },\n\n async get(\n orgId: string,\n projectId: string,\n feedbackId: string\n ): Promise<FeedbackRow> {\n return fetcher<FeedbackRow>(\n `/api/organizations/${orgId}/projects/${projectId}/feedback/${feedbackId}`\n );\n },\n\n async update(\n orgId: string,\n projectId: string,\n feedbackId: string,\n params: FeedbackUpdateParams\n ): Promise<FeedbackRow> {\n return fetcher<FeedbackRow>(\n `/api/organizations/${orgId}/projects/${projectId}/feedback/${feedbackId}`,\n {\n method: 'PATCH',\n body: JSON.stringify(params),\n }\n );\n },\n\n async delete(\n orgId: string,\n projectId: string,\n feedbackId: string\n ): Promise<void> {\n await fetcher(\n `/api/organizations/${orgId}/projects/${projectId}/feedback/${feedbackId}`,\n { method: 'DELETE' }\n );\n },\n };\n}\n","import type { Fetcher } from './client';\nimport type { TriageResult } from './types';\n\nexport function createTriageAPI(fetcher: Fetcher) {\n return {\n async run(orgId: string, projectId: string): Promise<TriageResult> {\n return fetcher<TriageResult>(\n `/api/organizations/${orgId}/projects/${projectId}/triage`,\n { method: 'POST' }\n );\n },\n };\n}\n","import type { Fetcher } from './client';\nimport type { IssueDraftRow, DraftUpdateParams } from './types';\n\nexport function createDraftsAPI(fetcher: Fetcher) {\n return {\n async list(\n orgId: string,\n projectId: string,\n params: { status?: string; composed_by?: string } = {}\n ): Promise<IssueDraftRow[]> {\n const query = new URLSearchParams();\n query.set('projectId', projectId);\n if (params.status) query.set('status', params.status);\n if (params.composed_by) query.set('composed_by', params.composed_by);\n return fetcher<IssueDraftRow[]>(\n `/api/organizations/${orgId}/issue-drafts?${query.toString()}`\n );\n },\n\n async get(orgId: string, draftId: string): Promise<IssueDraftRow> {\n return fetcher<IssueDraftRow>(\n `/api/organizations/${orgId}/issue-drafts/${draftId}`\n );\n },\n\n async update(\n orgId: string,\n draftId: string,\n params: DraftUpdateParams\n ): Promise<IssueDraftRow> {\n return fetcher<IssueDraftRow>(\n `/api/organizations/${orgId}/issue-drafts/${draftId}`,\n {\n method: 'PATCH',\n body: JSON.stringify(params),\n }\n );\n },\n\n async submit(\n orgId: string,\n draftId: string\n ): Promise<{ external_url: string }> {\n return fetcher<{ external_url: string }>(\n `/api/organizations/${orgId}/issue-drafts/${draftId}/submit`,\n { method: 'POST' }\n );\n },\n };\n}\n","import type { Fetcher } from './client';\nimport type { ProjectRow } from './types';\n\nexport function createProjectsAPI(fetcher: Fetcher) {\n return {\n async list(orgId: string): Promise<ProjectRow[]> {\n return fetcher<ProjectRow[]>(`/api/organizations/${orgId}/projects`);\n },\n };\n}\n","import type { Fetcher } from './client';\nimport type { OrganizationRow } from './types';\n\nexport function createOrgsAPI(fetcher: Fetcher) {\n return {\n async list(): Promise<OrganizationRow[]> {\n return fetcher<OrganizationRow[]>('/api/organizations');\n },\n };\n}\n","import type { Fetcher } from './client';\nimport type { TokenRow } from './types';\n\nexport function createUserAPI(fetcher: Fetcher) {\n return {\n async createToken(\n label: string,\n expiresAt?: string | null\n ): Promise<TokenRow> {\n return fetcher<TokenRow>('/api/user/tokens', {\n method: 'POST',\n body: JSON.stringify({\n label,\n expires_at: expiresAt ?? null,\n }),\n });\n },\n\n async listTokens(): Promise<TokenRow[]> {\n return fetcher<TokenRow[]>('/api/user/tokens');\n },\n\n async revokeToken(tokenId: string): Promise<void> {\n await fetcher(`/api/user/tokens/${tokenId}`, {\n method: 'DELETE',\n });\n },\n };\n}\n","import type { Fetcher } from './client';\nimport type {\n IntegrationRow,\n CreateIntegrationParams,\n TestConnectionResult,\n TargetOption,\n} from './types';\n\nexport function createIntegrationsAPI(fetcher: Fetcher) {\n return {\n async list(orgId: string): Promise<IntegrationRow[]> {\n return fetcher<IntegrationRow[]>(\n `/api/organizations/${orgId}/integrations`\n );\n },\n\n async create(\n orgId: string,\n params: CreateIntegrationParams\n ): Promise<IntegrationRow> {\n return fetcher<IntegrationRow>(\n `/api/organizations/${orgId}/integrations`,\n {\n method: 'POST',\n body: JSON.stringify(params),\n }\n );\n },\n\n async get(\n orgId: string,\n integrationId: string\n ): Promise<IntegrationRow> {\n return fetcher<IntegrationRow>(\n `/api/organizations/${orgId}/integrations/${integrationId}`\n );\n },\n\n async delete(orgId: string, integrationId: string): Promise<void> {\n await fetcher(\n `/api/organizations/${orgId}/integrations/${integrationId}`,\n { method: 'DELETE' }\n );\n },\n\n async test(\n orgId: string,\n integrationId: string\n ): Promise<TestConnectionResult> {\n return fetcher<TestConnectionResult>(\n `/api/organizations/${orgId}/integrations/${integrationId}/test`,\n { method: 'POST' }\n );\n },\n\n async listTargets(\n orgId: string,\n integrationId: string,\n parentId?: string\n ): Promise<TargetOption[]> {\n const query = parentId\n ? `?parentId=${encodeURIComponent(parentId)}`\n : '';\n return fetcher<TargetOption[]>(\n `/api/organizations/${orgId}/integrations/${integrationId}/targets${query}`\n );\n },\n };\n}\n","import { createFeedbackAPI } from './feedback';\nimport { createTriageAPI } from './triage';\nimport { createDraftsAPI } from './drafts';\nimport { createProjectsAPI } from './projects';\nimport { createOrgsAPI } from './orgs';\nimport { createUserAPI } from './tokens';\nimport { createIntegrationsAPI } from './integrations';\n\nexport interface ClientConfig {\n endpoint: string;\n token: string;\n}\n\nexport class ApiError extends Error {\n status: number;\n constructor(status: number, message: string) {\n super(message);\n this.name = 'ApiError';\n this.status = status;\n }\n}\n\nexport type Fetcher = <T = unknown>(\n path: string,\n init?: RequestInit\n) => Promise<T>;\n\nfunction createFetcher(config: ClientConfig): Fetcher {\n return async <T = unknown>(path: string, init?: RequestInit): Promise<T> => {\n const res = await fetch(`${config.endpoint}${path}`, {\n ...init,\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${config.token}`,\n ...init?.headers,\n },\n });\n if (!res.ok) {\n const body = await res.json().catch(() => ({}));\n throw new ApiError(\n res.status,\n (body as Record<string, string>).error || res.statusText\n );\n }\n if (res.status === 204) return null as T;\n return res.json() as Promise<T>;\n };\n}\n\nexport function createClient(config: ClientConfig) {\n const fetcher = createFetcher(config);\n return {\n feedback: createFeedbackAPI(fetcher),\n triage: createTriageAPI(fetcher),\n drafts: createDraftsAPI(fetcher),\n projects: createProjectsAPI(fetcher),\n orgs: createOrgsAPI(fetcher),\n user: createUserAPI(fetcher),\n integrations: createIntegrationsAPI(fetcher),\n };\n}\n\nexport type UidexClient = ReturnType<typeof createClient>;\n"],"mappings":"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","names":[]}
@@ -1,236 +0,0 @@
1
- interface PaginatedResponse<T> {
2
- data: T[];
3
- total: number;
4
- page: number;
5
- limit: number;
6
- }
7
- interface FeedbackRow {
8
- id: string;
9
- sequence_number: number;
10
- project_id: string;
11
- organization_id: string;
12
- type: 'bug' | 'feature' | 'improvement' | 'question';
13
- severity: 'low' | 'medium' | 'high' | 'critical';
14
- title: string | null;
15
- description: string;
16
- component_id: string;
17
- element: string | null;
18
- sources: {
19
- filePath: string;
20
- line: number;
21
- }[] | null;
22
- url: string;
23
- path: string;
24
- route: string | null;
25
- page_title: string | null;
26
- session_id: string | null;
27
- reporter_email: string | null;
28
- reporter_name: string | null;
29
- client_timestamp: string;
30
- viewport: {
31
- width: number;
32
- height: number;
33
- } | null;
34
- screen_size: {
35
- width: number;
36
- height: number;
37
- } | null;
38
- user_agent: string;
39
- locale: string | null;
40
- environment: string | null;
41
- app_version: string | null;
42
- browser_name: string | null;
43
- browser_version: string | null;
44
- os_name: string | null;
45
- os_version: string | null;
46
- device_type: string | null;
47
- console_logs: {
48
- level: string;
49
- message: string;
50
- timestamp: string;
51
- }[] | null;
52
- network_errors: {
53
- url: string;
54
- method: string;
55
- status: number | null;
56
- statusText: string;
57
- timestamp: string;
58
- }[] | null;
59
- metadata: Record<string, string> | null;
60
- screenshot_url: string | null;
61
- status: 'open' | 'triaged' | 'in_progress' | 'resolved' | 'closed';
62
- priority: 'low' | 'medium' | 'high' | 'urgent' | null;
63
- resolution: FeedbackResolution | null;
64
- assignee_id: string | null;
65
- duplicate_of_id: string | null;
66
- api_key_id: string | null;
67
- archived_at: string | null;
68
- created_at: string;
69
- updated_at: string;
70
- tags?: string[];
71
- }
72
- type FeedbackType = 'bug' | 'feature' | 'improvement' | 'question';
73
- type FeedbackSeverity = 'low' | 'medium' | 'high' | 'critical';
74
- type FeedbackStatus = 'open' | 'triaged' | 'in_progress' | 'resolved' | 'closed';
75
- type FeedbackPriority = 'low' | 'medium' | 'high' | 'urgent';
76
- type FeedbackResolution = 'fixed' | 'duplicate' | 'wont_fix' | 'by_design';
77
- interface FeedbackListParams {
78
- status?: FeedbackStatus | FeedbackStatus[];
79
- type?: FeedbackType | FeedbackType[];
80
- severity?: FeedbackSeverity | FeedbackSeverity[];
81
- componentId?: string;
82
- assigneeId?: string;
83
- environment?: string;
84
- tag?: string;
85
- search?: string;
86
- sequence_number?: number;
87
- sort?: string;
88
- order?: 'asc' | 'desc';
89
- page?: number;
90
- limit?: number;
91
- }
92
- interface FeedbackUpdateParams {
93
- status?: FeedbackStatus;
94
- priority?: FeedbackPriority | null;
95
- resolution?: FeedbackResolution | null;
96
- assignee_id?: string | null;
97
- duplicate_of_id?: string | null;
98
- tags?: string[];
99
- }
100
- interface IssueDraftRow {
101
- id: string;
102
- organization_id: string;
103
- project_id: string | null;
104
- integration_id: string | null;
105
- target_config: unknown;
106
- title: string;
107
- body: string;
108
- labels: string[];
109
- composed_by: 'manual' | 'auto';
110
- status: 'suggested' | 'draft' | 'submitted' | 'dismissed';
111
- reasoning: string | null;
112
- created_by: string | null;
113
- created_at: string;
114
- feedback_count?: number;
115
- feedback_ids?: string[];
116
- }
117
- interface TriageResult {
118
- proposals: IssueDraftRow[];
119
- updated: IssueDraftRow[];
120
- }
121
- type IssueDraftStatus = 'suggested' | 'draft' | 'submitted' | 'dismissed';
122
- interface DraftUpdateParams {
123
- title?: string;
124
- body?: string;
125
- labels?: string[];
126
- status?: IssueDraftStatus;
127
- integration_id?: string | null;
128
- target_config?: unknown;
129
- }
130
- interface ProjectRow {
131
- id: string;
132
- organization_id: string;
133
- name: string;
134
- slug: string;
135
- description: string | null;
136
- created_by: string | null;
137
- created_at: string;
138
- updated_at: string;
139
- }
140
- interface OrganizationRow {
141
- id: string;
142
- name: string;
143
- slug: string;
144
- avatar_url: string | null;
145
- created_at: string;
146
- updated_at: string;
147
- }
148
- interface TokenRow {
149
- id: string;
150
- token?: string;
151
- token_prefix: string;
152
- label: string;
153
- last_used_at: string | null;
154
- expires_at: string | null;
155
- revoked_at: string | null;
156
- created_at: string;
157
- }
158
- interface IntegrationRow {
159
- id: string;
160
- organization_id: string;
161
- provider: 'github' | 'jira';
162
- label: string;
163
- config: Record<string, unknown>;
164
- created_by: string | null;
165
- created_at: string;
166
- updated_at: string;
167
- }
168
- interface CreateIntegrationParams {
169
- provider: 'github' | 'jira';
170
- label: string;
171
- config: Record<string, unknown>;
172
- credentials: Record<string, unknown>;
173
- }
174
- interface TestConnectionResult {
175
- ok: boolean;
176
- error?: string;
177
- }
178
- interface TargetOption {
179
- id: string;
180
- label: string;
181
- children?: boolean;
182
- }
183
-
184
- interface ClientConfig {
185
- endpoint: string;
186
- token: string;
187
- }
188
- declare class ApiError extends Error {
189
- status: number;
190
- constructor(status: number, message: string);
191
- }
192
- type Fetcher = <T = unknown>(path: string, init?: RequestInit) => Promise<T>;
193
- declare function createClient(config: ClientConfig): {
194
- feedback: {
195
- list(orgId: string, projectId: string, params?: FeedbackListParams): Promise<PaginatedResponse<FeedbackRow>>;
196
- get(orgId: string, projectId: string, feedbackId: string): Promise<FeedbackRow>;
197
- update(orgId: string, projectId: string, feedbackId: string, params: FeedbackUpdateParams): Promise<FeedbackRow>;
198
- delete(orgId: string, projectId: string, feedbackId: string): Promise<void>;
199
- };
200
- triage: {
201
- run(orgId: string, projectId: string): Promise<TriageResult>;
202
- };
203
- drafts: {
204
- list(orgId: string, projectId: string, params?: {
205
- status?: string;
206
- composed_by?: string;
207
- }): Promise<IssueDraftRow[]>;
208
- get(orgId: string, draftId: string): Promise<IssueDraftRow>;
209
- update(orgId: string, draftId: string, params: DraftUpdateParams): Promise<IssueDraftRow>;
210
- submit(orgId: string, draftId: string): Promise<{
211
- external_url: string;
212
- }>;
213
- };
214
- projects: {
215
- list(orgId: string): Promise<ProjectRow[]>;
216
- };
217
- orgs: {
218
- list(): Promise<OrganizationRow[]>;
219
- };
220
- user: {
221
- createToken(label: string, expiresAt?: string | null): Promise<TokenRow>;
222
- listTokens(): Promise<TokenRow[]>;
223
- revokeToken(tokenId: string): Promise<void>;
224
- };
225
- integrations: {
226
- list(orgId: string): Promise<IntegrationRow[]>;
227
- create(orgId: string, params: CreateIntegrationParams): Promise<IntegrationRow>;
228
- get(orgId: string, integrationId: string): Promise<IntegrationRow>;
229
- delete(orgId: string, integrationId: string): Promise<void>;
230
- test(orgId: string, integrationId: string): Promise<TestConnectionResult>;
231
- listTargets(orgId: string, integrationId: string, parentId?: string): Promise<TargetOption[]>;
232
- };
233
- };
234
- type UidexClient = ReturnType<typeof createClient>;
235
-
236
- export { ApiError, type ClientConfig, type CreateIntegrationParams, type DraftUpdateParams, type FeedbackListParams, type FeedbackPriority, type FeedbackResolution, type FeedbackRow, type FeedbackSeverity, type FeedbackStatus, type FeedbackType, type FeedbackUpdateParams, type Fetcher, type IntegrationRow, type IssueDraftRow, type IssueDraftStatus, type OrganizationRow, type PaginatedResponse, type ProjectRow, type TargetOption, type TestConnectionResult, type TokenRow, type TriageResult, type UidexClient, createClient };