@undefineds.co/linx 0.2.13 → 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 +18 -45
- package/dist/lib/pi-adapter/pod-mirror.js.map +1 -1
- package/dist/lib/pi-adapter/pod-native.js +2 -0
- package/dist/lib/pi-adapter/pod-native.js.map +1 -1
- package/dist/lib/pi-adapter/runtime.js +1 -0
- package/dist/lib/pi-adapter/runtime.js.map +1 -1
- package/dist/lib/pi-adapter/stream.js +23 -2
- package/dist/lib/pi-adapter/stream.js.map +1 -1
- package/dist/lib/watch/pod-approval.js +133 -178
- package/dist/lib/watch/pod-approval.js.map +1 -1
- package/package.json +2 -2
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { setTimeout as delay } from 'node:timers/promises';
|
|
2
2
|
import { getDefaultPodDataSession } from '../pod-data-session.js';
|
|
3
|
-
import {
|
|
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';
|
|
@@ -108,16 +110,6 @@ function buildRequestMessage(request) {
|
|
|
108
110
|
}
|
|
109
111
|
return request.message;
|
|
110
112
|
}
|
|
111
|
-
function buildRequestAuditContext(record, request) {
|
|
112
|
-
return {
|
|
113
|
-
kind: request.kind,
|
|
114
|
-
message: buildRequestMessage(request),
|
|
115
|
-
...(request.kind === 'command-approval' && request.command ? { command: request.command } : {}),
|
|
116
|
-
...(request.kind === 'command-approval' && request.cwd ? { cwd: request.cwd } : {}),
|
|
117
|
-
backend: record.backend,
|
|
118
|
-
sessionId: record.id,
|
|
119
|
-
};
|
|
120
|
-
}
|
|
121
113
|
function extractToolCallId(request) {
|
|
122
114
|
if (!isRecord(request.raw)) {
|
|
123
115
|
return crypto.randomUUID();
|
|
@@ -129,7 +121,7 @@ function extractToolCallId(request) {
|
|
|
129
121
|
?? crypto.randomUUID();
|
|
130
122
|
}
|
|
131
123
|
function encodeDecisionReason(decision, note) {
|
|
132
|
-
return
|
|
124
|
+
return safeJsonStringify({
|
|
133
125
|
decision,
|
|
134
126
|
...(note?.trim() ? { note: note.trim() } : {}),
|
|
135
127
|
});
|
|
@@ -156,34 +148,25 @@ function parseDecisionReason(value) {
|
|
|
156
148
|
return null;
|
|
157
149
|
}
|
|
158
150
|
}
|
|
159
|
-
function
|
|
160
|
-
if (typeof value !== 'string' || !value.trim()) {
|
|
161
|
-
return null;
|
|
162
|
-
}
|
|
151
|
+
async function warnOnly(runtime, task) {
|
|
163
152
|
try {
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
const sessionId = normalizeString(parsed.sessionId);
|
|
171
|
-
if (!kind || !message || !sessionId) {
|
|
172
|
-
return null;
|
|
153
|
+
await task();
|
|
154
|
+
}
|
|
155
|
+
catch (error) {
|
|
156
|
+
if (runtime.onWarning) {
|
|
157
|
+
runtime.onWarning(error);
|
|
158
|
+
return;
|
|
173
159
|
}
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
...(normalizeString(parsed.command) ? { command: normalizeString(parsed.command) } : {}),
|
|
182
|
-
...(normalizeString(parsed.cwd) ? { cwd: normalizeString(parsed.cwd) } : {}),
|
|
183
|
-
};
|
|
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);
|
|
184
167
|
}
|
|
185
168
|
catch {
|
|
186
|
-
return
|
|
169
|
+
return JSON.stringify({ error: 'unserializable_context' });
|
|
187
170
|
}
|
|
188
171
|
}
|
|
189
172
|
function extractSessionId(sessionUri) {
|
|
@@ -206,22 +189,8 @@ function decisionFromApprovalRow(row) {
|
|
|
206
189
|
}
|
|
207
190
|
return 'accept';
|
|
208
191
|
}
|
|
209
|
-
function
|
|
210
|
-
const uriSet = new Set(approvalUris);
|
|
211
|
-
const matches = audits.filter((audit) => (audit.action === 'approval_requested'
|
|
212
|
-
&& ((audit.approval && uriSet.has(audit.approval))
|
|
213
|
-
|| (audit.session === row.session && audit.toolCallId === row.toolCallId))));
|
|
214
|
-
matches.sort((left, right) => toIsoString(right.createdAt, '').localeCompare(toIsoString(left.createdAt, '')));
|
|
215
|
-
return matches[0];
|
|
216
|
-
}
|
|
217
|
-
function normalizeApprovalSummary(row, audits) {
|
|
192
|
+
function normalizeApprovalSummary(row) {
|
|
218
193
|
const createdAt = toIsoString(row.createdAt, new Date(0).toISOString());
|
|
219
|
-
const approvalUris = [
|
|
220
|
-
buildApprovalUriForDate(row.session, row.id, new Date(createdAt)),
|
|
221
|
-
buildApprovalUri(row.session, row.id),
|
|
222
|
-
];
|
|
223
|
-
const requestAudit = requestAuditForApproval(row, approvalUris, audits);
|
|
224
|
-
const requestContext = parseRequestAuditContext(requestAudit?.context);
|
|
225
194
|
const sessionUri = row.session;
|
|
226
195
|
const decision = decisionFromApprovalRow(row);
|
|
227
196
|
return {
|
|
@@ -232,9 +201,7 @@ function normalizeApprovalSummary(row, audits) {
|
|
|
232
201
|
toolName: row.toolName,
|
|
233
202
|
risk: normalizeString(row.risk) ?? 'medium',
|
|
234
203
|
status: normalizeString(row.status) ?? 'pending',
|
|
235
|
-
message:
|
|
236
|
-
...(requestContext?.command ? { command: requestContext.command } : {}),
|
|
237
|
-
...(requestContext?.cwd ? { cwd: requestContext.cwd } : {}),
|
|
204
|
+
message: formatApprovalMessage(row),
|
|
238
205
|
...(normalizeString(row.assignedTo) ? { assignedTo: normalizeString(row.assignedTo) } : {}),
|
|
239
206
|
...(normalizeString(row.decisionBy) ? { decisionBy: normalizeString(row.decisionBy) } : {}),
|
|
240
207
|
...(decision ? { decision } : {}),
|
|
@@ -242,6 +209,18 @@ function normalizeApprovalSummary(row, audits) {
|
|
|
242
209
|
...(row.resolvedAt ? { resolvedAt: toIsoString(row.resolvedAt, createdAt) } : {}),
|
|
243
210
|
};
|
|
244
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
|
+
}
|
|
245
224
|
function formatSummaryHeadline(summary) {
|
|
246
225
|
return `${summary.id} | ${summary.status} | ${summary.risk} | session=${summary.sessionId}`;
|
|
247
226
|
}
|
|
@@ -357,22 +336,22 @@ async function writeApprovalRow(webId, fetcher, row) {
|
|
|
357
336
|
await upsertManagedTurtleBlock(fetcher, documentUrl, {
|
|
358
337
|
subject: subjectUrl,
|
|
359
338
|
triples: [
|
|
360
|
-
{ predicate: RDF_TYPE, object: iri(
|
|
361
|
-
{ predicate:
|
|
362
|
-
{ predicate:
|
|
363
|
-
{ predicate:
|
|
364
|
-
{ predicate:
|
|
365
|
-
{ predicate:
|
|
366
|
-
{ predicate:
|
|
367
|
-
{ predicate:
|
|
368
|
-
...(row.assignedTo ? [{ predicate:
|
|
369
|
-
...(row.decisionBy ? [{ predicate:
|
|
370
|
-
...(row.decisionRole ? [{ predicate:
|
|
371
|
-
...(row.onBehalfOf ? [{ predicate:
|
|
372
|
-
...(row.reason ? [{ predicate:
|
|
373
|
-
...(row.policyVersion ? [{ predicate:
|
|
374
|
-
{ predicate:
|
|
375
|
-
...(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())) }] : []),
|
|
376
355
|
],
|
|
377
356
|
});
|
|
378
357
|
}
|
|
@@ -398,17 +377,18 @@ async function writeAuditRow(webId, fetcher, row) {
|
|
|
398
377
|
await upsertManagedTurtleBlock(fetcher, documentUrl, {
|
|
399
378
|
subject: subjectUrl,
|
|
400
379
|
triples: [
|
|
401
|
-
{ predicate: RDF_TYPE, object: iri(
|
|
402
|
-
{ predicate:
|
|
403
|
-
{ predicate:
|
|
404
|
-
{ predicate:
|
|
405
|
-
...(row.onBehalfOf ? [{ predicate:
|
|
406
|
-
...(row.session ? [{ predicate:
|
|
407
|
-
...(row.
|
|
408
|
-
...(row.
|
|
409
|
-
...(row.
|
|
410
|
-
...(row.
|
|
411
|
-
{ 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())) },
|
|
412
392
|
],
|
|
413
393
|
});
|
|
414
394
|
}
|
|
@@ -445,17 +425,17 @@ async function writeGrantRow(webId, fetcher, row) {
|
|
|
445
425
|
await upsertManagedTurtleBlock(fetcher, documentUrl, {
|
|
446
426
|
subject: subjectUrl,
|
|
447
427
|
triples: [
|
|
448
|
-
{ predicate: RDF_TYPE, object: iri(
|
|
449
|
-
{ predicate: RDF_TYPE, object: iri(
|
|
450
|
-
{ predicate:
|
|
451
|
-
{ predicate:
|
|
452
|
-
{ predicate:
|
|
453
|
-
...(normalizeString(row.riskCeiling) ? [{ predicate:
|
|
454
|
-
{ predicate:
|
|
455
|
-
{ predicate:
|
|
456
|
-
...(normalizeString(row.onBehalfOf) ? [{ predicate:
|
|
457
|
-
{ predicate:
|
|
458
|
-
...(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)) }] : []),
|
|
459
439
|
],
|
|
460
440
|
});
|
|
461
441
|
}
|
|
@@ -464,22 +444,22 @@ async function writeInboxNotificationRow(webId, fetcher, row) {
|
|
|
464
444
|
await upsertManagedTurtleBlock(fetcher, url, {
|
|
465
445
|
subject: url,
|
|
466
446
|
triples: [
|
|
467
|
-
{ predicate: RDF_TYPE, object: iri(
|
|
468
|
-
...(row.actor ? [{ predicate:
|
|
469
|
-
{ predicate:
|
|
470
|
-
{ 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())) },
|
|
471
451
|
],
|
|
472
452
|
});
|
|
473
453
|
}
|
|
474
454
|
function approvalRowFromPredicates(url, predicates) {
|
|
475
|
-
const session = firstIri(predicates,
|
|
476
|
-
const toolCallId = firstLiteral(predicates,
|
|
477
|
-
const toolName = firstLiteral(predicates,
|
|
478
|
-
const target = firstIri(predicates,
|
|
479
|
-
const action = firstIri(predicates,
|
|
480
|
-
const risk = firstLiteral(predicates,
|
|
481
|
-
const status = firstLiteral(predicates,
|
|
482
|
-
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);
|
|
483
463
|
if (!session || !toolCallId || !toolName || !target || !action || !risk || !status || !createdAt) {
|
|
484
464
|
return null;
|
|
485
465
|
}
|
|
@@ -492,21 +472,21 @@ function approvalRowFromPredicates(url, predicates) {
|
|
|
492
472
|
action,
|
|
493
473
|
risk,
|
|
494
474
|
status,
|
|
495
|
-
assignedTo: firstIri(predicates,
|
|
496
|
-
decisionBy: firstIri(predicates,
|
|
497
|
-
decisionRole: firstLiteral(predicates,
|
|
498
|
-
onBehalfOf: firstIri(predicates,
|
|
499
|
-
reason: firstLiteral(predicates,
|
|
500
|
-
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),
|
|
501
481
|
createdAt,
|
|
502
|
-
resolvedAt: firstLiteral(predicates,
|
|
482
|
+
resolvedAt: firstLiteral(predicates, ApprovalVocab.resolvedAt),
|
|
503
483
|
};
|
|
504
484
|
}
|
|
505
485
|
function auditRowFromPredicates(url, predicates) {
|
|
506
|
-
const action = firstLiteral(predicates,
|
|
507
|
-
const actor = firstIri(predicates,
|
|
508
|
-
const actorRole = firstLiteral(predicates,
|
|
509
|
-
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);
|
|
510
490
|
if (!action || !actor || !actorRole || !createdAt) {
|
|
511
491
|
return null;
|
|
512
492
|
}
|
|
@@ -515,22 +495,23 @@ function auditRowFromPredicates(url, predicates) {
|
|
|
515
495
|
action,
|
|
516
496
|
actor,
|
|
517
497
|
actorRole,
|
|
518
|
-
onBehalfOf: firstIri(predicates,
|
|
519
|
-
session: firstIri(predicates,
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
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),
|
|
524
505
|
createdAt,
|
|
525
506
|
};
|
|
526
507
|
}
|
|
527
508
|
function grantRowFromPredicates(url, predicates) {
|
|
528
|
-
const target = firstIri(predicates,
|
|
529
|
-
const action = firstIri(predicates,
|
|
530
|
-
const effect = firstLiteral(predicates,
|
|
531
|
-
const decisionBy = firstIri(predicates,
|
|
532
|
-
const decisionRole = firstLiteral(predicates,
|
|
533
|
-
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);
|
|
534
515
|
if (!target || !action || !effect || !decisionBy || !decisionRole || !createdAt) {
|
|
535
516
|
return null;
|
|
536
517
|
}
|
|
@@ -539,12 +520,12 @@ function grantRowFromPredicates(url, predicates) {
|
|
|
539
520
|
target,
|
|
540
521
|
action,
|
|
541
522
|
effect,
|
|
542
|
-
riskCeiling: firstLiteral(predicates,
|
|
523
|
+
riskCeiling: firstLiteral(predicates, GrantVocab.riskCeiling),
|
|
543
524
|
decisionBy,
|
|
544
525
|
decisionRole,
|
|
545
|
-
onBehalfOf: firstIri(predicates,
|
|
526
|
+
onBehalfOf: firstIri(predicates, GrantVocab.onBehalfOf),
|
|
546
527
|
createdAt,
|
|
547
|
-
revokedAt: firstLiteral(predicates,
|
|
528
|
+
revokedAt: firstLiteral(predicates, GrantVocab.revokedAt),
|
|
548
529
|
};
|
|
549
530
|
}
|
|
550
531
|
export async function createRemoteWatchApproval(options) {
|
|
@@ -564,7 +545,7 @@ export async function createRemoteWatchApproval(options) {
|
|
|
564
545
|
risk: buildRisk(options.request),
|
|
565
546
|
...(options.request.kind === 'command-approval' && options.request.command ? { command: options.request.command } : {}),
|
|
566
547
|
...(options.request.kind === 'command-approval' && options.request.cwd ? { cwd: options.request.cwd } : {}),
|
|
567
|
-
|
|
548
|
+
entry: sessionUri,
|
|
568
549
|
}),
|
|
569
550
|
runtime: activeRuntime,
|
|
570
551
|
});
|
|
@@ -586,14 +567,7 @@ export async function createRemoteApproval(options) {
|
|
|
586
567
|
const assignedTo = subject.assignedTo ?? webId;
|
|
587
568
|
const onBehalfOf = subject.onBehalfOf ?? webId;
|
|
588
569
|
const policyVersion = subject.policyVersion ?? REMOTE_APPROVAL_POLICY_VERSION;
|
|
589
|
-
const
|
|
590
|
-
kind: request.kind,
|
|
591
|
-
message: request.message,
|
|
592
|
-
sessionId: extractSessionId(sessionUri),
|
|
593
|
-
toolName: request.toolName,
|
|
594
|
-
...(request.command ? { command: request.command } : {}),
|
|
595
|
-
...(request.cwd ? { cwd: request.cwd } : {}),
|
|
596
|
-
};
|
|
570
|
+
const requestEntry = request.entry ?? approvalUri;
|
|
597
571
|
await store.insertApproval({
|
|
598
572
|
id: approvalId,
|
|
599
573
|
session: sessionUri,
|
|
@@ -607,25 +581,27 @@ export async function createRemoteApproval(options) {
|
|
|
607
581
|
policyVersion,
|
|
608
582
|
createdAt: now,
|
|
609
583
|
});
|
|
610
|
-
|
|
584
|
+
const requestAudit = {
|
|
611
585
|
id: crypto.randomUUID(),
|
|
612
586
|
action: 'approval_requested',
|
|
613
587
|
actor: subject.actorUri,
|
|
614
588
|
actorRole: 'secretary',
|
|
615
589
|
onBehalfOf,
|
|
616
590
|
session: sessionUri,
|
|
591
|
+
entry: requestEntry,
|
|
617
592
|
toolCallId: request.toolCallId,
|
|
593
|
+
toolName: request.toolName,
|
|
618
594
|
approval: approvalUri,
|
|
619
|
-
context: JSON.stringify(requestContext),
|
|
620
595
|
policyVersion,
|
|
621
596
|
createdAt: now,
|
|
622
|
-
}
|
|
623
|
-
await store.
|
|
597
|
+
};
|
|
598
|
+
await warnOnly(activeRuntime, () => store.insertAudit(requestAudit));
|
|
599
|
+
await warnOnly(activeRuntime, () => store.insertInboxNotification({
|
|
624
600
|
id: crypto.randomUUID(),
|
|
625
601
|
actor: subject.actorUri,
|
|
626
602
|
object: approvalUri,
|
|
627
603
|
createdAt: now,
|
|
628
|
-
})
|
|
604
|
+
}));
|
|
629
605
|
return normalizeApprovalSummary({
|
|
630
606
|
id: approvalId,
|
|
631
607
|
session: sessionUri,
|
|
@@ -638,19 +614,7 @@ export async function createRemoteApproval(options) {
|
|
|
638
614
|
assignedTo,
|
|
639
615
|
policyVersion,
|
|
640
616
|
createdAt: now,
|
|
641
|
-
}
|
|
642
|
-
id: crypto.randomUUID(),
|
|
643
|
-
action: 'approval_requested',
|
|
644
|
-
actor: subject.actorUri,
|
|
645
|
-
actorRole: 'secretary',
|
|
646
|
-
onBehalfOf,
|
|
647
|
-
session: sessionUri,
|
|
648
|
-
toolCallId: request.toolCallId,
|
|
649
|
-
approval: approvalUri,
|
|
650
|
-
context: JSON.stringify(requestContext),
|
|
651
|
-
policyVersion,
|
|
652
|
-
createdAt: now,
|
|
653
|
-
}]);
|
|
617
|
+
});
|
|
654
618
|
});
|
|
655
619
|
}
|
|
656
620
|
export async function waitForRemoteWatchApproval(options) {
|
|
@@ -737,12 +701,9 @@ export async function listRemoteWatchApprovals(options = {}) {
|
|
|
737
701
|
const activeRuntime = options.runtime ?? await createDefaultRuntime();
|
|
738
702
|
const requestedStatus = options.status ?? 'pending';
|
|
739
703
|
return withRemoteApprovalStore(activeRuntime, async ({ store, webId }) => {
|
|
740
|
-
const
|
|
741
|
-
store.listApprovals(),
|
|
742
|
-
store.listAudits(),
|
|
743
|
-
]);
|
|
704
|
+
const approvals = await store.listApprovals();
|
|
744
705
|
return approvals
|
|
745
|
-
.map((row) => normalizeApprovalSummary(row
|
|
706
|
+
.map((row) => normalizeApprovalSummary(row))
|
|
746
707
|
.filter((summary) => !summary.assignedTo || summary.assignedTo === webId)
|
|
747
708
|
.filter((summary) => requestedStatus === 'all' || summary.status === requestedStatus)
|
|
748
709
|
.sort((left, right) => right.createdAt.localeCompare(left.createdAt));
|
|
@@ -757,8 +718,7 @@ export async function resolveRemoteWatchApproval(options) {
|
|
|
757
718
|
throw new Error(`Remote approval not found: ${options.approvalId}`);
|
|
758
719
|
}
|
|
759
720
|
if (row.status !== 'pending') {
|
|
760
|
-
|
|
761
|
-
return normalizeApprovalSummary(row, audits);
|
|
721
|
+
return normalizeApprovalSummary(row);
|
|
762
722
|
}
|
|
763
723
|
const now = activeRuntime.now();
|
|
764
724
|
const approvalCreatedAt = new Date(toIsoString(row.createdAt, now.toISOString()));
|
|
@@ -774,22 +734,20 @@ export async function resolveRemoteWatchApproval(options) {
|
|
|
774
734
|
reason: encodeDecisionReason(options.decision, options.note),
|
|
775
735
|
resolvedAt: now,
|
|
776
736
|
});
|
|
777
|
-
await store.insertAudit({
|
|
737
|
+
await warnOnly(activeRuntime, () => store.insertAudit({
|
|
778
738
|
id: crypto.randomUUID(),
|
|
779
739
|
action: nextStatus === 'approved' ? 'approval_approved' : 'approval_rejected',
|
|
780
740
|
actor: webId,
|
|
781
741
|
actorRole: 'human',
|
|
782
742
|
onBehalfOf: webId,
|
|
783
743
|
session: row.session,
|
|
744
|
+
entry: approvalUri,
|
|
784
745
|
toolCallId: row.toolCallId,
|
|
746
|
+
toolName: row.toolName,
|
|
785
747
|
approval: approvalUri,
|
|
786
|
-
context: JSON.stringify({
|
|
787
|
-
decision: options.decision,
|
|
788
|
-
...(options.note?.trim() ? { note: options.note.trim() } : {}),
|
|
789
|
-
}),
|
|
790
748
|
policyVersion: REMOTE_APPROVAL_POLICY_VERSION,
|
|
791
749
|
createdAt: now,
|
|
792
|
-
});
|
|
750
|
+
}));
|
|
793
751
|
if (options.decision === 'accept_for_session') {
|
|
794
752
|
const grantId = crypto.randomUUID();
|
|
795
753
|
await store.insertGrant({
|
|
@@ -803,19 +761,19 @@ export async function resolveRemoteWatchApproval(options) {
|
|
|
803
761
|
onBehalfOf: webId,
|
|
804
762
|
createdAt: now,
|
|
805
763
|
});
|
|
806
|
-
await store.insertInboxNotification({
|
|
764
|
+
await warnOnly(activeRuntime, () => store.insertInboxNotification({
|
|
807
765
|
id: crypto.randomUUID(),
|
|
808
766
|
actor: webId,
|
|
809
767
|
object: buildGrantUri(row.session, grantId),
|
|
810
768
|
createdAt: now,
|
|
811
|
-
})
|
|
769
|
+
}));
|
|
812
770
|
}
|
|
813
|
-
await store.insertInboxNotification({
|
|
771
|
+
await warnOnly(activeRuntime, () => store.insertInboxNotification({
|
|
814
772
|
id: crypto.randomUUID(),
|
|
815
773
|
actor: webId,
|
|
816
774
|
object: approvalUri,
|
|
817
775
|
createdAt: now,
|
|
818
|
-
})
|
|
776
|
+
}));
|
|
819
777
|
const nextRow = {
|
|
820
778
|
...row,
|
|
821
779
|
status: nextStatus,
|
|
@@ -825,15 +783,13 @@ export async function resolveRemoteWatchApproval(options) {
|
|
|
825
783
|
reason: encodeDecisionReason(options.decision, options.note),
|
|
826
784
|
resolvedAt: now,
|
|
827
785
|
};
|
|
828
|
-
|
|
829
|
-
return normalizeApprovalSummary(nextRow, audits);
|
|
786
|
+
return normalizeApprovalSummary(nextRow);
|
|
830
787
|
});
|
|
831
788
|
}
|
|
832
789
|
export const __podApprovalInternal = {
|
|
833
790
|
createAbortError,
|
|
834
791
|
createDefaultRuntime,
|
|
835
792
|
buildActionUri,
|
|
836
|
-
buildRequestAuditContext,
|
|
837
793
|
buildRisk,
|
|
838
794
|
buildToolName,
|
|
839
795
|
createNativeRemoteApprovalStore,
|
|
@@ -844,6 +800,5 @@ export const __podApprovalInternal = {
|
|
|
844
800
|
isRemoteApprovalAbortError,
|
|
845
801
|
normalizeApprovalSummary,
|
|
846
802
|
parseDecisionReason,
|
|
847
|
-
parseRequestAuditContext,
|
|
848
803
|
};
|
|
849
804
|
//# sourceMappingURL=pod-approval.js.map
|