@undefineds.co/linx 0.2.15 → 0.2.17

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 (103) hide show
  1. package/dist/generated/version.js +3 -0
  2. package/dist/generated/version.js.map +1 -0
  3. package/dist/index.js +51 -225
  4. package/dist/index.js.map +1 -1
  5. package/dist/lib/account-api.js +1 -1
  6. package/dist/lib/account-api.js.map +1 -1
  7. package/dist/lib/account-session.js +1 -1
  8. package/dist/lib/account-session.js.map +1 -1
  9. package/dist/lib/ai-command.js +59 -32
  10. package/dist/lib/ai-command.js.map +1 -1
  11. package/dist/lib/chat-api.js +19 -177
  12. package/dist/lib/chat-api.js.map +1 -1
  13. package/dist/lib/codex-plugin/bridge.js.map +1 -1
  14. package/dist/lib/codex-plugin/codex-native-proxy.js.map +1 -1
  15. package/dist/lib/codex-plugin/index.js.map +1 -1
  16. package/dist/lib/codex-plugin/runner.js.map +1 -1
  17. package/dist/lib/credentials-store.js +1 -7
  18. package/dist/lib/credentials-store.js.map +1 -1
  19. package/dist/lib/default-model.js +0 -1
  20. package/dist/lib/default-model.js.map +1 -1
  21. package/dist/lib/login-command.js +2 -17
  22. package/dist/lib/login-command.js.map +1 -1
  23. package/dist/lib/models.js +27 -2
  24. package/dist/lib/models.js.map +1 -1
  25. package/dist/lib/oidc-auth.js +13 -78
  26. package/dist/lib/oidc-auth.js.map +1 -1
  27. package/dist/lib/oidc-session-storage.js.map +1 -1
  28. package/dist/lib/pi-adapter/auth.js +5 -12
  29. package/dist/lib/pi-adapter/auth.js.map +1 -1
  30. package/dist/lib/pi-adapter/branding.js +75 -553
  31. package/dist/lib/pi-adapter/branding.js.map +1 -1
  32. package/dist/lib/pi-adapter/index.js.map +1 -1
  33. package/dist/lib/pi-adapter/interactive.js +4 -154
  34. package/dist/lib/pi-adapter/interactive.js.map +1 -1
  35. package/dist/lib/pi-adapter/runtime.js +23 -138
  36. package/dist/lib/pi-adapter/runtime.js.map +1 -1
  37. package/dist/lib/pi-adapter/stream.js +4 -154
  38. package/dist/lib/pi-adapter/stream.js.map +1 -1
  39. package/dist/lib/pi-adapter/theme.js.map +1 -1
  40. package/dist/lib/pod-chat-store.js +1 -1
  41. package/dist/lib/pod-chat-store.js.map +1 -1
  42. package/dist/lib/profile-identity.js +60 -16
  43. package/dist/lib/profile-identity.js.map +1 -1
  44. package/dist/lib/prompt.js.map +1 -1
  45. package/dist/lib/runtime-target.js +1 -1
  46. package/dist/lib/runtime-target.js.map +1 -1
  47. package/dist/lib/solid-auth.js.map +1 -1
  48. package/dist/lib/thread-utils.js.map +1 -1
  49. package/dist/lib/watch/archive.js +1 -1
  50. package/dist/lib/watch/archive.js.map +1 -1
  51. package/dist/lib/watch/auth.js +1 -1
  52. package/dist/lib/watch/auth.js.map +1 -1
  53. package/dist/lib/watch/codex-composer.js.map +1 -1
  54. package/dist/lib/watch/codex-footer.js.map +1 -1
  55. package/dist/lib/watch/codex-overlay.js.map +1 -1
  56. package/dist/lib/watch/codex-request-form.js +1 -1
  57. package/dist/lib/watch/codex-request-form.js.map +1 -1
  58. package/dist/lib/watch/codex-request-input.js.map +1 -1
  59. package/dist/lib/watch/display.js.map +1 -1
  60. package/dist/lib/watch/format.js.map +1 -1
  61. package/dist/lib/watch/hooks/claude.js.map +1 -1
  62. package/dist/lib/watch/hooks/codebuddy.js.map +1 -1
  63. package/dist/lib/watch/hooks/codex.js.map +1 -1
  64. package/dist/lib/watch/hooks/index.js.map +1 -1
  65. package/dist/lib/watch/hooks/shared.js +1 -0
  66. package/dist/lib/watch/hooks/shared.js.map +1 -1
  67. package/dist/lib/watch/index.js.map +1 -1
  68. package/dist/lib/watch/pod-ai.js +32 -16
  69. package/dist/lib/watch/pod-ai.js.map +1 -1
  70. package/dist/lib/watch/pod-approval.js +203 -481
  71. package/dist/lib/watch/pod-approval.js.map +1 -1
  72. package/dist/lib/watch/pod-persistence.js +37 -24
  73. package/dist/lib/watch/pod-persistence.js.map +1 -1
  74. package/dist/lib/watch/runner.js +1 -4
  75. package/dist/lib/watch/runner.js.map +1 -1
  76. package/dist/lib/watch/types.js.map +1 -1
  77. package/dist/skills/drizzle-solid/SKILL.md +340 -0
  78. package/dist/skills/pod-storage/SKILL.md +60 -0
  79. package/dist/skills/solid-modeling/SKILL.md +274 -0
  80. package/dist/skills/xpod-componentsjs/SKILL.md +284 -0
  81. package/dist/watch-cli.js.map +1 -1
  82. package/package.json +10 -3
  83. package/vendor/client/dist/client/index.d.ts +118 -0
  84. package/vendor/client/dist/client/index.js +260 -0
  85. package/vendor/client/dist/index.d.ts +1 -0
  86. package/vendor/client/dist/index.js +1 -0
  87. package/vendor/client/dist/watch/index.d.ts +226 -0
  88. package/vendor/client/dist/watch/index.js +1114 -0
  89. package/vendor/client/package.json +9 -0
  90. package/dist/lib/node-warning-filter.js +0 -34
  91. package/dist/lib/node-warning-filter.js.map +0 -1
  92. package/dist/lib/pi-adapter/pod-approval.js +0 -8
  93. package/dist/lib/pi-adapter/pod-approval.js.map +0 -1
  94. package/dist/lib/pi-adapter/pod-mirror-mapping.js +0 -189
  95. package/dist/lib/pi-adapter/pod-mirror-mapping.js.map +0 -1
  96. package/dist/lib/pi-adapter/pod-mirror.js +0 -334
  97. package/dist/lib/pi-adapter/pod-mirror.js.map +0 -1
  98. package/dist/lib/pi-adapter/pod-native.js +0 -477
  99. package/dist/lib/pi-adapter/pod-native.js.map +0 -1
  100. package/dist/lib/pi-adapter/session.js +0 -727
  101. package/dist/lib/pi-adapter/session.js.map +0 -1
  102. package/dist/lib/pod-data-session.js +0 -70
  103. package/dist/lib/pod-data-session.js.map +0 -1
@@ -1,18 +1,17 @@
1
1
  import { setTimeout as delay } from 'node:timers/promises';
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';
6
2
  const WATCH_CHAT_ID = 'linx-watch';
7
3
  const WATCH_AGENT_ID = 'linx-watch-assistant';
8
4
  const REMOTE_APPROVAL_POLICY_VERSION = 'linx-watch-remote-approval/v1';
9
5
  const DEFAULT_REMOTE_APPROVAL_POLL_MS = 1000;
10
- const remoteApprovalClientCache = new WeakMap();
11
6
  function createAbortError() {
12
7
  const error = new Error('The operation was aborted.');
13
8
  error.name = 'AbortError';
14
9
  return error;
15
10
  }
11
+ async function dynamicImport(specifier) {
12
+ const loader = new Function('modulePath', 'return import(modulePath)');
13
+ return loader(specifier);
14
+ }
16
15
  function normalizeString(value) {
17
16
  return typeof value === 'string' && value.trim() ? value.trim() : undefined;
18
17
  }
@@ -42,19 +41,10 @@ function buildThreadUri(webId, threadId) {
42
41
  return `${getPodBaseUrl(webId)}/.data/chat/${WATCH_CHAT_ID}/index.ttl#${threadId}`;
43
42
  }
44
43
  function buildApprovalUri(webIdOrUri, approvalId) {
45
- return buildApprovalResourceUrl(webIdOrUri, approvalId);
46
- }
47
- function buildApprovalUriForDate(webIdOrUri, approvalId, createdAt) {
48
- return buildApprovalResourceUrl(webIdOrUri, approvalId, createdAt);
49
- }
50
- function documentUrlFromResourceUri(resourceUri) {
51
- return resourceUri.split('#', 1)[0] ?? resourceUri;
44
+ return `${getPodBaseUrl(webIdOrUri)}/.data/approvals/${approvalId}.ttl`;
52
45
  }
53
46
  function buildGrantUri(webIdOrUri, grantId) {
54
- return buildGrantResourceUrl(webIdOrUri, grantId);
55
- }
56
- function buildGrantDocumentUrl(webIdOrUri) {
57
- return `${getPodBaseUrl(webIdOrUri)}/settings/autonomy/grants.ttl`;
47
+ return `${getPodBaseUrl(webIdOrUri)}/settings/autonomy/grants/${grantId}.ttl`;
58
48
  }
59
49
  function buildAgentUri(webId) {
60
50
  return `${getPodBaseUrl(webId)}/.data/agents/${WATCH_AGENT_ID}.ttl`;
@@ -113,6 +103,16 @@ function buildRequestMessage(request) {
113
103
  }
114
104
  return request.message;
115
105
  }
106
+ function buildRequestAuditContext(record, request) {
107
+ return {
108
+ kind: request.kind,
109
+ message: buildRequestMessage(request),
110
+ ...(request.kind === 'command-approval' && request.command ? { command: request.command } : {}),
111
+ ...(request.kind === 'command-approval' && request.cwd ? { cwd: request.cwd } : {}),
112
+ backend: record.backend,
113
+ sessionId: record.id,
114
+ };
115
+ }
116
116
  function extractToolCallId(request) {
117
117
  if (!isRecord(request.raw)) {
118
118
  return crypto.randomUUID();
@@ -124,7 +124,7 @@ function extractToolCallId(request) {
124
124
  ?? crypto.randomUUID();
125
125
  }
126
126
  function encodeDecisionReason(decision, note) {
127
- return safeJsonStringify({
127
+ return JSON.stringify({
128
128
  decision,
129
129
  ...(note?.trim() ? { note: note.trim() } : {}),
130
130
  });
@@ -151,25 +151,33 @@ function parseDecisionReason(value) {
151
151
  return null;
152
152
  }
153
153
  }
154
- async function warnOnly(runtime, task) {
155
- try {
156
- await task();
157
- }
158
- catch (error) {
159
- if (runtime.onWarning) {
160
- runtime.onWarning(error);
161
- return;
162
- }
163
- const message = error instanceof Error ? error.message : String(error);
164
- process.emitWarning(`LinX Pod sync failed: ${message}`);
154
+ function parseRequestAuditContext(value) {
155
+ if (typeof value !== 'string' || !value.trim()) {
156
+ return null;
165
157
  }
166
- }
167
- function safeJsonStringify(value) {
168
158
  try {
169
- return JSON.stringify(value);
159
+ const parsed = JSON.parse(value);
160
+ if (!isRecord(parsed)) {
161
+ return null;
162
+ }
163
+ const kind = normalizeString(parsed.kind);
164
+ const message = normalizeString(parsed.message);
165
+ const backend = normalizeString(parsed.backend);
166
+ const sessionId = normalizeString(parsed.sessionId);
167
+ if (!kind || !message || !backend || !sessionId) {
168
+ return null;
169
+ }
170
+ return {
171
+ kind: kind,
172
+ message,
173
+ backend: backend,
174
+ sessionId,
175
+ ...(normalizeString(parsed.command) ? { command: normalizeString(parsed.command) } : {}),
176
+ ...(normalizeString(parsed.cwd) ? { cwd: normalizeString(parsed.cwd) } : {}),
177
+ };
170
178
  }
171
179
  catch {
172
- return JSON.stringify({ error: 'unserializable_context' });
180
+ return null;
173
181
  }
174
182
  }
175
183
  function extractSessionId(sessionUri) {
@@ -192,20 +200,29 @@ function decisionFromApprovalRow(row) {
192
200
  }
193
201
  return 'accept';
194
202
  }
195
- function normalizeApprovalSummary(row) {
203
+ function requestAuditForApproval(approvalUri, audits) {
204
+ const matches = audits.filter((audit) => audit.approval === approvalUri && audit.action === 'approval_requested');
205
+ matches.sort((left, right) => toIsoString(right.createdAt, '').localeCompare(toIsoString(left.createdAt, '')));
206
+ return matches[0];
207
+ }
208
+ function normalizeApprovalSummary(row, audits) {
209
+ const approvalUri = buildApprovalUri(row.session, row.id);
210
+ const requestAudit = requestAuditForApproval(approvalUri, audits);
211
+ const requestContext = parseRequestAuditContext(requestAudit?.context);
196
212
  const createdAt = toIsoString(row.createdAt, new Date(0).toISOString());
197
213
  const sessionUri = row.session;
198
214
  const decision = decisionFromApprovalRow(row);
199
215
  return {
200
216
  id: row.id,
201
- ...(normalizeString(row.approvalUri) ? { approvalUri: normalizeString(row.approvalUri) } : {}),
202
217
  sessionId: extractSessionId(sessionUri),
203
218
  sessionUri,
204
219
  toolCallId: row.toolCallId,
205
220
  toolName: row.toolName,
206
221
  risk: normalizeString(row.risk) ?? 'medium',
207
222
  status: normalizeString(row.status) ?? 'pending',
208
- message: formatApprovalMessage(row),
223
+ message: requestContext?.message ?? row.toolName,
224
+ ...(requestContext?.command ? { command: requestContext.command } : {}),
225
+ ...(requestContext?.cwd ? { cwd: requestContext.cwd } : {}),
209
226
  ...(normalizeString(row.assignedTo) ? { assignedTo: normalizeString(row.assignedTo) } : {}),
210
227
  ...(normalizeString(row.decisionBy) ? { decisionBy: normalizeString(row.decisionBy) } : {}),
211
228
  ...(decision ? { decision } : {}),
@@ -213,18 +230,6 @@ function normalizeApprovalSummary(row) {
213
230
  ...(row.resolvedAt ? { resolvedAt: toIsoString(row.resolvedAt, createdAt) } : {}),
214
231
  };
215
232
  }
216
- function formatApprovalMessage(row) {
217
- if (row.toolName === 'commandExecution') {
218
- return 'Command execution approval';
219
- }
220
- if (row.toolName === 'fileChange') {
221
- return 'File change approval';
222
- }
223
- if (row.toolName === 'permissionRequest') {
224
- return 'Permission approval';
225
- }
226
- return row.toolName;
227
- }
228
233
  function formatSummaryHeadline(summary) {
229
234
  return `${summary.id} | ${summary.status} | ${summary.risk} | session=${summary.sessionId}`;
230
235
  }
@@ -243,11 +248,72 @@ export function isRemoteApprovalAbortError(error) {
243
248
  function missingRemoteApprovalCredentialsMessage() {
244
249
  return 'LinX remote approval requires `linx login` first.';
245
250
  }
251
+ function unsupportedRemoteApprovalAuthMessage() {
252
+ return 'LinX remote approval requires client credentials auth in `~/.linx`.';
253
+ }
246
254
  async function createDefaultRuntime() {
255
+ const [credentialsStore, solidAuth, models] = await Promise.all([
256
+ dynamicImport(new URL('../credentials-store.js', import.meta.url).href),
257
+ dynamicImport(new URL('../solid-auth.js', import.meta.url).href),
258
+ dynamicImport(new URL('...co/models.js', import.meta.url).href),
259
+ ]);
247
260
  return {
248
- getPodDataSession: getDefaultPodDataSession,
249
- createStore(webId, fetcher) {
250
- return createNativeRemoteApprovalStore(webId, fetcher);
261
+ loadCredentials: credentialsStore.loadCredentials,
262
+ getClientCredentials: credentialsStore.getClientCredentials,
263
+ authenticate: solidAuth.authenticate,
264
+ createStore(session) {
265
+ const db = models.drizzle(session, {
266
+ logger: false,
267
+ disableInteropDiscovery: true,
268
+ schema: models.solidSchema,
269
+ });
270
+ let initialized = false;
271
+ async function ensureInitialized() {
272
+ if (initialized) {
273
+ return;
274
+ }
275
+ initialized = true;
276
+ await db.init([
277
+ models.approvalTable,
278
+ models.auditTable,
279
+ models.grantTable,
280
+ models.inboxNotificationTable,
281
+ ]).catch(() => undefined);
282
+ }
283
+ return {
284
+ async listApprovals() {
285
+ await ensureInitialized();
286
+ return await db.select().from(models.approvalTable).execute();
287
+ },
288
+ async insertApproval(row) {
289
+ await ensureInitialized();
290
+ await db.insert(models.approvalTable).values(row).execute();
291
+ },
292
+ async updateApproval(id, patch) {
293
+ await ensureInitialized();
294
+ await db.update(models.approvalTable).set(patch).where(models.eq(models.approvalTable.id, id)).execute();
295
+ },
296
+ async listAudits() {
297
+ await ensureInitialized();
298
+ return await db.select().from(models.auditTable).execute();
299
+ },
300
+ async insertAudit(row) {
301
+ await ensureInitialized();
302
+ await db.insert(models.auditTable).values(row).execute();
303
+ },
304
+ async listGrants() {
305
+ await ensureInitialized();
306
+ return await db.select().from(models.grantTable).execute();
307
+ },
308
+ async insertGrant(row) {
309
+ await ensureInitialized();
310
+ await db.insert(models.grantTable).values(row).execute();
311
+ },
312
+ async insertInboxNotification(row) {
313
+ await ensureInitialized();
314
+ await db.insert(models.inboxNotificationTable).values(row).execute();
315
+ },
316
+ };
251
317
  },
252
318
  sleep(ms) {
253
319
  return delay(ms);
@@ -258,395 +324,97 @@ async function createDefaultRuntime() {
258
324
  };
259
325
  }
260
326
  async function withRemoteApprovalStore(runtime, fn) {
261
- const client = await getRemoteApprovalClient(runtime);
262
- if (!client) {
327
+ const stored = runtime.loadCredentials();
328
+ if (!stored) {
263
329
  throw new Error(missingRemoteApprovalCredentialsMessage());
264
330
  }
265
- return await fn({
266
- store: client.store,
267
- webId: client.session.webId,
268
- stored: client.session.credentials,
269
- });
270
- }
271
- async function getRemoteApprovalClient(runtime) {
272
- let promise = remoteApprovalClientCache.get(runtime);
273
- if (!promise) {
274
- promise = createRemoteApprovalClient(runtime)
275
- .then((client) => {
276
- if (!client) {
277
- remoteApprovalClientCache.delete(runtime);
278
- }
279
- return client;
280
- })
281
- .catch((error) => {
282
- remoteApprovalClientCache.delete(runtime);
283
- throw error;
284
- });
285
- remoteApprovalClientCache.set(runtime, promise);
286
- }
287
- return promise;
288
- }
289
- async function createRemoteApprovalClient(runtime) {
290
- const session = await runtime.getPodDataSession();
291
- if (!session) {
292
- return null;
293
- }
294
- return {
295
- session,
296
- store: runtime.createStore(session.webId, session.fetch),
297
- };
298
- }
299
- function createNativeRemoteApprovalStore(webId, fetcher) {
300
- return {
301
- listApprovals: () => listApprovalRows(webId, fetcher),
302
- findApproval: (id, options) => findApprovalRow(webId, fetcher, id, options),
303
- insertApproval: (row) => writeApprovalRow(webId, fetcher, row),
304
- async updateApproval(id, patch) {
305
- const existing = (await listApprovalRows(webId, fetcher)).find((row) => row.id === id);
306
- if (!existing) {
307
- throw new Error(`Remote approval not found: ${id}`);
308
- }
309
- await writeApprovalRow(webId, fetcher, { ...existing, ...patch });
310
- },
311
- listAudits: () => listAuditRows(webId, fetcher),
312
- insertAudit: (row) => writeAuditRow(webId, fetcher, row),
313
- listGrants: () => listGrantRows(webId, fetcher),
314
- insertGrant: (row) => writeGrantRow(webId, fetcher, row),
315
- insertInboxNotification: (row) => writeInboxNotificationRow(webId, fetcher, row),
316
- };
317
- }
318
- async function findApprovalRow(webId, fetcher, id, options = {}) {
319
- if (options.resourceUri) {
320
- return readApprovalRowFromResource(fetcher, options.resourceUri);
321
- }
322
- if (options.createdAt) {
323
- const createdAt = new Date(toIsoString(options.createdAt, new Date().toISOString()));
324
- return readApprovalRowFromResource(fetcher, buildApprovalResourceUrl(webId, id, createdAt));
331
+ const clientCredentials = runtime.getClientCredentials(stored);
332
+ if (!clientCredentials) {
333
+ throw new Error(unsupportedRemoteApprovalAuthMessage());
325
334
  }
326
- return (await listApprovalRows(webId, fetcher)).find((row) => row.id === id) ?? null;
327
- }
328
- async function readApprovalRowFromResource(fetcher, resourceUri) {
329
- const turtle = await readTurtleResource(fetcher, documentUrlFromResourceUri(resourceUri));
330
- if (!turtle) {
331
- return null;
332
- }
333
- for (const [subject, predicates] of parseManagedTurtleBlocks(turtle, documentUrlFromResourceUri(resourceUri))) {
334
- if (subject !== resourceUri) {
335
- continue;
336
- }
337
- const row = approvalRowFromPredicates(subject, predicates);
338
- if (row) {
339
- return row;
340
- }
335
+ const { session } = await runtime.authenticate(clientCredentials.clientId, clientCredentials.clientSecret, stored.url);
336
+ const webId = session.info.webId ?? stored.webId;
337
+ if (!webId) {
338
+ await session.logout().catch(() => undefined);
339
+ throw new Error('Remote approval authentication succeeded without a WebID.');
341
340
  }
342
- return null;
343
- }
344
- async function listApprovalRows(webId, fetcher) {
345
- const [currentUrls, legacyUrls] = await Promise.all([
346
- listTurtleResourcesRecursive(fetcher, `${getPodBaseUrl(webId)}/.data/approvals/`).catch(() => []),
347
- listTurtleResources(fetcher, `${getPodBaseUrl(webId)}/.data/approvals/`).catch(() => []),
348
- ]);
349
- const urls = [...new Set([...currentUrls, ...legacyUrls])];
350
- const rows = [];
351
- for (const url of urls.filter((entry) => entry.endsWith('.ttl'))) {
352
- const turtle = await readTurtleResource(fetcher, url).catch(() => null);
353
- if (!turtle)
354
- continue;
355
- for (const [subject, predicates] of parseManagedTurtleBlocks(turtle, url)) {
356
- const row = approvalRowFromPredicates(subject, predicates);
357
- if (row)
358
- rows.push(row);
359
- }
360
- }
361
- return rows;
362
- }
363
- async function writeApprovalRow(webId, fetcher, row) {
364
- const createdAt = new Date(toIsoString(row.createdAt, new Date().toISOString()));
365
- const documentUrl = buildApprovalDocumentUrl(webId, createdAt);
366
- const subjectUrl = buildApprovalResourceUrl(webId, row.id, createdAt);
367
- await upsertManagedTurtleBlock(fetcher, documentUrl, {
368
- subject: subjectUrl,
369
- triples: [
370
- { predicate: RDF_TYPE, object: iri(UDFS.ApprovalRequest) },
371
- { predicate: ApprovalVocab.session, object: iri(row.session) },
372
- { predicate: ApprovalVocab.toolCallId, object: literal(row.toolCallId) },
373
- { predicate: ApprovalVocab.toolName, object: literal(row.toolName) },
374
- { predicate: ApprovalVocab.target, object: iri(row.target) },
375
- { predicate: ApprovalVocab.action, object: iri(row.action) },
376
- { predicate: ApprovalVocab.risk, object: literal(row.risk) },
377
- { predicate: ApprovalVocab.status, object: literal(row.status) },
378
- ...(row.assignedTo ? [{ predicate: ApprovalVocab.assignedTo, object: iri(row.assignedTo) }] : []),
379
- ...(row.decisionBy ? [{ predicate: ApprovalVocab.decisionBy, object: iri(row.decisionBy) }] : []),
380
- ...(row.decisionRole ? [{ predicate: ApprovalVocab.decisionRole, object: literal(row.decisionRole) }] : []),
381
- ...(row.onBehalfOf ? [{ predicate: ApprovalVocab.onBehalfOf, object: iri(row.onBehalfOf) }] : []),
382
- ...(row.reason ? [{ predicate: ApprovalVocab.reason, object: literal(row.reason) }] : []),
383
- ...(row.policyVersion ? [{ predicate: ApprovalVocab.policyVersion, object: literal(row.policyVersion) }] : []),
384
- { predicate: ApprovalVocab.createdAt, object: literal(toIsoString(row.createdAt, new Date().toISOString())) },
385
- ...(row.resolvedAt ? [{ predicate: ApprovalVocab.resolvedAt, object: literal(toIsoString(row.resolvedAt, new Date().toISOString())) }] : []),
386
- ],
387
- });
388
- }
389
- async function listAuditRows(webId, fetcher) {
390
- const urls = await listTurtleResourcesRecursive(fetcher, `${getPodBaseUrl(webId)}/.data/audits/`);
391
- const rows = [];
392
- for (const url of urls.filter((entry) => entry.endsWith('.ttl'))) {
393
- const turtle = await readTurtleResource(fetcher, url).catch(() => null);
394
- if (!turtle)
395
- continue;
396
- for (const [subject, predicates] of parseManagedTurtleBlocks(turtle, url)) {
397
- const row = auditRowFromPredicates(subject, predicates);
398
- if (row)
399
- rows.push(row);
400
- }
401
- }
402
- return rows;
403
- }
404
- async function writeAuditRow(webId, fetcher, row) {
405
- const createdAt = new Date(toIsoString(row.createdAt, new Date().toISOString()));
406
- const documentUrl = buildAuditDocumentUrl(webId, createdAt);
407
- const subjectUrl = buildAuditResourceUrl(webId, row.id, createdAt);
408
- await upsertManagedTurtleBlock(fetcher, documentUrl, {
409
- subject: subjectUrl,
410
- triples: [
411
- { predicate: RDF_TYPE, object: iri(UDFS.AuditEntry) },
412
- { predicate: AuditVocab.action, object: literal(row.action) },
413
- { predicate: AuditVocab.actor, object: iri(row.actor) },
414
- { predicate: AuditVocab.actorRole, object: literal(row.actorRole) },
415
- ...(row.onBehalfOf ? [{ predicate: AuditVocab.onBehalfOf, object: iri(row.onBehalfOf) }] : []),
416
- ...(row.session ? [{ predicate: AuditVocab.session, object: iri(row.session) }] : []),
417
- ...(row.entry ? [{ predicate: AuditVocab.entry, object: iri(row.entry) }] : []),
418
- ...(row.toolCallId ? [{ predicate: AuditVocab.toolCallId, object: literal(row.toolCallId) }] : []),
419
- ...(row.toolName ? [{ predicate: AuditVocab.toolName, object: literal(row.toolName) }] : []),
420
- ...(row.approval ? [{ predicate: AuditVocab.approval, object: iri(row.approval) }] : []),
421
- ...(row.policyVersion ? [{ predicate: AuditVocab.policyVersion, object: literal(row.policyVersion) }] : []),
422
- { predicate: AuditVocab.createdAt, object: literal(toIsoString(row.createdAt, new Date().toISOString())) },
423
- ],
424
- });
425
- }
426
- async function listGrantRows(webId, fetcher) {
427
- const urls = [
428
- `${getPodBaseUrl(webId)}/settings/autonomy/grants.ttl`,
429
- ...await listTurtleResources(fetcher, `${getPodBaseUrl(webId)}/settings/autonomy/grants/`).catch(() => []),
430
- ];
431
- const rows = [];
432
- for (const url of urls.filter((entry) => entry.endsWith('.ttl'))) {
433
- const turtle = await readTurtleResource(fetcher, url).catch(() => null);
434
- if (!turtle)
435
- continue;
436
- for (const [subject, predicates] of parseManagedTurtleBlocks(turtle, url)) {
437
- const row = grantRowFromPredicates(subject, predicates);
438
- if (row)
439
- rows.push(row);
440
- }
441
- }
442
- return rows;
443
- }
444
- async function writeGrantRow(webId, fetcher, row) {
445
- const id = normalizeString(row.id) ?? crypto.randomUUID();
446
- const documentUrl = buildGrantDocumentUrl(webId);
447
- const subjectUrl = buildGrantResourceUrl(webId, id);
448
- const target = normalizeString(row.target);
449
- const action = normalizeString(row.action);
450
- const effect = normalizeString(row.effect);
451
- const decisionBy = normalizeString(row.decisionBy);
452
- const decisionRole = normalizeString(row.decisionRole);
453
- if (!target || !action || !effect || !decisionBy || !decisionRole) {
454
- throw new Error(`Invalid remote approval grant row: ${id}`);
455
- }
456
- await upsertManagedTurtleBlock(fetcher, documentUrl, {
457
- subject: subjectUrl,
458
- triples: [
459
- { predicate: RDF_TYPE, object: iri(ODRL.Policy) },
460
- { predicate: RDF_TYPE, object: iri(UDFS.AutonomyGrant) },
461
- { predicate: GrantVocab.target, object: iri(target) },
462
- { predicate: GrantVocab.action, object: iri(action) },
463
- { predicate: GrantVocab.effect, object: literal(effect) },
464
- ...(normalizeString(row.riskCeiling) ? [{ predicate: GrantVocab.riskCeiling, object: literal(normalizeString(row.riskCeiling)) }] : []),
465
- { predicate: GrantVocab.decisionBy, object: iri(decisionBy) },
466
- { predicate: GrantVocab.decisionRole, object: literal(decisionRole) },
467
- ...(normalizeString(row.onBehalfOf) ? [{ predicate: GrantVocab.onBehalfOf, object: iri(normalizeString(row.onBehalfOf)) }] : []),
468
- { predicate: GrantVocab.createdAt, object: literal(toIsoString(row.createdAt, new Date().toISOString())) },
469
- ...(normalizeString(row.revokedAt) ? [{ predicate: GrantVocab.revokedAt, object: literal(normalizeString(row.revokedAt)) }] : []),
470
- ],
471
- });
472
- }
473
- async function writeInboxNotificationRow(webId, fetcher, row) {
474
- const url = buildInboxResourceUrl(webId, row.id);
475
- await upsertManagedTurtleBlock(fetcher, url, {
476
- subject: url,
477
- triples: [
478
- { predicate: RDF_TYPE, object: iri(AS.Announce) },
479
- ...(row.actor ? [{ predicate: InboxNotificationVocab.actor, object: iri(row.actor) }] : []),
480
- { predicate: InboxNotificationVocab.object, object: iri(row.object) },
481
- { predicate: InboxNotificationVocab.createdAt, object: literal(toIsoString(row.createdAt, new Date().toISOString())) },
482
- ],
483
- });
484
- }
485
- function approvalRowFromPredicates(url, predicates) {
486
- const session = firstIri(predicates, ApprovalVocab.session);
487
- const toolCallId = firstLiteral(predicates, ApprovalVocab.toolCallId);
488
- const toolName = firstLiteral(predicates, ApprovalVocab.toolName);
489
- const target = firstIri(predicates, ApprovalVocab.target);
490
- const action = firstIri(predicates, ApprovalVocab.action);
491
- const risk = firstLiteral(predicates, ApprovalVocab.risk);
492
- const status = firstLiteral(predicates, ApprovalVocab.status);
493
- const createdAt = firstLiteral(predicates, ApprovalVocab.createdAt);
494
- if (!session || !toolCallId || !toolName || !target || !action || !risk || !status || !createdAt) {
495
- return null;
496
- }
497
- return {
498
- id: subjectIdFromResourceUrl(url),
499
- session,
500
- toolCallId,
501
- toolName,
502
- target,
503
- action,
504
- risk,
505
- status,
506
- assignedTo: firstIri(predicates, ApprovalVocab.assignedTo),
507
- decisionBy: firstIri(predicates, ApprovalVocab.decisionBy),
508
- decisionRole: firstLiteral(predicates, ApprovalVocab.decisionRole),
509
- onBehalfOf: firstIri(predicates, ApprovalVocab.onBehalfOf),
510
- reason: firstLiteral(predicates, ApprovalVocab.reason),
511
- policyVersion: firstLiteral(predicates, ApprovalVocab.policyVersion),
512
- createdAt,
513
- resolvedAt: firstLiteral(predicates, ApprovalVocab.resolvedAt),
514
- };
515
- }
516
- function auditRowFromPredicates(url, predicates) {
517
- const action = firstLiteral(predicates, AuditVocab.action);
518
- const actor = firstIri(predicates, AuditVocab.actor);
519
- const actorRole = firstLiteral(predicates, AuditVocab.actorRole);
520
- const createdAt = firstLiteral(predicates, AuditVocab.createdAt);
521
- if (!action || !actor || !actorRole || !createdAt) {
522
- return null;
341
+ try {
342
+ return await fn({
343
+ store: runtime.createStore(session),
344
+ webId,
345
+ stored,
346
+ });
523
347
  }
524
- return {
525
- id: subjectIdFromResourceUrl(url),
526
- action,
527
- actor,
528
- actorRole,
529
- onBehalfOf: firstIri(predicates, AuditVocab.onBehalfOf),
530
- session: firstIri(predicates, AuditVocab.session),
531
- entry: firstIri(predicates, AuditVocab.entry),
532
- toolCallId: firstLiteral(predicates, AuditVocab.toolCallId),
533
- toolName: firstLiteral(predicates, AuditVocab.toolName),
534
- approval: firstIri(predicates, AuditVocab.approval),
535
- policyVersion: firstLiteral(predicates, AuditVocab.policyVersion),
536
- createdAt,
537
- };
538
- }
539
- function grantRowFromPredicates(url, predicates) {
540
- const target = firstIri(predicates, GrantVocab.target);
541
- const action = firstIri(predicates, GrantVocab.action);
542
- const effect = firstLiteral(predicates, GrantVocab.effect);
543
- const decisionBy = firstIri(predicates, GrantVocab.decisionBy);
544
- const decisionRole = firstLiteral(predicates, GrantVocab.decisionRole);
545
- const createdAt = firstLiteral(predicates, GrantVocab.createdAt);
546
- if (!target || !action || !effect || !decisionBy || !decisionRole || !createdAt) {
547
- return null;
348
+ finally {
349
+ await session.logout().catch(() => undefined);
548
350
  }
549
- return {
550
- id: subjectIdFromResourceUrl(url),
551
- target,
552
- action,
553
- effect,
554
- riskCeiling: firstLiteral(predicates, GrantVocab.riskCeiling),
555
- decisionBy,
556
- decisionRole,
557
- onBehalfOf: firstIri(predicates, GrantVocab.onBehalfOf),
558
- createdAt,
559
- revokedAt: firstLiteral(predicates, GrantVocab.revokedAt),
560
- };
561
351
  }
562
352
  export async function createRemoteWatchApproval(options) {
563
353
  const activeRuntime = options.runtime ?? await createDefaultRuntime();
564
- return createRemoteApproval({
565
- subject: ({ webId }) => ({
566
- sessionUri: buildThreadUri(webId, options.record.id),
567
- actorUri: buildAgentUri(webId),
568
- policyVersion: REMOTE_APPROVAL_POLICY_VERSION,
569
- }),
570
- request: ({ sessionUri }) => ({
571
- kind: options.request.kind,
572
- message: buildRequestMessage(options.request),
573
- toolCallId: extractToolCallId(options.request),
574
- toolName: buildToolName(options.request),
575
- action: buildActionUri(options.request),
576
- risk: buildRisk(options.request),
577
- ...(options.request.kind === 'command-approval' && options.request.command ? { command: options.request.command } : {}),
578
- ...(options.request.kind === 'command-approval' && options.request.cwd ? { cwd: options.request.cwd } : {}),
579
- entry: sessionUri,
580
- }),
581
- runtime: activeRuntime,
582
- });
583
- }
584
- export async function createRemoteApproval(options) {
585
- const activeRuntime = options.runtime ?? await createDefaultRuntime();
586
- return withRemoteApprovalStore(activeRuntime, async ({ store, webId, stored }) => {
587
- const subject = typeof options.subject === 'function'
588
- ? options.subject({ webId, stored })
589
- : options.subject;
590
- const request = typeof options.request === 'function'
591
- ? options.request({ webId, stored, sessionUri: subject.sessionUri })
592
- : options.request;
354
+ return withRemoteApprovalStore(activeRuntime, async ({ store, webId }) => {
593
355
  const approvalId = crypto.randomUUID();
594
356
  const now = activeRuntime.now();
595
- const sessionUri = subject.sessionUri;
596
- const approvalUri = buildApprovalUriForDate(webId, approvalId, now);
597
- const targetUri = subject.targetUri ?? sessionUri;
598
- const assignedTo = subject.assignedTo ?? webId;
599
- const onBehalfOf = subject.onBehalfOf ?? webId;
600
- const policyVersion = subject.policyVersion ?? REMOTE_APPROVAL_POLICY_VERSION;
601
- const requestEntry = request.entry ?? approvalUri;
357
+ const sessionUri = buildThreadUri(webId, options.record.id);
358
+ const approvalUri = buildApprovalUri(webId, approvalId);
359
+ const toolCallId = extractToolCallId(options.request);
360
+ const requestContext = buildRequestAuditContext(options.record, options.request);
602
361
  await store.insertApproval({
603
362
  id: approvalId,
604
363
  session: sessionUri,
605
- toolCallId: request.toolCallId,
606
- toolName: request.toolName,
607
- target: targetUri,
608
- action: request.action,
609
- risk: request.risk,
364
+ toolCallId,
365
+ toolName: buildToolName(options.request),
366
+ target: sessionUri,
367
+ action: buildActionUri(options.request),
368
+ risk: buildRisk(options.request),
610
369
  status: 'pending',
611
- assignedTo,
612
- policyVersion,
370
+ assignedTo: webId,
371
+ policyVersion: REMOTE_APPROVAL_POLICY_VERSION,
613
372
  createdAt: now,
614
373
  });
615
- const requestAudit = {
374
+ await store.insertAudit({
616
375
  id: crypto.randomUUID(),
617
376
  action: 'approval_requested',
618
- actor: subject.actorUri,
377
+ actor: buildAgentUri(webId),
619
378
  actorRole: 'secretary',
620
- onBehalfOf,
379
+ onBehalfOf: webId,
621
380
  session: sessionUri,
622
- entry: requestEntry,
623
- toolCallId: request.toolCallId,
624
- toolName: request.toolName,
381
+ toolCallId,
625
382
  approval: approvalUri,
626
- policyVersion,
383
+ context: JSON.stringify(requestContext),
384
+ policyVersion: REMOTE_APPROVAL_POLICY_VERSION,
627
385
  createdAt: now,
628
- };
629
- await warnOnly(activeRuntime, () => store.insertAudit(requestAudit));
630
- await warnOnly(activeRuntime, () => store.insertInboxNotification({
386
+ });
387
+ await store.insertInboxNotification({
631
388
  id: crypto.randomUUID(),
632
- actor: subject.actorUri,
389
+ actor: buildAgentUri(webId),
633
390
  object: approvalUri,
634
391
  createdAt: now,
635
- }));
392
+ }).catch(() => undefined);
636
393
  return normalizeApprovalSummary({
637
394
  id: approvalId,
638
- approvalUri,
639
395
  session: sessionUri,
640
- toolCallId: request.toolCallId,
641
- toolName: request.toolName,
642
- target: targetUri,
643
- action: request.action,
644
- risk: request.risk,
396
+ toolCallId,
397
+ toolName: buildToolName(options.request),
398
+ target: sessionUri,
399
+ action: buildActionUri(options.request),
400
+ risk: buildRisk(options.request),
645
401
  status: 'pending',
646
- assignedTo,
647
- policyVersion,
402
+ assignedTo: webId,
403
+ policyVersion: REMOTE_APPROVAL_POLICY_VERSION,
648
404
  createdAt: now,
649
- });
405
+ }, [{
406
+ id: crypto.randomUUID(),
407
+ action: 'approval_requested',
408
+ actor: buildAgentUri(webId),
409
+ actorRole: 'secretary',
410
+ onBehalfOf: webId,
411
+ session: sessionUri,
412
+ toolCallId,
413
+ approval: approvalUri,
414
+ context: JSON.stringify(requestContext),
415
+ policyVersion: REMOTE_APPROVAL_POLICY_VERSION,
416
+ createdAt: now,
417
+ }]);
650
418
  });
651
419
  }
652
420
  export async function waitForRemoteWatchApproval(options) {
@@ -656,13 +424,10 @@ export async function waitForRemoteWatchApproval(options) {
656
424
  if (options.signal?.aborted) {
657
425
  throw createAbortError();
658
426
  }
659
- const row = await readRemoteApprovalRow(store, {
660
- approvalId: options.approvalId,
661
- approvalUri: options.approvalUri,
662
- });
427
+ const approvals = await store.listApprovals();
428
+ const row = approvals.find((entry) => entry.id === options.approvalId);
663
429
  if (!row) {
664
- await activeRuntime.sleep(options.pollMs ?? DEFAULT_REMOTE_APPROVAL_POLL_MS);
665
- continue;
430
+ throw new Error(`Remote approval disappeared before resolution: ${options.approvalId}`);
666
431
  }
667
432
  const decision = decisionFromApprovalRow(row);
668
433
  if (decision) {
@@ -695,40 +460,6 @@ export async function requestRemoteWatchApproval(options) {
695
460
  });
696
461
  return waitForRemoteWatchApproval({
697
462
  approvalId: summary.id,
698
- approvalUri: summary.approvalUri,
699
- pollMs: options.pollMs,
700
- signal: options.signal,
701
- runtime: activeRuntime,
702
- });
703
- }
704
- export async function requestRemoteApproval(options) {
705
- const activeRuntime = options.runtime ?? await createDefaultRuntime();
706
- const delegated = await withRemoteApprovalStore(activeRuntime, async ({ store, webId, stored }) => {
707
- const subject = typeof options.subject === 'function'
708
- ? options.subject({ webId, stored })
709
- : options.subject;
710
- const request = typeof options.request === 'function'
711
- ? options.request({ webId, stored, sessionUri: subject.sessionUri })
712
- : options.request;
713
- const grants = await store.listGrants();
714
- const requestTarget = subject.targetUri ?? subject.sessionUri;
715
- return grants.some((grant) => (grant.effect === 'allow'
716
- && grant.action === request.action
717
- && grant.target === requestTarget
718
- && riskScore(typeof grant.riskCeiling === 'string' ? grant.riskCeiling : undefined) >= riskScore(request.risk)
719
- && !grant.revokedAt));
720
- });
721
- if (delegated) {
722
- return 'accept_for_session';
723
- }
724
- const summary = await createRemoteApproval({
725
- subject: options.subject,
726
- request: options.request,
727
- runtime: activeRuntime,
728
- });
729
- return waitForRemoteWatchApproval({
730
- approvalId: summary.id,
731
- approvalUri: summary.approvalUri,
732
463
  pollMs: options.pollMs,
733
464
  signal: options.signal,
734
465
  runtime: activeRuntime,
@@ -738,9 +469,12 @@ export async function listRemoteWatchApprovals(options = {}) {
738
469
  const activeRuntime = options.runtime ?? await createDefaultRuntime();
739
470
  const requestedStatus = options.status ?? 'pending';
740
471
  return withRemoteApprovalStore(activeRuntime, async ({ store, webId }) => {
741
- const approvals = await store.listApprovals();
472
+ const [approvals, audits] = await Promise.all([
473
+ store.listApprovals(),
474
+ store.listAudits(),
475
+ ]);
742
476
  return approvals
743
- .map((row) => normalizeApprovalSummary(row))
477
+ .map((row) => normalizeApprovalSummary(row, audits))
744
478
  .filter((summary) => !summary.assignedTo || summary.assignedTo === webId)
745
479
  .filter((summary) => requestedStatus === 'all' || summary.status === requestedStatus)
746
480
  .sort((left, right) => right.createdAt.localeCompare(left.createdAt));
@@ -749,19 +483,17 @@ export async function listRemoteWatchApprovals(options = {}) {
749
483
  export async function resolveRemoteWatchApproval(options) {
750
484
  const activeRuntime = options.runtime ?? await createDefaultRuntime();
751
485
  return withRemoteApprovalStore(activeRuntime, async ({ store, webId }) => {
752
- const row = await readRemoteApprovalRow(store, {
753
- approvalId: options.approvalId,
754
- approvalUri: options.approvalUri,
755
- });
486
+ const approvals = await store.listApprovals();
487
+ const row = approvals.find((entry) => entry.id === options.approvalId);
756
488
  if (!row) {
757
489
  throw new Error(`Remote approval not found: ${options.approvalId}`);
758
490
  }
759
491
  if (row.status !== 'pending') {
760
- return normalizeApprovalSummary(row);
492
+ const audits = await store.listAudits();
493
+ return normalizeApprovalSummary(row, audits);
761
494
  }
762
495
  const now = activeRuntime.now();
763
- const approvalCreatedAt = new Date(toIsoString(row.createdAt, now.toISOString()));
764
- const approvalUri = buildApprovalUriForDate(row.session, row.id, approvalCreatedAt);
496
+ const approvalUri = buildApprovalUri(row.session, row.id);
765
497
  const nextStatus = options.decision === 'accept' || options.decision === 'accept_for_session'
766
498
  ? 'approved'
767
499
  : 'rejected';
@@ -773,20 +505,22 @@ export async function resolveRemoteWatchApproval(options) {
773
505
  reason: encodeDecisionReason(options.decision, options.note),
774
506
  resolvedAt: now,
775
507
  });
776
- await warnOnly(activeRuntime, () => store.insertAudit({
508
+ await store.insertAudit({
777
509
  id: crypto.randomUUID(),
778
510
  action: nextStatus === 'approved' ? 'approval_approved' : 'approval_rejected',
779
511
  actor: webId,
780
512
  actorRole: 'human',
781
513
  onBehalfOf: webId,
782
514
  session: row.session,
783
- entry: approvalUri,
784
515
  toolCallId: row.toolCallId,
785
- toolName: row.toolName,
786
516
  approval: approvalUri,
517
+ context: JSON.stringify({
518
+ decision: options.decision,
519
+ ...(options.note?.trim() ? { note: options.note.trim() } : {}),
520
+ }),
787
521
  policyVersion: REMOTE_APPROVAL_POLICY_VERSION,
788
522
  createdAt: now,
789
- }));
523
+ });
790
524
  if (options.decision === 'accept_for_session') {
791
525
  const grantId = crypto.randomUUID();
792
526
  await store.insertGrant({
@@ -800,19 +534,19 @@ export async function resolveRemoteWatchApproval(options) {
800
534
  onBehalfOf: webId,
801
535
  createdAt: now,
802
536
  });
803
- await warnOnly(activeRuntime, () => store.insertInboxNotification({
537
+ await store.insertInboxNotification({
804
538
  id: crypto.randomUUID(),
805
539
  actor: webId,
806
540
  object: buildGrantUri(row.session, grantId),
807
541
  createdAt: now,
808
- }));
542
+ }).catch(() => undefined);
809
543
  }
810
- await warnOnly(activeRuntime, () => store.insertInboxNotification({
544
+ await store.insertInboxNotification({
811
545
  id: crypto.randomUUID(),
812
546
  actor: webId,
813
547
  object: approvalUri,
814
548
  createdAt: now,
815
- }));
549
+ }).catch(() => undefined);
816
550
  const nextRow = {
817
551
  ...row,
818
552
  status: nextStatus,
@@ -822,35 +556,23 @@ export async function resolveRemoteWatchApproval(options) {
822
556
  reason: encodeDecisionReason(options.decision, options.note),
823
557
  resolvedAt: now,
824
558
  };
825
- return normalizeApprovalSummary(nextRow);
559
+ const audits = await store.listAudits();
560
+ return normalizeApprovalSummary(nextRow, audits);
826
561
  });
827
562
  }
828
- async function readRemoteApprovalRow(store, options) {
829
- if (store.findApproval) {
830
- const row = await store.findApproval(options.approvalId, {
831
- resourceUri: options.approvalUri,
832
- });
833
- if (row || options.approvalUri) {
834
- return row;
835
- }
836
- }
837
- const approvals = await store.listApprovals();
838
- return approvals.find((entry) => entry.id === options.approvalId) ?? null;
839
- }
840
563
  export const __podApprovalInternal = {
841
564
  createAbortError,
842
- createDefaultRuntime,
843
565
  buildActionUri,
566
+ buildRequestAuditContext,
844
567
  buildRisk,
845
568
  buildToolName,
846
- createNativeRemoteApprovalStore,
847
569
  extractToolCallId,
848
570
  decisionFromApprovalRow,
849
571
  encodeDecisionReason,
850
572
  formatSummaryHeadline,
851
- readRemoteApprovalRow,
852
573
  isRemoteApprovalAbortError,
853
574
  normalizeApprovalSummary,
854
575
  parseDecisionReason,
576
+ parseRequestAuditContext,
855
577
  };
856
578
  //# sourceMappingURL=pod-approval.js.map