@undefineds.co/linx 0.2.12 → 0.2.14
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/dist/lib/chat-api.js +31 -4
- package/dist/lib/chat-api.js.map +1 -1
- package/dist/lib/pi-adapter/interactive.js +37 -0
- package/dist/lib/pi-adapter/interactive.js.map +1 -1
- package/dist/lib/pi-adapter/pod-mirror.js +34 -90
- package/dist/lib/pi-adapter/pod-mirror.js.map +1 -1
- package/dist/lib/pi-adapter/pod-native.js +63 -8
- package/dist/lib/pi-adapter/pod-native.js.map +1 -1
- package/dist/lib/pi-adapter/runtime.js +22 -2
- package/dist/lib/pi-adapter/runtime.js.map +1 -1
- package/dist/lib/pi-adapter/session.js +163 -49
- package/dist/lib/pi-adapter/session.js.map +1 -1
- package/dist/lib/pi-adapter/stream.js +80 -3
- package/dist/lib/pi-adapter/stream.js.map +1 -1
- package/dist/lib/pod-data-session.js +70 -0
- package/dist/lib/pod-data-session.js.map +1 -0
- package/dist/lib/profile-identity.js +14 -58
- package/dist/lib/profile-identity.js.map +1 -1
- package/dist/lib/watch/pod-ai.js +16 -33
- package/dist/lib/watch/pod-ai.js.map +1 -1
- package/dist/lib/watch/pod-approval.js +221 -269
- package/dist/lib/watch/pod-approval.js.map +1 -1
- package/dist/lib/watch/pod-persistence.js +22 -36
- package/dist/lib/watch/pod-persistence.js.map +1 -1
- package/package.json +2 -2
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
import { setTimeout as delay } from 'node:timers/promises';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { getDefaultPodDataSession } from '../pod-data-session.js';
|
|
3
|
+
import { AS, ODRL, UDFS } from '@undefineds.co/models/namespaces';
|
|
4
|
+
import { ApprovalVocab, AuditVocab, GrantVocab, InboxNotificationVocab } from '@undefineds.co/models/vocab/sidecar';
|
|
5
|
+
import { buildApprovalDocumentUrl, RDF_TYPE, buildApprovalResourceUrl, buildAuditDocumentUrl, buildAuditResourceUrl, buildGrantResourceUrl, buildInboxResourceUrl, firstIri, firstLiteral, iri, listTurtleResources, listTurtleResourcesRecursive, literal, parseManagedTurtleBlocks, readTurtleResource, subjectIdFromResourceUrl, upsertManagedTurtleBlock, } from '../pi-adapter/pod-native.js';
|
|
4
6
|
const WATCH_CHAT_ID = 'linx-watch';
|
|
5
7
|
const WATCH_AGENT_ID = 'linx-watch-assistant';
|
|
6
8
|
const REMOTE_APPROVAL_POLICY_VERSION = 'linx-watch-remote-approval/v1';
|
|
7
9
|
const DEFAULT_REMOTE_APPROVAL_POLL_MS = 1000;
|
|
10
|
+
const remoteApprovalClientCache = new WeakMap();
|
|
8
11
|
function createAbortError() {
|
|
9
12
|
const error = new Error('The operation was aborted.');
|
|
10
13
|
error.name = 'AbortError';
|
|
11
14
|
return error;
|
|
12
15
|
}
|
|
13
|
-
async function dynamicImport(specifier) {
|
|
14
|
-
const loader = new Function('modulePath', 'return import(modulePath)');
|
|
15
|
-
return loader(specifier);
|
|
16
|
-
}
|
|
17
16
|
function normalizeString(value) {
|
|
18
17
|
return typeof value === 'string' && value.trim() ? value.trim() : undefined;
|
|
19
18
|
}
|
|
@@ -43,10 +42,16 @@ function buildThreadUri(webId, threadId) {
|
|
|
43
42
|
return `${getPodBaseUrl(webId)}/.data/chat/${WATCH_CHAT_ID}/index.ttl#${threadId}`;
|
|
44
43
|
}
|
|
45
44
|
function buildApprovalUri(webIdOrUri, approvalId) {
|
|
46
|
-
return
|
|
45
|
+
return buildApprovalResourceUrl(webIdOrUri, approvalId);
|
|
46
|
+
}
|
|
47
|
+
function buildApprovalUriForDate(webIdOrUri, approvalId, createdAt) {
|
|
48
|
+
return buildApprovalResourceUrl(webIdOrUri, approvalId, createdAt);
|
|
47
49
|
}
|
|
48
50
|
function buildGrantUri(webIdOrUri, grantId) {
|
|
49
|
-
return
|
|
51
|
+
return buildGrantResourceUrl(webIdOrUri, grantId);
|
|
52
|
+
}
|
|
53
|
+
function buildGrantDocumentUrl(webIdOrUri) {
|
|
54
|
+
return `${getPodBaseUrl(webIdOrUri)}/settings/autonomy/grants.ttl`;
|
|
50
55
|
}
|
|
51
56
|
function buildAgentUri(webId) {
|
|
52
57
|
return `${getPodBaseUrl(webId)}/.data/agents/${WATCH_AGENT_ID}.ttl`;
|
|
@@ -105,16 +110,6 @@ function buildRequestMessage(request) {
|
|
|
105
110
|
}
|
|
106
111
|
return request.message;
|
|
107
112
|
}
|
|
108
|
-
function buildRequestAuditContext(record, request) {
|
|
109
|
-
return {
|
|
110
|
-
kind: request.kind,
|
|
111
|
-
message: buildRequestMessage(request),
|
|
112
|
-
...(request.kind === 'command-approval' && request.command ? { command: request.command } : {}),
|
|
113
|
-
...(request.kind === 'command-approval' && request.cwd ? { cwd: request.cwd } : {}),
|
|
114
|
-
backend: record.backend,
|
|
115
|
-
sessionId: record.id,
|
|
116
|
-
};
|
|
117
|
-
}
|
|
118
113
|
function extractToolCallId(request) {
|
|
119
114
|
if (!isRecord(request.raw)) {
|
|
120
115
|
return crypto.randomUUID();
|
|
@@ -126,7 +121,7 @@ function extractToolCallId(request) {
|
|
|
126
121
|
?? crypto.randomUUID();
|
|
127
122
|
}
|
|
128
123
|
function encodeDecisionReason(decision, note) {
|
|
129
|
-
return
|
|
124
|
+
return safeJsonStringify({
|
|
130
125
|
decision,
|
|
131
126
|
...(note?.trim() ? { note: note.trim() } : {}),
|
|
132
127
|
});
|
|
@@ -153,34 +148,25 @@ function parseDecisionReason(value) {
|
|
|
153
148
|
return null;
|
|
154
149
|
}
|
|
155
150
|
}
|
|
156
|
-
function
|
|
157
|
-
if (typeof value !== 'string' || !value.trim()) {
|
|
158
|
-
return null;
|
|
159
|
-
}
|
|
151
|
+
async function warnOnly(runtime, task) {
|
|
160
152
|
try {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
const sessionId = normalizeString(parsed.sessionId);
|
|
168
|
-
if (!kind || !message || !sessionId) {
|
|
169
|
-
return null;
|
|
153
|
+
await task();
|
|
154
|
+
}
|
|
155
|
+
catch (error) {
|
|
156
|
+
if (runtime.onWarning) {
|
|
157
|
+
runtime.onWarning(error);
|
|
158
|
+
return;
|
|
170
159
|
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
...(normalizeString(parsed.command) ? { command: normalizeString(parsed.command) } : {}),
|
|
179
|
-
...(normalizeString(parsed.cwd) ? { cwd: normalizeString(parsed.cwd) } : {}),
|
|
180
|
-
};
|
|
160
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
161
|
+
process.emitWarning(`LinX Pod sync failed: ${message}`);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
function safeJsonStringify(value) {
|
|
165
|
+
try {
|
|
166
|
+
return JSON.stringify(value);
|
|
181
167
|
}
|
|
182
168
|
catch {
|
|
183
|
-
return
|
|
169
|
+
return JSON.stringify({ error: 'unserializable_context' });
|
|
184
170
|
}
|
|
185
171
|
}
|
|
186
172
|
function extractSessionId(sessionUri) {
|
|
@@ -203,15 +189,7 @@ function decisionFromApprovalRow(row) {
|
|
|
203
189
|
}
|
|
204
190
|
return 'accept';
|
|
205
191
|
}
|
|
206
|
-
function
|
|
207
|
-
const matches = audits.filter((audit) => audit.approval === approvalUri && audit.action === 'approval_requested');
|
|
208
|
-
matches.sort((left, right) => toIsoString(right.createdAt, '').localeCompare(toIsoString(left.createdAt, '')));
|
|
209
|
-
return matches[0];
|
|
210
|
-
}
|
|
211
|
-
function normalizeApprovalSummary(row, audits) {
|
|
212
|
-
const approvalUri = buildApprovalUri(row.session, row.id);
|
|
213
|
-
const requestAudit = requestAuditForApproval(approvalUri, audits);
|
|
214
|
-
const requestContext = parseRequestAuditContext(requestAudit?.context);
|
|
192
|
+
function normalizeApprovalSummary(row) {
|
|
215
193
|
const createdAt = toIsoString(row.createdAt, new Date(0).toISOString());
|
|
216
194
|
const sessionUri = row.session;
|
|
217
195
|
const decision = decisionFromApprovalRow(row);
|
|
@@ -223,9 +201,7 @@ function normalizeApprovalSummary(row, audits) {
|
|
|
223
201
|
toolName: row.toolName,
|
|
224
202
|
risk: normalizeString(row.risk) ?? 'medium',
|
|
225
203
|
status: normalizeString(row.status) ?? 'pending',
|
|
226
|
-
message:
|
|
227
|
-
...(requestContext?.command ? { command: requestContext.command } : {}),
|
|
228
|
-
...(requestContext?.cwd ? { cwd: requestContext.cwd } : {}),
|
|
204
|
+
message: formatApprovalMessage(row),
|
|
229
205
|
...(normalizeString(row.assignedTo) ? { assignedTo: normalizeString(row.assignedTo) } : {}),
|
|
230
206
|
...(normalizeString(row.decisionBy) ? { decisionBy: normalizeString(row.decisionBy) } : {}),
|
|
231
207
|
...(decision ? { decision } : {}),
|
|
@@ -233,6 +209,18 @@ function normalizeApprovalSummary(row, audits) {
|
|
|
233
209
|
...(row.resolvedAt ? { resolvedAt: toIsoString(row.resolvedAt, createdAt) } : {}),
|
|
234
210
|
};
|
|
235
211
|
}
|
|
212
|
+
function formatApprovalMessage(row) {
|
|
213
|
+
if (row.toolName === 'commandExecution') {
|
|
214
|
+
return 'Command execution approval';
|
|
215
|
+
}
|
|
216
|
+
if (row.toolName === 'fileChange') {
|
|
217
|
+
return 'File change approval';
|
|
218
|
+
}
|
|
219
|
+
if (row.toolName === 'permissionRequest') {
|
|
220
|
+
return 'Permission approval';
|
|
221
|
+
}
|
|
222
|
+
return row.toolName;
|
|
223
|
+
}
|
|
236
224
|
function formatSummaryHeadline(summary) {
|
|
237
225
|
return `${summary.id} | ${summary.status} | ${summary.risk} | session=${summary.sessionId}`;
|
|
238
226
|
}
|
|
@@ -251,37 +239,11 @@ export function isRemoteApprovalAbortError(error) {
|
|
|
251
239
|
function missingRemoteApprovalCredentialsMessage() {
|
|
252
240
|
return 'LinX remote approval requires `linx login` first.';
|
|
253
241
|
}
|
|
254
|
-
function unsupportedRemoteApprovalAuthMessage() {
|
|
255
|
-
return 'LinX remote approval requires a valid LinX login in `~/.linx`.';
|
|
256
|
-
}
|
|
257
242
|
async function createDefaultRuntime() {
|
|
258
|
-
const [credentialsStore, solidAuth, oidcAuth] = await Promise.all([
|
|
259
|
-
dynamicImport(new URL('../credentials-store.js', import.meta.url).href),
|
|
260
|
-
dynamicImport(new URL('../solid-auth.js', import.meta.url).href),
|
|
261
|
-
dynamicImport(new URL('../oidc-auth.js', import.meta.url).href),
|
|
262
|
-
]);
|
|
263
243
|
return {
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
authenticate: solidAuth.authenticate,
|
|
268
|
-
authenticatedFetch(url, token, init) {
|
|
269
|
-
const headers = new Headers(init?.headers);
|
|
270
|
-
headers.set('Authorization', `Bearer ${token}`);
|
|
271
|
-
return fetch(url, { ...init, headers });
|
|
272
|
-
},
|
|
273
|
-
createStore(sessionOrWebId, fetcher) {
|
|
274
|
-
const webId = typeof sessionOrWebId === 'string' ? sessionOrWebId : sessionOrWebId.info.webId;
|
|
275
|
-
if (!webId) {
|
|
276
|
-
throw new Error('Remote approval authentication succeeded without a WebID.');
|
|
277
|
-
}
|
|
278
|
-
const activeFetcher = fetcher ?? (typeof sessionOrWebId === 'string'
|
|
279
|
-
? undefined
|
|
280
|
-
: ((url, init) => sessionOrWebId.fetch(url, init)));
|
|
281
|
-
if (!activeFetcher) {
|
|
282
|
-
throw new Error('Remote approval authentication succeeded without a Pod fetcher.');
|
|
283
|
-
}
|
|
284
|
-
return createNativeRemoteApprovalStore(webId, activeFetcher);
|
|
244
|
+
getPodDataSession: getDefaultPodDataSession,
|
|
245
|
+
createStore(webId, fetcher) {
|
|
246
|
+
return createNativeRemoteApprovalStore(webId, fetcher);
|
|
285
247
|
},
|
|
286
248
|
sleep(ms) {
|
|
287
249
|
return delay(ms);
|
|
@@ -292,39 +254,43 @@ async function createDefaultRuntime() {
|
|
|
292
254
|
};
|
|
293
255
|
}
|
|
294
256
|
async function withRemoteApprovalStore(runtime, fn) {
|
|
295
|
-
const
|
|
296
|
-
if (!
|
|
257
|
+
const client = await getRemoteApprovalClient(runtime);
|
|
258
|
+
if (!client) {
|
|
297
259
|
throw new Error(missingRemoteApprovalCredentialsMessage());
|
|
298
260
|
}
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
const accessToken = await runtime.getOidcAccessToken?.(stored);
|
|
319
|
-
if (accessToken && stored.webId && runtime.authenticatedFetch) {
|
|
320
|
-
const fetcher = (url, init) => runtime.authenticatedFetch(url, accessToken, init);
|
|
321
|
-
return await fn({
|
|
322
|
-
store: runtime.createStore(stored.webId, fetcher),
|
|
323
|
-
webId: stored.webId,
|
|
324
|
-
stored,
|
|
261
|
+
return await fn({
|
|
262
|
+
store: client.store,
|
|
263
|
+
webId: client.session.webId,
|
|
264
|
+
stored: client.session.credentials,
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
async function getRemoteApprovalClient(runtime) {
|
|
268
|
+
let promise = remoteApprovalClientCache.get(runtime);
|
|
269
|
+
if (!promise) {
|
|
270
|
+
promise = createRemoteApprovalClient(runtime)
|
|
271
|
+
.then((client) => {
|
|
272
|
+
if (!client) {
|
|
273
|
+
remoteApprovalClientCache.delete(runtime);
|
|
274
|
+
}
|
|
275
|
+
return client;
|
|
276
|
+
})
|
|
277
|
+
.catch((error) => {
|
|
278
|
+
remoteApprovalClientCache.delete(runtime);
|
|
279
|
+
throw error;
|
|
325
280
|
});
|
|
281
|
+
remoteApprovalClientCache.set(runtime, promise);
|
|
326
282
|
}
|
|
327
|
-
|
|
283
|
+
return promise;
|
|
284
|
+
}
|
|
285
|
+
async function createRemoteApprovalClient(runtime) {
|
|
286
|
+
const session = await runtime.getPodDataSession();
|
|
287
|
+
if (!session) {
|
|
288
|
+
return null;
|
|
289
|
+
}
|
|
290
|
+
return {
|
|
291
|
+
session,
|
|
292
|
+
store: runtime.createStore(session.webId, session.fetch),
|
|
293
|
+
};
|
|
328
294
|
}
|
|
329
295
|
function createNativeRemoteApprovalStore(webId, fetcher) {
|
|
330
296
|
return {
|
|
@@ -345,99 +311,109 @@ function createNativeRemoteApprovalStore(webId, fetcher) {
|
|
|
345
311
|
};
|
|
346
312
|
}
|
|
347
313
|
async function listApprovalRows(webId, fetcher) {
|
|
348
|
-
const
|
|
314
|
+
const [currentUrls, legacyUrls] = await Promise.all([
|
|
315
|
+
listTurtleResourcesRecursive(fetcher, `${getPodBaseUrl(webId)}/.data/approvals/`).catch(() => []),
|
|
316
|
+
listTurtleResources(fetcher, `${getPodBaseUrl(webId)}/.data/approvals/`).catch(() => []),
|
|
317
|
+
]);
|
|
318
|
+
const urls = [...new Set([...currentUrls, ...legacyUrls])];
|
|
349
319
|
const rows = [];
|
|
350
320
|
for (const url of urls.filter((entry) => entry.endsWith('.ttl'))) {
|
|
351
321
|
const turtle = await readTurtleResource(fetcher, url).catch(() => null);
|
|
352
322
|
if (!turtle)
|
|
353
323
|
continue;
|
|
354
|
-
const predicates
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
rows.push(row);
|
|
324
|
+
for (const [subject, predicates] of parseManagedTurtleBlocks(turtle, url)) {
|
|
325
|
+
const row = approvalRowFromPredicates(subject, predicates);
|
|
326
|
+
if (row)
|
|
327
|
+
rows.push(row);
|
|
328
|
+
}
|
|
360
329
|
}
|
|
361
330
|
return rows;
|
|
362
331
|
}
|
|
363
332
|
async function writeApprovalRow(webId, fetcher, row) {
|
|
364
|
-
const
|
|
365
|
-
|
|
366
|
-
|
|
333
|
+
const createdAt = new Date(toIsoString(row.createdAt, new Date().toISOString()));
|
|
334
|
+
const documentUrl = buildApprovalDocumentUrl(webId, createdAt);
|
|
335
|
+
const subjectUrl = buildApprovalResourceUrl(webId, row.id, createdAt);
|
|
336
|
+
await upsertManagedTurtleBlock(fetcher, documentUrl, {
|
|
337
|
+
subject: subjectUrl,
|
|
367
338
|
triples: [
|
|
368
|
-
{ predicate: RDF_TYPE, object: iri(
|
|
369
|
-
{ predicate:
|
|
370
|
-
{ predicate:
|
|
371
|
-
{ predicate:
|
|
372
|
-
{ predicate:
|
|
373
|
-
{ predicate:
|
|
374
|
-
{ predicate:
|
|
375
|
-
{ predicate:
|
|
376
|
-
...(row.assignedTo ? [{ predicate:
|
|
377
|
-
...(row.decisionBy ? [{ predicate:
|
|
378
|
-
...(row.decisionRole ? [{ predicate:
|
|
379
|
-
...(row.onBehalfOf ? [{ predicate:
|
|
380
|
-
...(row.reason ? [{ predicate:
|
|
381
|
-
...(row.policyVersion ? [{ predicate:
|
|
382
|
-
{ predicate:
|
|
383
|
-
...(row.resolvedAt ? [{ predicate:
|
|
339
|
+
{ predicate: RDF_TYPE, object: iri(UDFS.ApprovalRequest) },
|
|
340
|
+
{ predicate: ApprovalVocab.session, object: iri(row.session) },
|
|
341
|
+
{ predicate: ApprovalVocab.toolCallId, object: literal(row.toolCallId) },
|
|
342
|
+
{ predicate: ApprovalVocab.toolName, object: literal(row.toolName) },
|
|
343
|
+
{ predicate: ApprovalVocab.target, object: iri(row.target) },
|
|
344
|
+
{ predicate: ApprovalVocab.action, object: iri(row.action) },
|
|
345
|
+
{ predicate: ApprovalVocab.risk, object: literal(row.risk) },
|
|
346
|
+
{ predicate: ApprovalVocab.status, object: literal(row.status) },
|
|
347
|
+
...(row.assignedTo ? [{ predicate: ApprovalVocab.assignedTo, object: iri(row.assignedTo) }] : []),
|
|
348
|
+
...(row.decisionBy ? [{ predicate: ApprovalVocab.decisionBy, object: iri(row.decisionBy) }] : []),
|
|
349
|
+
...(row.decisionRole ? [{ predicate: ApprovalVocab.decisionRole, object: literal(row.decisionRole) }] : []),
|
|
350
|
+
...(row.onBehalfOf ? [{ predicate: ApprovalVocab.onBehalfOf, object: iri(row.onBehalfOf) }] : []),
|
|
351
|
+
...(row.reason ? [{ predicate: ApprovalVocab.reason, object: literal(row.reason) }] : []),
|
|
352
|
+
...(row.policyVersion ? [{ predicate: ApprovalVocab.policyVersion, object: literal(row.policyVersion) }] : []),
|
|
353
|
+
{ predicate: ApprovalVocab.createdAt, object: literal(toIsoString(row.createdAt, new Date().toISOString())) },
|
|
354
|
+
...(row.resolvedAt ? [{ predicate: ApprovalVocab.resolvedAt, object: literal(toIsoString(row.resolvedAt, new Date().toISOString())) }] : []),
|
|
384
355
|
],
|
|
385
356
|
});
|
|
386
357
|
}
|
|
387
358
|
async function listAuditRows(webId, fetcher) {
|
|
388
|
-
const urls = await
|
|
359
|
+
const urls = await listTurtleResourcesRecursive(fetcher, `${getPodBaseUrl(webId)}/.data/audits/`);
|
|
389
360
|
const rows = [];
|
|
390
361
|
for (const url of urls.filter((entry) => entry.endsWith('.ttl'))) {
|
|
391
362
|
const turtle = await readTurtleResource(fetcher, url).catch(() => null);
|
|
392
363
|
if (!turtle)
|
|
393
364
|
continue;
|
|
394
|
-
const predicates
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
rows.push(row);
|
|
365
|
+
for (const [subject, predicates] of parseManagedTurtleBlocks(turtle, url)) {
|
|
366
|
+
const row = auditRowFromPredicates(subject, predicates);
|
|
367
|
+
if (row)
|
|
368
|
+
rows.push(row);
|
|
369
|
+
}
|
|
400
370
|
}
|
|
401
371
|
return rows;
|
|
402
372
|
}
|
|
403
373
|
async function writeAuditRow(webId, fetcher, row) {
|
|
404
|
-
const
|
|
405
|
-
|
|
406
|
-
|
|
374
|
+
const createdAt = new Date(toIsoString(row.createdAt, new Date().toISOString()));
|
|
375
|
+
const documentUrl = buildAuditDocumentUrl(webId, createdAt);
|
|
376
|
+
const subjectUrl = buildAuditResourceUrl(webId, row.id, createdAt);
|
|
377
|
+
await upsertManagedTurtleBlock(fetcher, documentUrl, {
|
|
378
|
+
subject: subjectUrl,
|
|
407
379
|
triples: [
|
|
408
|
-
{ predicate: RDF_TYPE, object: iri(
|
|
409
|
-
{ predicate:
|
|
410
|
-
{ predicate:
|
|
411
|
-
{ predicate:
|
|
412
|
-
...(row.onBehalfOf ? [{ predicate:
|
|
413
|
-
...(row.session ? [{ predicate:
|
|
414
|
-
...(row.
|
|
415
|
-
...(row.
|
|
416
|
-
...(row.
|
|
417
|
-
...(row.
|
|
418
|
-
{ predicate:
|
|
380
|
+
{ predicate: RDF_TYPE, object: iri(UDFS.AuditEntry) },
|
|
381
|
+
{ predicate: AuditVocab.action, object: literal(row.action) },
|
|
382
|
+
{ predicate: AuditVocab.actor, object: iri(row.actor) },
|
|
383
|
+
{ predicate: AuditVocab.actorRole, object: literal(row.actorRole) },
|
|
384
|
+
...(row.onBehalfOf ? [{ predicate: AuditVocab.onBehalfOf, object: iri(row.onBehalfOf) }] : []),
|
|
385
|
+
...(row.session ? [{ predicate: AuditVocab.session, object: iri(row.session) }] : []),
|
|
386
|
+
...(row.entry ? [{ predicate: AuditVocab.entry, object: iri(row.entry) }] : []),
|
|
387
|
+
...(row.toolCallId ? [{ predicate: AuditVocab.toolCallId, object: literal(row.toolCallId) }] : []),
|
|
388
|
+
...(row.toolName ? [{ predicate: AuditVocab.toolName, object: literal(row.toolName) }] : []),
|
|
389
|
+
...(row.approval ? [{ predicate: AuditVocab.approval, object: iri(row.approval) }] : []),
|
|
390
|
+
...(row.policyVersion ? [{ predicate: AuditVocab.policyVersion, object: literal(row.policyVersion) }] : []),
|
|
391
|
+
{ predicate: AuditVocab.createdAt, object: literal(toIsoString(row.createdAt, new Date().toISOString())) },
|
|
419
392
|
],
|
|
420
393
|
});
|
|
421
394
|
}
|
|
422
395
|
async function listGrantRows(webId, fetcher) {
|
|
423
|
-
const urls =
|
|
396
|
+
const urls = [
|
|
397
|
+
`${getPodBaseUrl(webId)}/settings/autonomy/grants.ttl`,
|
|
398
|
+
...await listTurtleResources(fetcher, `${getPodBaseUrl(webId)}/settings/autonomy/grants/`).catch(() => []),
|
|
399
|
+
];
|
|
424
400
|
const rows = [];
|
|
425
401
|
for (const url of urls.filter((entry) => entry.endsWith('.ttl'))) {
|
|
426
402
|
const turtle = await readTurtleResource(fetcher, url).catch(() => null);
|
|
427
403
|
if (!turtle)
|
|
428
404
|
continue;
|
|
429
|
-
const predicates
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
rows.push(row);
|
|
405
|
+
for (const [subject, predicates] of parseManagedTurtleBlocks(turtle, url)) {
|
|
406
|
+
const row = grantRowFromPredicates(subject, predicates);
|
|
407
|
+
if (row)
|
|
408
|
+
rows.push(row);
|
|
409
|
+
}
|
|
435
410
|
}
|
|
436
411
|
return rows;
|
|
437
412
|
}
|
|
438
413
|
async function writeGrantRow(webId, fetcher, row) {
|
|
439
414
|
const id = normalizeString(row.id) ?? crypto.randomUUID();
|
|
440
|
-
const
|
|
415
|
+
const documentUrl = buildGrantDocumentUrl(webId);
|
|
416
|
+
const subjectUrl = buildGrantResourceUrl(webId, id);
|
|
441
417
|
const target = normalizeString(row.target);
|
|
442
418
|
const action = normalizeString(row.action);
|
|
443
419
|
const effect = normalizeString(row.effect);
|
|
@@ -446,20 +422,20 @@ async function writeGrantRow(webId, fetcher, row) {
|
|
|
446
422
|
if (!target || !action || !effect || !decisionBy || !decisionRole) {
|
|
447
423
|
throw new Error(`Invalid remote approval grant row: ${id}`);
|
|
448
424
|
}
|
|
449
|
-
await upsertManagedTurtleBlock(fetcher,
|
|
450
|
-
subject:
|
|
425
|
+
await upsertManagedTurtleBlock(fetcher, documentUrl, {
|
|
426
|
+
subject: subjectUrl,
|
|
451
427
|
triples: [
|
|
452
|
-
{ predicate: RDF_TYPE, object: iri(
|
|
453
|
-
{ predicate: RDF_TYPE, object: iri(
|
|
454
|
-
{ predicate:
|
|
455
|
-
{ predicate:
|
|
456
|
-
{ predicate:
|
|
457
|
-
...(normalizeString(row.riskCeiling) ? [{ predicate:
|
|
458
|
-
{ predicate:
|
|
459
|
-
{ predicate:
|
|
460
|
-
...(normalizeString(row.onBehalfOf) ? [{ predicate:
|
|
461
|
-
{ predicate:
|
|
462
|
-
...(normalizeString(row.revokedAt) ? [{ predicate:
|
|
428
|
+
{ predicate: RDF_TYPE, object: iri(ODRL.Policy) },
|
|
429
|
+
{ predicate: RDF_TYPE, object: iri(UDFS.AutonomyGrant) },
|
|
430
|
+
{ predicate: GrantVocab.target, object: iri(target) },
|
|
431
|
+
{ predicate: GrantVocab.action, object: iri(action) },
|
|
432
|
+
{ predicate: GrantVocab.effect, object: literal(effect) },
|
|
433
|
+
...(normalizeString(row.riskCeiling) ? [{ predicate: GrantVocab.riskCeiling, object: literal(normalizeString(row.riskCeiling)) }] : []),
|
|
434
|
+
{ predicate: GrantVocab.decisionBy, object: iri(decisionBy) },
|
|
435
|
+
{ predicate: GrantVocab.decisionRole, object: literal(decisionRole) },
|
|
436
|
+
...(normalizeString(row.onBehalfOf) ? [{ predicate: GrantVocab.onBehalfOf, object: iri(normalizeString(row.onBehalfOf)) }] : []),
|
|
437
|
+
{ predicate: GrantVocab.createdAt, object: literal(toIsoString(row.createdAt, new Date().toISOString())) },
|
|
438
|
+
...(normalizeString(row.revokedAt) ? [{ predicate: GrantVocab.revokedAt, object: literal(normalizeString(row.revokedAt)) }] : []),
|
|
463
439
|
],
|
|
464
440
|
});
|
|
465
441
|
}
|
|
@@ -468,22 +444,22 @@ async function writeInboxNotificationRow(webId, fetcher, row) {
|
|
|
468
444
|
await upsertManagedTurtleBlock(fetcher, url, {
|
|
469
445
|
subject: url,
|
|
470
446
|
triples: [
|
|
471
|
-
{ predicate: RDF_TYPE, object: iri(
|
|
472
|
-
...(row.actor ? [{ predicate:
|
|
473
|
-
{ predicate:
|
|
474
|
-
{ predicate:
|
|
447
|
+
{ predicate: RDF_TYPE, object: iri(AS.Announce) },
|
|
448
|
+
...(row.actor ? [{ predicate: InboxNotificationVocab.actor, object: iri(row.actor) }] : []),
|
|
449
|
+
{ predicate: InboxNotificationVocab.object, object: iri(row.object) },
|
|
450
|
+
{ predicate: InboxNotificationVocab.createdAt, object: literal(toIsoString(row.createdAt, new Date().toISOString())) },
|
|
475
451
|
],
|
|
476
452
|
});
|
|
477
453
|
}
|
|
478
454
|
function approvalRowFromPredicates(url, predicates) {
|
|
479
|
-
const session = firstIri(predicates,
|
|
480
|
-
const toolCallId = firstLiteral(predicates,
|
|
481
|
-
const toolName = firstLiteral(predicates,
|
|
482
|
-
const target = firstIri(predicates,
|
|
483
|
-
const action = firstIri(predicates,
|
|
484
|
-
const risk = firstLiteral(predicates,
|
|
485
|
-
const status = firstLiteral(predicates,
|
|
486
|
-
const createdAt = firstLiteral(predicates,
|
|
455
|
+
const session = firstIri(predicates, ApprovalVocab.session);
|
|
456
|
+
const toolCallId = firstLiteral(predicates, ApprovalVocab.toolCallId);
|
|
457
|
+
const toolName = firstLiteral(predicates, ApprovalVocab.toolName);
|
|
458
|
+
const target = firstIri(predicates, ApprovalVocab.target);
|
|
459
|
+
const action = firstIri(predicates, ApprovalVocab.action);
|
|
460
|
+
const risk = firstLiteral(predicates, ApprovalVocab.risk);
|
|
461
|
+
const status = firstLiteral(predicates, ApprovalVocab.status);
|
|
462
|
+
const createdAt = firstLiteral(predicates, ApprovalVocab.createdAt);
|
|
487
463
|
if (!session || !toolCallId || !toolName || !target || !action || !risk || !status || !createdAt) {
|
|
488
464
|
return null;
|
|
489
465
|
}
|
|
@@ -496,21 +472,21 @@ function approvalRowFromPredicates(url, predicates) {
|
|
|
496
472
|
action,
|
|
497
473
|
risk,
|
|
498
474
|
status,
|
|
499
|
-
assignedTo: firstIri(predicates,
|
|
500
|
-
decisionBy: firstIri(predicates,
|
|
501
|
-
decisionRole: firstLiteral(predicates,
|
|
502
|
-
onBehalfOf: firstIri(predicates,
|
|
503
|
-
reason: firstLiteral(predicates,
|
|
504
|
-
policyVersion: firstLiteral(predicates,
|
|
475
|
+
assignedTo: firstIri(predicates, ApprovalVocab.assignedTo),
|
|
476
|
+
decisionBy: firstIri(predicates, ApprovalVocab.decisionBy),
|
|
477
|
+
decisionRole: firstLiteral(predicates, ApprovalVocab.decisionRole),
|
|
478
|
+
onBehalfOf: firstIri(predicates, ApprovalVocab.onBehalfOf),
|
|
479
|
+
reason: firstLiteral(predicates, ApprovalVocab.reason),
|
|
480
|
+
policyVersion: firstLiteral(predicates, ApprovalVocab.policyVersion),
|
|
505
481
|
createdAt,
|
|
506
|
-
resolvedAt: firstLiteral(predicates,
|
|
482
|
+
resolvedAt: firstLiteral(predicates, ApprovalVocab.resolvedAt),
|
|
507
483
|
};
|
|
508
484
|
}
|
|
509
485
|
function auditRowFromPredicates(url, predicates) {
|
|
510
|
-
const action = firstLiteral(predicates,
|
|
511
|
-
const actor = firstIri(predicates,
|
|
512
|
-
const actorRole = firstLiteral(predicates,
|
|
513
|
-
const createdAt = firstLiteral(predicates,
|
|
486
|
+
const action = firstLiteral(predicates, AuditVocab.action);
|
|
487
|
+
const actor = firstIri(predicates, AuditVocab.actor);
|
|
488
|
+
const actorRole = firstLiteral(predicates, AuditVocab.actorRole);
|
|
489
|
+
const createdAt = firstLiteral(predicates, AuditVocab.createdAt);
|
|
514
490
|
if (!action || !actor || !actorRole || !createdAt) {
|
|
515
491
|
return null;
|
|
516
492
|
}
|
|
@@ -519,22 +495,23 @@ function auditRowFromPredicates(url, predicates) {
|
|
|
519
495
|
action,
|
|
520
496
|
actor,
|
|
521
497
|
actorRole,
|
|
522
|
-
onBehalfOf: firstIri(predicates,
|
|
523
|
-
session: firstIri(predicates,
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
498
|
+
onBehalfOf: firstIri(predicates, AuditVocab.onBehalfOf),
|
|
499
|
+
session: firstIri(predicates, AuditVocab.session),
|
|
500
|
+
entry: firstIri(predicates, AuditVocab.entry),
|
|
501
|
+
toolCallId: firstLiteral(predicates, AuditVocab.toolCallId),
|
|
502
|
+
toolName: firstLiteral(predicates, AuditVocab.toolName),
|
|
503
|
+
approval: firstIri(predicates, AuditVocab.approval),
|
|
504
|
+
policyVersion: firstLiteral(predicates, AuditVocab.policyVersion),
|
|
528
505
|
createdAt,
|
|
529
506
|
};
|
|
530
507
|
}
|
|
531
508
|
function grantRowFromPredicates(url, predicates) {
|
|
532
|
-
const target = firstIri(predicates,
|
|
533
|
-
const action = firstIri(predicates,
|
|
534
|
-
const effect = firstLiteral(predicates,
|
|
535
|
-
const decisionBy = firstIri(predicates,
|
|
536
|
-
const decisionRole = firstLiteral(predicates,
|
|
537
|
-
const createdAt = firstLiteral(predicates,
|
|
509
|
+
const target = firstIri(predicates, GrantVocab.target);
|
|
510
|
+
const action = firstIri(predicates, GrantVocab.action);
|
|
511
|
+
const effect = firstLiteral(predicates, GrantVocab.effect);
|
|
512
|
+
const decisionBy = firstIri(predicates, GrantVocab.decisionBy);
|
|
513
|
+
const decisionRole = firstLiteral(predicates, GrantVocab.decisionRole);
|
|
514
|
+
const createdAt = firstLiteral(predicates, GrantVocab.createdAt);
|
|
538
515
|
if (!target || !action || !effect || !decisionBy || !decisionRole || !createdAt) {
|
|
539
516
|
return null;
|
|
540
517
|
}
|
|
@@ -543,12 +520,12 @@ function grantRowFromPredicates(url, predicates) {
|
|
|
543
520
|
target,
|
|
544
521
|
action,
|
|
545
522
|
effect,
|
|
546
|
-
riskCeiling: firstLiteral(predicates,
|
|
523
|
+
riskCeiling: firstLiteral(predicates, GrantVocab.riskCeiling),
|
|
547
524
|
decisionBy,
|
|
548
525
|
decisionRole,
|
|
549
|
-
onBehalfOf: firstIri(predicates,
|
|
526
|
+
onBehalfOf: firstIri(predicates, GrantVocab.onBehalfOf),
|
|
550
527
|
createdAt,
|
|
551
|
-
revokedAt: firstLiteral(predicates,
|
|
528
|
+
revokedAt: firstLiteral(predicates, GrantVocab.revokedAt),
|
|
552
529
|
};
|
|
553
530
|
}
|
|
554
531
|
export async function createRemoteWatchApproval(options) {
|
|
@@ -568,7 +545,7 @@ export async function createRemoteWatchApproval(options) {
|
|
|
568
545
|
risk: buildRisk(options.request),
|
|
569
546
|
...(options.request.kind === 'command-approval' && options.request.command ? { command: options.request.command } : {}),
|
|
570
547
|
...(options.request.kind === 'command-approval' && options.request.cwd ? { cwd: options.request.cwd } : {}),
|
|
571
|
-
|
|
548
|
+
entry: sessionUri,
|
|
572
549
|
}),
|
|
573
550
|
runtime: activeRuntime,
|
|
574
551
|
});
|
|
@@ -585,19 +562,12 @@ export async function createRemoteApproval(options) {
|
|
|
585
562
|
const approvalId = crypto.randomUUID();
|
|
586
563
|
const now = activeRuntime.now();
|
|
587
564
|
const sessionUri = subject.sessionUri;
|
|
588
|
-
const approvalUri =
|
|
565
|
+
const approvalUri = buildApprovalUriForDate(webId, approvalId, now);
|
|
589
566
|
const targetUri = subject.targetUri ?? sessionUri;
|
|
590
567
|
const assignedTo = subject.assignedTo ?? webId;
|
|
591
568
|
const onBehalfOf = subject.onBehalfOf ?? webId;
|
|
592
569
|
const policyVersion = subject.policyVersion ?? REMOTE_APPROVAL_POLICY_VERSION;
|
|
593
|
-
const
|
|
594
|
-
kind: request.kind,
|
|
595
|
-
message: request.message,
|
|
596
|
-
sessionId: extractSessionId(sessionUri),
|
|
597
|
-
toolName: request.toolName,
|
|
598
|
-
...(request.command ? { command: request.command } : {}),
|
|
599
|
-
...(request.cwd ? { cwd: request.cwd } : {}),
|
|
600
|
-
};
|
|
570
|
+
const requestEntry = request.entry ?? approvalUri;
|
|
601
571
|
await store.insertApproval({
|
|
602
572
|
id: approvalId,
|
|
603
573
|
session: sessionUri,
|
|
@@ -611,25 +581,27 @@ export async function createRemoteApproval(options) {
|
|
|
611
581
|
policyVersion,
|
|
612
582
|
createdAt: now,
|
|
613
583
|
});
|
|
614
|
-
|
|
584
|
+
const requestAudit = {
|
|
615
585
|
id: crypto.randomUUID(),
|
|
616
586
|
action: 'approval_requested',
|
|
617
587
|
actor: subject.actorUri,
|
|
618
588
|
actorRole: 'secretary',
|
|
619
589
|
onBehalfOf,
|
|
620
590
|
session: sessionUri,
|
|
591
|
+
entry: requestEntry,
|
|
621
592
|
toolCallId: request.toolCallId,
|
|
593
|
+
toolName: request.toolName,
|
|
622
594
|
approval: approvalUri,
|
|
623
|
-
context: JSON.stringify(requestContext),
|
|
624
595
|
policyVersion,
|
|
625
596
|
createdAt: now,
|
|
626
|
-
}
|
|
627
|
-
await store.
|
|
597
|
+
};
|
|
598
|
+
await warnOnly(activeRuntime, () => store.insertAudit(requestAudit));
|
|
599
|
+
await warnOnly(activeRuntime, () => store.insertInboxNotification({
|
|
628
600
|
id: crypto.randomUUID(),
|
|
629
601
|
actor: subject.actorUri,
|
|
630
602
|
object: approvalUri,
|
|
631
603
|
createdAt: now,
|
|
632
|
-
})
|
|
604
|
+
}));
|
|
633
605
|
return normalizeApprovalSummary({
|
|
634
606
|
id: approvalId,
|
|
635
607
|
session: sessionUri,
|
|
@@ -642,19 +614,7 @@ export async function createRemoteApproval(options) {
|
|
|
642
614
|
assignedTo,
|
|
643
615
|
policyVersion,
|
|
644
616
|
createdAt: now,
|
|
645
|
-
}
|
|
646
|
-
id: crypto.randomUUID(),
|
|
647
|
-
action: 'approval_requested',
|
|
648
|
-
actor: subject.actorUri,
|
|
649
|
-
actorRole: 'secretary',
|
|
650
|
-
onBehalfOf,
|
|
651
|
-
session: sessionUri,
|
|
652
|
-
toolCallId: request.toolCallId,
|
|
653
|
-
approval: approvalUri,
|
|
654
|
-
context: JSON.stringify(requestContext),
|
|
655
|
-
policyVersion,
|
|
656
|
-
createdAt: now,
|
|
657
|
-
}]);
|
|
617
|
+
});
|
|
658
618
|
});
|
|
659
619
|
}
|
|
660
620
|
export async function waitForRemoteWatchApproval(options) {
|
|
@@ -741,12 +701,9 @@ export async function listRemoteWatchApprovals(options = {}) {
|
|
|
741
701
|
const activeRuntime = options.runtime ?? await createDefaultRuntime();
|
|
742
702
|
const requestedStatus = options.status ?? 'pending';
|
|
743
703
|
return withRemoteApprovalStore(activeRuntime, async ({ store, webId }) => {
|
|
744
|
-
const
|
|
745
|
-
store.listApprovals(),
|
|
746
|
-
store.listAudits(),
|
|
747
|
-
]);
|
|
704
|
+
const approvals = await store.listApprovals();
|
|
748
705
|
return approvals
|
|
749
|
-
.map((row) => normalizeApprovalSummary(row
|
|
706
|
+
.map((row) => normalizeApprovalSummary(row))
|
|
750
707
|
.filter((summary) => !summary.assignedTo || summary.assignedTo === webId)
|
|
751
708
|
.filter((summary) => requestedStatus === 'all' || summary.status === requestedStatus)
|
|
752
709
|
.sort((left, right) => right.createdAt.localeCompare(left.createdAt));
|
|
@@ -761,11 +718,11 @@ export async function resolveRemoteWatchApproval(options) {
|
|
|
761
718
|
throw new Error(`Remote approval not found: ${options.approvalId}`);
|
|
762
719
|
}
|
|
763
720
|
if (row.status !== 'pending') {
|
|
764
|
-
|
|
765
|
-
return normalizeApprovalSummary(row, audits);
|
|
721
|
+
return normalizeApprovalSummary(row);
|
|
766
722
|
}
|
|
767
723
|
const now = activeRuntime.now();
|
|
768
|
-
const
|
|
724
|
+
const approvalCreatedAt = new Date(toIsoString(row.createdAt, now.toISOString()));
|
|
725
|
+
const approvalUri = buildApprovalUriForDate(row.session, row.id, approvalCreatedAt);
|
|
769
726
|
const nextStatus = options.decision === 'accept' || options.decision === 'accept_for_session'
|
|
770
727
|
? 'approved'
|
|
771
728
|
: 'rejected';
|
|
@@ -777,22 +734,20 @@ export async function resolveRemoteWatchApproval(options) {
|
|
|
777
734
|
reason: encodeDecisionReason(options.decision, options.note),
|
|
778
735
|
resolvedAt: now,
|
|
779
736
|
});
|
|
780
|
-
await store.insertAudit({
|
|
737
|
+
await warnOnly(activeRuntime, () => store.insertAudit({
|
|
781
738
|
id: crypto.randomUUID(),
|
|
782
739
|
action: nextStatus === 'approved' ? 'approval_approved' : 'approval_rejected',
|
|
783
740
|
actor: webId,
|
|
784
741
|
actorRole: 'human',
|
|
785
742
|
onBehalfOf: webId,
|
|
786
743
|
session: row.session,
|
|
744
|
+
entry: approvalUri,
|
|
787
745
|
toolCallId: row.toolCallId,
|
|
746
|
+
toolName: row.toolName,
|
|
788
747
|
approval: approvalUri,
|
|
789
|
-
context: JSON.stringify({
|
|
790
|
-
decision: options.decision,
|
|
791
|
-
...(options.note?.trim() ? { note: options.note.trim() } : {}),
|
|
792
|
-
}),
|
|
793
748
|
policyVersion: REMOTE_APPROVAL_POLICY_VERSION,
|
|
794
749
|
createdAt: now,
|
|
795
|
-
});
|
|
750
|
+
}));
|
|
796
751
|
if (options.decision === 'accept_for_session') {
|
|
797
752
|
const grantId = crypto.randomUUID();
|
|
798
753
|
await store.insertGrant({
|
|
@@ -806,19 +761,19 @@ export async function resolveRemoteWatchApproval(options) {
|
|
|
806
761
|
onBehalfOf: webId,
|
|
807
762
|
createdAt: now,
|
|
808
763
|
});
|
|
809
|
-
await store.insertInboxNotification({
|
|
764
|
+
await warnOnly(activeRuntime, () => store.insertInboxNotification({
|
|
810
765
|
id: crypto.randomUUID(),
|
|
811
766
|
actor: webId,
|
|
812
767
|
object: buildGrantUri(row.session, grantId),
|
|
813
768
|
createdAt: now,
|
|
814
|
-
})
|
|
769
|
+
}));
|
|
815
770
|
}
|
|
816
|
-
await store.insertInboxNotification({
|
|
771
|
+
await warnOnly(activeRuntime, () => store.insertInboxNotification({
|
|
817
772
|
id: crypto.randomUUID(),
|
|
818
773
|
actor: webId,
|
|
819
774
|
object: approvalUri,
|
|
820
775
|
createdAt: now,
|
|
821
|
-
})
|
|
776
|
+
}));
|
|
822
777
|
const nextRow = {
|
|
823
778
|
...row,
|
|
824
779
|
status: nextStatus,
|
|
@@ -828,15 +783,13 @@ export async function resolveRemoteWatchApproval(options) {
|
|
|
828
783
|
reason: encodeDecisionReason(options.decision, options.note),
|
|
829
784
|
resolvedAt: now,
|
|
830
785
|
};
|
|
831
|
-
|
|
832
|
-
return normalizeApprovalSummary(nextRow, audits);
|
|
786
|
+
return normalizeApprovalSummary(nextRow);
|
|
833
787
|
});
|
|
834
788
|
}
|
|
835
789
|
export const __podApprovalInternal = {
|
|
836
790
|
createAbortError,
|
|
837
791
|
createDefaultRuntime,
|
|
838
792
|
buildActionUri,
|
|
839
|
-
buildRequestAuditContext,
|
|
840
793
|
buildRisk,
|
|
841
794
|
buildToolName,
|
|
842
795
|
createNativeRemoteApprovalStore,
|
|
@@ -847,6 +800,5 @@ export const __podApprovalInternal = {
|
|
|
847
800
|
isRemoteApprovalAbortError,
|
|
848
801
|
normalizeApprovalSummary,
|
|
849
802
|
parseDecisionReason,
|
|
850
|
-
parseRequestAuditContext,
|
|
851
803
|
};
|
|
852
804
|
//# sourceMappingURL=pod-approval.js.map
|