@oxy.so/core 4.5.0-oxy-one.0 → 4.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (285) hide show
  1. package/README.md +1 -1
  2. package/dist/cjs/HttpService.js +63 -19
  3. package/dist/cjs/api/accounts.js +10 -3
  4. package/dist/cjs/api/agency.js +3 -1
  5. package/dist/cjs/api/apps.js +15 -4
  6. package/dist/cjs/api/assets.js +49 -12
  7. package/dist/cjs/api/auth.js +37 -11
  8. package/dist/cjs/api/billing.js +24 -7
  9. package/dist/cjs/api/civic.js +14 -4
  10. package/dist/cjs/api/follows.js +9 -2
  11. package/dist/cjs/api/identity.js +31 -9
  12. package/dist/cjs/api/nodes.js +3 -1
  13. package/dist/cjs/api/privacy.js +8 -2
  14. package/dist/cjs/api/session.js +15 -4
  15. package/dist/cjs/api/store.js +15 -5
  16. package/dist/cjs/api/topics.js +10 -3
  17. package/dist/cjs/api/users.js +16 -4
  18. package/dist/cjs/boot/sessionColdBoot.js +40 -13
  19. package/dist/cjs/constants/version.js +6 -6
  20. package/dist/cjs/crypto/identityMarker.js +3 -1
  21. package/dist/cjs/crypto/identityProof.js +6 -1
  22. package/dist/cjs/crypto/keyManager.js +87 -32
  23. package/dist/cjs/crypto/recoveryPhrase.js +2 -2
  24. package/dist/cjs/crypto/signatureService.js +3 -4
  25. package/dist/cjs/i18n/index.js +16 -3
  26. package/dist/cjs/i18n/locales/ar-SA.js +366 -366
  27. package/dist/cjs/i18n/locales/ca-ES.js +366 -366
  28. package/dist/cjs/i18n/locales/de-DE.js +366 -366
  29. package/dist/cjs/i18n/locales/en-US.js +1994 -1994
  30. package/dist/cjs/i18n/locales/es-ES.js +1994 -1994
  31. package/dist/cjs/i18n/locales/fr-FR.js +366 -366
  32. package/dist/cjs/i18n/locales/it-IT.js +366 -366
  33. package/dist/cjs/i18n/locales/ja-JP.js +366 -366
  34. package/dist/cjs/i18n/locales/ko-KR.js +366 -366
  35. package/dist/cjs/i18n/locales/pt-PT.js +366 -366
  36. package/dist/cjs/i18n/locales/zh-CN.js +366 -366
  37. package/dist/cjs/inference/OxyInferenceClient.js +12 -18
  38. package/dist/cjs/models/interfaces.js +11 -11
  39. package/dist/cjs/server/OxyServer.js +86 -28
  40. package/dist/cjs/server/agentAccount.js +6 -2
  41. package/dist/cjs/server/aliaMachineCredential.js +39 -14
  42. package/dist/cjs/server/auth.js +5 -4
  43. package/dist/cjs/server/capabilityTicket.js +5 -5
  44. package/dist/cjs/server/index.js +2 -1
  45. package/dist/cjs/server/liveCapabilityTicket.js +4 -1
  46. package/dist/cjs/server/middleware.js +61 -42
  47. package/dist/cjs/server/namespaces.js +28 -7
  48. package/dist/cjs/server/requesterAssertion.js +36 -30
  49. package/dist/cjs/server/serviceTokenLifetime.js +7 -4
  50. package/dist/cjs/server/traffic.js +53 -14
  51. package/dist/cjs/server/trafficNodeHttp.js +33 -8
  52. package/dist/cjs/server/workloadIdentity.client.js +4 -0
  53. package/dist/cjs/server/workloadIdentity.js +28 -1
  54. package/dist/cjs/session/SessionClient.js +54 -17
  55. package/dist/cjs/session/accountDelegationAccess.js +4 -6
  56. package/dist/cjs/session/accountDialogController.js +1 -1
  57. package/dist/cjs/session/authStateStore.js +18 -9
  58. package/dist/cjs/session/identityPin.js +6 -2
  59. package/dist/cjs/session/refresh.js +81 -23
  60. package/dist/cjs/session/sharedDeviceCredential.js +28 -15
  61. package/dist/cjs/shared/utils/errorUtils.js +1 -1
  62. package/dist/cjs/shared/utils/networkUtils.js +1 -1
  63. package/dist/cjs/shared/utils/themeUtils.js +1 -1
  64. package/dist/cjs/utils/accountCacheSweep.js +3 -1
  65. package/dist/cjs/utils/accountUtils.js +1 -3
  66. package/dist/cjs/utils/asyncUtils.js +1 -1
  67. package/dist/cjs/utils/authHelpers.js +2 -1
  68. package/dist/cjs/utils/avatarUtils.js +4 -2
  69. package/dist/cjs/utils/cache.js +1 -1
  70. package/dist/cjs/utils/cacheKey.js +3 -1
  71. package/dist/cjs/utils/deviceManager.js +4 -4
  72. package/dist/cjs/utils/errorUtils.js +6 -4
  73. package/dist/cjs/utils/languageUtils.js +404 -57
  74. package/dist/cjs/utils/profileLinks.js +1 -3
  75. package/dist/cjs/utils/requestUtils.js +7 -1
  76. package/dist/cjs/utils/userIdentity.js +1 -1
  77. package/dist/cjs/utils/validationUtils.js +5 -6
  78. package/dist/esm/HttpService.js +64 -20
  79. package/dist/esm/api/accounts.js +11 -4
  80. package/dist/esm/api/agency.js +3 -1
  81. package/dist/esm/api/apps.js +15 -4
  82. package/dist/esm/api/assets.js +49 -12
  83. package/dist/esm/api/auth.js +37 -11
  84. package/dist/esm/api/billing.js +25 -8
  85. package/dist/esm/api/civic.js +14 -4
  86. package/dist/esm/api/follows.js +9 -2
  87. package/dist/esm/api/identity.js +31 -9
  88. package/dist/esm/api/nodes.js +3 -1
  89. package/dist/esm/api/privacy.js +8 -2
  90. package/dist/esm/api/session.js +15 -4
  91. package/dist/esm/api/store.js +15 -5
  92. package/dist/esm/api/topics.js +10 -3
  93. package/dist/esm/api/users.js +16 -4
  94. package/dist/esm/boot/sessionColdBoot.js +41 -14
  95. package/dist/esm/constants/version.js +6 -6
  96. package/dist/esm/crypto/identityMarker.js +3 -1
  97. package/dist/esm/crypto/identityProof.js +6 -1
  98. package/dist/esm/crypto/internal.js +1 -1
  99. package/dist/esm/crypto/keyManager.js +87 -32
  100. package/dist/esm/crypto/recoveryPhrase.js +2 -2
  101. package/dist/esm/crypto/signatureService.js +3 -4
  102. package/dist/esm/i18n/index.js +16 -3
  103. package/dist/esm/i18n/locales/ar-SA.js +366 -366
  104. package/dist/esm/i18n/locales/ca-ES.js +366 -366
  105. package/dist/esm/i18n/locales/de-DE.js +366 -366
  106. package/dist/esm/i18n/locales/en-US.js +1994 -1994
  107. package/dist/esm/i18n/locales/es-ES.js +1994 -1994
  108. package/dist/esm/i18n/locales/fr-FR.js +366 -366
  109. package/dist/esm/i18n/locales/it-IT.js +366 -366
  110. package/dist/esm/i18n/locales/ja-JP.js +366 -366
  111. package/dist/esm/i18n/locales/ko-KR.js +366 -366
  112. package/dist/esm/i18n/locales/pt-PT.js +366 -366
  113. package/dist/esm/i18n/locales/zh-CN.js +366 -366
  114. package/dist/esm/index.js +1 -1
  115. package/dist/esm/inference/OxyInferenceClient.js +13 -19
  116. package/dist/esm/models/interfaces.js +11 -11
  117. package/dist/esm/server/OxyServer.js +87 -29
  118. package/dist/esm/server/agentAccount.js +6 -2
  119. package/dist/esm/server/aliaMachineCredential.js +39 -14
  120. package/dist/esm/server/auth.js +6 -5
  121. package/dist/esm/server/capabilityTicket.js +6 -6
  122. package/dist/esm/server/index.js +5 -5
  123. package/dist/esm/server/liveCapabilityTicket.js +6 -3
  124. package/dist/esm/server/middleware.js +62 -43
  125. package/dist/esm/server/namespaces.js +31 -10
  126. package/dist/esm/server/requesterAssertion.js +36 -30
  127. package/dist/esm/server/serviceTokenLifetime.js +7 -4
  128. package/dist/esm/server/traffic.js +55 -16
  129. package/dist/esm/server/trafficNodeHttp.js +34 -9
  130. package/dist/esm/server/userInvalidation.js +1 -1
  131. package/dist/esm/server/workloadIdentity.client.js +3 -0
  132. package/dist/esm/server/workloadIdentity.js +27 -1
  133. package/dist/esm/session/SessionClient.js +54 -17
  134. package/dist/esm/session/accountDelegationAccess.js +5 -7
  135. package/dist/esm/session/accountDialogController.js +1 -1
  136. package/dist/esm/session/authStateStore.js +18 -9
  137. package/dist/esm/session/identityPin.js +6 -2
  138. package/dist/esm/session/refresh.js +82 -24
  139. package/dist/esm/session/sharedDeviceCredential.js +28 -15
  140. package/dist/esm/shared/utils/errorUtils.js +1 -1
  141. package/dist/esm/shared/utils/networkUtils.js +1 -1
  142. package/dist/esm/shared/utils/themeUtils.js +1 -1
  143. package/dist/esm/utils/accountCacheSweep.js +3 -1
  144. package/dist/esm/utils/accountUtils.js +1 -3
  145. package/dist/esm/utils/asyncUtils.js +1 -1
  146. package/dist/esm/utils/authHelpers.js +2 -1
  147. package/dist/esm/utils/avatarUtils.js +4 -2
  148. package/dist/esm/utils/cache.js +1 -1
  149. package/dist/esm/utils/cacheKey.js +3 -1
  150. package/dist/esm/utils/deviceManager.js +4 -4
  151. package/dist/esm/utils/errorUtils.js +6 -4
  152. package/dist/esm/utils/languageUtils.js +404 -57
  153. package/dist/esm/utils/profileLinks.js +1 -3
  154. package/dist/esm/utils/requestUtils.js +7 -1
  155. package/dist/esm/utils/userIdentity.js +1 -1
  156. package/dist/esm/utils/validationUtils.js +5 -6
  157. package/dist/types/HttpService.d.ts +1 -1
  158. package/dist/types/api/accounts.d.ts +1 -1
  159. package/dist/types/api/apps.d.ts +4 -4
  160. package/dist/types/api/assets.d.ts +2 -0
  161. package/dist/types/api/auth.d.ts +8 -3
  162. package/dist/types/crypto/internal.d.ts +1 -1
  163. package/dist/types/index.d.ts +4 -4
  164. package/dist/types/server/index.d.ts +6 -6
  165. package/dist/types/server/requesterAssertion.d.ts +2 -2
  166. package/dist/types/server/workloadIdentity.client.d.ts +5 -1
  167. package/dist/types/server/workloadIdentity.d.ts +26 -0
  168. package/dist/types/session/accountDelegationAccess.d.ts +1 -1
  169. package/dist/types/session/index.d.ts +1 -1
  170. package/dist/types/utils/userIdentity.d.ts +1 -1
  171. package/dist/types/utils/validationUtils.d.ts +4 -5
  172. package/package.json +2 -3
  173. package/src/HttpService.ts +183 -53
  174. package/src/OxyServices.errors.ts +7 -3
  175. package/src/OxyServices.ts +6 -2
  176. package/src/api/accounts.ts +76 -26
  177. package/src/api/agency.ts +24 -9
  178. package/src/api/appData.ts +12 -2
  179. package/src/api/apps.ts +81 -31
  180. package/src/api/assets.ts +122 -40
  181. package/src/api/auth.ts +154 -79
  182. package/src/api/billing.ts +112 -65
  183. package/src/api/civic.ts +61 -19
  184. package/src/api/contacts.ts +4 -1
  185. package/src/api/devices.ts +54 -21
  186. package/src/api/follows.ts +88 -31
  187. package/src/api/identity.ts +101 -33
  188. package/src/api/linkedAccounts.ts +26 -8
  189. package/src/api/nodes.ts +18 -6
  190. package/src/api/notifications.ts +26 -6
  191. package/src/api/privacy.ts +42 -8
  192. package/src/api/reputation.ts +18 -7
  193. package/src/api/session.ts +23 -5
  194. package/src/api/store.ts +81 -31
  195. package/src/api/topics.ts +18 -6
  196. package/src/api/users.ts +98 -35
  197. package/src/boot/sessionColdBoot.ts +60 -19
  198. package/src/civic/payloads.ts +1 -4
  199. package/src/client/context.ts +6 -1
  200. package/src/constants/version.ts +7 -6
  201. package/src/crypto/aead.ts +1 -5
  202. package/src/crypto/ecdh.ts +1 -4
  203. package/src/crypto/identityDerivations.ts +5 -1
  204. package/src/crypto/identityMarker.ts +3 -1
  205. package/src/crypto/identityProof.ts +6 -1
  206. package/src/crypto/index.ts +11 -11
  207. package/src/crypto/internal.ts +6 -1
  208. package/src/crypto/keyManager.ts +348 -98
  209. package/src/crypto/recoveryPhrase.ts +14 -9
  210. package/src/crypto/registrationPow.ts +1 -1
  211. package/src/crypto/signatureService.ts +14 -6
  212. package/src/i18n/accountCategoryLabels.ts +1 -4
  213. package/src/i18n/accountRoleLabels.ts +1 -4
  214. package/src/i18n/index.ts +25 -7
  215. package/src/i18n/locales/ar-SA.ts +375 -366
  216. package/src/i18n/locales/ca-ES.ts +382 -366
  217. package/src/i18n/locales/de-DE.ts +387 -366
  218. package/src/i18n/locales/en-US.ts +2034 -1994
  219. package/src/i18n/locales/es-ES.ts +2043 -1994
  220. package/src/i18n/locales/fr-FR.ts +387 -366
  221. package/src/i18n/locales/it-IT.ts +380 -366
  222. package/src/i18n/locales/ja-JP.ts +380 -366
  223. package/src/i18n/locales/ko-KR.ts +377 -366
  224. package/src/i18n/locales/pt-PT.ts +383 -366
  225. package/src/i18n/locales/zh-CN.ts +373 -366
  226. package/src/i18n/trustTierLabels.ts +1 -4
  227. package/src/index.ts +371 -349
  228. package/src/inference/OxyInferenceClient.ts +784 -780
  229. package/src/models/interfaces.ts +30 -27
  230. package/src/server/OxyServer.ts +227 -68
  231. package/src/server/agentAccount.ts +8 -2
  232. package/src/server/aliaMachineCredential.ts +57 -16
  233. package/src/server/auth.ts +9 -5
  234. package/src/server/capabilityTicket.ts +30 -21
  235. package/src/server/index.ts +29 -6
  236. package/src/server/liveCapabilityTicket.ts +31 -9
  237. package/src/server/middleware.ts +212 -121
  238. package/src/server/namespaces.ts +247 -94
  239. package/src/server/rateLimit.ts +2 -4
  240. package/src/server/requesterAssertion.ts +93 -54
  241. package/src/server/serviceTokenLifetime.ts +9 -4
  242. package/src/server/traffic.ts +117 -23
  243. package/src/server/trafficNodeHttp.ts +61 -14
  244. package/src/server/userInvalidation.ts +1 -4
  245. package/src/server/workloadIdentity.client.ts +12 -1
  246. package/src/server/workloadIdentity.ts +52 -5
  247. package/src/session/SessionClient.ts +170 -49
  248. package/src/session/accountDelegationAccess.ts +24 -31
  249. package/src/session/accountDialogController.ts +59 -14
  250. package/src/session/accountSwitchTargets.ts +10 -15
  251. package/src/session/authStateStore.ts +121 -81
  252. package/src/session/deviceDirectory.ts +1 -3
  253. package/src/session/identityPin.ts +10 -11
  254. package/src/session/identitySession.ts +3 -1
  255. package/src/session/index.ts +87 -82
  256. package/src/session/refresh.ts +138 -44
  257. package/src/session/sessionClientHost.ts +1 -3
  258. package/src/session/sharedDeviceCredential.ts +35 -14
  259. package/src/session/socketLoader.ts +9 -2
  260. package/src/shared/utils/errorUtils.ts +5 -2
  261. package/src/shared/utils/networkUtils.ts +5 -8
  262. package/src/shared/utils/themeUtils.ts +2 -6
  263. package/src/types/buffer.d.ts +66 -21
  264. package/src/types/expo-secure-store.d.ts +5 -1
  265. package/src/utils/accountCacheSweep.ts +4 -5
  266. package/src/utils/accountUtils.ts +107 -108
  267. package/src/utils/apiUtils.ts +3 -3
  268. package/src/utils/asyncUtils.ts +2 -2
  269. package/src/utils/authHelpers.ts +10 -5
  270. package/src/utils/avatarUtils.ts +11 -6
  271. package/src/utils/cache.ts +9 -10
  272. package/src/utils/cacheKey.ts +5 -1
  273. package/src/utils/coldBoot.ts +1 -3
  274. package/src/utils/commonsDelivery.ts +1 -4
  275. package/src/utils/deviceManager.ts +15 -14
  276. package/src/utils/errorUtils.ts +68 -86
  277. package/src/utils/languageUtils.ts +407 -58
  278. package/src/utils/oauthPkce.ts +1 -4
  279. package/src/utils/platform.ts +0 -1
  280. package/src/utils/profileLinks.ts +2 -5
  281. package/src/utils/requestUtils.ts +18 -14
  282. package/src/utils/sessionUtils.ts +34 -33
  283. package/src/utils/userHandle.ts +3 -1
  284. package/src/utils/userIdentity.ts +1 -1
  285. package/src/utils/validationUtils.ts +11 -9
@@ -4,7 +4,23 @@
4
4
  * `server.assets.metadataByIds(...)` sits beside every client method of
5
5
  * `oxy.assets`.
6
6
  */
7
- import { capabilityTicketRequestSchema, foregroundExecutionAuthorizationInputSchema, type ForegroundExecutionAuthorizationInput, type ActorRef, type AppCapabilityCatalog, type AutonomyLevel, type CapabilityTicketClaims, type CapabilityTicketRequest, type GrantLimit, type PolicyDecision, type ResourceRef, type CreateOxyNotificationRequest, type AwardReputationInput, type ReputationTransaction, type ServiceLinkedAccountListResponse } from '@oxy.so/contracts';
7
+ import {
8
+ capabilityTicketRequestSchema,
9
+ foregroundExecutionAuthorizationInputSchema,
10
+ type ForegroundExecutionAuthorizationInput,
11
+ type ActorRef,
12
+ type AppCapabilityCatalog,
13
+ type AutonomyLevel,
14
+ type CapabilityTicketClaims,
15
+ type CapabilityTicketRequest,
16
+ type GrantLimit,
17
+ type PolicyDecision,
18
+ type ResourceRef,
19
+ type CreateOxyNotificationRequest,
20
+ type AwardReputationInput,
21
+ type ReputationTransaction,
22
+ type ServiceLinkedAccountListResponse,
23
+ } from '@oxy.so/contracts';
8
24
  import type { RequestOptions } from '../HttpService';
9
25
  import type { OxyContext, ServiceLane } from '../client/context';
10
26
  import type {
@@ -16,10 +32,18 @@ import type {
16
32
  import { AssetsApi } from '../api/assets';
17
33
  import { NotificationsApi } from '../api/notifications';
18
34
  import { LinkedAccountsApi } from '../api/linkedAccounts';
19
- import { AgencyApi, type CapabilityExecutionAuthorization, type RequesterAssertionGrant, type RequesterAssertionIntrospection } from '../api/agency';
35
+ import {
36
+ AgencyApi,
37
+ type CapabilityExecutionAuthorization,
38
+ type RequesterAssertionGrant,
39
+ type RequesterAssertionIntrospection,
40
+ } from '../api/agency';
20
41
  import { ReputationApi } from '../api/reputation';
21
42
  import { AppsApi } from '../api/apps';
22
- import { isOxyAliaMachinePrincipal, type AliaMachineCredentialIntrospection } from './aliaMachineCredential';
43
+ import {
44
+ isOxyAliaMachinePrincipal,
45
+ type AliaMachineCredentialIntrospection,
46
+ } from './aliaMachineCredential';
23
47
  import { ServiceAssetMetadataError, ServiceLinkedDownloadUrlError } from '../OxyServices.errors';
24
48
  import { extractErrorStatus } from '../utils/errorUtils';
25
49
  import { logger } from '../logger';
@@ -42,18 +66,29 @@ function lane(ctx: OxyContext): ServiceLane {
42
66
  }
43
67
 
44
68
  export class ServerAppsApi extends AppsApi {
45
- constructor(private readonly serverCtx: OxyContext) { super(serverCtx); }
69
+ constructor(private readonly serverCtx: OxyContext) {
70
+ super(serverCtx);
71
+ }
46
72
  /** Live receiver-bound lookup using THIS resource server's own service token. */
47
- async introspectAliaMachineCredential(token: string): Promise<AliaMachineCredentialIntrospection> {
73
+ async introspectAliaMachineCredential(
74
+ token: string,
75
+ ): Promise<AliaMachineCredentialIntrospection> {
48
76
  if (!token.startsWith('oxy_sk_') || token.length > 2048) return { active: false };
49
77
  const answer = await lane(this.serverCtx).request<unknown>(
50
- 'POST', '/internal/alia/machine-credentials/introspect', { token },
78
+ 'POST',
79
+ '/internal/alia/machine-credentials/introspect',
80
+ { token },
51
81
  { cache: false, retry: false },
52
82
  );
53
- if (!answer || typeof answer !== 'object' || Array.isArray(answer)) throw new Error('Invalid machine credential verdict');
83
+ if (!answer || typeof answer !== 'object' || Array.isArray(answer))
84
+ throw new Error('Invalid machine credential verdict');
54
85
  const record = answer as Record<string, unknown>;
55
86
  if (record.active === false && Object.keys(record).length === 1) return { active: false };
56
- if (record.active !== true || Object.keys(record).length !== 2 || !isOxyAliaMachinePrincipal(record.principal)) {
87
+ if (
88
+ record.active !== true ||
89
+ Object.keys(record).length !== 2 ||
90
+ !isOxyAliaMachinePrincipal(record.principal)
91
+ ) {
57
92
  throw new Error('Invalid machine credential verdict');
58
93
  }
59
94
  return { active: true, principal: record.principal };
@@ -67,7 +102,9 @@ function chunk<T>(items: T[], size: number): T[][] {
67
102
  }
68
103
 
69
104
  function uniqueIds(ids: string[]): string[] {
70
- return Array.from(new Set(ids.filter((id): id is string => typeof id === 'string' && id.trim().length > 0)));
105
+ return Array.from(
106
+ new Set(ids.filter((id): id is string => typeof id === 'string' && id.trim().length > 0)),
107
+ );
71
108
  }
72
109
 
73
110
  export class ServerAssetsApi extends AssetsApi {
@@ -81,7 +118,10 @@ export class ServerAssetsApi extends AssetsApi {
81
118
  * {@link ServiceAssetMetadataError} carrying the ids it could not resolve,
82
119
  * unless `{ partial: true }` asks for best-effort. Never cached.
83
120
  */
84
- async metadataByIds(ids: string[], options: { partial?: boolean } = {}): Promise<ServiceAssetMetadata[]> {
121
+ async metadataByIds(
122
+ ids: string[],
123
+ options: { partial?: boolean } = {},
124
+ ): Promise<ServiceAssetMetadata[]> {
85
125
  const unique = uniqueIds(ids);
86
126
  if (unique.length === 0) return [];
87
127
 
@@ -90,25 +130,31 @@ export class ServerAssetsApi extends AssetsApi {
90
130
  let firstError: unknown;
91
131
 
92
132
  const settled = await Promise.all(
93
- chunk(unique, SERVICE_ASSET_METADATA_CHUNK_SIZE).map(async (part): Promise<ServiceAssetMetadata[]> => {
94
- try {
95
- const entries = await lane(this.ctx).request<ServiceAssetMetadata[]>('POST', '/assets/service/by-ids', { ids: part });
96
- return Array.isArray(entries) ? entries : [];
97
- } catch (error: unknown) {
98
- const status = extractErrorStatus(error);
99
- logger.warn('assets.metadataByIds: chunk failed', {
100
- method: 'assets.metadataByIds',
101
- chunkSize: part.length,
102
- status,
103
- partial: options.partial === true,
104
- error: error instanceof Error ? error.message : String(error),
105
- });
106
- unresolvedIds.push(...part);
107
- if (typeof status === 'number') statuses.push(status);
108
- firstError ??= error;
109
- return [];
110
- }
111
- }),
133
+ chunk(unique, SERVICE_ASSET_METADATA_CHUNK_SIZE).map(
134
+ async (part): Promise<ServiceAssetMetadata[]> => {
135
+ try {
136
+ const entries = await lane(this.ctx).request<ServiceAssetMetadata[]>(
137
+ 'POST',
138
+ '/assets/service/by-ids',
139
+ { ids: part },
140
+ );
141
+ return Array.isArray(entries) ? entries : [];
142
+ } catch (error: unknown) {
143
+ const status = extractErrorStatus(error);
144
+ logger.warn('assets.metadataByIds: chunk failed', {
145
+ method: 'assets.metadataByIds',
146
+ chunkSize: part.length,
147
+ status,
148
+ partial: options.partial === true,
149
+ error: error instanceof Error ? error.message : String(error),
150
+ });
151
+ unresolvedIds.push(...part);
152
+ if (typeof status === 'number') statuses.push(status);
153
+ firstError ??= error;
154
+ return [];
155
+ }
156
+ },
157
+ ),
112
158
  );
113
159
 
114
160
  if (unresolvedIds.length > 0 && options.partial !== true) {
@@ -138,26 +184,32 @@ export class ServerAssetsApi extends AssetsApi {
138
184
  let firstError: unknown;
139
185
 
140
186
  const settled = await Promise.all(
141
- chunk(unique, SERVICE_LINKED_DOWNLOAD_URL_CHUNK_SIZE).map(async (part): Promise<ServiceLinkedDownloadUrl[]> => {
142
- try {
143
- const entries = await lane(this.ctx).request<ServiceLinkedDownloadUrl[]>('POST', '/assets/service/linked-url', { ids: part });
144
- return Array.isArray(entries) ? entries : [];
145
- } catch (error: unknown) {
146
- const status = extractErrorStatus(error);
147
- // `chunkSize` and `status`, never the ids and never a `url`: a minted
148
- // URL in a log line is a credential in a log line.
149
- logger.warn('assets.linkedDownloadUrls: chunk failed', {
150
- method: 'assets.linkedDownloadUrls',
151
- chunkSize: part.length,
152
- status,
153
- error: error instanceof Error ? error.message : String(error),
154
- });
155
- unresolvedIds.push(...part);
156
- if (typeof status === 'number') statuses.push(status);
157
- firstError ??= error;
158
- return [];
159
- }
160
- }),
187
+ chunk(unique, SERVICE_LINKED_DOWNLOAD_URL_CHUNK_SIZE).map(
188
+ async (part): Promise<ServiceLinkedDownloadUrl[]> => {
189
+ try {
190
+ const entries = await lane(this.ctx).request<ServiceLinkedDownloadUrl[]>(
191
+ 'POST',
192
+ '/assets/service/linked-url',
193
+ { ids: part },
194
+ );
195
+ return Array.isArray(entries) ? entries : [];
196
+ } catch (error: unknown) {
197
+ const status = extractErrorStatus(error);
198
+ // `chunkSize` and `status`, never the ids and never a `url`: a minted
199
+ // URL in a log line is a credential in a log line.
200
+ logger.warn('assets.linkedDownloadUrls: chunk failed', {
201
+ method: 'assets.linkedDownloadUrls',
202
+ chunkSize: part.length,
203
+ status,
204
+ error: error instanceof Error ? error.message : String(error),
205
+ });
206
+ unresolvedIds.push(...part);
207
+ if (typeof status === 'number') statuses.push(status);
208
+ firstError ??= error;
209
+ return [];
210
+ }
211
+ },
212
+ ),
161
213
  );
162
214
 
163
215
  if (unresolvedIds.length > 0) {
@@ -194,21 +246,29 @@ export class ServerAssetsApi extends AssetsApi {
194
246
  if (unique.length === 0) return [];
195
247
 
196
248
  const settled = await Promise.all(
197
- chunk(unique, SERVICE_ASSET_METADATA_BY_SHA_CHUNK_SIZE).map(async (part): Promise<ServiceAssetMetadataBySha[]> => {
198
- try {
199
- const body = options.ownerUserId ? { sha256s: part, ownerUserId: options.ownerUserId } : { sha256s: part };
200
- const entries = await lane(this.ctx).request<ServiceAssetMetadataBySha[]>('POST', '/assets/service/by-sha256', body);
201
- return Array.isArray(entries) ? entries : [];
202
- } catch (error: unknown) {
203
- logger.warn('assets.metadataBySha256: chunk failed, continuing with remaining chunks', {
204
- method: 'assets.metadataBySha256',
205
- chunkSize: part.length,
206
- status: extractErrorStatus(error),
207
- error: error instanceof Error ? error.message : String(error),
208
- });
209
- return [];
210
- }
211
- }),
249
+ chunk(unique, SERVICE_ASSET_METADATA_BY_SHA_CHUNK_SIZE).map(
250
+ async (part): Promise<ServiceAssetMetadataBySha[]> => {
251
+ try {
252
+ const body = options.ownerUserId
253
+ ? { sha256s: part, ownerUserId: options.ownerUserId }
254
+ : { sha256s: part };
255
+ const entries = await lane(this.ctx).request<ServiceAssetMetadataBySha[]>(
256
+ 'POST',
257
+ '/assets/service/by-sha256',
258
+ body,
259
+ );
260
+ return Array.isArray(entries) ? entries : [];
261
+ } catch (error: unknown) {
262
+ logger.warn('assets.metadataBySha256: chunk failed, continuing with remaining chunks', {
263
+ method: 'assets.metadataBySha256',
264
+ chunkSize: part.length,
265
+ status: extractErrorStatus(error),
266
+ error: error instanceof Error ? error.message : String(error),
267
+ });
268
+ return [];
269
+ }
270
+ },
271
+ ),
212
272
  );
213
273
  return settled.flat();
214
274
  }
@@ -222,7 +282,11 @@ export class ServerNotificationsApi extends NotificationsApi {
222
282
  * recipient's own account.
223
283
  */
224
284
  async create(data: CreateOxyNotificationRequest): Promise<Notification> {
225
- const res = await lane(this.ctx).request<{ notification: Notification }>('POST', '/notifications', data);
285
+ const res = await lane(this.ctx).request<{ notification: Notification }>(
286
+ 'POST',
287
+ '/notifications',
288
+ data,
289
+ );
226
290
  return res.notification;
227
291
  }
228
292
  }
@@ -274,33 +338,76 @@ interface ExecutionAuthorizationTerms {
274
338
  expiresAt: string;
275
339
  }
276
340
 
277
- export type CreateExecutionAuthorizationInput = ExecutionAuthorizationTerms & (
278
- | { kind: 'direct_request'; runId: string; stepId?: string; automationId?: never; maximumAutonomy: Exclude<AutonomyLevel, 'autonomous'> }
279
- | { kind: 'automation'; automationId: string; runId?: never; stepId?: never; maximumAutonomy: AutonomyLevel }
280
- );
341
+ export type CreateExecutionAuthorizationInput = ExecutionAuthorizationTerms &
342
+ (
343
+ | {
344
+ kind: 'direct_request';
345
+ runId: string;
346
+ stepId?: string;
347
+ automationId?: never;
348
+ maximumAutonomy: Exclude<AutonomyLevel, 'autonomous'>;
349
+ }
350
+ | {
351
+ kind: 'automation';
352
+ automationId: string;
353
+ runId?: never;
354
+ stepId?: never;
355
+ maximumAutonomy: AutonomyLevel;
356
+ }
357
+ );
281
358
 
282
359
  function agencyAuthorityOptions(signal?: AbortSignal): RequestOptions {
283
360
  signal?.throwIfAborted();
284
- return { cache: false, deduplicate: false, retry: false, skipAuth: true, timeout: 5000, ...(signal ? { signal } : {}) };
361
+ return {
362
+ cache: false,
363
+ deduplicate: false,
364
+ retry: false,
365
+ skipAuth: true,
366
+ timeout: 5000,
367
+ ...(signal ? { signal } : {}),
368
+ };
285
369
  }
286
370
 
287
371
  export class ServerAgencyApi extends AgencyApi {
288
372
  /** Live registry discovery with this service's existing capability scopes. */
289
- async serviceCatalogs(input: { appId?: string; signal?: AbortSignal } = {}): Promise<ServiceCapabilityCatalog[]> {
373
+ async serviceCatalogs(
374
+ input: { appId?: string; signal?: AbortSignal } = {},
375
+ ): Promise<ServiceCapabilityCatalog[]> {
290
376
  const path = `/capabilities/catalogs${input.appId === undefined ? '' : `?appId=${encodeURIComponent(input.appId)}`}`;
291
- const result = await lane(this.ctx).request<{ registrations: ServiceCapabilityCatalog[] }>('GET', path, undefined, agencyAuthorityOptions(input.signal));
377
+ const result = await lane(this.ctx).request<{ registrations: ServiceCapabilityCatalog[] }>(
378
+ 'GET',
379
+ path,
380
+ undefined,
381
+ agencyAuthorityOptions(input.signal),
382
+ );
292
383
  return result.registrations;
293
384
  }
294
385
 
295
386
  /** Existing Oxy execution authority is required; this call creates none. */
296
- async issueCapabilityTicket(input: CapabilityTicketRequest, options: { signal?: AbortSignal } = {}): Promise<CapabilityTicketGrant> {
297
- return lane(this.ctx).request<CapabilityTicketGrant>('POST', '/capabilities/tickets', capabilityTicketRequestSchema.parse(input), agencyAuthorityOptions(options.signal));
387
+ async issueCapabilityTicket(
388
+ input: CapabilityTicketRequest,
389
+ options: { signal?: AbortSignal } = {},
390
+ ): Promise<CapabilityTicketGrant> {
391
+ return lane(this.ctx).request<CapabilityTicketGrant>(
392
+ 'POST',
393
+ '/capabilities/tickets',
394
+ capabilityTicketRequestSchema.parse(input),
395
+ agencyAuthorityOptions(options.signal),
396
+ );
298
397
  }
299
398
 
300
399
  /** Receiving app authenticates live introspection using its own service credential. */
301
- async introspectCapabilityTicket(ticket: string, options: { signal?: AbortSignal } = {}): Promise<CapabilityTicketIntrospection> {
400
+ async introspectCapabilityTicket(
401
+ ticket: string,
402
+ options: { signal?: AbortSignal } = {},
403
+ ): Promise<CapabilityTicketIntrospection> {
302
404
  if (ticket.trim() === '') throw new Error('A capability ticket is required');
303
- return lane(this.ctx).request<CapabilityTicketIntrospection>('POST', '/capabilities/tickets/introspect', { ticket }, agencyAuthorityOptions(options.signal));
405
+ return lane(this.ctx).request<CapabilityTicketIntrospection>(
406
+ 'POST',
407
+ '/capabilities/tickets/introspect',
408
+ { ticket },
409
+ agencyAuthorityOptions(options.signal),
410
+ );
304
411
  }
305
412
 
306
413
  /**
@@ -308,30 +415,69 @@ export class ServerAgencyApi extends AgencyApi {
308
415
  * The service bearer and attribution headers cannot substitute for that user.
309
416
  * The token goes only to this client's configured Oxy authority; never retry.
310
417
  */
311
- async createExecutionAuthorization(input: CreateExecutionAuthorizationInput, options: { requesterToken: string; signal?: AbortSignal }): Promise<CapabilityExecutionAuthorization> {
312
- if (options.requesterToken === '' || /\s/.test(options.requesterToken)) throw new Error('A requester bearer is required');
313
- const result = await this.ctx.request<{ authorization: CapabilityExecutionAuthorization }>('POST', '/capabilities/execution-authorizations', input, {
314
- ...agencyAuthorityOptions(options.signal),
315
- headers: { Authorization: `Bearer ${options.requesterToken}` },
316
- });
418
+ async createExecutionAuthorization(
419
+ input: CreateExecutionAuthorizationInput,
420
+ options: { requesterToken: string; signal?: AbortSignal },
421
+ ): Promise<CapabilityExecutionAuthorization> {
422
+ if (options.requesterToken === '' || /\s/.test(options.requesterToken))
423
+ throw new Error('A requester bearer is required');
424
+ const result = await this.ctx.request<{ authorization: CapabilityExecutionAuthorization }>(
425
+ 'POST',
426
+ '/capabilities/execution-authorizations',
427
+ input,
428
+ {
429
+ ...agencyAuthorityOptions(options.signal),
430
+ headers: { Authorization: `Bearer ${options.requesterToken}` },
431
+ },
432
+ );
317
433
  return result.authorization;
318
434
  }
319
435
 
320
436
  /** Revoke a direct approval on its canonical requester-authenticated lane. */
321
- async revokeExecutionAuthorization(authorizationId: string, options: { requesterToken: string; signal?: AbortSignal }): Promise<void> {
437
+ async revokeExecutionAuthorization(
438
+ authorizationId: string,
439
+ options: { requesterToken: string; signal?: AbortSignal },
440
+ ): Promise<void> {
322
441
  options.signal?.throwIfAborted();
323
- if (!authorizationId || authorizationId.length > 255 || /\s/.test(authorizationId)) throw new Error('An execution authorization id is required');
324
- if (!options.requesterToken || options.requesterToken.length > 16_384 || /\s/.test(options.requesterToken)) throw new Error('A requester bearer is required');
325
- await this.ctx.request<void>('DELETE', `/capabilities/execution-authorizations/${encodeURIComponent(authorizationId)}`,
326
- undefined, { ...agencyAuthorityOptions(options.signal), headers: { Authorization: `Bearer ${options.requesterToken}` } });
442
+ if (!authorizationId || authorizationId.length > 255 || /\s/.test(authorizationId))
443
+ throw new Error('An execution authorization id is required');
444
+ if (
445
+ !options.requesterToken ||
446
+ options.requesterToken.length > 16_384 ||
447
+ /\s/.test(options.requesterToken)
448
+ )
449
+ throw new Error('A requester bearer is required');
450
+ await this.ctx.request<void>(
451
+ 'DELETE',
452
+ `/capabilities/execution-authorizations/${encodeURIComponent(authorizationId)}`,
453
+ undefined,
454
+ {
455
+ ...agencyAuthorityOptions(options.signal),
456
+ headers: { Authorization: `Bearer ${options.requesterToken}` },
457
+ },
458
+ );
327
459
  }
328
460
 
329
461
  /** Independent service proof plus present requester bearer, sent only to Oxy. */
330
- async createForegroundExecutionAuthorization(input: ForegroundExecutionAuthorizationInput, options: { requesterToken: string; signal?: AbortSignal }): Promise<CapabilityExecutionAuthorization> {
331
- if (options.requesterToken === '' || options.requesterToken.length > 16_384 || /\s/.test(options.requesterToken)) throw new Error('A requester bearer is required');
332
- const result = await lane(this.ctx).request<{ authorization: CapabilityExecutionAuthorization }>(
333
- 'POST', '/capabilities/foreground-execution-authorizations',
334
- { ...foregroundExecutionAuthorizationInputSchema.parse(input), subjectToken: options.requesterToken },
462
+ async createForegroundExecutionAuthorization(
463
+ input: ForegroundExecutionAuthorizationInput,
464
+ options: { requesterToken: string; signal?: AbortSignal },
465
+ ): Promise<CapabilityExecutionAuthorization> {
466
+ if (
467
+ options.requesterToken === '' ||
468
+ options.requesterToken.length > 16_384 ||
469
+ /\s/.test(options.requesterToken)
470
+ )
471
+ throw new Error('A requester bearer is required');
472
+ const result = await lane(this.ctx).request<{
473
+ authorization: CapabilityExecutionAuthorization;
474
+ }>(
475
+ 'POST',
476
+ '/capabilities/foreground-execution-authorizations',
477
+ {
478
+ ...foregroundExecutionAuthorizationInputSchema.parse(input),
479
+ subjectToken: options.requesterToken,
480
+ },
335
481
  agencyAuthorityOptions(options.signal),
336
482
  );
337
483
  return result.authorization;
@@ -344,7 +490,10 @@ export class ServerAgencyApi extends AgencyApi {
344
490
  * forward it anywhere else. Not retried: a refusal is an answer, and the
345
491
  * caller mints per turn.
346
492
  */
347
- async mintRequesterAssertion(input: { agentId: string; subjectToken: string }): Promise<RequesterAssertionGrant> {
493
+ async mintRequesterAssertion(input: {
494
+ agentId: string;
495
+ subjectToken: string;
496
+ }): Promise<RequesterAssertionGrant> {
348
497
  return lane(this.ctx).request<RequesterAssertionGrant>(
349
498
  'POST',
350
499
  '/internal/native-agents/requester-assertions',
@@ -378,7 +527,11 @@ export class ServerReputationApi extends ReputationApi {
378
527
  * moves it by hand. Invalidates cached reputation reads.
379
528
  */
380
529
  async award(input: AwardReputationInput): Promise<ReputationTransaction> {
381
- const res = await lane(this.ctx).request<{ transaction: ReputationTransaction }>('POST', '/reputation/award', input);
530
+ const res = await lane(this.ctx).request<{ transaction: ReputationTransaction }>(
531
+ 'POST',
532
+ '/reputation/award',
533
+ input,
534
+ );
382
535
  this.ctx.oxy.cache.deletePrefix(REPUTATION_CACHE_PREFIX);
383
536
  return res.transaction;
384
537
  }
@@ -197,8 +197,7 @@ function maskIPv6(ip: string, bits: number): string {
197
197
  * salt. The result is a short hex digest with no colons, so it is Redis-safe.
198
198
  */
199
199
  function hashAnonymousIp(ip: string): string {
200
- const normalized =
201
- isIPv6(ip) && !ip.startsWith('::ffff:') ? maskIPv6(ip, IPV6_SUBNET_BITS) : ip;
200
+ const normalized = isIPv6(ip) && !ip.startsWith('::ffff:') ? maskIPv6(ip, IPV6_SUBNET_BITS) : ip;
202
201
  const salt = process.env.IP_HASH_SALT || process.env.DEVICE_ID_SALT || '';
203
202
  return createHmac('sha256', salt).update(`rl|${normalized}`).digest('hex').slice(0, 24);
204
203
  }
@@ -273,8 +272,7 @@ export function createOxyRateLimit(
273
272
  // not just to the bucket calculation.
274
273
  const resolveSession = createOptionalOxyAuth(oxy, { auth });
275
274
 
276
- const skip = (req: Request): boolean =>
277
- isBuiltInExempt(req) || (exempt ? exempt(req) : false);
275
+ const skip = (req: Request): boolean => isBuiltInExempt(req) || (exempt ? exempt(req) : false);
278
276
 
279
277
  const limiter = rateLimit({
280
278
  windowMs,