@unbrained/pm-web 2026.7.28 → 2026.7.29
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.
- package/CHANGELOG.md +12 -0
- package/dist/index.js +1 -1
- package/dist/oidc.js.map +1 -1
- package/dist/routes/extensions.d.ts +1 -1
- package/dist/routes/oidc.d.ts +1 -1
- package/dist/routes/pm.js +125 -0
- package/dist/routes/pm.js.map +1 -1
- package/dist/services/mutation-event-watcher.d.ts +1 -1
- package/dist/services/package-catalog.d.ts +28 -4
- package/dist/services/package-catalog.js +67 -5
- package/dist/services/package-catalog.js.map +1 -1
- package/dist/services/pm-runner.d.ts +1 -1
- package/dist/services/pm-runner.js +8 -1
- package/dist/services/pm-runner.js.map +1 -1
- package/dist/services/project-watcher.d.ts +1 -1
- package/dist/services/realtime-bus.d.ts +1 -1
- package/manifest.json +1 -1
- package/package.json +21 -6
- package/public/src/api-types.js +17 -0
- package/public/src/api-types.js.map +1 -0
- package/public/src/api-types.ts +618 -0
- package/public/src/api.js +6 -3
- package/public/src/api.js.map +1 -1
- package/public/src/api.ts +30 -10
- package/public/src/app.js +4 -4
- package/public/src/app.js.map +1 -1
- package/public/src/app.ts +47 -12
- package/public/src/i18n/de.json +2 -1
- package/public/src/i18n/en.json +2 -1
- package/public/src/i18n/es.json +2 -1
- package/public/src/i18n/zh.json +2 -1
- package/public/src/i18n.ts +1 -1
- package/public/src/sw.ts +1 -0
- package/public/src/types.ts +11 -2
- package/public/src/views/activity.js +1 -1
- package/public/src/views/activity.js.map +1 -1
- package/public/src/views/activity.ts +5 -4
- package/public/src/views/calendar.js +1 -1
- package/public/src/views/calendar.js.map +1 -1
- package/public/src/views/calendar.ts +13 -11
- package/public/src/views/comments-audit.js.map +1 -1
- package/public/src/views/comments-audit.ts +7 -6
- package/public/src/views/config.js +1 -1
- package/public/src/views/config.js.map +1 -1
- package/public/src/views/config.ts +2 -2
- package/public/src/views/context.js +3 -3
- package/public/src/views/context.js.map +1 -1
- package/public/src/views/context.ts +10 -9
- package/public/src/views/create.js.map +1 -1
- package/public/src/views/create.ts +3 -2
- package/public/src/views/dedupe.js +5 -5
- package/public/src/views/dedupe.js.map +1 -1
- package/public/src/views/dedupe.ts +9 -8
- package/public/src/views/export.js.map +1 -1
- package/public/src/views/export.ts +2 -2
- package/public/src/views/github.js +5 -4
- package/public/src/views/github.js.map +1 -1
- package/public/src/views/github.ts +20 -18
- package/public/src/views/graph.js +7 -9
- package/public/src/views/graph.js.map +1 -1
- package/public/src/views/graph.ts +11 -13
- package/public/src/views/groups.js +1 -1
- package/public/src/views/groups.js.map +1 -1
- package/public/src/views/groups.ts +9 -8
- package/public/src/views/health.js +16 -2
- package/public/src/views/health.js.map +1 -1
- package/public/src/views/health.ts +26 -8
- package/public/src/views/items.js +18 -12
- package/public/src/views/items.js.map +1 -1
- package/public/src/views/items.ts +65 -35
- package/public/src/views/normalize.js.map +1 -1
- package/public/src/views/normalize.ts +5 -4
- package/public/src/views/packages.js +10 -1
- package/public/src/views/packages.js.map +1 -1
- package/public/src/views/packages.ts +19 -2
- package/public/src/views/plan.js +0 -2
- package/public/src/views/plan.js.map +1 -1
- package/public/src/views/plan.ts +5 -6
- package/public/src/views/projects.js.map +1 -1
- package/public/src/views/projects.ts +8 -7
- package/public/src/views/search.js.map +1 -1
- package/public/src/views/search.ts +3 -2
- package/public/src/views/settings.js.map +1 -1
- package/public/src/views/settings.ts +8 -6
- package/public/src/views/shared.js.map +1 -1
- package/public/src/views/shared.ts +4 -3
- package/public/src/views/sharing.js.map +1 -1
- package/public/src/views/sharing.ts +5 -4
- package/public/src/views/stats.js +1 -1
- package/public/src/views/stats.js.map +1 -1
- package/public/src/views/stats.ts +10 -9
- package/public/src/views/templates.js.map +1 -1
- package/public/src/views/templates.ts +6 -5
- package/public/src/views/validate.js.map +1 -1
- package/public/src/views/validate.ts +6 -5
- package/public/sw.js +1 -0
|
@@ -0,0 +1,618 @@
|
|
|
1
|
+
// ═══════════════════════════════════════════════════════════════
|
|
2
|
+
// API RESPONSE TYPES
|
|
3
|
+
// ═══════════════════════════════════════════════════════════════
|
|
4
|
+
//
|
|
5
|
+
// Response shapes for the browser client (`public/src`) typed against what the
|
|
6
|
+
// server routes in `src/routes/` actually return from their `res.json(...)`
|
|
7
|
+
// calls. Domain entities are reused from `types.ts` (`Item`, `Project`,
|
|
8
|
+
// `User`, `Comment`, `HistoryEntry`, `Note`, `TestEntry`, `FileEntry`,
|
|
9
|
+
// `Learning`, `Stats`, `HealthData`, `Group`, `Share`, …) rather than
|
|
10
|
+
// redeclared here.
|
|
11
|
+
//
|
|
12
|
+
// Several pm-CLI-backed routes answer with `res.json(result.parsed || { … })`,
|
|
13
|
+
// so the happy-path fields mirror the pm CLI's JSON output and every field is
|
|
14
|
+
// optional where the server may legitimately omit it (or answer with an
|
|
15
|
+
// `{ error }` envelope on failure).
|
|
16
|
+
|
|
17
|
+
import type {
|
|
18
|
+
Comment,
|
|
19
|
+
FileEntry,
|
|
20
|
+
Group,
|
|
21
|
+
HealthData,
|
|
22
|
+
HealthIssue,
|
|
23
|
+
HistoryEntry,
|
|
24
|
+
Item,
|
|
25
|
+
Learning,
|
|
26
|
+
Note,
|
|
27
|
+
Project,
|
|
28
|
+
ProjectSchema,
|
|
29
|
+
Share,
|
|
30
|
+
Stats,
|
|
31
|
+
TestEntry,
|
|
32
|
+
User,
|
|
33
|
+
} from './types.js';
|
|
34
|
+
|
|
35
|
+
/** Response from `GET /api/auth/me` — see src/routes/auth.ts. */
|
|
36
|
+
export interface AuthMeResponse {
|
|
37
|
+
user: User;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** Response from `PATCH /api/auth/profile` — see src/routes/auth.ts. */
|
|
41
|
+
export interface ProfileResponse {
|
|
42
|
+
user: User;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** Response from `PATCH /api/auth/github-token` — see src/routes/auth.ts. */
|
|
46
|
+
export interface GithubTokenResponse {
|
|
47
|
+
ok: boolean;
|
|
48
|
+
hasToken: boolean;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** Response from `GET /api/projects` and `GET /api/projects/:id` — see src/routes/projects.ts. */
|
|
52
|
+
export interface ProjectRow extends Project {
|
|
53
|
+
/** Whether the requesting user owns the project (server alias `is_owner`). */
|
|
54
|
+
is_owner?: boolean;
|
|
55
|
+
/** `"edit"` or `"view"` — the caller's permission on this project. */
|
|
56
|
+
permission?: string;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** Response from `GET /api/projects` — see src/routes/projects.ts. */
|
|
60
|
+
export interface ProjectsResponse {
|
|
61
|
+
projects: ProjectRow[];
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** Response from `POST /api/projects` — see src/routes/projects.ts. */
|
|
65
|
+
export interface CreateProjectResponse {
|
|
66
|
+
project: Project;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** Response from `GET /api/projects/:id/shares` — see src/routes/sharing.ts. */
|
|
70
|
+
export interface ShareRow extends Share {
|
|
71
|
+
user_id?: string;
|
|
72
|
+
user_email?: string;
|
|
73
|
+
user_display_name?: string;
|
|
74
|
+
userDisplayName?: string;
|
|
75
|
+
group_id?: string;
|
|
76
|
+
group_name?: string;
|
|
77
|
+
shared_at?: string;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** Response from `GET /api/projects/:id/shares` — see src/routes/sharing.ts. */
|
|
81
|
+
export interface SharesResponse {
|
|
82
|
+
shares: ShareRow[];
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/** Response from `GET /api/shared` — see src/routes/sharing.ts. */
|
|
86
|
+
export interface SharedProject extends Project {
|
|
87
|
+
owner_id?: string;
|
|
88
|
+
owner_email?: string;
|
|
89
|
+
owner_display_name?: string;
|
|
90
|
+
permission?: string;
|
|
91
|
+
shared_at?: string;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/** Response from `GET /api/shared` — see src/routes/sharing.ts. */
|
|
95
|
+
export interface SharedProjectsResponse {
|
|
96
|
+
projects: SharedProject[];
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/** A group row as returned by `GET /api/groups` — see src/routes/groups.ts. */
|
|
100
|
+
export interface GroupListRow {
|
|
101
|
+
id: string;
|
|
102
|
+
owner_id?: string;
|
|
103
|
+
name: string;
|
|
104
|
+
description?: string;
|
|
105
|
+
/**
|
|
106
|
+
* Member count as reported by the server.
|
|
107
|
+
*
|
|
108
|
+
* A **string**, not a number: the list query aliases a Postgres `COUNT(*)`
|
|
109
|
+
* (`int8`), which node-postgres serialises as a string to avoid precision
|
|
110
|
+
* loss, and the create path in src/routes/groups.ts returns the literal `"1"`.
|
|
111
|
+
* Coerce with `Number(...)` before any arithmetic or sorting.
|
|
112
|
+
*/
|
|
113
|
+
member_count: string;
|
|
114
|
+
role?: string;
|
|
115
|
+
created_at?: string;
|
|
116
|
+
updated_at?: string;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/** Response from `GET /api/groups` — see src/routes/groups.ts. */
|
|
120
|
+
export interface GroupsResponse {
|
|
121
|
+
groups: GroupListRow[];
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/** A member row as returned by `GET /api/groups/:id` — see src/routes/groups.ts. */
|
|
125
|
+
export interface GroupMemberRow {
|
|
126
|
+
id?: string;
|
|
127
|
+
user_id?: string;
|
|
128
|
+
userId?: string;
|
|
129
|
+
role?: string;
|
|
130
|
+
invited_at?: string;
|
|
131
|
+
email?: string;
|
|
132
|
+
display_name?: string;
|
|
133
|
+
displayName?: string;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/** Response from `GET /api/groups/:id` — see src/routes/groups.ts. */
|
|
137
|
+
export interface GroupDetailResponse {
|
|
138
|
+
group: Group & { members: GroupMemberRow[]; owner_id?: string };
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/** Response from `GET /api/projects/:id/pm/schema` — see src/routes/pm.ts. */
|
|
142
|
+
export type SchemaResponse = ProjectSchema;
|
|
143
|
+
|
|
144
|
+
/** Common list envelope for `pm list` / `pm list-all` — see src/routes/pm.ts. */
|
|
145
|
+
export interface ListResponse {
|
|
146
|
+
items: Item[];
|
|
147
|
+
error?: string;
|
|
148
|
+
[key: string]: unknown;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/** Response from `POST /api/projects/:id/pm/create` — see src/routes/pm.ts. */
|
|
152
|
+
export interface CreateItemResponse {
|
|
153
|
+
item?: { id?: string };
|
|
154
|
+
id?: string;
|
|
155
|
+
error?: string;
|
|
156
|
+
[key: string]: unknown;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/** Response from `GET /api/projects/:id/pm/get/:itemId` — see src/routes/pm.ts. */
|
|
160
|
+
export type ItemResponse = { item?: Item } & Partial<Item>;
|
|
161
|
+
|
|
162
|
+
/** Response from `GET /api/projects/:id/pm/comments/:itemId` — see src/routes/pm.ts. */
|
|
163
|
+
export interface CommentsResponse {
|
|
164
|
+
comments?: Comment[];
|
|
165
|
+
error?: string;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/** Response from `GET /api/projects/:id/pm/notes/:itemId` — see src/routes/pm.ts. */
|
|
169
|
+
export interface NotesResponse {
|
|
170
|
+
notes?: Note[];
|
|
171
|
+
error?: string;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/** Response from `GET /api/projects/:id/pm/history/:itemId` — see src/routes/pm.ts. */
|
|
175
|
+
export interface HistoryResponse {
|
|
176
|
+
history?: HistoryEntry[];
|
|
177
|
+
error?: string;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/** Response from `GET /api/projects/:id/pm/learnings/:itemId` — see src/routes/pm.ts. */
|
|
181
|
+
export interface LearningsResponse {
|
|
182
|
+
learnings?: Learning[];
|
|
183
|
+
error?: string;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/** Response from `GET /api/projects/:id/pm/tests/:itemId` — see src/routes/pm.ts. */
|
|
187
|
+
export interface TestsResponse {
|
|
188
|
+
tests?: TestEntry[];
|
|
189
|
+
error?: string;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/** Response from `GET /api/projects/:id/pm/files/:itemId` — see src/routes/pm.ts. */
|
|
193
|
+
export interface FilesResponse {
|
|
194
|
+
files?: FileEntry[];
|
|
195
|
+
error?: string;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Loose dependency row from `pm deps`. The pm CLI emits several key spellings
|
|
200
|
+
* (`targetId`/`id`, `rel`/`relationship`/`kind`/`type`, …) so this mirrors the
|
|
201
|
+
* `RawDependency` shape the items view already normalises.
|
|
202
|
+
*/
|
|
203
|
+
export interface DepRow {
|
|
204
|
+
targetId?: string;
|
|
205
|
+
id?: string;
|
|
206
|
+
rel?: string;
|
|
207
|
+
relationship?: string;
|
|
208
|
+
kind?: string;
|
|
209
|
+
type?: string;
|
|
210
|
+
target?: string;
|
|
211
|
+
targetTitle?: string;
|
|
212
|
+
title?: string;
|
|
213
|
+
[key: string]: unknown;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/** Response from `GET /api/projects/:id/pm/deps/:itemId` — see src/routes/pm.ts. */
|
|
217
|
+
export interface DepsResponse {
|
|
218
|
+
deps?: DepRow[];
|
|
219
|
+
dependencies?: DepRow[];
|
|
220
|
+
error?: string;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/** One field-level change a dry-run plans for an item. */
|
|
224
|
+
export interface ItemPlanChange {
|
|
225
|
+
field: string;
|
|
226
|
+
before: unknown;
|
|
227
|
+
after: unknown;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* A planned item from a `pm update-many --dry-run` response (`item_plans[]`).
|
|
232
|
+
*
|
|
233
|
+
* Carries `id` and the per-field `changes` only — the CLI does **not** include
|
|
234
|
+
* the item title here, so callers must render `changes` rather than reaching
|
|
235
|
+
* for a title that never arrives.
|
|
236
|
+
*/
|
|
237
|
+
export interface ItemPlan {
|
|
238
|
+
id: string;
|
|
239
|
+
changes: ItemPlanChange[];
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/** One per-item outcome row from an applied `pm update-many` (`rows[]`). */
|
|
243
|
+
export interface UpdateManyRow {
|
|
244
|
+
id: string;
|
|
245
|
+
status: string;
|
|
246
|
+
changed_fields: string[];
|
|
247
|
+
warnings: string[];
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/** Rollback checkpoint recorded by an applied `pm update-many`. */
|
|
251
|
+
export interface UpdateManyCheckpoint {
|
|
252
|
+
id: string;
|
|
253
|
+
created_at: string;
|
|
254
|
+
path: string;
|
|
255
|
+
rollback_command: string;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Response from `POST /api/projects/:id/pm/update-many`.
|
|
260
|
+
*
|
|
261
|
+
* The express handler is a pass-through (`res.json(result.parsed || {})` in
|
|
262
|
+
* src/routes/pm.ts), so the authority for this shape is `pm update-many --json`
|
|
263
|
+
* itself, not the route. Verified against pm-cli 2026.7.28 by running both
|
|
264
|
+
* modes and enumerating the top-level keys:
|
|
265
|
+
*
|
|
266
|
+
* - `--dry-run` -> `mode, matched_count, dry_run, filters,
|
|
267
|
+
* planned_update_options, item_plans, ids`
|
|
268
|
+
* - apply -> the same minus `item_plans`, plus `checkpoint, updated_count,
|
|
269
|
+
* skipped_count, failed_count, rows`
|
|
270
|
+
*
|
|
271
|
+
* Fields present in only one mode are optional here. Note that `count`,
|
|
272
|
+
* `total`, `updated`, `items`, and `matched` are **not** emitted in either mode;
|
|
273
|
+
* earlier client code read them as fallbacks, which could never resolve.
|
|
274
|
+
*/
|
|
275
|
+
export interface UpdateManyResponse {
|
|
276
|
+
mode?: string;
|
|
277
|
+
dry_run?: boolean;
|
|
278
|
+
matched_count?: number;
|
|
279
|
+
filters?: Record<string, unknown>;
|
|
280
|
+
planned_update_options?: Record<string, unknown>;
|
|
281
|
+
ids?: string[];
|
|
282
|
+
/** Dry-run only. */
|
|
283
|
+
item_plans?: ItemPlan[];
|
|
284
|
+
/** Apply only. */
|
|
285
|
+
checkpoint?: UpdateManyCheckpoint;
|
|
286
|
+
updated_count?: number;
|
|
287
|
+
skipped_count?: number;
|
|
288
|
+
failed_count?: number;
|
|
289
|
+
rows?: UpdateManyRow[];
|
|
290
|
+
error?: string;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/** A per-item close result row from `pm close-many`. */
|
|
294
|
+
export interface CloseManyRow {
|
|
295
|
+
id: string;
|
|
296
|
+
status: 'ok' | 'failed';
|
|
297
|
+
error?: string;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/** Response from `POST /api/projects/:id/pm/close-many` — see src/routes/pm.ts. */
|
|
301
|
+
export interface CloseManyResponse {
|
|
302
|
+
closed_count?: number;
|
|
303
|
+
failed_count?: number;
|
|
304
|
+
skipped_count?: number;
|
|
305
|
+
matched_count?: number;
|
|
306
|
+
rows?: CloseManyRow[];
|
|
307
|
+
error?: string;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/** Response from `GET /api/projects/:id/pm/stats` — see src/routes/pm.ts. */
|
|
311
|
+
export type StatsResponse = { stats?: Stats } & Partial<Stats> & { error?: string };
|
|
312
|
+
|
|
313
|
+
/** Response from `GET /api/projects/:id/pm/health` — see src/routes/pm.ts. */
|
|
314
|
+
export type HealthResponse = { health?: HealthData } & Partial<HealthData> & { error?: string };
|
|
315
|
+
|
|
316
|
+
/** Response from `GET /api/projects/:id/pm/activity` — see src/routes/pm.ts. */
|
|
317
|
+
export interface ActivityEntry extends HistoryEntry {
|
|
318
|
+
type?: string;
|
|
319
|
+
title?: string;
|
|
320
|
+
id?: string;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/** Response from `GET /api/projects/:id/pm/activity` — see src/routes/pm.ts. */
|
|
324
|
+
export interface ActivityResponse {
|
|
325
|
+
activity?: ActivityEntry[];
|
|
326
|
+
items?: ActivityEntry[];
|
|
327
|
+
error?: string;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/** Response from `POST /api/projects/:id/pm/search` — see src/routes/pm.ts. */
|
|
331
|
+
export interface SearchResponse {
|
|
332
|
+
results?: Item[];
|
|
333
|
+
items?: Item[];
|
|
334
|
+
count?: number;
|
|
335
|
+
error?: string;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
/** A validation issue from `pm validate`. */
|
|
339
|
+
export interface ValidateIssue {
|
|
340
|
+
message?: string;
|
|
341
|
+
description?: string;
|
|
342
|
+
id?: string;
|
|
343
|
+
level?: string;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/** Response from `GET /api/projects/:id/pm/validate` — see src/routes/pm.ts. */
|
|
347
|
+
export interface ValidateResponse {
|
|
348
|
+
issues?: ValidateIssue[];
|
|
349
|
+
errors?: ValidateIssue[];
|
|
350
|
+
violations?: ValidateIssue[];
|
|
351
|
+
warnings?: ValidateIssue[];
|
|
352
|
+
summary?: string;
|
|
353
|
+
ok?: boolean;
|
|
354
|
+
error?: string;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
/** A calendar event from `pm calendar --view month`. */
|
|
358
|
+
export interface CalendarEvent {
|
|
359
|
+
id?: string;
|
|
360
|
+
itemId?: string;
|
|
361
|
+
type?: string;
|
|
362
|
+
title?: string;
|
|
363
|
+
name?: string;
|
|
364
|
+
date?: string;
|
|
365
|
+
dueDate?: string;
|
|
366
|
+
timestamp?: string;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
/**
|
|
370
|
+
* A calendar row as rendered in the calendar view. Combines the field spellings
|
|
371
|
+
* from `pm calendar` events (`itemId`/`name`/`date`/`dueDate`/`timestamp`) with
|
|
372
|
+
* the plain `Item` shape used by the `items` fallback so both code paths share
|
|
373
|
+
* one optional-everything type.
|
|
374
|
+
*/
|
|
375
|
+
export type CalendarListItem = CalendarEvent;
|
|
376
|
+
|
|
377
|
+
/** Response from `GET /api/projects/:id/pm/calendar` — see src/routes/pm.ts. */
|
|
378
|
+
export interface CalendarResponse {
|
|
379
|
+
events?: CalendarEvent[];
|
|
380
|
+
items?: Item[];
|
|
381
|
+
error?: string;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/** Response from `GET /api/projects/:id/pm/context` — see src/routes/pm.ts. */
|
|
385
|
+
export interface ContextResponse {
|
|
386
|
+
context?: ContextResponse;
|
|
387
|
+
summary?: string;
|
|
388
|
+
description?: string;
|
|
389
|
+
activeItems?: Item[];
|
|
390
|
+
inProgress?: Item[];
|
|
391
|
+
open?: Item[];
|
|
392
|
+
blockedItems?: Item[];
|
|
393
|
+
blocked?: Item[];
|
|
394
|
+
recentActivity?: ActivityEntry[];
|
|
395
|
+
activity?: ActivityEntry[];
|
|
396
|
+
error?: string;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
/** A duplicate-group row from `pm dedupe-audit`. */
|
|
400
|
+
export interface DedupeGroup {
|
|
401
|
+
score?: number;
|
|
402
|
+
items?: Array<Item | string>;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/** Response from `GET /api/projects/:id/pm/dedupe-audit` — see src/routes/pm.ts. */
|
|
406
|
+
export interface DedupeResponse {
|
|
407
|
+
groups?: DedupeGroup[];
|
|
408
|
+
duplicates?: DedupeGroup[];
|
|
409
|
+
error?: string;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
/** A normalisation change from `pm normalize`. */
|
|
413
|
+
export interface NormalizeChange {
|
|
414
|
+
message?: string;
|
|
415
|
+
description?: string;
|
|
416
|
+
id?: string;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
/** The normalisation plan from `pm normalize`. */
|
|
420
|
+
export interface NormalizePlan {
|
|
421
|
+
items?: NormalizeChange[];
|
|
422
|
+
changes?: NormalizeChange[];
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
/** Response from `POST /api/projects/:id/pm/normalize` — see src/routes/pm.ts. */
|
|
426
|
+
export type NormalizeResponse = {
|
|
427
|
+
plan?: NormalizePlan;
|
|
428
|
+
normalization?: NormalizePlan;
|
|
429
|
+
} & Partial<NormalizePlan> & { error?: string };
|
|
430
|
+
|
|
431
|
+
/** A row in the `by_type` breakdown from `pm comments-audit`. */
|
|
432
|
+
export interface CommentsAuditTypeRow {
|
|
433
|
+
type?: string;
|
|
434
|
+
items_scanned?: number;
|
|
435
|
+
items_with_comments?: number;
|
|
436
|
+
comments_total?: number;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
/** An item row from `pm comments-audit`. */
|
|
440
|
+
export interface CommentsAuditItem extends Item {
|
|
441
|
+
comment_count?: number;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
/** Summary block from `pm comments-audit`. */
|
|
445
|
+
export interface CommentsAuditSummary {
|
|
446
|
+
totals?: {
|
|
447
|
+
items_scanned?: number;
|
|
448
|
+
items_with_comments?: number;
|
|
449
|
+
comments_total?: number;
|
|
450
|
+
};
|
|
451
|
+
coverage?: {
|
|
452
|
+
items_with_comments_percent?: number;
|
|
453
|
+
};
|
|
454
|
+
by_type?: CommentsAuditTypeRow[];
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
/** Response from `GET /api/projects/:id/pm/comments-audit` — see src/routes/pm.ts. */
|
|
458
|
+
export interface CommentsAuditResponse {
|
|
459
|
+
items?: CommentsAuditItem[];
|
|
460
|
+
summary?: CommentsAuditSummary;
|
|
461
|
+
error?: string;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
/** Default values a template may pre-fill. */
|
|
465
|
+
export interface TemplateDefaults {
|
|
466
|
+
type?: string;
|
|
467
|
+
priority?: number;
|
|
468
|
+
tags?: string[];
|
|
469
|
+
description?: string;
|
|
470
|
+
sprint?: string;
|
|
471
|
+
release?: string;
|
|
472
|
+
assignee?: string;
|
|
473
|
+
acceptance_criteria?: string;
|
|
474
|
+
acceptanceCriteria?: string;
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
/** A template from `pm templates list`. */
|
|
478
|
+
export interface TemplateEntry {
|
|
479
|
+
name?: string;
|
|
480
|
+
id?: string;
|
|
481
|
+
type?: string;
|
|
482
|
+
priority?: number;
|
|
483
|
+
tags?: string[];
|
|
484
|
+
description?: string;
|
|
485
|
+
sprint?: string;
|
|
486
|
+
release?: string;
|
|
487
|
+
assignee?: string;
|
|
488
|
+
acceptance_criteria?: string;
|
|
489
|
+
acceptanceCriteria?: string;
|
|
490
|
+
defaults?: TemplateDefaults;
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
/** Response from `GET /api/projects/:id/pm/templates` — see src/routes/pm.ts. */
|
|
494
|
+
export interface TemplatesResponse {
|
|
495
|
+
templates?: TemplateEntry[];
|
|
496
|
+
error?: string;
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
/** Response from `GET /api/projects/:id/github` — see src/routes/github.ts. */
|
|
500
|
+
export interface GitHubRepoResponse {
|
|
501
|
+
owner: string | null;
|
|
502
|
+
repo: string | null;
|
|
503
|
+
syncEnabled: boolean;
|
|
504
|
+
linked: boolean;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
/** A GitHub issue from `GET /api/projects/:id/github/issues` — see src/routes/github.ts. */
|
|
508
|
+
export interface GitHubIssueRow {
|
|
509
|
+
number: number;
|
|
510
|
+
title: string;
|
|
511
|
+
body?: string | null;
|
|
512
|
+
state?: 'open' | 'closed';
|
|
513
|
+
labels?: Array<{ name: string }>;
|
|
514
|
+
assignee?: { login: string } | null;
|
|
515
|
+
html_url?: string;
|
|
516
|
+
created_at?: string;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
/** Response from `GET /api/projects/:id/github/issues` — see src/routes/github.ts. */
|
|
520
|
+
export interface GitHubIssuesResponse {
|
|
521
|
+
issues: GitHubIssueRow[];
|
|
522
|
+
error?: string;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
/** A pushed item from `POST /api/projects/:id/github/push` — see src/routes/github.ts. */
|
|
526
|
+
export interface GitHubPushedItem {
|
|
527
|
+
pmItemId: string;
|
|
528
|
+
issueNumber: number;
|
|
529
|
+
issueUrl: string;
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
/** Response from `POST /api/projects/:id/github/push` — see src/routes/github.ts. */
|
|
533
|
+
export interface GitHubPushResponse {
|
|
534
|
+
pushed: GitHubPushedItem[];
|
|
535
|
+
errors: string[];
|
|
536
|
+
total: number;
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
/** Response from `PATCH /api/projects/:id/github/push/:itemId` — see src/routes/github.ts. */
|
|
540
|
+
export interface GitHubPushUpdateResponse {
|
|
541
|
+
ok?: boolean;
|
|
542
|
+
issueNumber?: number;
|
|
543
|
+
issueUrl?: string;
|
|
544
|
+
error?: string;
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
/** Response from `POST /api/projects/:id/github/import` — see src/routes/github.ts. */
|
|
548
|
+
export interface GitHubImportResponse {
|
|
549
|
+
created: string[];
|
|
550
|
+
errors: string[];
|
|
551
|
+
total: number;
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
/** Response from `GET /api/projects/:id/pm/plan/:planId` — see src/routes/pm.ts. */
|
|
555
|
+
export interface PlanResponse {
|
|
556
|
+
plan?: PlanResponsePayload;
|
|
557
|
+
description?: string;
|
|
558
|
+
error?: string;
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
/** Plan payload shared by the plan list and detail responses. */
|
|
562
|
+
export interface PlanResponsePayload {
|
|
563
|
+
id?: string;
|
|
564
|
+
title?: string;
|
|
565
|
+
description?: string;
|
|
566
|
+
status?: string;
|
|
567
|
+
steps?: Array<PlanStepPayload>;
|
|
568
|
+
approvedAt?: string;
|
|
569
|
+
approved_at?: string;
|
|
570
|
+
createdAt?: string;
|
|
571
|
+
created_at?: string;
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
/** A step within a plan payload. */
|
|
575
|
+
export interface PlanStepPayload {
|
|
576
|
+
id?: string;
|
|
577
|
+
ref?: string;
|
|
578
|
+
title?: string;
|
|
579
|
+
description?: string;
|
|
580
|
+
status?: string;
|
|
581
|
+
blockedReason?: string;
|
|
582
|
+
blocked_reason?: string;
|
|
583
|
+
dependsOn?: string[];
|
|
584
|
+
depends_on?: string[];
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
/**
|
|
588
|
+
* Response from `POST /api/projects/:id/pm/items/:itemId/history-repair`.
|
|
589
|
+
*
|
|
590
|
+
* Mirrors `pm history-repair --json`, verified against pm-cli 2026.7.28. The
|
|
591
|
+
* payload carries no `message` field, so summarise `history` rather than looking
|
|
592
|
+
* for prose. Original note:
|
|
593
|
+
* src/routes/pm.ts. NOTE: no such route is currently mounted on the server, so
|
|
594
|
+
* the call rejects at runtime; the type models the `message` field the dry-run
|
|
595
|
+
* toast reads so the (unreachable) success branch stays type-clean.
|
|
596
|
+
*/
|
|
597
|
+
export interface HistoryRepairResponse {
|
|
598
|
+
id?: string;
|
|
599
|
+
dry_run?: boolean;
|
|
600
|
+
/** Whether the repair changed (or would change) the history chain. */
|
|
601
|
+
changed?: boolean;
|
|
602
|
+
history?: {
|
|
603
|
+
path?: string;
|
|
604
|
+
entries_scanned?: number;
|
|
605
|
+
chain_drift_before?: boolean;
|
|
606
|
+
entries_rehashed?: number;
|
|
607
|
+
entries_patch_repaired?: number;
|
|
608
|
+
converted_replace_to_add?: number;
|
|
609
|
+
skipped_ops?: number;
|
|
610
|
+
reconciled_with_item?: boolean;
|
|
611
|
+
audit_entry_added?: boolean;
|
|
612
|
+
verify_ok?: boolean;
|
|
613
|
+
verify_errors?: string[];
|
|
614
|
+
};
|
|
615
|
+
warnings?: string[];
|
|
616
|
+
generated_at?: string;
|
|
617
|
+
error?: string;
|
|
618
|
+
}
|
package/public/src/api.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
// ═══════════════════════════════════════════════════════════════
|
|
2
2
|
// API CLIENT
|
|
3
3
|
// ═══════════════════════════════════════════════════════════════
|
|
4
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Fetch wrapper for the `/api` endpoints. Generic in `T` so each call site is
|
|
6
|
+
* typed against the response interface declared in `api-types.ts`.
|
|
7
|
+
*/
|
|
5
8
|
export async function api(method, path, body) {
|
|
6
9
|
const opts = {
|
|
7
10
|
method,
|
|
@@ -17,11 +20,11 @@ export async function api(method, path, body) {
|
|
|
17
20
|
}
|
|
18
21
|
return data;
|
|
19
22
|
}
|
|
20
|
-
|
|
23
|
+
/** Response from `GET /api/projects/:projectId/pm/guide` — see src/routes/pm.ts. */
|
|
21
24
|
export async function getGuide(projectId) {
|
|
22
25
|
return api('GET', `/projects/${projectId}/pm/guide`);
|
|
23
26
|
}
|
|
24
|
-
|
|
27
|
+
/** Response from `GET /api/projects/:projectId/pm/guide/:topicId` — see src/routes/pm.ts. */
|
|
25
28
|
export async function getGuideTopic(projectId, topicId) {
|
|
26
29
|
return api('GET', `/projects/${projectId}/pm/guide/${encodeURIComponent(topicId)}`);
|
|
27
30
|
}
|
package/public/src/api.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.js","sourceRoot":"","sources":["api.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,aAAa;AACb,kEAAkE;AAElE
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["api.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,aAAa;AACb,kEAAkE;AAElE;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,GAAG,CAAc,MAAc,EAAE,IAAY,EAAE,IAAc;IACjF,MAAM,IAAI,GAAgB;QACxB,MAAM;QACN,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,WAAW,EAAE,SAAS;KACvB,CAAC;IACF,IAAI,IAAI,KAAK,SAAS;QAAE,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACzD,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,MAAM,GAAG,IAAI,EAAE,IAAI,CAAC,CAAC;IAC7C,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAA4B,EAAE,CAAC,CAAC,EAAE,CAAC,CAAM,CAAC;IAC9E,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,MAAM,CAAE,IAAgC,CAAC,KAAK,IAAI,QAAQ,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC3F,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,oFAAoF;AACpF,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,SAAiB;IAC9C,OAAO,GAAG,CAAgB,KAAK,EAAE,aAAa,SAAS,WAAW,CAAC,CAAC;AACtE,CAAC;AAED,6FAA6F;AAC7F,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,SAAiB,EAAE,OAAe;IACpE,OAAO,GAAG,CAAqB,KAAK,EAAE,aAAa,SAAS,aAAa,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;AAC1G,CAAC"}
|