@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 +41 -0
- package/README.md +1 -2
- package/dist/app.js +2 -0
- package/dist/app.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/routes/extensions.d.ts +16 -0
- package/dist/routes/extensions.js +214 -0
- package/dist/routes/extensions.js.map +1 -0
- package/dist/services/package-catalog.d.ts +84 -0
- package/dist/services/package-catalog.js +194 -0
- package/dist/services/package-catalog.js.map +1 -0
- package/dist/services/pm-runner.d.ts +65 -0
- package/dist/services/pm-runner.js +75 -46
- package/dist/services/pm-runner.js.map +1 -1
- package/manifest.json +1 -1
- package/package.json +5 -7
- package/public/index.html +4 -0
- package/public/src/app.js +7 -0
- package/public/src/app.js.map +1 -1
- package/public/src/app.ts +8 -0
- package/public/src/constants.js +1 -1
- package/public/src/constants.js.map +1 -1
- package/public/src/constants.ts +1 -1
- package/public/src/i18n/de.json +24 -1
- package/public/src/i18n/en.json +24 -1
- package/public/src/i18n/es.json +24 -1
- package/public/src/i18n/zh.json +25 -2
- package/public/src/sw.ts +1 -0
- package/public/src/views/packages.js +221 -0
- package/public/src/views/packages.js.map +1 -0
- package/public/src/views/packages.ts +238 -0
- package/public/src/views/router.js +5 -0
- package/public/src/views/router.js.map +1 -1
- package/public/src/views/router.ts +3 -0
- package/public/sw.js +1 -0
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
|
|
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":"AAAA,OAAO,OAAyB,MAAM,SAAS,CAAC;AAChD,OAAO,YAAY,MAAM,eAAe,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACjG,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC/D,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;AAE3D;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,cAAc;IACd,gBAAgB;IAChB,OAAO;IACP,iBAAiB;CACT,CAAC;AAEX,gFAAgF;AAChF,MAAM,CAAC,MAAM,eAAe,GAA2B;IACrD,YAAY,EAAE,eAAe;IAC7B,cAAc,EAAE,iBAAiB;IACjC,MAAM,EAAE,QAAQ;IAChB,UAAU,EAAE,kBAAkB;CAC/B,CAAC;AAEF,MAAM,UAAU,oBAAoB,CAAC,GAAG,GAAsB,OAAO,CAAC,GAAG;IACvE,MAAM,UAAU,GAAG,GAAG,CAAC,gBAAgB,EAAE,IAAI,EAAE,CAAC;IAChD,IAAI,CAAC,UAAU;QAAE,OAAO,UAAU,CAAC;IACnC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAChE,CAAC;IAED,MAAM,IAAI,GAAG,YAAY,CAAC,UAAU,CAAC,CAAC;IACtC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;IACnE,CAAC;IACD,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;QAC/B,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,IAAI,OAAO,CAAC,CAAC;QAClD,IAAI,CAAC;YACH,IAAI,SAAS,CAAC,SAAS,CAAC,CAAC,cAAc,EAAE,EAAE,CAAC;gBAC1C,MAAM,IAAI,KAAK,CAAC,yBAAyB,IAAI,oCAAoC,CAAC,CAAC;YACrF,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACvD,MAAM,IAAI,KAAK,CAAC,6CAA6C,IAAI,QAAQ,CAAC,CAAC;YAC7E,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;QACD,MAAM,QAAQ,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;QACzC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC;YAC/E,MAAM,IAAI,KAAK,CAAC,yBAAyB,IAAI,kDAAkD,CAAC,CAAC;QACnG,CAAC;QACD,UAAU,CAAC,QAAQ,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;IACvC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,SAAS;IACvB,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;IACtB,MAAM,aAAa,GAAG,oBAAoB,EAAE,CAAC;IAE7C,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;IACxC,GAAG,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC,CAAC;IAExB,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;QAC9B,GAAG,CAAC,SAAS,CAAC,eAAe,EAAE,uDAAuD,CAAC,CAAC;QACxF,GAAG,CAAC,SAAS,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;QACpC,GAAG,CAAC,SAAS,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;QAC9B,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,GAAG,CAAC,GAAG,CACL,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE;QACzB,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;KACzD,CAAC,CACH,CAAC;IAEF,mBAAmB;IACnB,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QAC1B,GAAG,CAAC,SAAS,CAAC,wBAAwB,EAAE,SAAS,CAAC,CAAC;QACnD,GAAG,CAAC,SAAS,CAAC,iBAAiB,EAAE,YAAY,CAAC,CAAC;QAC/C,GAAG,CAAC,SAAS,CAAC,iBAAiB,EAAE,iCAAiC,CAAC,CAAC;QACpE,IAAI,EAAE,CAAC;IACT,CAAC,CAAC,CAAC;IAEH,4EAA4E;IAC5E,+EAA+E;IAC/E,MAAM,cAAc,GAAG,CAAC,GAAG,EAAE;QAC3B,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CACpB,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,CAC5C,CAAC;YAC1B,OAAO,GAAG,CAAC,OAAO,IAAI,SAAS,CAAC;QAClC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,SAAS,CAAC;QACnB,CAAC;IACH,CAAC,CAAC,EAAE,CAAC;IACL,GAAG,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC;IAEpF,MAAM,UAAU,GAAG,IAAI,GAAG,CAAS,WAAW,CAAC,CAAC;IAEhD,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,EAAE;QACrD,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;YAC1B,GAAG,CAAC,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACxB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,GAAG,CAAC,GAAG,CAAC,CAAC,eAAe,EAAE,iBAAiB,EAAE,QAAQ,EAAE,kBAAkB,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QACvF,wEAAwE;QACxE,mEAAmE;QACnE,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACnD,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1B,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;YACtB,OAAO;QACT,CAAC;QACD,GAAG,CAAC,SAAS,CAAC,eAAe,EAAE,UAAU,CAAC,CAAC;QAC3C,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,GAAG,IAAI,OAAO,CAAC,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,aAAa;IACb,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;IACjC,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;IACjC,GAAG,CAAC,GAAG,CAAC,eAAe,EAAE,cAAc,CAAC,CAAC;IACzC,GAAG,CAAC,GAAG,CAAC,6BAA6B,EAAE,QAAQ,CAAC,CAAC;IACjD,GAAG,CAAC,GAAG,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;IACrC,GAAG,CAAC,GAAG,CAAC,0BAA0B,EAAE,YAAY,CAAC,CAAC;IAClD,GAAG,CAAC,GAAG,CAAC,aAAa,EAAE,kBAAkB,CAAC,CAAC;IAC3C,GAAG,CAAC,GAAG,CAAC,0BAA0B,EAAE,YAAY,CAAC,CAAC;IAClD,GAAG,CAAC,GAAG,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;IAEnC,0EAA0E;IAC1E,8DAA8D;IAC9D,GAAG,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;QACrC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,yDAAyD;IACzD,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;QACjC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
1
|
+
{"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAAA,OAAO,OAAyB,MAAM,SAAS,CAAC;AAChD,OAAO,YAAY,MAAM,eAAe,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACjG,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC/D,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;AAE3D;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,cAAc;IACd,gBAAgB;IAChB,OAAO;IACP,iBAAiB;CACT,CAAC;AAEX,gFAAgF;AAChF,MAAM,CAAC,MAAM,eAAe,GAA2B;IACrD,YAAY,EAAE,eAAe;IAC7B,cAAc,EAAE,iBAAiB;IACjC,MAAM,EAAE,QAAQ;IAChB,UAAU,EAAE,kBAAkB;CAC/B,CAAC;AAEF,MAAM,UAAU,oBAAoB,CAAC,GAAG,GAAsB,OAAO,CAAC,GAAG;IACvE,MAAM,UAAU,GAAG,GAAG,CAAC,gBAAgB,EAAE,IAAI,EAAE,CAAC;IAChD,IAAI,CAAC,UAAU;QAAE,OAAO,UAAU,CAAC;IACnC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAChE,CAAC;IAED,MAAM,IAAI,GAAG,YAAY,CAAC,UAAU,CAAC,CAAC;IACtC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;IACnE,CAAC;IACD,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;QAC/B,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,IAAI,OAAO,CAAC,CAAC;QAClD,IAAI,CAAC;YACH,IAAI,SAAS,CAAC,SAAS,CAAC,CAAC,cAAc,EAAE,EAAE,CAAC;gBAC1C,MAAM,IAAI,KAAK,CAAC,yBAAyB,IAAI,oCAAoC,CAAC,CAAC;YACrF,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACvD,MAAM,IAAI,KAAK,CAAC,6CAA6C,IAAI,QAAQ,CAAC,CAAC;YAC7E,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;QACD,MAAM,QAAQ,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;QACzC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC;YAC/E,MAAM,IAAI,KAAK,CAAC,yBAAyB,IAAI,kDAAkD,CAAC,CAAC;QACnG,CAAC;QACD,UAAU,CAAC,QAAQ,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;IACvC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,SAAS;IACvB,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;IACtB,MAAM,aAAa,GAAG,oBAAoB,EAAE,CAAC;IAE7C,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;IACxC,GAAG,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC,CAAC;IAExB,GAAG,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;QAC9B,GAAG,CAAC,SAAS,CAAC,eAAe,EAAE,uDAAuD,CAAC,CAAC;QACxF,GAAG,CAAC,SAAS,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;QACpC,GAAG,CAAC,SAAS,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;QAC9B,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,GAAG,CAAC,GAAG,CACL,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE;QACzB,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;KACzD,CAAC,CACH,CAAC;IAEF,mBAAmB;IACnB,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QAC1B,GAAG,CAAC,SAAS,CAAC,wBAAwB,EAAE,SAAS,CAAC,CAAC;QACnD,GAAG,CAAC,SAAS,CAAC,iBAAiB,EAAE,YAAY,CAAC,CAAC;QAC/C,GAAG,CAAC,SAAS,CAAC,iBAAiB,EAAE,iCAAiC,CAAC,CAAC;QACpE,IAAI,EAAE,CAAC;IACT,CAAC,CAAC,CAAC;IAEH,4EAA4E;IAC5E,+EAA+E;IAC/E,MAAM,cAAc,GAAG,CAAC,GAAG,EAAE;QAC3B,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CACpB,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,CAC5C,CAAC;YAC1B,OAAO,GAAG,CAAC,OAAO,IAAI,SAAS,CAAC;QAClC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,SAAS,CAAC;QACnB,CAAC;IACH,CAAC,CAAC,EAAE,CAAC;IACL,GAAG,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC;IAEpF,MAAM,UAAU,GAAG,IAAI,GAAG,CAAS,WAAW,CAAC,CAAC;IAEhD,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,EAAE;QACrD,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;YAC1B,GAAG,CAAC,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACxB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,GAAG,CAAC,GAAG,CAAC,CAAC,eAAe,EAAE,iBAAiB,EAAE,QAAQ,EAAE,kBAAkB,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QACvF,wEAAwE;QACxE,mEAAmE;QACnE,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACnD,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1B,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;YACtB,OAAO;QACT,CAAC;QACD,GAAG,CAAC,SAAS,CAAC,eAAe,EAAE,UAAU,CAAC,CAAC;QAC3C,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,GAAG,IAAI,OAAO,CAAC,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,aAAa;IACb,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;IACjC,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;IACjC,GAAG,CAAC,GAAG,CAAC,eAAe,EAAE,cAAc,CAAC,CAAC;IACzC,GAAG,CAAC,GAAG,CAAC,6BAA6B,EAAE,QAAQ,CAAC,CAAC;IACjD,GAAG,CAAC,GAAG,CAAC,qCAAqC,EAAE,gBAAgB,CAAC,CAAC;IACjE,GAAG,CAAC,GAAG,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;IACrC,GAAG,CAAC,GAAG,CAAC,0BAA0B,EAAE,YAAY,CAAC,CAAC;IAClD,GAAG,CAAC,GAAG,CAAC,aAAa,EAAE,kBAAkB,CAAC,CAAC;IAC3C,GAAG,CAAC,GAAG,CAAC,0BAA0B,EAAE,YAAY,CAAC,CAAC;IAClD,GAAG,CAAC,GAAG,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;IAEnC,0EAA0E;IAC1E,8DAA8D;IAC9D,GAAG,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;QACrC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,yDAAyD;IACzD,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;QACjC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,OAAO,GAAG,CAAC;AACb,CAAC"}
|
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.
|
|
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[];
|