@unbrained/pm-web 2026.7.27 → 2026.7.28

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 CHANGED
@@ -1,11 +1,29 @@
1
1
  # Changelog
2
2
 
3
+ ## 2026.7.28 - 2026-07-28
4
+
5
+ ### Added
6
+
7
+ - Per-project package catalog so every pm package is installable from the web UI ([pm-web-28aw](https://github.com/unbraind/pm-web/blob/main/.agents/pm/features/pm-web-28aw.toon))
8
+
9
+ ### Fixed
10
+
11
+ - Require edit permission for package catalog mutations in pm-web ([pm-web-rknk](https://github.com/unbraind/pm-web/blob/main/.agents/pm/issues/pm-web-rknk.toon))
12
+
13
+ ### Other
14
+
15
+ - Adopt pm-cli 2026.7.28 in the hosted web UI package ([pm-web-g7ed](https://github.com/unbraind/pm-web/blob/main/.agents/pm/chores/pm-web-g7ed.toon))
16
+
3
17
  ## 2026.7.27 - 2026-07-27
4
18
 
5
19
  ### Added
6
20
 
7
21
  - Replace per-request pm processes with typed PmClient dispatch and cursor pagination ([pm-web-wyum](https://github.com/unbraind/pm-web/blob/main/.agents/pm/features/pm-web-wyum.toon))
8
22
 
23
+ ### Fixed
24
+
25
+ - web status/stop/doctor shadow the host-owned --json global and fail to register on pm-cli 2026.7.27 ([pm-web-snn2](https://github.com/unbraind/pm-web/blob/main/.agents/pm/issues/pm-web-snn2.toon))
26
+
9
27
  ### Other
10
28
 
11
29
  - Move pm-web onto pm-cli 2026.7.26 and pm-changelog 2026.7.25 ([pm-web-orfk](https://github.com/unbraind/pm-web/blob/main/.agents/pm/chores/pm-web-orfk.toon))
@@ -14,12 +32,18 @@
14
32
 
15
33
  ### Added
16
34
 
35
+ - Full pm ecosystem production pass for pm-web ([pm-web-i98h](https://github.com/unbraind/pm-web/blob/main/.agents/pm/features/pm-web-i98h.toon))
17
36
  - Realtime mutation-event subscription replaces filesystem polling as the primary out-of-band change detector ([pm-web-vwaq](https://github.com/unbraind/pm-web/blob/main/.agents/pm/features/pm-web-vwaq.toon))
18
37
 
38
+ ### Other
39
+
40
+ - Enable governance duplicate-detection advisory mode and restore parent_reference=warn ([pm-web-0nc9](https://github.com/unbraind/pm-web/blob/main/.agents/pm/chores/pm-web-0nc9.toon))
41
+
19
42
  ## 2026.7.25 - 2026-07-25
20
43
 
21
44
  ### Other
22
45
 
46
+ - Adopt --respect-item-release in changelog scripts and bump pm-changelog to 2026.7.24 ([pm-web-hgx4](https://github.com/unbraind/pm-web/blob/main/.agents/pm/chores/pm-web-hgx4.toon))
23
47
  - project-watcher: bounded round-robin scan for projects beyond MAX_FILES_PER_PROJECT (8000) ([pm-web-acwm](https://github.com/unbraind/pm-web/blob/main/.agents/pm/tasks/pm-web-acwm.toon))
24
48
 
25
49
  ## 2026.7.24 - 2026-07-24
@@ -48,6 +72,14 @@
48
72
 
49
73
  - Harden release bun-verify so registry-mirror lag cannot block the GitHub release ([pm-web-rwsr](https://github.com/unbraind/pm-web/blob/main/.agents/pm/chores/pm-web-rwsr.toon))
50
74
 
75
+ ## 2026.7.17-1 - 2026-07-17
76
+
77
+ ### Added
78
+
79
+ - Chinese (zh) locale for package-owned UI strings ([pm-web-t6v6](https://github.com/unbraind/pm-web/blob/main/.agents/pm/features/pm-web-t6v6.toon))
80
+ - Spanish (es) locale for package-owned UI strings ([pm-web-2ut6](https://github.com/unbraind/pm-web/blob/main/.agents/pm/features/pm-web-2ut6.toon))
81
+ - i18n plumbing + German locale for package-owned UI strings ([pm-web-y80b](https://github.com/unbraind/pm-web/blob/main/.agents/pm/features/pm-web-y80b.toon))
82
+
51
83
  ## 2026.7.17 - 2026-07-16
52
84
 
53
85
  ### Added
@@ -84,6 +116,7 @@
84
116
 
85
117
  ### Other
86
118
 
119
+ - Ecosystem release readiness pass 2026-07-06 ([pm-web-f9r8](https://github.com/unbraind/pm-web/blob/main/.agents/pm/tasks/pm-web-f9r8.toon))
87
120
  - Align Node engine with pm CLI runtime ([pm-web-ndeb](https://github.com/unbraind/pm-web/blob/main/.agents/pm/tasks/pm-web-ndeb.toon))
88
121
  - Generate pm-web package declarations and refresh bundled graph toolchain ([pm-web-1xkj](https://github.com/unbraind/pm-web/blob/main/.agents/pm/tasks/pm-web-1xkj.toon))
89
122
  - Regenerate CHANGELOG after pm close item ([pm-web-0ww0](https://github.com/unbraind/pm-web/blob/main/.agents/pm/tasks/pm-web-0ww0.toon))
@@ -112,6 +145,8 @@
112
145
 
113
146
  ### Other
114
147
 
148
+ - Full-cycle hardening wave: pm-web ([pm-web-3x0r](https://github.com/unbraind/pm-web/blob/main/.agents/pm/tasks/pm-web-3x0r.toon))
149
+ - Align pm-web with pm CLI 2026.6.12 release readiness ([pm-web-gtdz](https://github.com/unbraind/pm-web/blob/main/.agents/pm/tasks/pm-web-gtdz.toon))
115
150
  - Restore self-hosted daily release automation ([pm-web-hgjp](https://github.com/unbraind/pm-web/blob/main/.agents/pm/tasks/pm-web-hgjp.toon))
116
151
 
117
152
  ## 2026.6.9 - 2026-06-09
@@ -150,6 +185,12 @@
150
185
  - Implement 'pm web stop' command + pidfile-on-detach ([pm-web-odwq](https://github.com/unbraind/pm-web/blob/main/.agents/pm/tasks/pm-web-odwq.toon))
151
186
  - Implement 'pm web status' command ([pm-web-8eqs](https://github.com/unbraind/pm-web/blob/main/.agents/pm/tasks/pm-web-8eqs.toon))
152
187
 
188
+ ## 2026.6.2 - 2026-06-02
189
+
190
+ ### Added
191
+
192
+ - Add kanban board + full-text search data endpoints (contracts-driven) ([pm-web-9sno](https://github.com/unbraind/pm-web/blob/main/.agents/pm/features/pm-web-9sno.toon))
193
+
153
194
  ## 2026.5.30 - 2026-05-30
154
195
 
155
196
  ### Fixed
package/README.md CHANGED
@@ -123,7 +123,6 @@ pm web doctor --json
123
123
  | `NEO4J_URI` | No | Neo4j Bolt URI for graph sync |
124
124
  | `NEO4J_USER` / `NEO4J_USERNAME` | No | Neo4j username |
125
125
  | `NEO4J_PASSWORD` | No | Neo4j password |
126
- | `PM_GRAPH_EXTENSION_PATH` | No | Bundled pm-graph extension path, default `extensions/pm-graph` |
127
126
  | `PM_WEB_LEGAL_DIR` | Production | Absolute path to a complete, private, operator-reviewed legal-page overlay; see `docs/LEGAL_DEPLOYMENT_BOUNDARY.md` |
128
127
  | `OIDC_ISSUER` | No | Provider issuer URL; setting any OIDC variable enables strict configuration validation |
129
128
  | `OIDC_CLIENT_ID` / `OIDC_CLIENT_SECRET` | With OIDC | OIDC confidential client credentials |
@@ -132,7 +131,7 @@ pm web doctor --json
132
131
  | `OIDC_SCOPES` | No | Requested scopes (default: `openid profile email`) |
133
132
  | `OIDC_REQUIRE_VERIFIED_EMAIL` | No | Reject identities without a provider-verified email when `true` |
134
133
 
135
- New pm-web projects configure local Ollama search automatically and install the bundled `pm-graph` extension into the project workspace. Neo4j graph rows are scoped per pm-web project so syncing one project does not overwrite another.
134
+ New pm-web projects configure local Ollama search automatically and install the `pm-graph` package into the project workspace (from npm, via the per-project package catalog). Neo4j graph rows are scoped per pm-web project so syncing one project does not overwrite another.
136
135
 
137
136
  Saved GitHub personal access tokens are encrypted at rest before they are written to PostgreSQL. Existing plaintext tokens from older installs still work when read, and are replaced with encrypted values the next time the user saves a token.
138
137
 
package/dist/app.js CHANGED
@@ -7,6 +7,7 @@ import { authRouter } from "./routes/auth.js";
7
7
  import { oidcRouter } from "./routes/oidc.js";
8
8
  import { projectsRouter } from "./routes/projects.js";
9
9
  import { pmRouter } from "./routes/pm.js";
10
+ import { extensionsRouter } from "./routes/extensions.js";
10
11
  import { groupsRouter } from "./routes/groups.js";
11
12
  import { sharesRouter, sharedWithMeRouter } from "./routes/sharing.js";
12
13
  import { githubRouter } from "./routes/github.js";
@@ -134,6 +135,7 @@ export function createApp() {
134
135
  app.use("/api/auth", authRouter);
135
136
  app.use("/api/projects", projectsRouter);
136
137
  app.use("/api/projects/:projectId/pm", pmRouter);
138
+ app.use("/api/projects/:projectId/extensions", extensionsRouter);
137
139
  app.use("/api/groups", groupsRouter);
138
140
  app.use("/api/projects/:id/shares", sharesRouter);
139
141
  app.use("/api/shared", sharedWithMeRouter);
package/dist/app.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -176,7 +176,7 @@ function processAlive(pid) {
176
176
  }
177
177
  export default defineExtension({
178
178
  name: "pm-web",
179
- version: "2026.7.27",
179
+ version: "2026.7.28",
180
180
  activate(api) {
181
181
  // -----------------------------------------------------------------------
182
182
  // Command: pm web [--port <port>] [--detach]
@@ -0,0 +1,16 @@
1
+ import { type PackageCatalogEntry } from "../services/package-catalog.js";
2
+ declare const router: import("express-serve-static-core").Router;
3
+ /** The realtime event type broadcast on every successful extension mutation. */
4
+ export declare const EXTENSIONS_CHANGED_EVENT = "extensions-changed";
5
+ /** The catalog entry joined with its live per-project state, for the GET list. */
6
+ export interface PackageCatalogRow extends PackageCatalogEntry {
7
+ installed: boolean;
8
+ version: string | null;
9
+ active: boolean;
10
+ enabled: boolean;
11
+ runtimeActive: boolean;
12
+ activationStatus: string | null;
13
+ managed: boolean;
14
+ sourceKind: string | null;
15
+ }
16
+ export { router as extensionsRouter };
@@ -0,0 +1,214 @@
1
+ // ═══════════════════════════════════════════════════════════════
2
+ // EXTENSIONS ROUTES — per-project pm package catalog management
3
+ // ═══════════════════════════════════════════════════════════════
4
+ //
5
+ // pm-web used to support exactly one pm package — a vendored copy of pm-graph —
6
+ // and offered no way to install any other. These routes expose the full pm
7
+ // package catalog (src/services/package-catalog.ts) joined with the live
8
+ // per-project state from `pm extension --json`, and let a user install,
9
+ // activate, deactivate, and uninstall packages for a project.
10
+ //
11
+ // SECURITY-CRITICAL: every `:name` route parameter is validated against the
12
+ // catalog BEFORE it is passed to any pm command. A catalog lookup miss must
13
+ // 400 before any process spawn — a user-supplied string can never be
14
+ // interpolated into an install target. The install target is the matched
15
+ // entry's own `npmSpec` constant, so the spawn argument always comes from the
16
+ // catalog, never from the raw request string.
17
+ //
18
+ // The router is mounted under the same project-scoped path as the pm router
19
+ // (`/api/projects/:projectId/extensions`), so `:projectId` is available via
20
+ // Express mergeParams. Authorization mirrors src/routes/pm.ts: a user must own
21
+ // or be shared on the project; one user can never touch another user's
22
+ // project. Every successful mutation publishes on the existing realtime bus
23
+ // (src/services/sse.ts) so all collaborators on the project see the change
24
+ // live — consistent with how item mutations already broadcast.
25
+ import { Router } from "express";
26
+ import { requireAuth } from "../middleware/auth.js";
27
+ import { verifyProjectAccess } from "./projects.js";
28
+ import { routeParam } from "./route-params.js";
29
+ import { INSTALL_COMMAND_TIMEOUT_MS, readProjectExtensionStates, runPm, getProjectDir, } from "../services/pm-runner.js";
30
+ import { PACKAGE_CATALOG, findCatalogEntry, } from "../services/package-catalog.js";
31
+ import { broadcastProjectEvent } from "../services/sse.js";
32
+ const router = Router({ mergeParams: true });
33
+ router.use(requireAuth);
34
+ /**
35
+ * Resolve and validate `:name` against the catalog exactly once per request.
36
+ *
37
+ * SECURITY GATE. Express runs a `router.param` callback before any matching
38
+ * route handler, so a mutation route physically cannot run without the
39
+ * validated entry — the previous per-handler lookup relied on every future
40
+ * route remembering to repeat it, and a route that forgot would pass an
41
+ * unvalidated string toward a process spawn.
42
+ *
43
+ * The resolved entry is stashed on the response so handlers read a catalog
44
+ * constant rather than the request string.
45
+ */
46
+ router.param("name", (req, res, next, value) => {
47
+ const entry = findCatalogEntry(value);
48
+ if (!entry) {
49
+ res.status(400).json({ error: `Unknown package: ${value}` });
50
+ return;
51
+ }
52
+ res.locals.catalogEntry = entry;
53
+ next();
54
+ });
55
+ /** The catalog entry resolved by the `:name` param gate above. */
56
+ function catalogEntry(res) {
57
+ return res.locals.catalogEntry;
58
+ }
59
+ /** The realtime event type broadcast on every successful extension mutation. */
60
+ export const EXTENSIONS_CHANGED_EVENT = "extensions-changed";
61
+ /** Verify project access (owner or shared) and return the pm-runner ref. */
62
+ async function verifyProject(userId, projectId) {
63
+ const access = await verifyProjectAccess(userId, projectId);
64
+ if (!access)
65
+ return null;
66
+ return {
67
+ slug: access.slug,
68
+ prefix: access.prefix,
69
+ ownerUserId: access.ownerUserId,
70
+ permission: access.permission,
71
+ };
72
+ }
73
+ /**
74
+ * Resolve the project for a mutating request, enforcing edit permission.
75
+ *
76
+ * Installing, activating, or removing a package changes the workspace for
77
+ * *every* collaborator, so it is an edit-level action. Sharing grants either
78
+ * `"view"` or `"edit"`; without this check a view-only collaborator could
79
+ * install or uninstall packages on someone else's project. Mirrors the
80
+ * guard `routes/pm.ts` applies to item mutations.
81
+ *
82
+ * Responds and returns `null` when access is denied, so callers `return`
83
+ * immediately on a null result.
84
+ */
85
+ async function requireEditableProject(req, res) {
86
+ const project = await verifyProject(req.user.userId, routeParam(req, "projectId"));
87
+ if (!project) {
88
+ res.status(404).json({ error: "Project not found" });
89
+ return null;
90
+ }
91
+ if (project.permission !== "edit") {
92
+ res.status(403).json({ error: "This project is shared as view-only." });
93
+ return null;
94
+ }
95
+ return project;
96
+ }
97
+ function toRow(entry, state) {
98
+ return {
99
+ ...entry,
100
+ installed: Boolean(state),
101
+ version: state?.version ?? null,
102
+ active: Boolean(state?.active),
103
+ enabled: Boolean(state?.enabled),
104
+ runtimeActive: Boolean(state?.runtime_active),
105
+ activationStatus: state?.activation_status ?? null,
106
+ managed: Boolean(state?.managed),
107
+ sourceKind: state?.source?.kind ?? null,
108
+ };
109
+ }
110
+ /** Broadcast an extensions-changed event to all project collaborators. */
111
+ function broadcastExtensionsChanged(projectId, userId, name, operation) {
112
+ broadcastProjectEvent(projectId, {
113
+ type: EXTENSIONS_CHANGED_EVENT,
114
+ data: { userId, name, operation },
115
+ });
116
+ }
117
+ // GET /api/projects/:projectId/extensions
118
+ // Catalog joined with live `pm extension --json` state.
119
+ router.get("/", async (req, res) => {
120
+ // Read-only: a view-only collaborator may see which packages a project uses,
121
+ // they just cannot change them.
122
+ const project = await verifyProject(req.user.userId, routeParam(req, "projectId"));
123
+ if (!project) {
124
+ res.status(404).json({ error: "Project not found" });
125
+ return;
126
+ }
127
+ const { ok, states, error } = await readProjectExtensionStates(getProjectDir(project.ownerUserId, project.slug));
128
+ const rows = PACKAGE_CATALOG.map((entry) => toRow(entry, states.get(entry.name)));
129
+ // Surface a failed read rather than rendering every package as "not
130
+ // installed", which is indistinguishable from a healthy empty project.
131
+ res.json(ok ? { packages: rows } : { packages: rows, stateError: error });
132
+ });
133
+ // POST /api/projects/:projectId/extensions/:name/install
134
+ router.post("/:name/install", async (req, res) => {
135
+ const project = await requireEditableProject(req, res);
136
+ if (!project)
137
+ return;
138
+ const entry = catalogEntry(res);
139
+ const result = await runPm({
140
+ // entry.npmSpec is a catalog constant, never the request string.
141
+ args: ["install", entry.npmSpec, "--project"],
142
+ userId: project.ownerUserId,
143
+ slug: project.slug,
144
+ jsonOutput: true,
145
+ // Installs resolve and download from the npm registry; the 30s default is
146
+ // sized for local commands and leaves too thin a margin for a cold cache.
147
+ timeoutMs: INSTALL_COMMAND_TIMEOUT_MS,
148
+ });
149
+ if (!result.ok) {
150
+ res.status(400).json({ error: result.stderr || `Failed to install ${entry.name}` });
151
+ return;
152
+ }
153
+ broadcastExtensionsChanged(routeParam(req, "projectId"), req.user.userId, entry.name, "install");
154
+ res.status(201).json(result.parsed || { ok: true, name: entry.name });
155
+ });
156
+ // POST /api/projects/:projectId/extensions/:name/activate
157
+ router.post("/:name/activate", async (req, res) => {
158
+ const project = await requireEditableProject(req, res);
159
+ if (!project)
160
+ return;
161
+ const entry = catalogEntry(res);
162
+ const result = await runPm({
163
+ args: ["extension", "activate", entry.name, "--project"],
164
+ userId: project.ownerUserId,
165
+ slug: project.slug,
166
+ jsonOutput: true,
167
+ });
168
+ if (!result.ok) {
169
+ res.status(400).json({ error: result.stderr || `Failed to activate ${entry.name}` });
170
+ return;
171
+ }
172
+ broadcastExtensionsChanged(routeParam(req, "projectId"), req.user.userId, entry.name, "activate");
173
+ res.json(result.parsed || { ok: true, name: entry.name });
174
+ });
175
+ // POST /api/projects/:projectId/extensions/:name/deactivate
176
+ router.post("/:name/deactivate", async (req, res) => {
177
+ const project = await requireEditableProject(req, res);
178
+ if (!project)
179
+ return;
180
+ const entry = catalogEntry(res);
181
+ const result = await runPm({
182
+ args: ["extension", "deactivate", entry.name, "--project"],
183
+ userId: project.ownerUserId,
184
+ slug: project.slug,
185
+ jsonOutput: true,
186
+ });
187
+ if (!result.ok) {
188
+ res.status(400).json({ error: result.stderr || `Failed to deactivate ${entry.name}` });
189
+ return;
190
+ }
191
+ broadcastExtensionsChanged(routeParam(req, "projectId"), req.user.userId, entry.name, "deactivate");
192
+ res.json(result.parsed || { ok: true, name: entry.name });
193
+ });
194
+ // DELETE /api/projects/:projectId/extensions/:name
195
+ router.delete("/:name", async (req, res) => {
196
+ const project = await requireEditableProject(req, res);
197
+ if (!project)
198
+ return;
199
+ const entry = catalogEntry(res);
200
+ const result = await runPm({
201
+ args: ["extension", "uninstall", entry.name, "--project"],
202
+ userId: project.ownerUserId,
203
+ slug: project.slug,
204
+ jsonOutput: true,
205
+ });
206
+ if (!result.ok) {
207
+ res.status(400).json({ error: result.stderr || `Failed to uninstall ${entry.name}` });
208
+ return;
209
+ }
210
+ broadcastExtensionsChanged(routeParam(req, "projectId"), req.user.userId, entry.name, "uninstall");
211
+ res.json(result.parsed || { ok: true, name: entry.name });
212
+ });
213
+ export { router as extensionsRouter };
214
+ //# sourceMappingURL=extensions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extensions.js","sourceRoot":"","sources":["../../src/routes/extensions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,84 @@
1
+ /**
2
+ * The set of capabilities a pm package can declare, mirrored verbatim from
3
+ * each package's `manifest.json` `capabilities` array. The union is kept
4
+ * open-ended as a string array (not a closed enum) because the pm extension
5
+ * contract may add new capability kinds upstream; pinning a closed list here
6
+ * would reject a future package that uses a capability we have not enumerated.
7
+ */
8
+ export type PackageCapability = string;
9
+ /**
10
+ * Honest gating metadata so the UI can tell a user what they must configure
11
+ * before a package is useful. Both fields are OPTIONAL — most packages work
12
+ * with no external setup.
13
+ *
14
+ * - `requiresService`: a backing service the package talks to (e.g. Neo4j for
15
+ * pm-graph's sync). When set, the UI explains that the package's
16
+ * service-dependent features will not work until the service is reachable.
17
+ * `optional: true` means the package is still useful without the service
18
+ * (e.g. pm-graph's offline export/analyze work without Neo4j).
19
+ *
20
+ * - `requiresCredentials`: human-supplied secrets the package needs for its
21
+ * network-mutating commands (e.g. JIRA_API_TOKEN, LINEAR_API_KEY,
22
+ * PM_SLACK_WEBHOOK, GITHUB_TOKEN). Each entry names the env var(s) and a
23
+ * short human description. The UI must not pretend these are one-click; it
24
+ * surfaces the variables the user must set.
25
+ */
26
+ export interface ServiceRequirement {
27
+ /** Display name of the backing service, e.g. "Neo4j". */
28
+ name: string;
29
+ /** True when the package is useful without the service (best-effort). */
30
+ optional?: boolean;
31
+ }
32
+ export interface CredentialRequirement {
33
+ /** Display label for what the credentials unlock, e.g. "Jira sync". */
34
+ label: string;
35
+ /** Environment variable(s) the package reads for the credentials. */
36
+ envVars: string[];
37
+ /**
38
+ * True when the package is partially usable without the credentials (e.g.
39
+ * `--dry-run` paths, unauthenticated reads). When false, the package is
40
+ * inert until the credentials are configured.
41
+ */
42
+ optional?: boolean;
43
+ }
44
+ export interface PackageCatalogEntry {
45
+ /** Canonical npm package name, e.g. `pm-graph`. */
46
+ readonly name: string;
47
+ /** The install spec passed to `pm install`, always `npm:<name>`. */
48
+ readonly npmSpec: string;
49
+ /** Human-friendly title, e.g. `Graph`. */
50
+ readonly title: string;
51
+ /** One-line description, mirrored from the package's manifest/package.json. */
52
+ readonly description: string;
53
+ /** Capabilities declared in the package manifest. */
54
+ readonly capabilities: readonly PackageCapability[];
55
+ /** Backing service the package needs (optional). */
56
+ readonly requiresService?: ServiceRequirement;
57
+ /** Credentials the user must configure (optional). */
58
+ readonly requiresCredentials?: readonly CredentialRequirement[];
59
+ }
60
+ /**
61
+ * The catalog. Order is the display order in the UI. The list is exhaustive
62
+ * over user-facing pm packages: every package in the fleet that is not an
63
+ * authoring template (`pm-starter`/`pm-ts-starter`) and not pm-web itself is
64
+ * here. `pm-starter`/`pm-ts-starter` are authoring templates, not user-facing
65
+ * packages; `pm-web` is this package.
66
+ */
67
+ export declare const PACKAGE_CATALOG: readonly PackageCatalogEntry[];
68
+ /**
69
+ * Look up a catalog entry by package name. Returns the entry or `undefined`
70
+ * when the name is not in the catalog. This is the security-critical gate:
71
+ * route handlers MUST call this and reject with 400 on a miss BEFORE passing
72
+ * the name to any pm command, so a user-supplied string can never be
73
+ * interpolated into an install target.
74
+ */
75
+ export declare function findCatalogEntry(name: string): PackageCatalogEntry | undefined;
76
+ /**
77
+ * Resolve a package name to its verified npm install spec
78
+ * (`npm:<name>`), or `null` when the name is not in the catalog. Route
79
+ * handlers use this to obtain the spawn argument without ever building an
80
+ * install target from a raw user string.
81
+ */
82
+ export declare function resolveNpmSpec(name: string): string | null;
83
+ /** The immutable list of catalog package names, in display order. */
84
+ export declare function catalogNames(): readonly string[];