@bevel-software/platform-core-backend 0.21.0 → 0.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (177) hide show
  1. package/dist/core/create-core-server.d.ts.map +1 -1
  2. package/dist/core/create-core-server.js +32 -2
  3. package/dist/core/create-core-server.js.map +1 -1
  4. package/dist/core/create-core-services.d.ts +13 -1
  5. package/dist/core/create-core-services.d.ts.map +1 -1
  6. package/dist/core/create-core-services.js +51 -5
  7. package/dist/core/create-core-services.js.map +1 -1
  8. package/dist/modules/access/access-requests.contract.d.ts +75 -0
  9. package/dist/modules/access/access-requests.contract.d.ts.map +1 -0
  10. package/dist/modules/access/access-requests.contract.js +20 -0
  11. package/dist/modules/access/access-requests.contract.js.map +1 -0
  12. package/dist/modules/access/access-requests.routes.d.ts +35 -0
  13. package/dist/modules/access/access-requests.routes.d.ts.map +1 -0
  14. package/dist/modules/access/access-requests.routes.js +237 -0
  15. package/dist/modules/access/access-requests.routes.js.map +1 -0
  16. package/dist/modules/access/access-requests.service.d.ts +123 -0
  17. package/dist/modules/access/access-requests.service.d.ts.map +1 -0
  18. package/dist/modules/access/access-requests.service.js +337 -0
  19. package/dist/modules/access/access-requests.service.js.map +1 -0
  20. package/dist/modules/access-model/access-grammar.d.ts +12 -0
  21. package/dist/modules/access-model/access-grammar.d.ts.map +1 -1
  22. package/dist/modules/access-model/access-grammar.js +24 -0
  23. package/dist/modules/access-model/access-grammar.js.map +1 -1
  24. package/dist/modules/auth/auth.service.d.ts +26 -1
  25. package/dist/modules/auth/auth.service.d.ts.map +1 -1
  26. package/dist/modules/auth/auth.service.js +11 -2
  27. package/dist/modules/auth/auth.service.js.map +1 -1
  28. package/dist/modules/github-app/github-app.client.d.ts +101 -0
  29. package/dist/modules/github-app/github-app.client.d.ts.map +1 -0
  30. package/dist/modules/github-app/github-app.client.js +222 -0
  31. package/dist/modules/github-app/github-app.client.js.map +1 -0
  32. package/dist/modules/github-app/github-app.connection.d.ts +102 -0
  33. package/dist/modules/github-app/github-app.connection.d.ts.map +1 -0
  34. package/dist/modules/github-app/github-app.connection.js +185 -0
  35. package/dist/modules/github-app/github-app.connection.js.map +1 -0
  36. package/dist/modules/github-app/github-app.routes.d.ts +59 -0
  37. package/dist/modules/github-app/github-app.routes.d.ts.map +1 -0
  38. package/dist/modules/github-app/github-app.routes.js +323 -0
  39. package/dist/modules/github-app/github-app.routes.js.map +1 -0
  40. package/dist/modules/github-app/index.d.ts +4 -0
  41. package/dist/modules/github-app/index.d.ts.map +1 -0
  42. package/dist/modules/github-app/index.js +4 -0
  43. package/dist/modules/github-app/index.js.map +1 -0
  44. package/dist/modules/kb-fs/remote-url.d.ts +22 -0
  45. package/dist/modules/kb-fs/remote-url.d.ts.map +1 -0
  46. package/dist/modules/kb-fs/remote-url.js +35 -0
  47. package/dist/modules/kb-fs/remote-url.js.map +1 -0
  48. package/dist/modules/plugins/join-proposals.d.ts +17 -5
  49. package/dist/modules/plugins/join-proposals.d.ts.map +1 -1
  50. package/dist/modules/plugins/join-proposals.js +76 -22
  51. package/dist/modules/plugins/join-proposals.js.map +1 -1
  52. package/dist/modules/plugins/join-requests.service.d.ts +111 -18
  53. package/dist/modules/plugins/join-requests.service.d.ts.map +1 -1
  54. package/dist/modules/plugins/join-requests.service.js +173 -29
  55. package/dist/modules/plugins/join-requests.service.js.map +1 -1
  56. package/dist/modules/plugins/plugins.routes.d.ts.map +1 -1
  57. package/dist/modules/plugins/plugins.routes.js +3 -2
  58. package/dist/modules/plugins/plugins.routes.js.map +1 -1
  59. package/dist/modules/settings/deployment-settings.service.d.ts +22 -1
  60. package/dist/modules/settings/deployment-settings.service.d.ts.map +1 -1
  61. package/dist/modules/settings/deployment-settings.service.js +93 -4
  62. package/dist/modules/settings/deployment-settings.service.js.map +1 -1
  63. package/dist/modules/settings/managed-repository.d.ts +43 -0
  64. package/dist/modules/settings/managed-repository.d.ts.map +1 -0
  65. package/dist/modules/settings/managed-repository.js +60 -0
  66. package/dist/modules/settings/managed-repository.js.map +1 -0
  67. package/dist/modules/settings/repository-source.d.ts +128 -0
  68. package/dist/modules/settings/repository-source.d.ts.map +1 -0
  69. package/dist/modules/settings/repository-source.js +150 -0
  70. package/dist/modules/settings/repository-source.js.map +1 -0
  71. package/dist/modules/settings/setup.routes.d.ts +27 -4
  72. package/dist/modules/settings/setup.routes.d.ts.map +1 -1
  73. package/dist/modules/settings/setup.routes.js +187 -13
  74. package/dist/modules/settings/setup.routes.js.map +1 -1
  75. package/dist/modules/skills/skill-access-requests.routes.d.ts +6 -8
  76. package/dist/modules/skills/skill-access-requests.routes.d.ts.map +1 -1
  77. package/dist/modules/skills/skill-access-requests.routes.js +24 -63
  78. package/dist/modules/skills/skill-access-requests.routes.js.map +1 -1
  79. package/dist/modules/tool-helpers/tool-context.d.ts.map +1 -1
  80. package/dist/modules/tool-helpers/tool-context.js +15 -0
  81. package/dist/modules/tool-helpers/tool-context.js.map +1 -1
  82. package/dist/modules/workflow/agent-tools/workflow.tools.d.ts.map +1 -1
  83. package/dist/modules/workflow/agent-tools/workflow.tools.js +38 -2
  84. package/dist/modules/workflow/agent-tools/workflow.tools.js.map +1 -1
  85. package/dist/modules/workflow/git/git.service.d.ts +3 -1
  86. package/dist/modules/workflow/git/git.service.d.ts.map +1 -1
  87. package/dist/modules/workflow/git/git.service.js +17 -4
  88. package/dist/modules/workflow/git/git.service.js.map +1 -1
  89. package/dist/modules/workflow/git/node-git-runner.d.ts.map +1 -1
  90. package/dist/modules/workflow/git/node-git-runner.js +5 -0
  91. package/dist/modules/workflow/git/node-git-runner.js.map +1 -1
  92. package/dist/modules/workflow/git/pull-request.service.d.ts +45 -0
  93. package/dist/modules/workflow/git/pull-request.service.d.ts.map +1 -1
  94. package/dist/modules/workflow/git/pull-request.service.js +99 -0
  95. package/dist/modules/workflow/git/pull-request.service.js.map +1 -1
  96. package/dist/modules/workflow/workflow.routes.d.ts.map +1 -1
  97. package/dist/modules/workflow/workflow.routes.js +3 -1
  98. package/dist/modules/workflow/workflow.routes.js.map +1 -1
  99. package/dist/modules/workflow/workflow.service.d.ts +34 -7
  100. package/dist/modules/workflow/workflow.service.d.ts.map +1 -1
  101. package/dist/modules/workflow/workflow.service.js +148 -48
  102. package/dist/modules/workflow/workflow.service.js.map +1 -1
  103. package/dist/modules/workspace/startup/kb-startup-runner.d.ts +66 -0
  104. package/dist/modules/workspace/startup/kb-startup-runner.d.ts.map +1 -1
  105. package/dist/modules/workspace/startup/kb-startup-runner.js +148 -0
  106. package/dist/modules/workspace/startup/kb-startup-runner.js.map +1 -1
  107. package/dist/modules/workspace/workspace.service.d.ts.map +1 -1
  108. package/dist/modules/workspace/workspace.service.js +17 -1
  109. package/dist/modules/workspace/workspace.service.js.map +1 -1
  110. package/dist/modules/workspace/workspace.tools.d.ts.map +1 -1
  111. package/dist/modules/workspace/workspace.tools.js +28 -2
  112. package/dist/modules/workspace/workspace.tools.js.map +1 -1
  113. package/dist/shared/domain-errors.d.ts +39 -0
  114. package/dist/shared/domain-errors.d.ts.map +1 -1
  115. package/dist/shared/domain-errors.js +55 -0
  116. package/dist/shared/domain-errors.js.map +1 -1
  117. package/dist/shared/git.contract.d.ts +10 -0
  118. package/dist/shared/git.contract.d.ts.map +1 -1
  119. package/dist/shared/git.contract.js.map +1 -1
  120. package/package.json +3 -3
  121. package/src/core/create-core-server.ts +37 -1
  122. package/src/core/create-core-services.ts +65 -8
  123. package/src/modules/access/__tests__/access-requests.recut.test.ts +134 -0
  124. package/src/modules/access/__tests__/access-requests.routes.test.ts +610 -0
  125. package/src/modules/access/access-requests.contract.ts +93 -0
  126. package/src/modules/access/access-requests.routes.ts +286 -0
  127. package/src/modules/access/access-requests.service.ts +420 -0
  128. package/src/modules/access-model/access-grammar.ts +22 -0
  129. package/src/modules/auth/__tests__/auth.service.test.ts +38 -0
  130. package/src/modules/auth/auth.service.ts +28 -1
  131. package/src/modules/github-app/__tests__/github-app.test.ts +848 -0
  132. package/src/modules/github-app/github-app.client.ts +268 -0
  133. package/src/modules/github-app/github-app.connection.ts +204 -0
  134. package/src/modules/github-app/github-app.routes.ts +359 -0
  135. package/src/modules/github-app/index.ts +19 -0
  136. package/src/modules/kb-fs/__tests__/remote-url.test.ts +38 -0
  137. package/src/modules/kb-fs/remote-url.ts +35 -0
  138. package/src/modules/plugins/__tests__/join-proposals.test.ts +100 -19
  139. package/src/modules/plugins/__tests__/join-requests.service.test.ts +27 -11
  140. package/src/modules/plugins/__tests__/join-requests.settlement.test.ts +371 -0
  141. package/src/modules/plugins/__tests__/plugins.routes.test.ts +1 -1
  142. package/src/modules/plugins/join-proposals.ts +87 -19
  143. package/src/modules/plugins/join-requests.service.ts +199 -39
  144. package/src/modules/plugins/plugins.routes.ts +3 -2
  145. package/src/modules/settings/__tests__/repository-source.test.ts +191 -0
  146. package/src/modules/settings/__tests__/setup.routes.git-mode.test.ts +353 -0
  147. package/src/modules/settings/__tests__/setup.routes.github-app.test.ts +282 -0
  148. package/src/modules/settings/__tests__/setup.routes.managed-phase.test.ts +233 -0
  149. package/src/modules/settings/deployment-settings.service.ts +109 -3
  150. package/src/modules/settings/managed-repository.ts +68 -0
  151. package/src/modules/settings/repository-source.ts +197 -0
  152. package/src/modules/settings/setup.routes.ts +214 -10
  153. package/src/modules/skills/__tests__/skill-access-requests.routes.test.ts +5 -1
  154. package/src/modules/skills/skill-access-requests.routes.ts +25 -75
  155. package/src/modules/tool-helpers/tool-context.ts +15 -0
  156. package/src/modules/workflow/__tests__/apply-failure.test.ts +9 -1
  157. package/src/modules/workflow/__tests__/workflow.service.facade.test.ts +159 -8
  158. package/src/modules/workflow/__tests__/workflow.service.update-from-target.test.ts +146 -40
  159. package/src/modules/workflow/agent-tools/__tests__/workflow.tools.test.ts +141 -1
  160. package/src/modules/workflow/agent-tools/workflow.tools.ts +49 -3
  161. package/src/modules/workflow/git/__tests__/git.service.pull.test.ts +121 -0
  162. package/src/modules/workflow/git/__tests__/pull-request.service.getPrDetail.test.ts +145 -2
  163. package/src/modules/workflow/git/__tests__/pull-request.service.viewer-can-delete.test.ts +166 -0
  164. package/src/modules/workflow/git/git.service.ts +25 -4
  165. package/src/modules/workflow/git/node-git-runner.ts +6 -0
  166. package/src/modules/workflow/git/pull-request.service.ts +119 -0
  167. package/src/modules/workflow/workflow.routes.ts +3 -1
  168. package/src/modules/workflow/workflow.service.ts +170 -52
  169. package/src/modules/workspace/__tests__/workspace.service.unknown-branch.test.ts +43 -0
  170. package/src/modules/workspace/__tests__/workspace.tools.branch-errors.test.ts +233 -7
  171. package/src/modules/workspace/__tests__/workspace.tools.test.ts +35 -3
  172. package/src/modules/workspace/startup/__tests__/kb-startup-runner.test.ts +211 -0
  173. package/src/modules/workspace/startup/kb-startup-runner.ts +159 -0
  174. package/src/modules/workspace/workspace.service.ts +17 -1
  175. package/src/modules/workspace/workspace.tools.ts +35 -0
  176. package/src/shared/domain-errors.ts +58 -0
  177. package/src/shared/git.contract.ts +10 -0
@@ -0,0 +1,237 @@
1
+ import express from 'express';
2
+ import { logger } from '../../shared/logging.js';
3
+ import { branchForWorkspaceId } from '../../shared/workspace-id.js';
4
+ import { AccessMutationError, AccessMutationService, fileCarriesAccessRules, governingFolderOf, } from './access-mutation.service.js';
5
+ import { toHttpError as sharedToHttpError } from './admin-route-helpers.js';
6
+ import { isRequestLevel, rulesFileFor, REQUEST_NOTE_MAX, } from './access-requests.contract.js';
7
+ import { AccessRequestsService, extractRequestNote, itemNameOf, } from './access-requests.service.js';
8
+ import '../auth/auth.middleware.js'; // Express Request.userId augmentation
9
+ const log = logger('access.request');
10
+ /**
11
+ * Asking for Can edit or Owner on one item, and the editors' answer.
12
+ *
13
+ * POST /api/workspace/:id/access/request → { ok, number, state, level }
14
+ * GET /api/workspace/:id/access/request?path=&kind= → { state, level?, number? }
15
+ * GET /api/workspace/:id/access/requests?path=&kind= → { requests } (editors)
16
+ * POST /api/workspace/:id/access/requests/:n/reconcile → { closed }
17
+ *
18
+ * LIVE WORKSPACE ONLY. A draft branch's rules may differ from the ones the
19
+ * person is asking about, and a request opened against a draft would propose a
20
+ * grant into a branch nobody merges — so every route here refuses any
21
+ * workspace but the default one, rather than quietly retargeting.
22
+ *
23
+ * Fail-closed like the rest of the access family: an item the caller cannot
24
+ * read answers as unknown, and the editors' listing answers `[]` to everyone
25
+ * else rather than 403 — "am I an editor here" stays a question only the
26
+ * server answers.
27
+ */
28
+ export function createAccessRequestRoutes(deps) {
29
+ const { accessControl, workspaceService, authService, workflow, lifecycle, kb } = deps;
30
+ const { kbDirName } = kb;
31
+ const router = express.Router({ mergeParams: true });
32
+ const mutation = new AccessMutationService(workspaceService, accessControl, kbDirName);
33
+ const requests = new AccessRequestsService({ workflow, workspaceService, lifecycle, kb });
34
+ async function requireUser(req, res) {
35
+ if (!req.userId) {
36
+ res.status(401).json({ error: 'Unauthenticated' });
37
+ return null;
38
+ }
39
+ const user = await authService.getUserById(req.userId);
40
+ if (!user) {
41
+ res.status(401).json({ error: 'User not found' });
42
+ return null;
43
+ }
44
+ return user;
45
+ }
46
+ /** Workspace-relative (what the dialog holds) → repo-relative (what the model speaks). */
47
+ function toRepoRelative(p) {
48
+ const prefix = `${kbDirName}/`;
49
+ if (p === kbDirName)
50
+ return '';
51
+ return p.startsWith(prefix) ? p.slice(prefix.length) : p;
52
+ }
53
+ /**
54
+ * Refuse a target that could escape the KB repo, or that is spelled in more
55
+ * than one way. Mirrors the grant route's guard — the branch name and the
56
+ * spliced path are both derived from this string, so two spellings of one
57
+ * item would be two different requests.
58
+ */
59
+ function assertSafeTarget(repoRelTarget, kind) {
60
+ if (kind === 'file' && !repoRelTarget) {
61
+ throw new AccessMutationError('file path is required');
62
+ }
63
+ if (repoRelTarget.startsWith('/') ||
64
+ repoRelTarget.includes('\\') ||
65
+ repoRelTarget.includes('\0') ||
66
+ repoRelTarget.split('/').some((s) => s === '..' || s === '.')) {
67
+ throw new AccessMutationError('path must stay inside the KB repo');
68
+ }
69
+ }
70
+ /**
71
+ * The (live workspace, readable item) pair every route here needs, or null
72
+ * after the refusal has been answered.
73
+ *
74
+ * The two refusals are deliberately different shapes: a non-default
75
+ * workspace is the CALLER asking the wrong question (400), while an item the
76
+ * caller cannot read answers exactly as one that does not exist (404) — a
77
+ * 403 would confirm the item is there.
78
+ */
79
+ async function resolveTarget(req, res, rawPath, rawKind) {
80
+ const user = await requireUser(req, res);
81
+ if (!user)
82
+ return null;
83
+ const wsId = kb.defaultWorkspaceId();
84
+ if (branchForWorkspaceId(String(req.params.id)) !== kb.defaultBranch) {
85
+ res.status(400).json({
86
+ error: 'Access requests are only made on the live workspace.',
87
+ kind: 'not-live-workspace',
88
+ });
89
+ return null;
90
+ }
91
+ if (typeof rawPath !== 'string') {
92
+ res.status(400).json({ error: 'path is required', kind: 'access-error' });
93
+ return null;
94
+ }
95
+ const kind = rawKind === 'folder' ? 'folder' : 'file';
96
+ const target = { path: toRepoRelative(rawPath), kind };
97
+ try {
98
+ assertSafeTarget(target.path, kind);
99
+ }
100
+ catch (err) {
101
+ const { status, body } = sharedToHttpError(err, 'access');
102
+ res.status(status).json(body);
103
+ return null;
104
+ }
105
+ if (!(await accessControl.canRead(wsId, user.email, target.path))) {
106
+ res.status(404).json({ error: 'Not found', kind: 'unknown-target' });
107
+ return null;
108
+ }
109
+ return { user, target, wsId };
110
+ }
111
+ /** Can the caller change this item's rules — the gate an Accept runs through. */
112
+ const isEditor = (wsId, email, target) => accessControl.canWrite(wsId, email, rulesFileFor(target));
113
+ /**
114
+ * A FILE that cannot hold rules of its own is governed by its folder, and
115
+ * there is nothing here to request. The dialog already points at the folder
116
+ * for these; the route says the same thing rather than splicing YAML into a
117
+ * PDF. Content counts as much as the name — bytes that are not text refuse
118
+ * too, exactly as the grant route refuses them.
119
+ */
120
+ async function assertCanCarryRules(wsId, target) {
121
+ if (target.kind !== 'file')
122
+ return;
123
+ if (fileCarriesAccessRules(target.path) && (await mutation.targetHoldsText(wsId, target.path))) {
124
+ return;
125
+ }
126
+ throw new AccessMutationError(`Access for this file is managed on its folder. Ask there instead.`, 409, { kind: 'folder-governs', folder: governingFolderOf(target.path) });
127
+ }
128
+ router.post('/workspace/:id/access/request', async (req, res) => {
129
+ const body = (req.body ?? {});
130
+ const ctx = await resolveTarget(req, res, body.path, body.kind);
131
+ if (!ctx)
132
+ return;
133
+ const { user, target, wsId } = ctx;
134
+ try {
135
+ if (!isRequestLevel(body.level)) {
136
+ throw new AccessMutationError('level must be "write" or "owner"');
137
+ }
138
+ const note = typeof body.note === 'string' ? body.note : '';
139
+ if (typeof body.note !== 'undefined' && typeof body.note !== 'string') {
140
+ throw new AccessMutationError('note must be text');
141
+ }
142
+ if (note.length > REQUEST_NOTE_MAX) {
143
+ throw new AccessMutationError(`A note can be at most ${REQUEST_NOTE_MAX} characters.`);
144
+ }
145
+ await assertCanCarryRules(wsId, target);
146
+ if (await isEditor(wsId, user.email, target)) {
147
+ throw new AccessMutationError(`You can already change who can use this ${target.kind}.`, 409, { kind: 'already-writable' });
148
+ }
149
+ const opened = await requests.open({
150
+ user,
151
+ target,
152
+ itemName: itemNameOf(target.path),
153
+ level: body.level,
154
+ note,
155
+ });
156
+ res.json({ ok: true, state: 'pending', number: opened.number, level: opened.level });
157
+ }
158
+ catch (err) {
159
+ const { status, body: errBody } = sharedToHttpError(err, 'access');
160
+ if (status >= 500)
161
+ log.error('failed to open an access request:', { err });
162
+ res.status(status).json(errBody);
163
+ }
164
+ });
165
+ router.get('/workspace/:id/access/request', async (req, res) => {
166
+ const ctx = await resolveTarget(req, res, req.query.path, req.query.kind);
167
+ if (!ctx)
168
+ return;
169
+ try {
170
+ res.json(await requests.status(ctx.user, ctx.target));
171
+ }
172
+ catch (err) {
173
+ log.error('failed to read an access request:', { err });
174
+ res.status(500).json({ error: 'Failed to read the request' });
175
+ }
176
+ });
177
+ router.get('/workspace/:id/access/requests', async (req, res) => {
178
+ const ctx = await resolveTarget(req, res, req.query.path, req.query.kind);
179
+ if (!ctx)
180
+ return;
181
+ const { user, target, wsId } = ctx;
182
+ try {
183
+ if (!(await isEditor(wsId, user.email, target))) {
184
+ res.json({ requests: [] });
185
+ return;
186
+ }
187
+ const crs = await workflow.listChangeRequests();
188
+ const rows = await lifecycle.list(target.path, target, crs, user);
189
+ // The note lives in the request's description and nowhere else, so it
190
+ // is read back per request. Bounded by the open requests on ONE item —
191
+ // a handful at most — and a detail that cannot be fetched costs the
192
+ // note, never the line it belongs to.
193
+ const withNotes = await Promise.all(rows.map(async (row) => {
194
+ const detail = await workflow
195
+ .getChangeRequestDetail(row.number, { patches: false })
196
+ .catch(() => null);
197
+ const note = extractRequestNote(detail?.body);
198
+ return note ? { ...row, note } : row;
199
+ }));
200
+ res.json({ requests: withNotes });
201
+ }
202
+ catch (err) {
203
+ log.error('failed to list access requests:', { err });
204
+ res.status(500).json({ error: 'Failed to list access requests' });
205
+ }
206
+ });
207
+ router.post('/workspace/:id/access/requests/:number/reconcile', async (req, res) => {
208
+ const body = (req.body ?? {});
209
+ const ctx = await resolveTarget(req, res, body.path, body.kind);
210
+ if (!ctx)
211
+ return;
212
+ const { user, target, wsId } = ctx;
213
+ try {
214
+ if (!(await isEditor(wsId, user.email, target))) {
215
+ res.status(404).json({ error: 'Not found' });
216
+ return;
217
+ }
218
+ const number = Number(req.params.number);
219
+ if (!Number.isSafeInteger(number) || number <= 0) {
220
+ res.status(400).json({ error: 'Invalid change request number' });
221
+ return;
222
+ }
223
+ const cr = await workflow.getChangeRequest(number);
224
+ if (!cr) {
225
+ res.status(404).json({ error: 'Not found' });
226
+ return;
227
+ }
228
+ res.json({ closed: await lifecycle.reconcile(target.path, target, cr, user) });
229
+ }
230
+ catch (err) {
231
+ log.error('failed to reconcile an access request:', { err });
232
+ res.status(500).json({ error: 'Failed to reconcile the request' });
233
+ }
234
+ });
235
+ return router;
236
+ }
237
+ //# sourceMappingURL=access-requests.routes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"access-requests.routes.js","sourceRoot":"","sources":["../../../src/modules/access/access-requests.routes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,123 @@
1
+ import { type AuthUser, type IWorkflowService } from '@bevel-software/platform-shared';
2
+ import type { KbContext } from '../../shared/kb-context.js';
3
+ import type { WorkspaceService } from '../workspace/workspace.service.js';
4
+ import { type AccessRequestTarget, type IAccessRequestLifecycle, type RequestLevel } from './access-requests.contract.js';
5
+ export declare const LEVEL_LABEL: Record<RequestLevel, string>;
6
+ /** What the requester's own dialog shows in place of the control. */
7
+ export interface AccessRequestStatus {
8
+ /**
9
+ * - `none` nothing outstanding; show the control.
10
+ * - `pending` a request is open and still asking for something.
11
+ * - `not-accepted` their last request closed without the access landing.
12
+ */
13
+ state: 'none' | 'pending' | 'not-accepted';
14
+ level?: RequestLevel;
15
+ number?: number;
16
+ }
17
+ /** The name an item is called by in a title — the last path segment. */
18
+ export declare function itemNameOf(repoRelPath: string): string;
19
+ /**
20
+ * Neutralise every character a markdown renderer would read as structure.
21
+ *
22
+ * The note is somebody's free text and it lands in a change request's
23
+ * description, which IS rendered. Escaping it is what makes "plain text" true:
24
+ * without this a note can carry a heading, a link, or an image pointing at a
25
+ * URL that logs whoever opens the request.
26
+ */
27
+ export declare function escapeMarkdown(text: string): string;
28
+ /**
29
+ * The requester's own words, back out of a request's description, or
30
+ * undefined when they wrote none. Unescaped exactly as they were escaped, so
31
+ * what the banner shows is what was typed.
32
+ */
33
+ /**
34
+ * The level a request asks for, off its own description. Undefined for a
35
+ * request opened before this marker existed — those are the skill route's,
36
+ * and the skill route only ever asked for `write`.
37
+ */
38
+ export declare function extractRequestLevel(body: string | null | undefined): RequestLevel | undefined;
39
+ export declare function extractRequestNote(body: string | null | undefined): string | undefined;
40
+ /**
41
+ * Asking for Can edit or Owner on ONE item, and reading back what came of it.
42
+ *
43
+ * A request is a change request whose branch proposes exactly one grant in the
44
+ * item's own rules — a folder's `access.md`, or a file's own frontmatter — and
45
+ * nothing else. There is no request table: the branch IS the request, named
46
+ * deterministically from (person, item), so a second click finds the first
47
+ * click's request instead of opening a rival. Editors answer it by granting
48
+ * through the ordinary access path, and it retires itself
49
+ * ({@link IAccessRequestLifecycle}) once the access has landed however it
50
+ * landed.
51
+ *
52
+ * Keyed on the ITEM'S PATH, which is what the skill page's "Request write
53
+ * access" keys on too — so a Can edit request on a skill's folder and that
54
+ * button open one request, shown on both surfaces.
55
+ */
56
+ export declare class AccessRequestsService {
57
+ private readonly deps;
58
+ constructor(deps: {
59
+ workflow: IWorkflowService;
60
+ workspaceService: WorkspaceService;
61
+ lifecycle: IAccessRequestLifecycle;
62
+ kb: Pick<KbContext, 'defaultBranch' | 'defaultWorkspaceId' | 'kbDirName'>;
63
+ });
64
+ /** The branch a request from `email` about `target` always lives on. */
65
+ branchFor(email: string, target: AccessRequestTarget): string;
66
+ /**
67
+ * Open `user`'s request for `level` on `target`, or answer with the one they
68
+ * already have open. Never opens a second request for the same pair.
69
+ */
70
+ open(input: {
71
+ user: AuthUser;
72
+ target: AccessRequestTarget;
73
+ itemName: string;
74
+ level: RequestLevel;
75
+ note?: string;
76
+ }): Promise<{
77
+ number: number;
78
+ level: RequestLevel;
79
+ }>;
80
+ /**
81
+ * What `user`'s dialog should say about `target`.
82
+ *
83
+ * The two states are answered from DIFFERENT sources, because different
84
+ * things prove them:
85
+ *
86
+ * pending an open request on this branch. That is the whole proof,
87
+ * and the level comes off the request itself — asking the
88
+ * branch would make "Requested: …" depend on whether this
89
+ * clone has fetched a ref that may be seconds old.
90
+ * not-accepted a closed request AND a branch that still carries an unmet
91
+ * proposal naming this person. A settled request has no
92
+ * branch left, so an accepted one can never read as
93
+ * declined; a branch that cannot be read proves nothing and
94
+ * reads as `none`, which shows the control rather than
95
+ * claiming a refusal nobody made.
96
+ */
97
+ status(user: AuthUser, target: AccessRequestTarget): Promise<AccessRequestStatus>;
98
+ /**
99
+ * The level change request `number` asks for, off its own description.
100
+ *
101
+ * `write` when the description does not say: every request that predates the
102
+ * marker came from the skill page's "Request write access", which asks for
103
+ * exactly that. A detail that cannot be fetched falls there too — the line
104
+ * it feeds says which level was asked for, and Can edit is the lesser claim.
105
+ */
106
+ private levelOf;
107
+ /**
108
+ * The level `email`'s branch still asks for on `target`, or null when it
109
+ * asks for nothing they do not already hold. Owner wins when a branch
110
+ * somehow carries both — it is the larger of the two, and it is the one the
111
+ * person is still waiting on.
112
+ */
113
+ private levelAskedOn;
114
+ /**
115
+ * The live rules text to splice onto. A folder with no `access.md` yet is
116
+ * normal and reads as empty; a FILE that is not there is not — a request
117
+ * must not conjure the file it asks about.
118
+ */
119
+ private readLive;
120
+ /** The description an editor reads: who, what, where, the note, and how to answer. */
121
+ private describe;
122
+ }
123
+ //# sourceMappingURL=access-requests.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"access-requests.service.d.ts","sourceRoot":"","sources":["../../../src/modules/access/access-requests.service.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,QAAQ,EACb,KAAK,gBAAgB,EACtB,MAAM,iCAAiC,CAAC;AAMzC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAE5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAG1E,OAAO,EAEL,KAAK,mBAAmB,EACxB,KAAK,uBAAuB,EAC5B,KAAK,YAAY,EAClB,MAAM,+BAA+B,CAAC;AAKvC,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,CAGpD,CAAC;AAEF,qEAAqE;AACrE,MAAM,WAAW,mBAAmB;IAClC;;;;OAIG;IACH,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,cAAc,CAAC;IAC3C,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wEAAwE;AACxE,wBAAgB,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAGtD;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD;AA6BD;;;;GAIG;AACH;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,YAAY,GAAG,SAAS,CAG7F;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CActF;AAED;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,qBAAqB;IAE9B,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAAJ,IAAI,EAAE;QACrB,QAAQ,EAAE,gBAAgB,CAAC;QAC3B,gBAAgB,EAAE,gBAAgB,CAAC;QACnC,SAAS,EAAE,uBAAuB,CAAC;QACnC,EAAE,EAAE,IAAI,CAAC,SAAS,EAAE,eAAe,GAAG,oBAAoB,GAAG,WAAW,CAAC,CAAC;KAC3E;IAGH,wEAAwE;IACxE,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,mBAAmB,GAAG,MAAM;IAI7D;;;OAGG;IACG,IAAI,CAAC,KAAK,EAAE;QAChB,IAAI,EAAE,QAAQ,CAAC;QACf,MAAM,EAAE,mBAAmB,CAAC;QAC5B,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,YAAY,CAAC;QACpB,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,YAAY,CAAA;KAAE,CAAC;IA0IpD;;;;;;;;;;;;;;;;OAgBG;IACG,MAAM,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAiBvF;;;;;;;OAOG;YACW,OAAO;IAOrB;;;;;OAKG;YACW,YAAY;IAkB1B;;;;OAIG;YACW,QAAQ;IAgBtB,sFAAsF;IACtF,OAAO,CAAC,QAAQ;CA0BjB"}