@unbrained/pm-web 2026.7.28 → 2026.7.30
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 +22 -0
- package/dist/index.js +1 -1
- package/dist/oidc.js.map +1 -1
- package/dist/routes/admin.js +4 -1
- package/dist/routes/admin.js.map +1 -1
- package/dist/routes/extensions.d.ts +1 -1
- package/dist/routes/groups.js +5 -1
- package/dist/routes/groups.js.map +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/routes/projects.js +3 -1
- package/dist/routes/projects.js.map +1 -1
- package/dist/routes/route-params.d.ts +57 -1
- package/dist/routes/route-params.js +88 -0
- package/dist/routes/route-params.js.map +1 -1
- package/dist/routes/sharing.js +6 -1
- package/dist/routes/sharing.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 +24 -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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"projects.js","sourceRoot":"","sources":["../../src/routes/projects.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,WAAW,EAAoB,MAAM,uBAAuB,CAAC;AACtE,OAAO,EAAE,WAAW,EAAiB,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACxF,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/
|
|
1
|
+
{"version":3,"file":"projects.js","sourceRoot":"","sources":["../../src/routes/projects.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,2 +1,58 @@
|
|
|
1
|
-
import type { Request } from "express";
|
|
1
|
+
import type { NextFunction, Request, RequestHandler, Response } from "express";
|
|
2
|
+
/**
|
|
3
|
+
* Read a route parameter as a single string.
|
|
4
|
+
*
|
|
5
|
+
* Express types a param as `string | string[]`, because a repeated capture can
|
|
6
|
+
* produce an array. Routes here always want one value, so an array collapses to
|
|
7
|
+
* its first element and a missing param becomes the empty string rather than
|
|
8
|
+
* `undefined`, which keeps every call site free of null handling.
|
|
9
|
+
*
|
|
10
|
+
* @param req Request carrying the matched route parameters.
|
|
11
|
+
* @param name Parameter name to read.
|
|
12
|
+
* @returns The parameter value, or `""` when absent.
|
|
13
|
+
*/
|
|
2
14
|
export declare function routeParam(req: Pick<Request, "params">, name: string): string;
|
|
15
|
+
/**
|
|
16
|
+
* Report whether a value is shaped like a UUID.
|
|
17
|
+
*
|
|
18
|
+
* @param value Candidate identifier, typically straight from the URL.
|
|
19
|
+
* @returns True when the value can be cast to `uuid` by PostgreSQL.
|
|
20
|
+
*/
|
|
21
|
+
export declare function isUuid(value: string): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Reject malformed UUID path parameters with 400 before they reach SQL.
|
|
24
|
+
*
|
|
25
|
+
* Without this guard a non-UUID path segment travels all the way into a query
|
|
26
|
+
* such as `WHERE id = $1`, where PostgreSQL raises `invalid input syntax for
|
|
27
|
+
* type uuid`. The surrounding `catch` then reports 500 — telling a client that
|
|
28
|
+
* the server failed when in fact the request was malformed, and writing a
|
|
29
|
+
* stack trace to the logs for what is ordinary bad input. Validating the shape
|
|
30
|
+
* first turns that into an accurate 400 and keeps the logs meaningful.
|
|
31
|
+
*
|
|
32
|
+
* Only the listed names are checked, and only when present on the matched
|
|
33
|
+
* route. That matters because not every identifier in this API is a UUID: pm
|
|
34
|
+
* item ids (`itemId`), plan and step refs, and extension keys are opaque
|
|
35
|
+
* strings, so a blanket guard would reject valid requests.
|
|
36
|
+
*
|
|
37
|
+
* Use this form for routers whose parameter arrives from the *mount path* (for
|
|
38
|
+
* example `sharesRouter`, mounted at `/api/projects/:id/shares` with
|
|
39
|
+
* `mergeParams: true`), where router-level middleware does see the merged
|
|
40
|
+
* params. For a router's own route parameters, prefer `router.param(name, …)`,
|
|
41
|
+
* which Express invokes only once the route has matched.
|
|
42
|
+
*
|
|
43
|
+
* @param names Parameter names to validate when present.
|
|
44
|
+
* @returns Middleware that answers 400 on a malformed identifier.
|
|
45
|
+
*/
|
|
46
|
+
export declare function requireUuidParams(...names: readonly string[]): RequestHandler;
|
|
47
|
+
/**
|
|
48
|
+
* Build an Express `router.param` handler that rejects a malformed UUID with 400.
|
|
49
|
+
*
|
|
50
|
+
* The `router.param` hook is the right place for a router's own path
|
|
51
|
+
* parameters: it fires after the route matches and before the handler runs, so
|
|
52
|
+
* a single registration covers every route using that parameter without each
|
|
53
|
+
* handler repeating the check.
|
|
54
|
+
*
|
|
55
|
+
* @param name Parameter name, used in the error message.
|
|
56
|
+
* @returns A `router.param` callback answering 400 on a malformed identifier.
|
|
57
|
+
*/
|
|
58
|
+
export declare function uuidParamGuard(name: string): (req: Request, res: Response, next: NextFunction, value: string) => void;
|
|
@@ -1,7 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Read a route parameter as a single string.
|
|
3
|
+
*
|
|
4
|
+
* Express types a param as `string | string[]`, because a repeated capture can
|
|
5
|
+
* produce an array. Routes here always want one value, so an array collapses to
|
|
6
|
+
* its first element and a missing param becomes the empty string rather than
|
|
7
|
+
* `undefined`, which keeps every call site free of null handling.
|
|
8
|
+
*
|
|
9
|
+
* @param req Request carrying the matched route parameters.
|
|
10
|
+
* @param name Parameter name to read.
|
|
11
|
+
* @returns The parameter value, or `""` when absent.
|
|
12
|
+
*/
|
|
1
13
|
export function routeParam(req, name) {
|
|
2
14
|
const value = req.params[name];
|
|
3
15
|
if (Array.isArray(value))
|
|
4
16
|
return value[0] ?? "";
|
|
5
17
|
return value ?? "";
|
|
6
18
|
}
|
|
19
|
+
/**
|
|
20
|
+
* Matches the canonical 8-4-4-4-12 hexadecimal UUID form.
|
|
21
|
+
*
|
|
22
|
+
* Deliberately shape-only: it does not check the version or variant nibbles,
|
|
23
|
+
* because the goal is to reject input PostgreSQL cannot cast, not to police
|
|
24
|
+
* which UUID version a client sends. Seeded test fixtures and `gen_random_uuid()`
|
|
25
|
+
* both satisfy it.
|
|
26
|
+
*/
|
|
27
|
+
const UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
28
|
+
/**
|
|
29
|
+
* Report whether a value is shaped like a UUID.
|
|
30
|
+
*
|
|
31
|
+
* @param value Candidate identifier, typically straight from the URL.
|
|
32
|
+
* @returns True when the value can be cast to `uuid` by PostgreSQL.
|
|
33
|
+
*/
|
|
34
|
+
export function isUuid(value) {
|
|
35
|
+
return UUID_PATTERN.test(value);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Reject malformed UUID path parameters with 400 before they reach SQL.
|
|
39
|
+
*
|
|
40
|
+
* Without this guard a non-UUID path segment travels all the way into a query
|
|
41
|
+
* such as `WHERE id = $1`, where PostgreSQL raises `invalid input syntax for
|
|
42
|
+
* type uuid`. The surrounding `catch` then reports 500 — telling a client that
|
|
43
|
+
* the server failed when in fact the request was malformed, and writing a
|
|
44
|
+
* stack trace to the logs for what is ordinary bad input. Validating the shape
|
|
45
|
+
* first turns that into an accurate 400 and keeps the logs meaningful.
|
|
46
|
+
*
|
|
47
|
+
* Only the listed names are checked, and only when present on the matched
|
|
48
|
+
* route. That matters because not every identifier in this API is a UUID: pm
|
|
49
|
+
* item ids (`itemId`), plan and step refs, and extension keys are opaque
|
|
50
|
+
* strings, so a blanket guard would reject valid requests.
|
|
51
|
+
*
|
|
52
|
+
* Use this form for routers whose parameter arrives from the *mount path* (for
|
|
53
|
+
* example `sharesRouter`, mounted at `/api/projects/:id/shares` with
|
|
54
|
+
* `mergeParams: true`), where router-level middleware does see the merged
|
|
55
|
+
* params. For a router's own route parameters, prefer `router.param(name, …)`,
|
|
56
|
+
* which Express invokes only once the route has matched.
|
|
57
|
+
*
|
|
58
|
+
* @param names Parameter names to validate when present.
|
|
59
|
+
* @returns Middleware that answers 400 on a malformed identifier.
|
|
60
|
+
*/
|
|
61
|
+
export function requireUuidParams(...names) {
|
|
62
|
+
return (req, res, next) => {
|
|
63
|
+
for (const name of names) {
|
|
64
|
+
const value = req.params[name];
|
|
65
|
+
if (value === undefined)
|
|
66
|
+
continue;
|
|
67
|
+
if (!isUuid(routeParam(req, name))) {
|
|
68
|
+
res.status(400).json({ error: `Invalid ${name}` });
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
next();
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Build an Express `router.param` handler that rejects a malformed UUID with 400.
|
|
77
|
+
*
|
|
78
|
+
* The `router.param` hook is the right place for a router's own path
|
|
79
|
+
* parameters: it fires after the route matches and before the handler runs, so
|
|
80
|
+
* a single registration covers every route using that parameter without each
|
|
81
|
+
* handler repeating the check.
|
|
82
|
+
*
|
|
83
|
+
* @param name Parameter name, used in the error message.
|
|
84
|
+
* @returns A `router.param` callback answering 400 on a malformed identifier.
|
|
85
|
+
*/
|
|
86
|
+
export function uuidParamGuard(name) {
|
|
87
|
+
return (_req, res, next, value) => {
|
|
88
|
+
if (!isUuid(value)) {
|
|
89
|
+
res.status(400).json({ error: `Invalid ${name}` });
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
next();
|
|
93
|
+
};
|
|
94
|
+
}
|
|
7
95
|
//# sourceMappingURL=route-params.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route-params.js","sourceRoot":"","sources":["../../src/routes/route-params.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,UAAU,CAAC,GAA4B,EAAE,IAAY;IACnE,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC/B,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAChD,OAAO,KAAK,IAAI,EAAE,CAAC;AACrB,CAAC"}
|
|
1
|
+
{"version":3,"file":"route-params.js","sourceRoot":"","sources":["../../src/routes/route-params.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,UAAU,CAAC,GAA4B,EAAE,IAAY;IACnE,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC/B,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAChD,OAAO,KAAK,IAAI,EAAE,CAAC;AACrB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,YAAY,GAAG,iEAAiE,CAAC;AAEvF;;;;;GAKG;AACH,MAAM,UAAU,MAAM,CAAC,KAAa;IAClC,OAAO,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAClC,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,UAAU,iBAAiB,CAAC,GAAG,KAAwB;IAC3D,OAAO,CAAC,GAAY,EAAE,GAAa,EAAE,IAAkB,EAAQ,EAAE;QAC/D,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAC/B,IAAI,KAAK,KAAK,SAAS;gBAAE,SAAS;YAClC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC;gBACnC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,WAAW,IAAI,EAAE,EAAE,CAAC,CAAC;gBACnD,OAAO;YACT,CAAC;QACH,CAAC;QACD,IAAI,EAAE,CAAC;IACT,CAAC,CAAC;AACJ,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,cAAc,CAC5B,IAAY;IAEZ,OAAO,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE;QAChC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;YACnB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,WAAW,IAAI,EAAE,EAAE,CAAC,CAAC;YACnD,OAAO;QACT,CAAC;QACD,IAAI,EAAE,CAAC;IACT,CAAC,CAAC;AACJ,CAAC"}
|
package/dist/routes/sharing.js
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import { Router } from "express";
|
|
2
2
|
import { pool } from "../db.js";
|
|
3
3
|
import { requireAuth } from "../middleware/auth.js";
|
|
4
|
-
import { routeParam } from "./route-params.js";
|
|
4
|
+
import { routeParam, requireUuidParams, uuidParamGuard } from "./route-params.js";
|
|
5
5
|
const sharesRouter = Router({ mergeParams: true });
|
|
6
6
|
sharesRouter.use(requireAuth);
|
|
7
|
+
// The project id arrives from the mount path (/api/projects/:id/shares) and is
|
|
8
|
+
// visible to router-level middleware because this router sets mergeParams;
|
|
9
|
+
// :shareId is this router's own parameter, so it needs the param hook instead.
|
|
10
|
+
sharesRouter.use(requireUuidParams("id", "projectId"));
|
|
11
|
+
sharesRouter.param("shareId", uuidParamGuard("shareId"));
|
|
7
12
|
// Helper: verify project ownership for sharing operations
|
|
8
13
|
async function verifyProjectOwner(userId, projectId) {
|
|
9
14
|
const result = await pool.query(`SELECT id FROM pm_projects WHERE id = $1 AND user_id = $2`, [projectId, userId]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sharing.js","sourceRoot":"","sources":["../../src/routes/sharing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,WAAW,EAAoB,MAAM,uBAAuB,CAAC;AACtE,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"sharing.js","sourceRoot":"","sources":["../../src/routes/sharing.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type MutationEvent } from "@unbrained/pm-cli/sdk";
|
|
2
|
-
import { type SSEEvent } from "./sse.
|
|
2
|
+
import { type SSEEvent } from "./sse.ts";
|
|
3
3
|
/** Options for the async generator subscription seam. Mirrors the SDK's `SubscribeMutationEventsOptions`. */
|
|
4
4
|
export interface SubscribeOptions {
|
|
5
5
|
/** Tracker root path (`.agents/pm` under the project directory). */
|
|
@@ -6,6 +6,22 @@
|
|
|
6
6
|
* would reject a future package that uses a capability we have not enumerated.
|
|
7
7
|
*/
|
|
8
8
|
export type PackageCapability = string;
|
|
9
|
+
/**
|
|
10
|
+
* Catalog grouping: user-facing product extensions vs. authoring reference
|
|
11
|
+
* templates.
|
|
12
|
+
*
|
|
13
|
+
* - `"extension"` — a product extension a user installs for its functionality
|
|
14
|
+
* (e.g. pm-graph, pm-jira). This is the default and the only category the
|
|
15
|
+
* catalog originally carried.
|
|
16
|
+
* - `"template"` — a reference/scaffold extension that a user installs to
|
|
17
|
+
* learn the extension API. It registers real commands (it ships
|
|
18
|
+
* `manifest.json` + `dist/` and calls `registerCommand`), so installing it
|
|
19
|
+
* is a genuine operation, but its purpose is to be read and copied — it is
|
|
20
|
+
* the reference implementation covering every capability type. The UI
|
|
21
|
+
* badges template entries so a user can tell a learning scaffold from a
|
|
22
|
+
* product extension.
|
|
23
|
+
*/
|
|
24
|
+
export type PackageCategory = "extension" | "template";
|
|
9
25
|
/**
|
|
10
26
|
* Honest gating metadata so the UI can tell a user what they must configure
|
|
11
27
|
* before a package is useful. Both fields are OPTIONAL — most packages work
|
|
@@ -52,6 +68,13 @@ export interface PackageCatalogEntry {
|
|
|
52
68
|
readonly description: string;
|
|
53
69
|
/** Capabilities declared in the package manifest. */
|
|
54
70
|
readonly capabilities: readonly PackageCapability[];
|
|
71
|
+
/**
|
|
72
|
+
* Whether this is a user-facing product extension (`"extension"`) or an
|
|
73
|
+
* authoring reference template (`"template"`). The UI badges template
|
|
74
|
+
* entries so a user can distinguish a learning scaffold from a product
|
|
75
|
+
* extension. See {@link PackageCategory}.
|
|
76
|
+
*/
|
|
77
|
+
readonly category: PackageCategory;
|
|
55
78
|
/** Backing service the package needs (optional). */
|
|
56
79
|
readonly requiresService?: ServiceRequirement;
|
|
57
80
|
/** Credentials the user must configure (optional). */
|
|
@@ -59,10 +82,11 @@ export interface PackageCatalogEntry {
|
|
|
59
82
|
}
|
|
60
83
|
/**
|
|
61
84
|
* The catalog. Order is the display order in the UI. The list is exhaustive
|
|
62
|
-
* over
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
85
|
+
* over every published pm package except `pm-web` itself (it is the host and
|
|
86
|
+
* cannot install itself). The {@link PackageCategory} field on each entry
|
|
87
|
+
* distinguishes user-facing product extensions from authoring reference
|
|
88
|
+
* templates; the two starter packages sort last so product extensions appear
|
|
89
|
+
* first.
|
|
66
90
|
*/
|
|
67
91
|
export declare const PACKAGE_CATALOG: readonly PackageCatalogEntry[];
|
|
68
92
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// ═══════════════════════════════════════════════════════════════
|
|
2
|
-
// PACKAGE CATALOG — the typed, immutable list of every
|
|
2
|
+
// PACKAGE CATALOG — the typed, immutable list of every installable pm package
|
|
3
3
|
// ═══════════════════════════════════════════════════════════════
|
|
4
4
|
//
|
|
5
5
|
// pm-web used to ship exactly one pm package — a vendored copy of pm-graph
|
|
@@ -10,6 +10,16 @@
|
|
|
10
10
|
// pm command is ever spawned. A user-supplied name can never reach an install
|
|
11
11
|
// target — a catalog lookup miss must 400 before any process spawn.
|
|
12
12
|
//
|
|
13
|
+
// The catalog is exhaustive over every published pm package except `pm-web`
|
|
14
|
+
// itself (this package IS the host, so it cannot install itself). The
|
|
15
|
+
// `category` field distinguishes user-facing product extensions
|
|
16
|
+
// (`"extension"`) from authoring reference templates (`"template"`): the
|
|
17
|
+
// starters are real, published npm packages that ship `manifest.json` +
|
|
18
|
+
// `dist/` and call `registerCommand`, so installing them genuinely registers
|
|
19
|
+
// working commands — they exist to be read and copied as reference
|
|
20
|
+
// implementations covering every capability type, and the UI badges them so a
|
|
21
|
+
// user can tell a learning scaffold from a product extension.
|
|
22
|
+
//
|
|
13
23
|
// Truthfulness contract: the catalog mirrors each package's real
|
|
14
24
|
// `manifest.json` (name, capabilities) and README (gating). Do NOT invent
|
|
15
25
|
// capabilities or hide requirements here — the UI surfaces `requiresService`
|
|
@@ -21,10 +31,11 @@
|
|
|
21
31
|
// UI lie.
|
|
22
32
|
/**
|
|
23
33
|
* The catalog. Order is the display order in the UI. The list is exhaustive
|
|
24
|
-
* over
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
34
|
+
* over every published pm package except `pm-web` itself (it is the host and
|
|
35
|
+
* cannot install itself). The {@link PackageCategory} field on each entry
|
|
36
|
+
* distinguishes user-facing product extensions from authoring reference
|
|
37
|
+
* templates; the two starter packages sort last so product extensions appear
|
|
38
|
+
* first.
|
|
28
39
|
*/
|
|
29
40
|
export const PACKAGE_CATALOG = [
|
|
30
41
|
{
|
|
@@ -33,6 +44,7 @@ export const PACKAGE_CATALOG = [
|
|
|
33
44
|
title: "Graph",
|
|
34
45
|
description: "Knowledge graph and dependency graph extension for pm CLI workspaces, with optional Neo4j sync.",
|
|
35
46
|
capabilities: ["commands", "importers", "services"],
|
|
47
|
+
category: "extension",
|
|
36
48
|
requiresService: { name: "Neo4j", optional: true },
|
|
37
49
|
},
|
|
38
50
|
{
|
|
@@ -41,6 +53,7 @@ export const PACKAGE_CATALOG = [
|
|
|
41
53
|
title: "Beads",
|
|
42
54
|
description: "Beads JSONL importer/exporter. Import work items from the Beads JSONL format into pm and export pm items back to Beads JSONL, preserving ids and dependency edges.",
|
|
43
55
|
capabilities: ["commands", "schema", "importers"],
|
|
56
|
+
category: "extension",
|
|
44
57
|
},
|
|
45
58
|
{
|
|
46
59
|
name: "pm-brief",
|
|
@@ -48,6 +61,7 @@ export const PACKAGE_CATALOG = [
|
|
|
48
61
|
title: "Brief",
|
|
49
62
|
description: "Token-budgeted agent briefs and next-work plans for pm workspaces",
|
|
50
63
|
capabilities: ["commands", "renderers", "schema"],
|
|
64
|
+
category: "extension",
|
|
51
65
|
},
|
|
52
66
|
{
|
|
53
67
|
name: "pm-changelog",
|
|
@@ -55,6 +69,7 @@ export const PACKAGE_CATALOG = [
|
|
|
55
69
|
title: "Changelog",
|
|
56
70
|
description: "Generate CHANGELOG.md release notes from pm-cli items",
|
|
57
71
|
capabilities: ["commands", "schema", "importers", "renderers"],
|
|
72
|
+
category: "extension",
|
|
58
73
|
},
|
|
59
74
|
{
|
|
60
75
|
name: "pm-context",
|
|
@@ -62,6 +77,7 @@ export const PACKAGE_CATALOG = [
|
|
|
62
77
|
title: "Context",
|
|
63
78
|
description: "Generate deterministic pm context packs for agent handoffs, reviews, and status briefs",
|
|
64
79
|
capabilities: ["commands", "renderers", "schema"],
|
|
80
|
+
category: "extension",
|
|
65
81
|
},
|
|
66
82
|
{
|
|
67
83
|
name: "pm-csv",
|
|
@@ -69,6 +85,7 @@ export const PACKAGE_CATALOG = [
|
|
|
69
85
|
title: "CSV",
|
|
70
86
|
description: "CSV importer and exporter for pm-cli",
|
|
71
87
|
capabilities: ["commands", "importers", "schema"],
|
|
88
|
+
category: "extension",
|
|
72
89
|
},
|
|
73
90
|
{
|
|
74
91
|
name: "pm-gantt-chart",
|
|
@@ -76,6 +93,7 @@ export const PACKAGE_CATALOG = [
|
|
|
76
93
|
title: "Gantt Chart",
|
|
77
94
|
description: "ASCII Gantt chart renderer + multi-format exporter for pm-cli",
|
|
78
95
|
capabilities: ["commands", "schema", "importers", "preflight"],
|
|
96
|
+
category: "extension",
|
|
79
97
|
},
|
|
80
98
|
{
|
|
81
99
|
name: "pm-github",
|
|
@@ -83,6 +101,7 @@ export const PACKAGE_CATALOG = [
|
|
|
83
101
|
title: "GitHub",
|
|
84
102
|
description: "GitHub Issues + Projects v2 integration. Imports issues as pm items (`pm github import`), exports pm items as GitHub issues, syncs issue state, and bidirectionally syncs pm items with a GitHub Projects v2 board (`pm github project import/sync/list/fields`) — mapping pm status to the board Status column with idempotent, no-data-loss provenance.",
|
|
85
103
|
capabilities: ["commands", "importers", "schema", "hooks", "preflight", "search"],
|
|
104
|
+
category: "extension",
|
|
86
105
|
requiresCredentials: [
|
|
87
106
|
{
|
|
88
107
|
label: "GitHub token (for private repos, 5000 req/hr, and export/push)",
|
|
@@ -97,6 +116,7 @@ export const PACKAGE_CATALOG = [
|
|
|
97
116
|
title: "Jira",
|
|
98
117
|
description: "Jira issue sync for pm-cli",
|
|
99
118
|
capabilities: ["commands", "schema", "importers", "hooks", "preflight"],
|
|
119
|
+
category: "extension",
|
|
100
120
|
requiresCredentials: [
|
|
101
121
|
{
|
|
102
122
|
label: "Jira API credentials (for live sync, import, and export --push)",
|
|
@@ -110,6 +130,7 @@ export const PACKAGE_CATALOG = [
|
|
|
110
130
|
title: "Linear",
|
|
111
131
|
description: "Linear.app issue sync for pm-cli",
|
|
112
132
|
capabilities: ["commands", "schema", "importers", "preflight"],
|
|
133
|
+
category: "extension",
|
|
113
134
|
requiresCredentials: [
|
|
114
135
|
{
|
|
115
136
|
label: "Linear API key (for live import/export and validate --check-network)",
|
|
@@ -123,6 +144,7 @@ export const PACKAGE_CATALOG = [
|
|
|
123
144
|
title: "Ops",
|
|
124
145
|
description: "Multi-repo fleet operations for pm-cli",
|
|
125
146
|
capabilities: ["commands", "renderers", "schema", "parser"],
|
|
147
|
+
category: "extension",
|
|
126
148
|
},
|
|
127
149
|
{
|
|
128
150
|
name: "pm-presets",
|
|
@@ -130,6 +152,7 @@ export const PACKAGE_CATALOG = [
|
|
|
130
152
|
title: "Presets",
|
|
131
153
|
description: "All 7 official pm-cli workspace presets in one package: bug-triage, indie-dev, open-source, software-sprint, startup-roadmap, kanban, agent-workflow",
|
|
132
154
|
capabilities: ["commands", "schema"],
|
|
155
|
+
category: "extension",
|
|
133
156
|
},
|
|
134
157
|
{
|
|
135
158
|
name: "pm-slack",
|
|
@@ -137,6 +160,7 @@ export const PACKAGE_CATALOG = [
|
|
|
137
160
|
title: "Slack",
|
|
138
161
|
description: "Slack notifications for pm item lifecycle events",
|
|
139
162
|
capabilities: ["commands", "hooks", "schema", "preflight"],
|
|
163
|
+
category: "extension",
|
|
140
164
|
requiresCredentials: [
|
|
141
165
|
{
|
|
142
166
|
label: "Slack webhook (for posting notifications)",
|
|
@@ -150,6 +174,7 @@ export const PACKAGE_CATALOG = [
|
|
|
150
174
|
title: "Slack Standup",
|
|
151
175
|
description: "Post pm context as a Slack standup message",
|
|
152
176
|
capabilities: ["commands", "schema", "importers", "preflight", "services"],
|
|
177
|
+
category: "extension",
|
|
153
178
|
requiresCredentials: [
|
|
154
179
|
{
|
|
155
180
|
label: "Slack webhook (for posting the standup)",
|
|
@@ -163,6 +188,43 @@ export const PACKAGE_CATALOG = [
|
|
|
163
188
|
title: "Todos",
|
|
164
189
|
description: "TODO round-trip. Import/export/sync markdown checkboxes, todo.txt, jsonl, checkbox, and pi coding-agent todo JSON as pm items.",
|
|
165
190
|
capabilities: ["commands", "schema", "importers", "preflight"],
|
|
191
|
+
category: "extension",
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
name: "pm-starter",
|
|
195
|
+
npmSpec: "npm:pm-starter",
|
|
196
|
+
title: "Starter",
|
|
197
|
+
description: "Complete starter/scaffold extension for pm-cli showing all capability types",
|
|
198
|
+
capabilities: [
|
|
199
|
+
"commands",
|
|
200
|
+
"renderers",
|
|
201
|
+
"hooks",
|
|
202
|
+
"schema",
|
|
203
|
+
"importers",
|
|
204
|
+
"search",
|
|
205
|
+
"parser",
|
|
206
|
+
"preflight",
|
|
207
|
+
"services",
|
|
208
|
+
],
|
|
209
|
+
category: "template",
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
name: "pm-ts-starter",
|
|
213
|
+
npmSpec: "npm:pm-ts-starter",
|
|
214
|
+
title: "TypeScript Starter",
|
|
215
|
+
description: "TypeScript reference extension for pm-cli covering all capability types",
|
|
216
|
+
capabilities: [
|
|
217
|
+
"commands",
|
|
218
|
+
"renderers",
|
|
219
|
+
"hooks",
|
|
220
|
+
"schema",
|
|
221
|
+
"importers",
|
|
222
|
+
"search",
|
|
223
|
+
"parser",
|
|
224
|
+
"preflight",
|
|
225
|
+
"services",
|
|
226
|
+
],
|
|
227
|
+
category: "template",
|
|
166
228
|
},
|
|
167
229
|
];
|
|
168
230
|
/** A frozen map keyed by package name for O(1) catalog lookup. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"package-catalog.js","sourceRoot":"","sources":["../../src/services/package-catalog.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,8EAA8E;AAC9E,kEAAkE;AAClE,EAAE;AACF,2EAA2E;AAC3E,uEAAuE;AACvE,4EAA4E;AAC5E,0EAA0E;AAC1E,2EAA2E;AAC3E,8EAA8E;AAC9E,oEAAoE;AACpE,EAAE;AACF,iEAAiE;AACjE,0EAA0E;AAC1E,6EAA6E;AAC7E,8EAA8E;AAC9E,6DAA6D;AAC7D,gFAAgF;AAChF,0EAA0E;AAC1E,8EAA8E;AAC9E,UAAU;
|
|
1
|
+
{"version":3,"file":"package-catalog.js","sourceRoot":"","sources":["../../src/services/package-catalog.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { PmClient, PmCliError, isPmCliExpectedError, EXIT_CODE, type GetItemAtResult } from "@unbrained/pm-cli/sdk";
|
|
2
2
|
export { PmCliError, isPmCliExpectedError, EXIT_CODE, type GetItemAtResult };
|
|
3
3
|
export declare class Semaphore {
|
|
4
|
-
private readonly limit;
|
|
5
4
|
private active;
|
|
6
5
|
private readonly waiting;
|
|
6
|
+
private readonly limit;
|
|
7
7
|
constructor(limit: number);
|
|
8
8
|
acquire(): Promise<() => void>;
|
|
9
9
|
}
|
|
@@ -14,9 +14,9 @@ function positiveInteger(value, fallback) {
|
|
|
14
14
|
return Number.isSafeInteger(parsed) && parsed > 0 ? parsed : fallback;
|
|
15
15
|
}
|
|
16
16
|
export class Semaphore {
|
|
17
|
-
limit;
|
|
18
17
|
active = 0;
|
|
19
18
|
waiting = [];
|
|
19
|
+
limit;
|
|
20
20
|
constructor(limit) {
|
|
21
21
|
this.limit = limit;
|
|
22
22
|
}
|
|
@@ -420,6 +420,13 @@ const POSITIONAL_KEYS = {
|
|
|
420
420
|
"pause-task": ["id"],
|
|
421
421
|
"close-task": ["id", "reason"],
|
|
422
422
|
history: ["id"],
|
|
423
|
+
// `pm schema [subcommand] [name]` — e.g. `schema add-type Spike`. Without this
|
|
424
|
+
// mapping both positionals are dropped and the SDK rejects the call with
|
|
425
|
+
// "Missing required argument: subcommand".
|
|
426
|
+
schema: ["subcommand", "name"],
|
|
427
|
+
// `pm history-repair [id]` — omitted only when `--all` is passed, which the
|
|
428
|
+
// per-item route never does.
|
|
429
|
+
"history-repair": ["id"],
|
|
423
430
|
config: ["scope", "configAction", "key", "value"],
|
|
424
431
|
};
|
|
425
432
|
const PM_CLIENT_CACHE_MAX = positiveInteger(process.env.PM_WEB_PM_CLIENT_CACHE_MAX, 256);
|