@undefineds.co/linx 0.3.5 → 0.3.8

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 (172) hide show
  1. package/README.md +58 -23
  2. package/dist/generated/version.js +1 -1
  3. package/dist/generated/version.js.map +1 -1
  4. package/dist/index.js +336 -162
  5. package/dist/index.js.map +1 -1
  6. package/dist/lib/account-session.js +4 -8
  7. package/dist/lib/account-session.js.map +1 -1
  8. package/dist/lib/ai-command.js +228 -178
  9. package/dist/lib/ai-command.js.map +1 -1
  10. package/dist/lib/auto-mode/archive.js +38 -7
  11. package/dist/lib/auto-mode/archive.js.map +1 -1
  12. package/dist/lib/auto-mode/auth.js.map +1 -1
  13. package/dist/lib/auto-mode/display.js +71 -45
  14. package/dist/lib/auto-mode/display.js.map +1 -1
  15. package/dist/lib/auto-mode/format.js +9 -7
  16. package/dist/lib/auto-mode/format.js.map +1 -1
  17. package/dist/lib/auto-mode/hooks/claude.js +12 -2
  18. package/dist/lib/auto-mode/hooks/claude.js.map +1 -1
  19. package/dist/lib/auto-mode/hooks/codex.js +17 -7
  20. package/dist/lib/auto-mode/hooks/codex.js.map +1 -1
  21. package/dist/lib/auto-mode/hooks/index.js +28 -8
  22. package/dist/lib/auto-mode/hooks/index.js.map +1 -1
  23. package/dist/lib/auto-mode/pod-ai.js +20 -37
  24. package/dist/lib/auto-mode/pod-ai.js.map +1 -1
  25. package/dist/lib/auto-mode/pod-approval.js +124 -195
  26. package/dist/lib/auto-mode/pod-approval.js.map +1 -1
  27. package/dist/lib/auto-mode/pod-persistence.js +169 -90
  28. package/dist/lib/auto-mode/pod-persistence.js.map +1 -1
  29. package/dist/lib/auto-mode/runner.js +683 -81
  30. package/dist/lib/auto-mode/runner.js.map +1 -1
  31. package/dist/lib/auto-mode/secretary.js +186 -41
  32. package/dist/lib/auto-mode/secretary.js.map +1 -1
  33. package/dist/lib/auto-mode-command.js +32 -32
  34. package/dist/lib/auto-mode-command.js.map +1 -1
  35. package/dist/lib/chat-api.js +242 -50
  36. package/dist/lib/chat-api.js.map +1 -1
  37. package/dist/lib/codex-plugin/bridge.js +164 -17
  38. package/dist/lib/codex-plugin/bridge.js.map +1 -1
  39. package/dist/lib/codex-plugin/codex-native-proxy.js +370 -34
  40. package/dist/lib/codex-plugin/codex-native-proxy.js.map +1 -1
  41. package/dist/lib/credentials-store.js +33 -42
  42. package/dist/lib/credentials-store.js.map +1 -1
  43. package/dist/lib/linx-cloud-errors.js +61 -0
  44. package/dist/lib/linx-cloud-errors.js.map +1 -0
  45. package/dist/lib/linx-tui-contract.js +8 -5
  46. package/dist/lib/linx-tui-contract.js.map +1 -1
  47. package/dist/lib/login-command.js +9 -2
  48. package/dist/lib/login-command.js.map +1 -1
  49. package/dist/lib/models.js +3 -20
  50. package/dist/lib/models.js.map +1 -1
  51. package/dist/lib/oidc-auth.js +143 -17
  52. package/dist/lib/oidc-auth.js.map +1 -1
  53. package/dist/lib/oidc-session-storage.js +2 -6
  54. package/dist/lib/oidc-session-storage.js.map +1 -1
  55. package/dist/lib/pi-adapter/auto-input-controller.js +988 -0
  56. package/dist/lib/pi-adapter/auto-input-controller.js.map +1 -0
  57. package/dist/lib/pi-adapter/backend-command.js +2 -0
  58. package/dist/lib/pi-adapter/backend-command.js.map +1 -0
  59. package/dist/lib/pi-adapter/backend-credentials.js +80 -0
  60. package/dist/lib/pi-adapter/backend-credentials.js.map +1 -0
  61. package/dist/lib/pi-adapter/branding.js +246 -108
  62. package/dist/lib/pi-adapter/branding.js.map +1 -1
  63. package/dist/lib/pi-adapter/control-state.js +72 -0
  64. package/dist/lib/pi-adapter/control-state.js.map +1 -0
  65. package/dist/lib/pi-adapter/interactive.js +2634 -30
  66. package/dist/lib/pi-adapter/interactive.js.map +1 -1
  67. package/dist/lib/pi-adapter/pod-approval.js +382 -210
  68. package/dist/lib/pi-adapter/pod-approval.js.map +1 -1
  69. package/dist/lib/pi-adapter/pod-mirror-mapping.js +71 -17
  70. package/dist/lib/pi-adapter/pod-mirror-mapping.js.map +1 -1
  71. package/dist/lib/pi-adapter/pod-mirror.js +531 -64
  72. package/dist/lib/pi-adapter/pod-mirror.js.map +1 -1
  73. package/dist/lib/pi-adapter/pod-native.js +81 -85
  74. package/dist/lib/pi-adapter/pod-native.js.map +1 -1
  75. package/dist/lib/pi-adapter/pod-status-output.js +54 -0
  76. package/dist/lib/pi-adapter/pod-status-output.js.map +1 -0
  77. package/dist/lib/pi-adapter/runtime.js +458 -228
  78. package/dist/lib/pi-adapter/runtime.js.map +1 -1
  79. package/dist/lib/pi-adapter/session-control.js +509 -0
  80. package/dist/lib/pi-adapter/session-control.js.map +1 -0
  81. package/dist/lib/pi-adapter/session.js +35 -22
  82. package/dist/lib/pi-adapter/session.js.map +1 -1
  83. package/dist/lib/pi-adapter/stream.js +89 -32
  84. package/dist/lib/pi-adapter/stream.js.map +1 -1
  85. package/dist/lib/pi-adapter/sync-recovery.js +89 -0
  86. package/dist/lib/pi-adapter/sync-recovery.js.map +1 -0
  87. package/dist/lib/pi-adapter/web-fetch.js +13 -14
  88. package/dist/lib/pi-adapter/web-fetch.js.map +1 -1
  89. package/dist/lib/pod-chat-store.js +254 -78
  90. package/dist/lib/pod-chat-store.js.map +1 -1
  91. package/dist/lib/pod-data-session.js +156 -35
  92. package/dist/lib/pod-data-session.js.map +1 -1
  93. package/dist/lib/solid-auth-store.js +27 -0
  94. package/dist/lib/solid-auth-store.js.map +1 -0
  95. package/dist/lib/solid-auth.js +2 -4
  96. package/dist/lib/solid-auth.js.map +1 -1
  97. package/dist/lib/solid-client-credentials-login.js +100 -0
  98. package/dist/lib/solid-client-credentials-login.js.map +1 -0
  99. package/dist/lib/solid-local-store.js +31 -0
  100. package/dist/lib/solid-local-store.js.map +1 -0
  101. package/dist/lib/symphony/archive.js +328 -18
  102. package/dist/lib/symphony/archive.js.map +1 -1
  103. package/dist/lib/symphony/pod-projection.js +2222 -0
  104. package/dist/lib/symphony/pod-projection.js.map +1 -0
  105. package/dist/lib/symphony-command.js +602 -178
  106. package/dist/lib/symphony-command.js.map +1 -1
  107. package/dist/lib/sync-checkpoint-store.js +74 -0
  108. package/dist/lib/sync-checkpoint-store.js.map +1 -0
  109. package/dist/skills/symphony/SKILL.md +665 -0
  110. package/package.json +15 -9
  111. package/vendor/agent-runtime/dist/agent-runtime.d.ts +137 -0
  112. package/vendor/agent-runtime/dist/agent-runtime.js +211 -0
  113. package/vendor/agent-runtime/dist/auto-mode.d.ts +78 -13
  114. package/vendor/agent-runtime/dist/auto-mode.js +288 -31
  115. package/vendor/agent-runtime/dist/control-plane.d.ts +28 -0
  116. package/vendor/agent-runtime/dist/control-plane.js +79 -0
  117. package/vendor/agent-runtime/dist/file-sync.d.ts +157 -0
  118. package/vendor/agent-runtime/dist/file-sync.js +314 -0
  119. package/vendor/agent-runtime/dist/index.d.ts +7 -0
  120. package/vendor/agent-runtime/dist/index.js +7 -0
  121. package/vendor/agent-runtime/dist/reconciler.d.ts +117 -0
  122. package/vendor/agent-runtime/dist/reconciler.js +361 -0
  123. package/vendor/agent-runtime/dist/symphony.d.ts +128 -8
  124. package/vendor/agent-runtime/dist/symphony.js +362 -57
  125. package/vendor/agent-runtime/dist/sync.d.ts +271 -0
  126. package/vendor/agent-runtime/dist/sync.js +550 -0
  127. package/vendor/agent-runtime/dist/thread-reconciler-controller.d.ts +58 -0
  128. package/vendor/agent-runtime/dist/thread-reconciler-controller.js +137 -0
  129. package/vendor/agent-runtime/dist/turn-controller.js +2 -2
  130. package/vendor/agent-runtime/dist/wake-scheduler.d.ts +67 -0
  131. package/vendor/agent-runtime/dist/wake-scheduler.js +194 -0
  132. package/vendor/agent-runtime/package.json +8 -1
  133. package/vendor/pi-web-access/CHANGELOG.md +387 -0
  134. package/vendor/pi-web-access/LICENSE +21 -0
  135. package/vendor/pi-web-access/README.md +352 -0
  136. package/vendor/pi-web-access/activity.ts +101 -0
  137. package/vendor/pi-web-access/banner.png +0 -0
  138. package/vendor/pi-web-access/chrome-cookies.ts +322 -0
  139. package/vendor/pi-web-access/code-search.ts +107 -0
  140. package/vendor/pi-web-access/curator-page.ts +3359 -0
  141. package/vendor/pi-web-access/curator-server.ts +605 -0
  142. package/vendor/pi-web-access/exa.ts +520 -0
  143. package/vendor/pi-web-access/extract.ts +641 -0
  144. package/vendor/pi-web-access/gemini-api.ts +112 -0
  145. package/vendor/pi-web-access/gemini-search.ts +361 -0
  146. package/vendor/pi-web-access/gemini-url-context.ts +126 -0
  147. package/vendor/pi-web-access/gemini-web-config.ts +52 -0
  148. package/vendor/pi-web-access/gemini-web.ts +396 -0
  149. package/vendor/pi-web-access/github-api.ts +196 -0
  150. package/vendor/pi-web-access/github-extract.ts +634 -0
  151. package/vendor/pi-web-access/index.ts +2346 -0
  152. package/vendor/pi-web-access/package.json +45 -0
  153. package/vendor/pi-web-access/pdf-extract.ts +192 -0
  154. package/vendor/pi-web-access/perplexity.ts +195 -0
  155. package/vendor/pi-web-access/pi-web-fetch-demo.mp4 +0 -0
  156. package/vendor/pi-web-access/rsc-extract.ts +338 -0
  157. package/vendor/pi-web-access/skills/librarian/SKILL.md +195 -0
  158. package/vendor/pi-web-access/storage.ts +72 -0
  159. package/vendor/pi-web-access/summary-review.ts +276 -0
  160. package/vendor/pi-web-access/test/gemini-web-cookie-opt-in.test.mjs +41 -0
  161. package/vendor/pi-web-access/test/pdf-extract.test.mjs +95 -0
  162. package/vendor/pi-web-access/utils.ts +44 -0
  163. package/vendor/pi-web-access/video-extract.ts +378 -0
  164. package/vendor/pi-web-access/youtube-extract.ts +310 -0
  165. package/dist/lib/pi-adapter/auth.js +0 -68
  166. package/dist/lib/pi-adapter/auth.js.map +0 -1
  167. package/dist/lib/pi-adapter/pod-tools.js +0 -140
  168. package/dist/lib/pi-adapter/pod-tools.js.map +0 -1
  169. package/dist/skills/drizzle-solid/SKILL.md +0 -340
  170. package/dist/skills/pod-storage/SKILL.md +0 -100
  171. package/dist/skills/solid-modeling/SKILL.md +0 -274
  172. package/dist/skills/xpod-componentsjs/SKILL.md +0 -284
@@ -1,13 +1,14 @@
1
1
  import { setTimeout as delay } from 'node:timers/promises';
2
+ import { resolvePodBaseUrl } from '@undefineds.co/drizzle-solid';
2
3
  import { getDefaultPodDataSession } from '../pod-data-session.js';
3
- import { approvalResource, auditResource, buildApprovalSubjectPath, buildGrantSubjectPath, drizzle, grantResource, inboxNotificationResource, solidResources, } from '../models.js';
4
+ import { agentResource, approvalResource, auditResource, chatResource, drizzle, grantResource, inboxNotificationResource, solidResources, threadRepository, } from '../models.js';
4
5
  import { AS, ODRL, UDFS } from '@undefineds.co/models/namespaces';
5
6
  import { ApprovalVocab, AuditVocab, GrantReadVocab, GrantVocab, InboxNotificationVocab } from '@undefineds.co/models/vocab/sidecar';
6
- import { autoModeApprovalActionUri, autoModeApprovalRequestMessage, autoModeApprovalRisk, autoModeApprovalToolName, } from '../../../vendor/agent-runtime/dist/auto-mode.js';
7
+ import { autoModeApprovalActionUri, autoModeApprovalDecisionForStoredApproval, autoModeApprovalRequestMessage, autoModeApprovalRisk, autoModeApprovalToolName, buildAutoModeApprovalDecisionReason, encodeAutoModeApprovalOptions, parseAutoModeApprovalDecisionReason, parseAutoModeApprovalOptions, shouldMaterializeAutoModeGrant, } from '../../../vendor/agent-runtime/dist/auto-mode.js';
7
8
  import { resolveAutoModeGrantCoverage } from './secretary.js';
8
9
  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';
9
10
  const AUTO_MODE_CHAT_ID_PREFIX = 'linx-auto-mode';
10
- const AUTO_MODE_AGENT_ID = 'linx-auto-mode-assistant';
11
+ const AUTO_MODE_AGENT_ID = '__secretary__';
11
12
  const REMOTE_APPROVAL_POLICY_VERSION = 'linx-auto-mode-remote-approval/v1';
12
13
  const DEFAULT_REMOTE_APPROVAL_POLL_MS = 1000;
13
14
  const DEFAULT_WARN_ONLY_TIMEOUT_MS = 5000;
@@ -17,6 +18,7 @@ const MAX_APPROVAL_CONTEXT_LENGTH = 1400;
17
18
  const MIN_GRANT_COVERAGE_CONFIDENCE = 0.75;
18
19
  const MAX_GRANT_COVERAGE_CANDIDATES = 5;
19
20
  const remoteApprovalClientCache = new WeakMap();
21
+ let remoteApprovalSyncSeq = 0;
20
22
  function createAbortError() {
21
23
  const error = new Error('The operation was aborted.');
22
24
  error.name = 'AbortError';
@@ -37,42 +39,32 @@ function toIsoString(value, fallback) {
37
39
  }
38
40
  return fallback;
39
41
  }
40
- function getPodBaseUrl(webIdOrUri) {
41
- if (webIdOrUri.includes('/profile/card#me')) {
42
- return webIdOrUri.replace('/profile/card#me', '').replace(/\/$/, '');
43
- }
44
- const match = webIdOrUri.match(/^(https?:\/\/[^?#]+?)(?:\/\.data\/|\/inbox\/)/u);
45
- if (match) {
46
- return match[1].replace(/\/$/, '');
47
- }
48
- return webIdOrUri.replace(/\/$/, '');
49
- }
50
42
  function buildAutoModeChatId(record) {
51
43
  return `${AUTO_MODE_CHAT_ID_PREFIX}-${record.backend}`;
52
44
  }
53
- function buildThreadUri(webId, record) {
54
- return `${getPodBaseUrl(webId)}/.data/chat/${buildAutoModeChatId(record)}/index.ttl#${record.id}`;
45
+ function buildAutoModeChatUri(webId, record) {
46
+ return chatResource.buildIri(webId, { id: buildAutoModeChatId(record) });
55
47
  }
56
- function buildApprovalUriForDate(webIdOrUri, approvalId, createdAt) {
57
- return buildPodResourceIri(webIdOrUri, buildApprovalSubjectPath(approvalId, createdAt));
48
+ function autoModeThreadUri(webId, record) {
49
+ return threadRepository.iriForChat(webId, buildAutoModeChatId(record), record.id);
50
+ }
51
+ function approvalIriForCreatedAt(webIdOrUri, approvalId, createdAt) {
52
+ return approvalResource.buildIri(webIdOrUri, {
53
+ id: approvalId,
54
+ createdAt,
55
+ });
58
56
  }
59
57
  function documentUrlFromResourceUri(resourceUri) {
60
58
  return resourceUri.split('#', 1)[0] ?? resourceUri;
61
59
  }
62
- function buildGrantUri(webIdOrUri, grantId) {
63
- return buildPodResourceIri(webIdOrUri, buildGrantSubjectPath(grantId));
64
- }
65
- function buildPodResourceIri(webIdOrUri, relativeUri) {
66
- if (/^https?:\/\//.test(relativeUri)) {
67
- return relativeUri;
68
- }
69
- return new URL(relativeUri.replace(/^\//, ''), `${getPodBaseUrl(webIdOrUri)}/`).toString();
60
+ function grantIri(webIdOrUri, grantId) {
61
+ return buildGrantResourceUrl(webIdOrUri, grantId);
70
62
  }
71
63
  function buildGrantSchemaUri(webIdOrUri) {
72
- return `${getPodBaseUrl(webIdOrUri)}/settings/autonomy/schema/grant.ttl#GrantWikiPage`;
64
+ return new URL('settings/autonomy/schema/grant.ttl#GrantWikiPage', `${resolvePodBaseUrl(webIdOrUri)}/`).toString();
73
65
  }
74
- function buildAgentUri(webId) {
75
- return `${getPodBaseUrl(webId)}/.data/agents/${AUTO_MODE_AGENT_ID}.ttl`;
66
+ function autoModeAgentUri(webId) {
67
+ return agentResource.buildIri(webId, { id: AUTO_MODE_AGENT_ID });
76
68
  }
77
69
  function buildActionUri(request) {
78
70
  return autoModeApprovalActionUri(request);
@@ -108,34 +100,6 @@ function extractToolCallId(request) {
108
100
  ?? normalizeString(params?.toolCallId)
109
101
  ?? crypto.randomUUID();
110
102
  }
111
- function encodeDecisionReason(decision, note) {
112
- return safeJsonStringify({
113
- decision,
114
- ...(note?.trim() ? { note: note.trim() } : {}),
115
- });
116
- }
117
- function parseDecisionReason(value) {
118
- if (typeof value !== 'string' || !value.trim()) {
119
- return null;
120
- }
121
- try {
122
- const parsed = JSON.parse(value);
123
- if (!isRecord(parsed)) {
124
- return null;
125
- }
126
- const decision = normalizeString(parsed.decision);
127
- if (!decision || !['accept', 'accept_for_session', 'decline', 'cancel'].includes(decision)) {
128
- return null;
129
- }
130
- return {
131
- decision: decision,
132
- ...(normalizeString(parsed.note) ? { note: normalizeString(parsed.note) } : {}),
133
- };
134
- }
135
- catch {
136
- return null;
137
- }
138
- }
139
103
  async function warnOnly(runtime, task) {
140
104
  try {
141
105
  await Promise.race([
@@ -240,7 +204,7 @@ function grantWikiTagsFromApproval(row, explicitTags) {
240
204
  }
241
205
  function grantContextFromApproval(row) {
242
206
  return safeCompactJson({
243
- sourceApproval: buildApprovalUriForDate(row.session, row.id, new Date(toIsoString(row.createdAt, new Date().toISOString()))),
207
+ sourceApproval: approvalIriForCreatedAt(row.session, row.id, new Date(toIsoString(row.createdAt, new Date().toISOString()))),
244
208
  session: row.session,
245
209
  toolCallId: row.toolCallId,
246
210
  toolName: row.toolName,
@@ -277,45 +241,7 @@ function grantSourceHash(row) {
277
241
  return `approval:${row.id}:${row.toolCallId}:${row.risk}`;
278
242
  }
279
243
  function encodeApprovalOptions(options) {
280
- if (!options || options.length === 0) {
281
- return undefined;
282
- }
283
- return safeJsonStringify(options);
284
- }
285
- function parseApprovalOptions(value) {
286
- if (typeof value !== 'string' || !value.trim()) {
287
- return undefined;
288
- }
289
- try {
290
- const parsed = JSON.parse(value);
291
- if (!Array.isArray(parsed)) {
292
- return undefined;
293
- }
294
- const options = parsed
295
- .map((option) => {
296
- if (!isRecord(option)) {
297
- return null;
298
- }
299
- const optionId = normalizeString(option.optionId);
300
- const label = normalizeString(option.label);
301
- if (!optionId || !label) {
302
- return null;
303
- }
304
- const kind = normalizeString(option.kind);
305
- const description = normalizeString(option.description);
306
- return {
307
- optionId,
308
- label,
309
- ...(kind ? { kind } : {}),
310
- ...(description ? { description } : {}),
311
- };
312
- })
313
- .filter((option) => option !== null);
314
- return options.length > 0 ? options : undefined;
315
- }
316
- catch {
317
- return undefined;
318
- }
244
+ return encodeAutoModeApprovalOptions(options);
319
245
  }
320
246
  function normalizeDateLike(value) {
321
247
  if (value instanceof Date) {
@@ -344,24 +270,17 @@ function extractSessionId(sessionUri) {
344
270
  return sessionUri;
345
271
  }
346
272
  function decisionFromApprovalRow(row) {
347
- const status = normalizeString(row.status);
348
- if (status === 'pending') {
349
- return null;
350
- }
351
- const parsed = parseDecisionReason(row.reason);
352
- if (status === 'rejected') {
353
- return parsed?.decision === 'cancel' ? 'cancel' : 'decline';
354
- }
355
- if (parsed?.decision === 'accept_for_session') {
356
- return 'accept_for_session';
357
- }
358
- return 'accept';
273
+ return autoModeApprovalDecisionForStoredApproval({
274
+ status: normalizeString(row.status),
275
+ reason: row.reason,
276
+ approvalOptions: row.approvalOptions,
277
+ });
359
278
  }
360
279
  function normalizeApprovalSummary(row) {
361
280
  const createdAt = toIsoString(row.createdAt, new Date(0).toISOString());
362
281
  const sessionUri = row.session;
363
282
  const decision = decisionFromApprovalRow(row);
364
- const approvalOptions = parseApprovalOptions(row.approvalOptions);
283
+ const approvalOptions = parseAutoModeApprovalOptions(row.approvalOptions);
365
284
  return {
366
285
  id: row.id,
367
286
  ...(normalizeString(row.approvalUri) ? { approvalUri: normalizeString(row.approvalUri) } : {}),
@@ -375,7 +294,7 @@ function normalizeApprovalSummary(row) {
375
294
  ...(normalizeString(row.assignedTo) ? { assignedTo: normalizeString(row.assignedTo) } : {}),
376
295
  ...(normalizeString(row.decisionBy) ? { decisionBy: normalizeString(row.decisionBy) } : {}),
377
296
  ...(decision ? { decision } : {}),
378
- ...(approvalOptions ? { approvalOptions } : {}),
297
+ ...(approvalOptions.length > 0 ? { approvalOptions } : {}),
379
298
  createdAt,
380
299
  ...(row.expiresAt ? { expiresAt: toIsoString(row.expiresAt, createdAt) } : {}),
381
300
  ...(row.resolvedAt ? { resolvedAt: toIsoString(row.resolvedAt, createdAt) } : {}),
@@ -501,7 +420,7 @@ function createSharedModelRemoteApprovalStore(webId, getDb) {
501
420
  }
502
421
  if (options.createdAt) {
503
422
  const createdAt = new Date(toIsoString(options.createdAt, new Date().toISOString()));
504
- const iri = buildApprovalUriForDate(webId, id, createdAt);
423
+ const iri = approvalIriForCreatedAt(webId, id, createdAt);
505
424
  const row = await modelFindByIri(getDb, approvalResource, iri);
506
425
  return row ? enrichApprovalRow(webId, row, iri) : null;
507
426
  }
@@ -514,7 +433,7 @@ function createSharedModelRemoteApprovalStore(webId, getDb) {
514
433
  updateApproval: async (id, patch, options = {}) => {
515
434
  const explicitIri = options.resourceUri
516
435
  ?? normalizeString(patch.approvalUri)
517
- ?? (options.createdAt ? buildApprovalUriForDate(webId, id, new Date(toIsoString(options.createdAt, new Date().toISOString()))) : undefined);
436
+ ?? (options.createdAt ? approvalIriForCreatedAt(webId, id, new Date(toIsoString(options.createdAt, new Date().toISOString()))) : undefined);
518
437
  if (explicitIri) {
519
438
  await modelUpdateByIri(getDb, approvalResource, explicitIri, omitInternalFields(patch));
520
439
  return;
@@ -543,18 +462,11 @@ async function modelList(getDb, resource) {
543
462
  }
544
463
  async function modelFindByIri(getDb, resource, iri) {
545
464
  const db = await getDb();
546
- if (typeof db.findByIri === 'function') {
547
- return await db.findByIri(resource, iri);
548
- }
549
- const rows = await db.select().from(resource).whereByIri(iri).execute();
550
- return rows[0] ?? null;
465
+ return await db.findByIri(resource, iri);
551
466
  }
552
467
  async function modelFindById(getDb, resource, id) {
553
468
  const db = await getDb();
554
- if (typeof db.findById === 'function') {
555
- return await db.findById(resource, id);
556
- }
557
- throw new Error('Remote approval shared model store requires findById support');
469
+ return await db.findById(resource, id);
558
470
  }
559
471
  async function modelInsert(getDb, resource, row) {
560
472
  const db = await getDb();
@@ -565,31 +477,14 @@ async function modelUpdateByIri(getDb, resource, iri, patch) {
565
477
  const update = stripUndefined(patch);
566
478
  delete update.id;
567
479
  delete update.approvalUri;
568
- if (typeof db.updateByIri === 'function') {
569
- await db.updateByIri(resource, iri, update);
570
- return;
571
- }
572
- const query = db.update(resource).set(update);
573
- if (typeof query.whereByIri !== 'function') {
574
- throw new Error('Remote approval shared model store requires updateByIri/whereByIri support');
575
- }
576
- await query.whereByIri(iri).execute();
480
+ await db.updateByIri(resource, iri, update);
577
481
  }
578
482
  async function modelUpdateById(getDb, resource, id, patch) {
579
483
  const db = await getDb();
580
484
  const update = stripUndefined(patch);
581
485
  delete update.id;
582
486
  delete update.approvalUri;
583
- if (typeof db.updateById === 'function') {
584
- return await db.updateById(resource, id, update);
585
- }
586
- const row = await modelFindById(getDb, resource, id);
587
- const iri = rowSubject(row ?? {});
588
- if (!iri) {
589
- return null;
590
- }
591
- await modelUpdateByIri(getDb, resource, iri, update);
592
- return await modelFindByIri(getDb, resource, iri);
487
+ return await db.updateById(resource, id, update);
593
488
  }
594
489
  function stripUndefined(row) {
595
490
  const next = {};
@@ -605,7 +500,6 @@ function omitInternalFields(row) {
605
500
  delete next.approvalUri;
606
501
  delete next['@id'];
607
502
  delete next.subject;
608
- delete next.source;
609
503
  delete next.uri;
610
504
  return next;
611
505
  }
@@ -621,7 +515,7 @@ function enrichApprovalRow(webId, row, explicitIri) {
621
515
  approvalUri: explicitIri
622
516
  ?? normalizeString(row.approvalUri)
623
517
  ?? rowSubject(row)
624
- ?? buildApprovalUriForDate(webId, row.id, createdAt),
518
+ ?? approvalIriForCreatedAt(webId, row.id, createdAt),
625
519
  };
626
520
  }
627
521
  function createNativeRemoteApprovalStore(webId, fetcher) {
@@ -677,7 +571,7 @@ async function readApprovalRowFromResource(fetcher, resourceUri) {
677
571
  async function listApprovalRows(webId, fetcher) {
678
572
  const urls = [
679
573
  ...recentApprovalDocumentUrls(webId),
680
- ...await listTurtleResources(fetcher, `${getPodBaseUrl(webId)}/.data/approvals/`).catch(() => []),
574
+ ...await listTurtleResources(fetcher, `${resolvePodBaseUrl(webId)}/.data/approvals/`).catch(() => []),
681
575
  ];
682
576
  const rows = [];
683
577
  for (const url of [...new Set(urls)].filter((entry) => entry.endsWith('.ttl'))) {
@@ -731,7 +625,7 @@ async function writeApprovalRow(webId, fetcher, row) {
731
625
  });
732
626
  }
733
627
  async function listAuditRows(webId, fetcher) {
734
- const urls = await listTurtleResourcesRecursive(fetcher, `${getPodBaseUrl(webId)}/.data/audits/`);
628
+ const urls = await listTurtleResourcesRecursive(fetcher, `${resolvePodBaseUrl(webId)}/.data/audits/`);
735
629
  const rows = [];
736
630
  for (const url of urls.filter((entry) => entry.endsWith('.ttl'))) {
737
631
  const turtle = await readTurtleResource(fetcher, url).catch(() => null);
@@ -769,7 +663,7 @@ async function writeAuditRow(webId, fetcher, row) {
769
663
  }
770
664
  async function listGrantRows(webId, fetcher) {
771
665
  const urls = [
772
- ...await listTurtleResources(fetcher, `${getPodBaseUrl(webId)}/settings/autonomy/grants/`).catch(() => []),
666
+ ...await listTurtleResources(fetcher, `${resolvePodBaseUrl(webId)}/settings/autonomy/grants/`).catch(() => []),
773
667
  ];
774
668
  const rows = [];
775
669
  for (const url of urls.filter((entry) => entry.endsWith('.ttl'))) {
@@ -989,8 +883,8 @@ async function resolveSemanticGrantDecision(options) {
989
883
  }
990
884
  function buildAutoModeGrantRequestContext(input) {
991
885
  return {
992
- session: buildThreadUri(input.webId, input.record),
993
- target: buildThreadUri(input.webId, input.record),
886
+ session: autoModeThreadUri(input.webId, input.record),
887
+ target: autoModeThreadUri(input.webId, input.record),
994
888
  action: buildActionUri(input.request),
995
889
  risk: buildRisk(input.request),
996
890
  toolName: buildToolName(input.request),
@@ -1002,7 +896,7 @@ function buildAutoModeGrantRequestContext(input) {
1002
896
  function buildGenericGrantRequestContext(input) {
1003
897
  return {
1004
898
  session: input.subject.sessionUri,
1005
- target: input.subject.targetUri ?? input.subject.sessionUri,
899
+ target: input.subject.target ?? input.subject.sessionUri,
1006
900
  action: input.request.action,
1007
901
  risk: input.request.risk,
1008
902
  toolName: input.request.toolName,
@@ -1014,8 +908,8 @@ export async function createRemoteAutoModeApproval(options) {
1014
908
  const activeRuntime = options.runtime ?? await createDefaultRuntime();
1015
909
  return createRemoteApproval({
1016
910
  subject: ({ webId }) => ({
1017
- sessionUri: buildThreadUri(webId, options.record),
1018
- actorUri: buildAgentUri(webId),
911
+ sessionUri: autoModeThreadUri(webId, options.record),
912
+ actorUri: autoModeAgentUri(webId),
1019
913
  policyVersion: REMOTE_APPROVAL_POLICY_VERSION,
1020
914
  }),
1021
915
  request: ({ sessionUri }) => ({
@@ -1047,8 +941,8 @@ export async function createRemoteApproval(options) {
1047
941
  const approvalId = crypto.randomUUID();
1048
942
  const now = activeRuntime.now();
1049
943
  const sessionUri = subject.sessionUri;
1050
- const approvalUri = buildApprovalUriForDate(webId, approvalId, now);
1051
- const targetUri = subject.targetUri ?? sessionUri;
944
+ const approvalUri = approvalIriForCreatedAt(webId, approvalId, now);
945
+ const target = subject.target ?? sessionUri;
1052
946
  const assignedTo = subject.assignedTo ?? webId;
1053
947
  const onBehalfOf = subject.onBehalfOf ?? webId;
1054
948
  const policyVersion = subject.policyVersion ?? REMOTE_APPROVAL_POLICY_VERSION;
@@ -1061,7 +955,7 @@ export async function createRemoteApproval(options) {
1061
955
  session: sessionUri,
1062
956
  toolCallId: request.toolCallId,
1063
957
  toolName: request.toolName,
1064
- target: targetUri,
958
+ target,
1065
959
  action: request.action,
1066
960
  risk: request.risk,
1067
961
  status: 'pending',
@@ -1099,7 +993,7 @@ export async function createRemoteApproval(options) {
1099
993
  session: sessionUri,
1100
994
  toolCallId: request.toolCallId,
1101
995
  toolName: request.toolName,
1102
- target: targetUri,
996
+ target,
1103
997
  action: request.action,
1104
998
  risk: request.risk,
1105
999
  status: 'pending',
@@ -1159,13 +1053,21 @@ export async function requestRemoteAutoModeApproval(options) {
1159
1053
  request: options.request,
1160
1054
  runtime: activeRuntime,
1161
1055
  });
1162
- return waitForRemoteAutoModeApproval({
1056
+ const decision = await waitForRemoteAutoModeApproval({
1163
1057
  approvalId: summary.id,
1164
1058
  approvalUri: summary.approvalUri,
1165
1059
  pollMs: options.pollMs,
1166
1060
  signal: options.signal,
1167
1061
  runtime: activeRuntime,
1168
1062
  });
1063
+ if (decision === 'accept_for_session') {
1064
+ await materializeRemoteAutoModeGrant({
1065
+ approvalId: summary.id,
1066
+ approvalUri: summary.approvalUri,
1067
+ runtime: activeRuntime,
1068
+ });
1069
+ }
1070
+ return decision;
1169
1071
  }
1170
1072
  export async function resolveExistingRemoteAutoModeGrant(options) {
1171
1073
  const activeRuntime = options.runtime ?? await createDefaultRuntime();
@@ -1249,7 +1151,7 @@ export async function resolveRemoteAutoModeApproval(options) {
1249
1151
  }
1250
1152
  const now = activeRuntime.now();
1251
1153
  const approvalCreatedAt = new Date(toIsoString(row.createdAt, now.toISOString()));
1252
- const approvalUri = buildApprovalUriForDate(row.session, row.id, approvalCreatedAt);
1154
+ const approvalUri = approvalIriForCreatedAt(row.session, row.id, approvalCreatedAt);
1253
1155
  const nextStatus = options.decision === 'accept' || options.decision === 'accept_for_session'
1254
1156
  ? 'approved'
1255
1157
  : 'rejected';
@@ -1259,7 +1161,7 @@ export async function resolveRemoteAutoModeApproval(options) {
1259
1161
  decisionBy: webId,
1260
1162
  decisionRole,
1261
1163
  onBehalfOf: webId,
1262
- reason: encodeDecisionReason(options.decision, options.note),
1164
+ reason: buildAutoModeApprovalDecisionReason(options.decision, options.note),
1263
1165
  resolvedAt: now,
1264
1166
  }, {
1265
1167
  resourceUri: options.approvalUri ?? row.approvalUri ?? approvalUri,
@@ -1278,41 +1180,6 @@ export async function resolveRemoteAutoModeApproval(options) {
1278
1180
  policyVersion: REMOTE_APPROVAL_POLICY_VERSION,
1279
1181
  createdAt: now,
1280
1182
  }));
1281
- if (options.decision === 'accept_for_session') {
1282
- const grantId = crypto.randomUUID();
1283
- const body = grantWikiBodyFromApproval(row, options.grantWikiBody);
1284
- await store.insertGrant({
1285
- id: grantId,
1286
- target: row.target,
1287
- action: row.action,
1288
- title: grantWikiTitleFromApproval(row, options.grantWikiTitle),
1289
- summary: grantWikiSummaryFromApproval(row, options.grantWikiSummary),
1290
- body,
1291
- schema: buildGrantSchemaUri(webId),
1292
- pageKind: 'autonomy-grant',
1293
- wikiStatus: 'active',
1294
- tags: grantWikiTagsFromApproval(row, options.grantWikiTags),
1295
- source: 'approval',
1296
- sourceHash: grantSourceHash(row),
1297
- compiledAt: now,
1298
- compiledFrom: [approvalUri],
1299
- related: [row.session],
1300
- effect: 'allow',
1301
- riskCeiling: row.risk,
1302
- policy: grantIndexTextFromWikiBody(body),
1303
- context: grantContextFromApproval(row),
1304
- decisionBy: webId,
1305
- decisionRole,
1306
- onBehalfOf: webId,
1307
- createdAt: now,
1308
- });
1309
- await warnOnly(activeRuntime, () => store.insertInboxNotification({
1310
- id: crypto.randomUUID(),
1311
- actor: webId,
1312
- object: buildGrantUri(row.session, grantId),
1313
- createdAt: now,
1314
- }));
1315
- }
1316
1183
  await warnOnly(activeRuntime, () => store.insertInboxNotification({
1317
1184
  id: crypto.randomUUID(),
1318
1185
  actor: webId,
@@ -1325,12 +1192,73 @@ export async function resolveRemoteAutoModeApproval(options) {
1325
1192
  decisionBy: webId,
1326
1193
  decisionRole,
1327
1194
  onBehalfOf: webId,
1328
- reason: encodeDecisionReason(options.decision, options.note),
1195
+ reason: buildAutoModeApprovalDecisionReason(options.decision, options.note),
1329
1196
  resolvedAt: now,
1330
1197
  };
1331
1198
  return normalizeApprovalSummary(nextRow);
1332
1199
  });
1333
1200
  }
1201
+ export async function materializeRemoteAutoModeGrant(options) {
1202
+ const activeRuntime = options.runtime ?? await createDefaultRuntime();
1203
+ return withRemoteApprovalStore(activeRuntime, async ({ store, webId }) => {
1204
+ const row = await readRemoteApprovalRow(store, {
1205
+ approvalId: options.approvalId,
1206
+ approvalUri: options.approvalUri,
1207
+ });
1208
+ if (!row || row.status !== 'approved') {
1209
+ return null;
1210
+ }
1211
+ const decision = decisionFromApprovalRow(row);
1212
+ if (!shouldMaterializeAutoModeGrant(decision)) {
1213
+ return null;
1214
+ }
1215
+ const existing = await store.listGrants();
1216
+ const sourceHash = grantSourceHash(row);
1217
+ const existingGrant = existing.find((grant) => grant.source === 'approval' && grant.sourceHash === sourceHash);
1218
+ if (existingGrant) {
1219
+ return existingGrant;
1220
+ }
1221
+ const now = activeRuntime.now();
1222
+ const decisionRole = options.decisionRole ?? (row.decisionRole === 'secretary' ? 'secretary' : 'human');
1223
+ const grantId = crypto.randomUUID();
1224
+ const body = grantWikiBodyFromApproval(row, options.grantWikiBody);
1225
+ const approvalCreatedAt = new Date(toIsoString(row.createdAt, now.toISOString()));
1226
+ const approvalUri = options.approvalUri ?? row.approvalUri ?? approvalIriForCreatedAt(row.session, row.id, approvalCreatedAt);
1227
+ const grant = {
1228
+ id: grantId,
1229
+ target: row.target,
1230
+ action: row.action,
1231
+ title: grantWikiTitleFromApproval(row, options.grantWikiTitle),
1232
+ summary: grantWikiSummaryFromApproval(row, options.grantWikiSummary),
1233
+ body,
1234
+ schema: buildGrantSchemaUri(webId),
1235
+ pageKind: 'autonomy-grant',
1236
+ wikiStatus: 'active',
1237
+ tags: grantWikiTagsFromApproval(row, options.grantWikiTags),
1238
+ source: 'approval',
1239
+ sourceHash,
1240
+ compiledAt: now,
1241
+ compiledFrom: [approvalUri],
1242
+ related: [row.session],
1243
+ effect: 'allow',
1244
+ riskCeiling: row.risk,
1245
+ policy: grantIndexTextFromWikiBody(body),
1246
+ context: grantContextFromApproval(row),
1247
+ decisionBy: row.decisionBy ?? webId,
1248
+ decisionRole,
1249
+ onBehalfOf: row.onBehalfOf ?? webId,
1250
+ createdAt: now,
1251
+ };
1252
+ await store.insertGrant(grant);
1253
+ await warnOnly(activeRuntime, () => store.insertInboxNotification({
1254
+ id: crypto.randomUUID(),
1255
+ actor: webId,
1256
+ object: grantIri(row.session, grantId),
1257
+ createdAt: now,
1258
+ }));
1259
+ return grant;
1260
+ });
1261
+ }
1334
1262
  async function readRemoteApprovalRow(store, options) {
1335
1263
  if (store.findApproval) {
1336
1264
  const row = await store.findApproval(options.approvalId, {
@@ -1353,11 +1281,12 @@ export const __podApprovalInternal = {
1353
1281
  createNativeRemoteApprovalStore,
1354
1282
  extractToolCallId,
1355
1283
  decisionFromApprovalRow,
1356
- encodeDecisionReason,
1284
+ encodeDecisionReason: buildAutoModeApprovalDecisionReason,
1357
1285
  formatSummaryHeadline,
1286
+ grantSourceHash,
1358
1287
  readRemoteApprovalRow,
1359
1288
  isRemoteApprovalAbortError,
1360
1289
  normalizeApprovalSummary,
1361
- parseDecisionReason,
1290
+ parseDecisionReason: parseAutoModeApprovalDecisionReason,
1362
1291
  };
1363
1292
  //# sourceMappingURL=pod-approval.js.map