@omnicross/core 0.1.2 → 0.1.3

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 (131) hide show
  1. package/dist/auth/GeminiCodeAssistProjectResolver.cjs +6 -1
  2. package/dist/auth/GeminiCodeAssistProjectResolver.js +6 -1
  3. package/dist/{chunk-SN3YWBX7.cjs → chunk-2FMI2B6V.cjs} +2329 -533
  4. package/dist/{chunk-XBSYYZIY.cjs → chunk-3QOSDDNI.cjs} +39 -3
  5. package/dist/{chunk-2FEVTJWG.js → chunk-4DECIFU7.js} +2162 -366
  6. package/dist/chunk-4IH4EL7M.cjs +9 -0
  7. package/dist/chunk-5ENKBSWO.js +311 -0
  8. package/dist/chunk-6RPZADX3.cjs +92 -0
  9. package/dist/chunk-AEOZIDEB.cjs +32 -0
  10. package/dist/chunk-BO4RFWBR.js +89 -0
  11. package/dist/{chunk-MNYKI4CI.js → chunk-CWM2ZDU5.js} +36 -0
  12. package/dist/chunk-CZHZGRU7.js +383 -0
  13. package/dist/{chunk-4NBS6KPV.cjs → chunk-DQ5VAYZ6.cjs} +7 -8
  14. package/dist/chunk-HUZZZ3JL.js +32 -0
  15. package/dist/{chunk-QOCNX236.js → chunk-IAXWICZU.js} +24 -1
  16. package/dist/{chunk-V5KPWNYX.cjs → chunk-JMJBSACD.cjs} +3 -3
  17. package/dist/chunk-L74VDN4A.cjs +32 -0
  18. package/dist/{chunk-74TMJA7Z.js → chunk-N5QFKSDO.js} +7 -4
  19. package/dist/{chunk-LKZJEL6E.cjs → chunk-Q27JY5RG.cjs} +6 -4
  20. package/dist/{chunk-SPVWWUHX.cjs → chunk-QWBWGODS.cjs} +24 -1
  21. package/dist/chunk-RPII3E6Z.cjs +145 -0
  22. package/dist/chunk-S6JGLF3G.cjs +89 -0
  23. package/dist/chunk-SVXC36MU.cjs +383 -0
  24. package/dist/chunk-TKJMZBAH.js +32 -0
  25. package/dist/{chunk-ZSVQT3PW.js → chunk-UBWEBKRC.js} +5 -6
  26. package/dist/chunk-UNEFIWXI.cjs +32 -0
  27. package/dist/chunk-VQY5W4YW.cjs +311 -0
  28. package/dist/chunk-WNY4WMRF.js +32 -0
  29. package/dist/chunk-XEKD23J5.js +9 -0
  30. package/dist/chunk-XTEI64OU.js +145 -0
  31. package/dist/chunk-XX6NQJMA.js +92 -0
  32. package/dist/{chunk-N3V2J5ZO.cjs → chunk-Y6OM7EV7.cjs} +7 -4
  33. package/dist/{chunk-745DV5FL.js → chunk-Y7FO65VT.js} +3 -3
  34. package/dist/{chunk-PXUJF5HS.js → chunk-ZY6KU6P3.js} +4 -2
  35. package/dist/completion/CompletionService.cjs +22 -15
  36. package/dist/completion/CompletionService.js +21 -14
  37. package/dist/completion/NativeSearchInjector.cjs +3 -3
  38. package/dist/completion/NativeSearchInjector.js +2 -2
  39. package/dist/completion/openrouter-headers.cjs +3 -6
  40. package/dist/completion/openrouter-headers.d.cts +9 -12
  41. package/dist/completion/openrouter-headers.d.ts +9 -12
  42. package/dist/completion/openrouter-headers.js +2 -5
  43. package/dist/completion/openrouter-models.cjs +4 -3
  44. package/dist/completion/openrouter-models.js +2 -1
  45. package/dist/completion.cjs +22 -15
  46. package/dist/completion.js +21 -14
  47. package/dist/index.cjs +139 -17
  48. package/dist/index.d.cts +40 -10
  49. package/dist/index.d.ts +40 -10
  50. package/dist/index.js +146 -24
  51. package/dist/outbound-api/routeResolver.cjs +5 -2
  52. package/dist/outbound-api/routeResolver.d.cts +8 -2
  53. package/dist/outbound-api/routeResolver.d.ts +8 -2
  54. package/dist/outbound-api/routeResolver.js +4 -1
  55. package/dist/outbound-api/types.cjs +6 -1
  56. package/dist/outbound-api/types.d.cts +11 -144
  57. package/dist/outbound-api/types.d.ts +11 -144
  58. package/dist/outbound-api/types.js +6 -0
  59. package/dist/outbound-api.cjs +133 -15
  60. package/dist/outbound-api.d.cts +786 -25
  61. package/dist/outbound-api.d.ts +786 -25
  62. package/dist/outbound-api.js +137 -19
  63. package/dist/pipeline/AuthSource.d.cts +23 -1
  64. package/dist/pipeline/AuthSource.d.ts +23 -1
  65. package/dist/pipeline/LlmConfigProviderAuth.cjs +3 -3
  66. package/dist/pipeline/LlmConfigProviderAuth.js +2 -2
  67. package/dist/pipeline/SubscriptionAccountHealth.cjs +22 -0
  68. package/dist/pipeline/SubscriptionAccountHealth.d.cts +235 -0
  69. package/dist/pipeline/SubscriptionAccountHealth.d.ts +235 -0
  70. package/dist/pipeline/SubscriptionAccountHealth.js +22 -0
  71. package/dist/pipeline/SubscriptionAuthSource.cjs +2 -2
  72. package/dist/pipeline/SubscriptionAuthSource.d.cts +3 -2
  73. package/dist/pipeline/SubscriptionAuthSource.d.ts +3 -2
  74. package/dist/pipeline/SubscriptionAuthSource.js +1 -1
  75. package/dist/pipeline/SubscriptionAuthStrategy.d.cts +24 -1
  76. package/dist/pipeline/SubscriptionAuthStrategy.d.ts +24 -1
  77. package/dist/pipeline/auditSink.cjs +14 -0
  78. package/dist/pipeline/auditSink.d.cts +48 -0
  79. package/dist/pipeline/auditSink.d.ts +48 -0
  80. package/dist/pipeline/auditSink.js +14 -0
  81. package/dist/pipeline/billingEmit.cjs +14 -0
  82. package/dist/pipeline/billingEmit.d.cts +49 -0
  83. package/dist/pipeline/billingEmit.d.ts +49 -0
  84. package/dist/pipeline/billingEmit.js +14 -0
  85. package/dist/ports/usage-event-store.d.cts +26 -1
  86. package/dist/ports/usage-event-store.d.ts +26 -1
  87. package/dist/ports.d.cts +7 -1
  88. package/dist/ports.d.ts +7 -1
  89. package/dist/provider-proxy/ProviderProxy.cjs +22 -15
  90. package/dist/provider-proxy/ProviderProxy.js +21 -14
  91. package/dist/provider-proxy/identity/SubscriptionIdentityStore.cjs +15 -0
  92. package/dist/provider-proxy/identity/SubscriptionIdentityStore.d.cts +121 -0
  93. package/dist/provider-proxy/identity/SubscriptionIdentityStore.d.ts +121 -0
  94. package/dist/provider-proxy/identity/SubscriptionIdentityStore.js +15 -0
  95. package/dist/provider-proxy/identity/fingerprintHeaders.cjs +20 -0
  96. package/dist/provider-proxy/identity/fingerprintHeaders.d.cts +89 -0
  97. package/dist/provider-proxy/identity/fingerprintHeaders.d.ts +89 -0
  98. package/dist/provider-proxy/identity/fingerprintHeaders.js +20 -0
  99. package/dist/provider-proxy/ingress/providerProxyShared.cjs +22 -15
  100. package/dist/provider-proxy/ingress/providerProxyShared.d.cts +11 -2
  101. package/dist/provider-proxy/ingress/providerProxyShared.d.ts +11 -2
  102. package/dist/provider-proxy/ingress/providerProxyShared.js +21 -14
  103. package/dist/provider-proxy/matchText.cjs +4 -2
  104. package/dist/provider-proxy/matchText.d.cts +14 -1
  105. package/dist/provider-proxy/matchText.d.ts +14 -1
  106. package/dist/provider-proxy/matchText.js +3 -1
  107. package/dist/provider-proxy/types.d.cts +23 -0
  108. package/dist/provider-proxy/types.d.ts +23 -0
  109. package/dist/provider-proxy.cjs +22 -15
  110. package/dist/provider-proxy.js +21 -14
  111. package/dist/{routeResolver-HE-ZO0fO.d.ts → routeResolver-B1NglTfe.d.ts} +36 -10
  112. package/dist/{routeResolver-BrbK6ja9.d.cts → routeResolver-CbG5uBgm.d.cts} +36 -10
  113. package/dist/transformer/transformers.cjs +7 -7
  114. package/dist/transformer/transformers.js +7 -7
  115. package/dist/transformer.cjs +5 -5
  116. package/dist/transformer.js +4 -4
  117. package/dist/types-6OUY_xfA.d.ts +830 -0
  118. package/dist/types-aBFFXoBz.d.cts +830 -0
  119. package/dist/usage/usage-recorder.cjs +2 -2
  120. package/dist/usage/usage-recorder.d.cts +19 -1
  121. package/dist/usage/usage-recorder.d.ts +19 -1
  122. package/dist/usage/usage-recorder.js +1 -1
  123. package/dist/usage.cjs +2 -2
  124. package/dist/usage.js +1 -1
  125. package/package.json +4 -2
  126. package/dist/chunk-3MEACFK3.js +0 -193
  127. package/dist/chunk-6VIXXLMX.cjs +0 -14
  128. package/dist/chunk-E3WHL7CO.js +0 -14
  129. package/dist/chunk-G2FUJNA2.cjs +0 -193
  130. package/dist/{chunk-UYPEN5XE.cjs → chunk-FFALUUZZ.cjs} +5 -5
  131. package/dist/{chunk-O466Y272.js → chunk-MQNDWYPN.js} +6 -6
@@ -1,4 +1,4 @@
1
- import { UsageEventInput, UsageDateRange, UsageTotals, ModelUsageRow, ApiKeyUsageRow, MessageUsageRow, SessionCacheStats } from '@omnicross/contracts/usage-stats-types';
1
+ import { UsageEventInput, UsageDateRange, UsageTotals, ModelUsageRow, ApiKeyUsageRow, UsageTimeBucket, UsageTimeSeriesBucket, MessageUsageRow, SessionCacheStats } from '@omnicross/contracts/usage-stats-types';
2
2
 
3
3
  /**
4
4
  * `UsageEventStore` — core-owned port for usage-event persistence + aggregation.
@@ -20,6 +20,31 @@ interface UsageEventStore {
20
20
  getByModel(range: UsageDateRange): Promise<ModelUsageRow[]>;
21
21
  /** Per-API-key breakdown over a date range. */
22
22
  getByApiKey(range: UsageDateRange): Promise<ApiKeyUsageRow[]>;
23
+ /**
24
+ * ONE scan of a single key's events (`ts < endTs`, EXCLUSIVE) summing its
25
+ * `costUsd` into all three windows at once: `totalUsd` (whole history),
26
+ * `dailyUsd` (`ts >= dayStartTs`) and `weeklyUsd` (`ts >= weekStartTs`). Used by
27
+ * the outbound key-policy spend tracker to LAZILY seed a key on first use (once
28
+ * per newly-seen key, NOT per request — a single pass, not three). A key with
29
+ * no attributed events yields all zeros.
30
+ */
31
+ getSpendByKey(query: {
32
+ apiKeyId: string;
33
+ dayStartTs: number;
34
+ weekStartTs: number;
35
+ endTs: number;
36
+ }): Promise<{
37
+ totalUsd: number;
38
+ dailyUsd: number;
39
+ weeklyUsd: number;
40
+ }>;
41
+ /**
42
+ * Time-series aggregation over `range`, bucketed at `bucket` granularity using
43
+ * the store host's LOCAL-time boundaries. EVERY bucket in the range is
44
+ * returned (empty ones zero-filled), ascending by `bucketStartTs`; an empty
45
+ * range (`startTs >= endTs`) returns `[]`.
46
+ */
47
+ getTimeSeries(range: UsageDateRange, bucket: UsageTimeBucket): Promise<UsageTimeSeriesBucket[]>;
23
48
  /** Message-level rows for one session. */
24
49
  getMessagesForSession(sessionId: string): Promise<MessageUsageRow[]>;
25
50
  /** Cumulative cache hit/miss stats for one session. */
@@ -1,4 +1,4 @@
1
- import { UsageEventInput, UsageDateRange, UsageTotals, ModelUsageRow, ApiKeyUsageRow, MessageUsageRow, SessionCacheStats } from '@omnicross/contracts/usage-stats-types';
1
+ import { UsageEventInput, UsageDateRange, UsageTotals, ModelUsageRow, ApiKeyUsageRow, UsageTimeBucket, UsageTimeSeriesBucket, MessageUsageRow, SessionCacheStats } from '@omnicross/contracts/usage-stats-types';
2
2
 
3
3
  /**
4
4
  * `UsageEventStore` — core-owned port for usage-event persistence + aggregation.
@@ -20,6 +20,31 @@ interface UsageEventStore {
20
20
  getByModel(range: UsageDateRange): Promise<ModelUsageRow[]>;
21
21
  /** Per-API-key breakdown over a date range. */
22
22
  getByApiKey(range: UsageDateRange): Promise<ApiKeyUsageRow[]>;
23
+ /**
24
+ * ONE scan of a single key's events (`ts < endTs`, EXCLUSIVE) summing its
25
+ * `costUsd` into all three windows at once: `totalUsd` (whole history),
26
+ * `dailyUsd` (`ts >= dayStartTs`) and `weeklyUsd` (`ts >= weekStartTs`). Used by
27
+ * the outbound key-policy spend tracker to LAZILY seed a key on first use (once
28
+ * per newly-seen key, NOT per request — a single pass, not three). A key with
29
+ * no attributed events yields all zeros.
30
+ */
31
+ getSpendByKey(query: {
32
+ apiKeyId: string;
33
+ dayStartTs: number;
34
+ weekStartTs: number;
35
+ endTs: number;
36
+ }): Promise<{
37
+ totalUsd: number;
38
+ dailyUsd: number;
39
+ weeklyUsd: number;
40
+ }>;
41
+ /**
42
+ * Time-series aggregation over `range`, bucketed at `bucket` granularity using
43
+ * the store host's LOCAL-time boundaries. EVERY bucket in the range is
44
+ * returned (empty ones zero-filled), ascending by `bucketStartTs`; an empty
45
+ * range (`startTs >= endTs`) returns `[]`.
46
+ */
47
+ getTimeSeries(range: UsageDateRange, bucket: UsageTimeBucket): Promise<UsageTimeSeriesBucket[]>;
23
48
  /** Message-level rows for one session. */
24
49
  getMessagesForSession(sessionId: string): Promise<MessageUsageRow[]>;
25
50
  /** Cumulative cache hit/miss stats for one session. */
package/dist/ports.d.cts CHANGED
@@ -5,7 +5,7 @@ export { ProviderConfigSource } from './ports/provider-config-source.cjs';
5
5
  export { UsageEventStore } from './ports/usage-event-store.cjs';
6
6
  export { WebSearchBackend } from './ports/web-search-backend.cjs';
7
7
  export { UsageRecorderImport as UsageSink } from './provider-proxy/types.cjs';
8
- export { OutboundKeyDb as OutboundCredentialStore } from './outbound-api/types.cjs';
8
+ export { O as OutboundCredentialStore } from './types-aBFFXoBz.cjs';
9
9
  import '@omnicross/contracts/pricing-types';
10
10
  import '@omnicross/contracts/llm-config';
11
11
  import './transformer/types.cjs';
@@ -20,4 +20,10 @@ import './completion/ApiKeyPoolService.cjs';
20
20
  import './pipeline/AuthSource.cjs';
21
21
  import './pipeline/SubscriptionAuthSource.cjs';
22
22
  import './pipeline/SubscriptionAuthStrategy.cjs';
23
+ import '@omnicross/contracts/account-tokens-types';
24
+ import '@omnicross/contracts/audit-types';
25
+ import '@omnicross/contracts/billing-types';
26
+ import '@omnicross/contracts/health-logging-types';
27
+ import '@omnicross/contracts/voucher-types';
28
+ import '@omnicross/contracts/webhook-types';
23
29
  import './ProviderProxy-CnMQYN59.cjs';
package/dist/ports.d.ts CHANGED
@@ -5,7 +5,7 @@ export { ProviderConfigSource } from './ports/provider-config-source.js';
5
5
  export { UsageEventStore } from './ports/usage-event-store.js';
6
6
  export { WebSearchBackend } from './ports/web-search-backend.js';
7
7
  export { UsageRecorderImport as UsageSink } from './provider-proxy/types.js';
8
- export { OutboundKeyDb as OutboundCredentialStore } from './outbound-api/types.js';
8
+ export { O as OutboundCredentialStore } from './types-6OUY_xfA.js';
9
9
  import '@omnicross/contracts/pricing-types';
10
10
  import '@omnicross/contracts/llm-config';
11
11
  import './transformer/types.js';
@@ -20,4 +20,10 @@ import './completion/ApiKeyPoolService.js';
20
20
  import './pipeline/AuthSource.js';
21
21
  import './pipeline/SubscriptionAuthSource.js';
22
22
  import './pipeline/SubscriptionAuthStrategy.js';
23
+ import '@omnicross/contracts/account-tokens-types';
24
+ import '@omnicross/contracts/audit-types';
25
+ import '@omnicross/contracts/billing-types';
26
+ import '@omnicross/contracts/health-logging-types';
27
+ import '@omnicross/contracts/voucher-types';
28
+ import '@omnicross/contracts/webhook-types';
23
29
  import './ProviderProxy-C-xqrkKi.js';
@@ -1,40 +1,47 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
2
 
3
3
 
4
- var _chunkSN3YWBX7cjs = require('../chunk-SN3YWBX7.cjs');
5
- require('../chunk-SPVWWUHX.cjs');
4
+ var _chunk2FMI2B6Vcjs = require('../chunk-2FMI2B6V.cjs');
6
5
  require('../chunk-HQP3K7PU.cjs');
7
6
  require('../chunk-FZ46M34D.cjs');
8
7
  require('../chunk-46ZIFWYG.cjs');
9
- require('../chunk-GBHYAGX3.cjs');
10
8
  require('../chunk-3OPYJG76.cjs');
11
- require('../chunk-UYPEN5XE.cjs');
12
- require('../chunk-7YN22L2H.cjs');
13
- require('../chunk-2DCNB7DF.cjs');
9
+ require('../chunk-FFALUUZZ.cjs');
14
10
  require('../chunk-C72S6TTV.cjs');
15
11
  require('../chunk-DWKQZ2SK.cjs');
16
12
  require('../chunk-4VAVYUZS.cjs');
13
+ require('../chunk-7YN22L2H.cjs');
14
+ require('../chunk-2DCNB7DF.cjs');
17
15
  require('../chunk-EYZYXJTJ.cjs');
18
16
  require('../chunk-YMFAJFQT.cjs');
19
- require('../chunk-XBSYYZIY.cjs');
17
+ require('../chunk-3QOSDDNI.cjs');
18
+ require('../chunk-GBHYAGX3.cjs');
19
+ require('../chunk-RPII3E6Z.cjs');
20
+ require('../chunk-6RPZADX3.cjs');
21
+ require('../chunk-QWBWGODS.cjs');
22
+ require('../chunk-NYUNU75A.cjs');
23
+ require('../chunk-VQY5W4YW.cjs');
24
+ require('../chunk-Y6OM7EV7.cjs');
25
+ require('../chunk-SVNDB62D.cjs');
20
26
  require('../chunk-R3HK6R4B.cjs');
27
+ require('../chunk-AEOZIDEB.cjs');
28
+ require('../chunk-L74VDN4A.cjs');
21
29
  require('../chunk-KUU2RNG6.cjs');
22
- require('../chunk-LKZJEL6E.cjs');
30
+ require('../chunk-Q27JY5RG.cjs');
23
31
  require('../chunk-QXD4MV2X.cjs');
24
- require('../chunk-NYUNU75A.cjs');
25
- require('../chunk-N3V2J5ZO.cjs');
26
- require('../chunk-SVNDB62D.cjs');
27
32
  require('../chunk-A2YMUCBT.cjs');
28
- require('../chunk-G2FUJNA2.cjs');
33
+ require('../chunk-SVXC36MU.cjs');
29
34
  require('../chunk-QBZJ7P2T.cjs');
35
+ require('../chunk-4IH4EL7M.cjs');
30
36
  require('../chunk-SUEGJ75D.cjs');
37
+ require('../chunk-S6JGLF3G.cjs');
31
38
  require('../chunk-RSJ3TWJQ.cjs');
32
39
  require('../chunk-YGXJGRFI.cjs');
33
40
  require('../chunk-NZYN7C3P.cjs');
34
- require('../chunk-V5KPWNYX.cjs');
35
- require('../chunk-6VIXXLMX.cjs');
41
+ require('../chunk-JMJBSACD.cjs');
36
42
  require('../chunk-GMMT7RVN.cjs');
43
+ require('../chunk-UNEFIWXI.cjs');
37
44
 
38
45
 
39
46
 
40
- exports.ProviderProxy = _chunkSN3YWBX7cjs.ProviderProxy; exports.isLoopbackAddress = _chunkSN3YWBX7cjs.isLoopbackAddress;
47
+ exports.ProviderProxy = _chunk2FMI2B6Vcjs.ProviderProxy; exports.isLoopbackAddress = _chunk2FMI2B6Vcjs.isLoopbackAddress;
@@ -1,39 +1,46 @@
1
1
  import {
2
2
  ProviderProxy,
3
3
  isLoopbackAddress
4
- } from "../chunk-2FEVTJWG.js";
5
- import "../chunk-QOCNX236.js";
4
+ } from "../chunk-4DECIFU7.js";
6
5
  import "../chunk-VVEHS2LI.js";
7
6
  import "../chunk-46RLHI7D.js";
8
7
  import "../chunk-G2UTNSGU.js";
9
- import "../chunk-MZNPGW5Q.js";
10
8
  import "../chunk-DK4A7DLE.js";
11
- import "../chunk-O466Y272.js";
12
- import "../chunk-C7PSERMH.js";
13
- import "../chunk-5HTVET6E.js";
9
+ import "../chunk-MQNDWYPN.js";
14
10
  import "../chunk-Z7LUNECE.js";
15
11
  import "../chunk-ZJZAOKI7.js";
16
12
  import "../chunk-FTQ7IQUC.js";
13
+ import "../chunk-C7PSERMH.js";
14
+ import "../chunk-5HTVET6E.js";
17
15
  import "../chunk-7VU7V2E4.js";
18
16
  import "../chunk-ZLX3KGXX.js";
19
- import "../chunk-MNYKI4CI.js";
17
+ import "../chunk-CWM2ZDU5.js";
18
+ import "../chunk-MZNPGW5Q.js";
19
+ import "../chunk-XTEI64OU.js";
20
+ import "../chunk-XX6NQJMA.js";
21
+ import "../chunk-IAXWICZU.js";
22
+ import "../chunk-5ERIZW3D.js";
23
+ import "../chunk-5ENKBSWO.js";
24
+ import "../chunk-N5QFKSDO.js";
25
+ import "../chunk-AVYJ4YBN.js";
20
26
  import "../chunk-DRWHTIIZ.js";
27
+ import "../chunk-WNY4WMRF.js";
28
+ import "../chunk-TKJMZBAH.js";
21
29
  import "../chunk-JO5NLTLY.js";
22
- import "../chunk-PXUJF5HS.js";
30
+ import "../chunk-ZY6KU6P3.js";
23
31
  import "../chunk-JWC6APFQ.js";
24
- import "../chunk-5ERIZW3D.js";
25
- import "../chunk-74TMJA7Z.js";
26
- import "../chunk-AVYJ4YBN.js";
27
32
  import "../chunk-H5JUT3KV.js";
28
- import "../chunk-3MEACFK3.js";
33
+ import "../chunk-CZHZGRU7.js";
29
34
  import "../chunk-AQ5TNQB7.js";
35
+ import "../chunk-XEKD23J5.js";
30
36
  import "../chunk-5ZQBEOMD.js";
37
+ import "../chunk-BO4RFWBR.js";
31
38
  import "../chunk-Z7Y2NPHY.js";
32
39
  import "../chunk-S4WBV25P.js";
33
40
  import "../chunk-CDHS2QDC.js";
34
- import "../chunk-745DV5FL.js";
35
- import "../chunk-E3WHL7CO.js";
41
+ import "../chunk-Y7FO65VT.js";
36
42
  import "../chunk-FMOBD2OQ.js";
43
+ import "../chunk-HUZZZ3JL.js";
37
44
  export {
38
45
  ProviderProxy,
39
46
  isLoopbackAddress
@@ -0,0 +1,15 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
+
3
+
4
+
5
+
6
+
7
+ var _chunkRPII3E6Zcjs = require('../../chunk-RPII3E6Z.cjs');
8
+ require('../../chunk-6RPZADX3.cjs');
9
+
10
+
11
+
12
+
13
+
14
+
15
+ exports.CC_HEADER_TTL_MS = _chunkRPII3E6Zcjs.CC_HEADER_TTL_MS; exports.SubscriptionIdentityStore = _chunkRPII3E6Zcjs.SubscriptionIdentityStore; exports.__resetSharedIdentityStoreForTests = _chunkRPII3E6Zcjs.__resetSharedIdentityStoreForTests; exports.getSharedIdentityStore = _chunkRPII3E6Zcjs.getSharedIdentityStore; exports.setSharedIdentityStore = _chunkRPII3E6Zcjs.setSharedIdentityStore;
@@ -0,0 +1,121 @@
1
+ /**
2
+ * SubscriptionIdentityStore — the per-account client-identity capture/freeze/replay
3
+ * store for claude-subscription outbound traffic (subscription-client-fingerprint
4
+ * #7, design D1/D4/D5/D7).
5
+ *
6
+ * Shaped like the existing in-memory `SubscriptionAccountHealth` tracker: an
7
+ * in-memory `Map`, an injectable `now` clock, NO external deps. It is keyed by an
8
+ * opaque `providerId + '\0' + accountId` string — core never learns "account"
9
+ * semantics (exactly the health-tracker precedent), and there is NO
10
+ * `@omnicross/subscriptions` import. It carries NO token/secret: the capture
11
+ * whitelist + `sanitizeFrozenHeaders` exclude `authorization`/`x-api-key`/`cookie`
12
+ * at BOTH ingress and store-normalize.
13
+ *
14
+ * Freeze/replay model (D4 — never fabricate):
15
+ * - The FIRST captured fingerprint set for an account is FROZEN; every later
16
+ * outbound request for that account REPLAYS that frozen set → a stable
17
+ * per-account identity. Stainless headers are frozen-stable forever; the
18
+ * non-stainless (CC) headers refresh on a 7-day TTL from a newer real
19
+ * observation (P2, `refreshNonStainless`).
20
+ * - Values are ONLY ever REAL captured client values — nothing here invents a
21
+ * `x-stainless-*`. An un-captured account replays NOTHING (the caller then
22
+ * applies at most the operator UA baseline).
23
+ *
24
+ * Persistence (P2, D5): OPTIONAL. When a persistence port is installed
25
+ * (`setPersistence`), a first-seen freeze / TTL refresh is written through to the
26
+ * account entry (additive NON-secret metadata) so the identity survives restart;
27
+ * at boot the daemon `seed()`s the store from the persisted entries. In-memory-only
28
+ * (no port) is the P1 default — a real client re-captures after restart.
29
+ *
30
+ * @module provider-proxy/identity/SubscriptionIdentityStore
31
+ */
32
+ /** A frozen per-account client identity (the captured fingerprint headers). */
33
+ interface FrozenIdentity {
34
+ /** The captured fingerprint headers (lowercased keys; token/secret excluded). */
35
+ headers: Record<string, string>;
36
+ /** Epoch ms of the freeze (or last TTL refresh). */
37
+ capturedAt: number;
38
+ }
39
+ /**
40
+ * Write-through persistence port (P2, D5). The store calls `persist` on a
41
+ * first-seen freeze / TTL refresh; the daemon implementation writes the identity
42
+ * onto the account entry. Fire-and-forget — the store swallows any throw so the
43
+ * hot path is never affected. Core defines the port; the daemon supplies it (the
44
+ * `setUpstreamProxyResolver` / `setWebhookSink` precedent — no daemon import).
45
+ */
46
+ interface IdentityPersistencePort {
47
+ persist(providerId: string, accountId: string, identity: FrozenIdentity): void;
48
+ }
49
+ /** The CC-header (non-stainless) refresh TTL — 7 days (design D6/P2). */
50
+ declare const CC_HEADER_TTL_MS: number;
51
+ /** Constructor knobs (all optional). */
52
+ interface SubscriptionIdentityStoreOptions {
53
+ /** Injectable clock (ms). Default `Date.now`. */
54
+ now?: () => number;
55
+ /** Whether capture/replay engages. Default `false` (byte-identical outbound). */
56
+ enabled?: boolean;
57
+ /** Operator UA baseline applied ONLY when nothing was captured (piece 4). */
58
+ ua?: string;
59
+ /** The CC-header refresh TTL (ms). Default {@link CC_HEADER_TTL_MS}. */
60
+ ccHeaderTtlMs?: number;
61
+ }
62
+ declare class SubscriptionIdentityStore {
63
+ private readonly identities;
64
+ private readonly now;
65
+ private enabled;
66
+ private ua;
67
+ private ccHeaderTtlMs;
68
+ private persistence;
69
+ constructor(opts?: SubscriptionIdentityStoreOptions);
70
+ /** Whether capture/replay is engaged (config flag). */
71
+ isEnabled(): boolean;
72
+ /** The operator UA baseline (piece 4), or undefined when unset. */
73
+ uaBaseline(): string | undefined;
74
+ /**
75
+ * Re-apply config to the LIVE shared instance (bootstrap, mirroring the health
76
+ * tracker's `configure`). Only defined fields override; `ua: null` clears the
77
+ * baseline.
78
+ */
79
+ configure(opts: {
80
+ enabled?: boolean;
81
+ ua?: string | null;
82
+ }): void;
83
+ /** Install (or clear) the write-through persistence port (P2). */
84
+ setPersistence(port: IdentityPersistencePort | null): void;
85
+ /**
86
+ * Boot seed (P2, D5): install a PERSISTED identity for an account, but NEVER
87
+ * over a live in-memory capture (a re-captured identity from this session wins).
88
+ * A no-op for an empty/absent identity. Does NOT write back through the port.
89
+ */
90
+ seed(providerId: string, accountId: string, identity: FrozenIdentity | undefined): void;
91
+ /**
92
+ * Capture a real client's fingerprint headers for an account. First-seen ⇒
93
+ * FREEZE the whole (sanitized) bag. Already-frozen ⇒ within the TTL, no change
94
+ * (stable identity); past the TTL, refresh the NON-stainless headers from the
95
+ * new observation while keeping stainless frozen-stable (P2). An empty/absent
96
+ * account id or an empty sanitized bag is a no-op (so an account with no
97
+ * fingerprint headers never freezes an empty identity → the caller falls back
98
+ * to the UA baseline). Fires the persistence port on a freeze/refresh.
99
+ */
100
+ capture(providerId: string, accountId: string, incoming: Record<string, string>, now?: number): void;
101
+ /**
102
+ * The frozen identity headers for an account, or `undefined` when none is
103
+ * frozen (or the frozen set is empty). Returns a COPY (the caller merges it into
104
+ * a mutable outbound header bag).
105
+ */
106
+ replay(providerId: string, accountId: string): Record<string, string> | undefined;
107
+ /** Whether an identity is frozen for an account (admin coarse status — D7). */
108
+ hasIdentity(providerId: string, accountId: string): boolean;
109
+ /** The freeze/refresh time for an account's identity (admin coarse status). */
110
+ capturedAt(providerId: string, accountId: string): number | undefined;
111
+ private emitPersist;
112
+ private key;
113
+ }
114
+ /** The shared identity store; lazily constructs a default (disabled) instance. */
115
+ declare function getSharedIdentityStore(): SubscriptionIdentityStore;
116
+ /** Install a specific store at bootstrap (idempotent; last write wins). */
117
+ declare function setSharedIdentityStore(instance: SubscriptionIdentityStore): void;
118
+ /** Reset the shared singleton (tests / teardown only). */
119
+ declare function __resetSharedIdentityStoreForTests(): void;
120
+
121
+ export { CC_HEADER_TTL_MS, type FrozenIdentity, type IdentityPersistencePort, SubscriptionIdentityStore, type SubscriptionIdentityStoreOptions, __resetSharedIdentityStoreForTests, getSharedIdentityStore, setSharedIdentityStore };
@@ -0,0 +1,121 @@
1
+ /**
2
+ * SubscriptionIdentityStore — the per-account client-identity capture/freeze/replay
3
+ * store for claude-subscription outbound traffic (subscription-client-fingerprint
4
+ * #7, design D1/D4/D5/D7).
5
+ *
6
+ * Shaped like the existing in-memory `SubscriptionAccountHealth` tracker: an
7
+ * in-memory `Map`, an injectable `now` clock, NO external deps. It is keyed by an
8
+ * opaque `providerId + '\0' + accountId` string — core never learns "account"
9
+ * semantics (exactly the health-tracker precedent), and there is NO
10
+ * `@omnicross/subscriptions` import. It carries NO token/secret: the capture
11
+ * whitelist + `sanitizeFrozenHeaders` exclude `authorization`/`x-api-key`/`cookie`
12
+ * at BOTH ingress and store-normalize.
13
+ *
14
+ * Freeze/replay model (D4 — never fabricate):
15
+ * - The FIRST captured fingerprint set for an account is FROZEN; every later
16
+ * outbound request for that account REPLAYS that frozen set → a stable
17
+ * per-account identity. Stainless headers are frozen-stable forever; the
18
+ * non-stainless (CC) headers refresh on a 7-day TTL from a newer real
19
+ * observation (P2, `refreshNonStainless`).
20
+ * - Values are ONLY ever REAL captured client values — nothing here invents a
21
+ * `x-stainless-*`. An un-captured account replays NOTHING (the caller then
22
+ * applies at most the operator UA baseline).
23
+ *
24
+ * Persistence (P2, D5): OPTIONAL. When a persistence port is installed
25
+ * (`setPersistence`), a first-seen freeze / TTL refresh is written through to the
26
+ * account entry (additive NON-secret metadata) so the identity survives restart;
27
+ * at boot the daemon `seed()`s the store from the persisted entries. In-memory-only
28
+ * (no port) is the P1 default — a real client re-captures after restart.
29
+ *
30
+ * @module provider-proxy/identity/SubscriptionIdentityStore
31
+ */
32
+ /** A frozen per-account client identity (the captured fingerprint headers). */
33
+ interface FrozenIdentity {
34
+ /** The captured fingerprint headers (lowercased keys; token/secret excluded). */
35
+ headers: Record<string, string>;
36
+ /** Epoch ms of the freeze (or last TTL refresh). */
37
+ capturedAt: number;
38
+ }
39
+ /**
40
+ * Write-through persistence port (P2, D5). The store calls `persist` on a
41
+ * first-seen freeze / TTL refresh; the daemon implementation writes the identity
42
+ * onto the account entry. Fire-and-forget — the store swallows any throw so the
43
+ * hot path is never affected. Core defines the port; the daemon supplies it (the
44
+ * `setUpstreamProxyResolver` / `setWebhookSink` precedent — no daemon import).
45
+ */
46
+ interface IdentityPersistencePort {
47
+ persist(providerId: string, accountId: string, identity: FrozenIdentity): void;
48
+ }
49
+ /** The CC-header (non-stainless) refresh TTL — 7 days (design D6/P2). */
50
+ declare const CC_HEADER_TTL_MS: number;
51
+ /** Constructor knobs (all optional). */
52
+ interface SubscriptionIdentityStoreOptions {
53
+ /** Injectable clock (ms). Default `Date.now`. */
54
+ now?: () => number;
55
+ /** Whether capture/replay engages. Default `false` (byte-identical outbound). */
56
+ enabled?: boolean;
57
+ /** Operator UA baseline applied ONLY when nothing was captured (piece 4). */
58
+ ua?: string;
59
+ /** The CC-header refresh TTL (ms). Default {@link CC_HEADER_TTL_MS}. */
60
+ ccHeaderTtlMs?: number;
61
+ }
62
+ declare class SubscriptionIdentityStore {
63
+ private readonly identities;
64
+ private readonly now;
65
+ private enabled;
66
+ private ua;
67
+ private ccHeaderTtlMs;
68
+ private persistence;
69
+ constructor(opts?: SubscriptionIdentityStoreOptions);
70
+ /** Whether capture/replay is engaged (config flag). */
71
+ isEnabled(): boolean;
72
+ /** The operator UA baseline (piece 4), or undefined when unset. */
73
+ uaBaseline(): string | undefined;
74
+ /**
75
+ * Re-apply config to the LIVE shared instance (bootstrap, mirroring the health
76
+ * tracker's `configure`). Only defined fields override; `ua: null` clears the
77
+ * baseline.
78
+ */
79
+ configure(opts: {
80
+ enabled?: boolean;
81
+ ua?: string | null;
82
+ }): void;
83
+ /** Install (or clear) the write-through persistence port (P2). */
84
+ setPersistence(port: IdentityPersistencePort | null): void;
85
+ /**
86
+ * Boot seed (P2, D5): install a PERSISTED identity for an account, but NEVER
87
+ * over a live in-memory capture (a re-captured identity from this session wins).
88
+ * A no-op for an empty/absent identity. Does NOT write back through the port.
89
+ */
90
+ seed(providerId: string, accountId: string, identity: FrozenIdentity | undefined): void;
91
+ /**
92
+ * Capture a real client's fingerprint headers for an account. First-seen ⇒
93
+ * FREEZE the whole (sanitized) bag. Already-frozen ⇒ within the TTL, no change
94
+ * (stable identity); past the TTL, refresh the NON-stainless headers from the
95
+ * new observation while keeping stainless frozen-stable (P2). An empty/absent
96
+ * account id or an empty sanitized bag is a no-op (so an account with no
97
+ * fingerprint headers never freezes an empty identity → the caller falls back
98
+ * to the UA baseline). Fires the persistence port on a freeze/refresh.
99
+ */
100
+ capture(providerId: string, accountId: string, incoming: Record<string, string>, now?: number): void;
101
+ /**
102
+ * The frozen identity headers for an account, or `undefined` when none is
103
+ * frozen (or the frozen set is empty). Returns a COPY (the caller merges it into
104
+ * a mutable outbound header bag).
105
+ */
106
+ replay(providerId: string, accountId: string): Record<string, string> | undefined;
107
+ /** Whether an identity is frozen for an account (admin coarse status — D7). */
108
+ hasIdentity(providerId: string, accountId: string): boolean;
109
+ /** The freeze/refresh time for an account's identity (admin coarse status). */
110
+ capturedAt(providerId: string, accountId: string): number | undefined;
111
+ private emitPersist;
112
+ private key;
113
+ }
114
+ /** The shared identity store; lazily constructs a default (disabled) instance. */
115
+ declare function getSharedIdentityStore(): SubscriptionIdentityStore;
116
+ /** Install a specific store at bootstrap (idempotent; last write wins). */
117
+ declare function setSharedIdentityStore(instance: SubscriptionIdentityStore): void;
118
+ /** Reset the shared singleton (tests / teardown only). */
119
+ declare function __resetSharedIdentityStoreForTests(): void;
120
+
121
+ export { CC_HEADER_TTL_MS, type FrozenIdentity, type IdentityPersistencePort, SubscriptionIdentityStore, type SubscriptionIdentityStoreOptions, __resetSharedIdentityStoreForTests, getSharedIdentityStore, setSharedIdentityStore };
@@ -0,0 +1,15 @@
1
+ import {
2
+ CC_HEADER_TTL_MS,
3
+ SubscriptionIdentityStore,
4
+ __resetSharedIdentityStoreForTests,
5
+ getSharedIdentityStore,
6
+ setSharedIdentityStore
7
+ } from "../../chunk-XTEI64OU.js";
8
+ import "../../chunk-XX6NQJMA.js";
9
+ export {
10
+ CC_HEADER_TTL_MS,
11
+ SubscriptionIdentityStore,
12
+ __resetSharedIdentityStoreForTests,
13
+ getSharedIdentityStore,
14
+ setSharedIdentityStore
15
+ };
@@ -0,0 +1,20 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
+
3
+
4
+
5
+
6
+
7
+
8
+
9
+
10
+ var _chunk6RPZADX3cjs = require('../../chunk-6RPZADX3.cjs');
11
+
12
+
13
+
14
+
15
+
16
+
17
+
18
+
19
+
20
+ exports.STAINLESS_PREFIX = _chunk6RPZADX3cjs.STAINLESS_PREFIX; exports.applyFingerprint = _chunk6RPZADX3cjs.applyFingerprint; exports.captureCallerIdentity = _chunk6RPZADX3cjs.captureCallerIdentity; exports.extractFingerprintHeaders = _chunk6RPZADX3cjs.extractFingerprintHeaders; exports.isStainless = _chunk6RPZADX3cjs.isStainless; exports.mergeFrozenIdentity = _chunk6RPZADX3cjs.mergeFrozenIdentity; exports.refreshNonStainless = _chunk6RPZADX3cjs.refreshNonStainless; exports.sanitizeFrozenHeaders = _chunk6RPZADX3cjs.sanitizeFrozenHeaders;
@@ -0,0 +1,89 @@
1
+ import { SubscriptionIdentityStore } from './SubscriptionIdentityStore.cjs';
2
+
3
+ /**
4
+ * fingerprintHeaders — the PURE half of subscription client-fingerprint replay
5
+ * (subscription-client-fingerprint #7, design D2/D3/D4/D7).
6
+ *
7
+ * Holds ONLY pure functions (no state, no store): the capture WHITELIST
8
+ * (`extractFingerprintHeaders`), the store-normalizer (`sanitizeFrozenHeaders`),
9
+ * the TTL refresh split (`refreshNonStainless`), the outbound merge
10
+ * (`mergeFrozenIdentity`), and the one composition entrypoint the relay calls
11
+ * (`applyFingerprint`, which takes the store INSTANCE as a parameter so this file
12
+ * never imports the store at runtime — no cycle).
13
+ *
14
+ * SAFETY CORE (non-negotiable):
15
+ * - The capture whitelist is POSITIVE (`x-stainless-*` + a small set of
16
+ * Claude-Code / Anthropic-SDK header names) AND has an explicit EXCLUSION of
17
+ * `authorization` / `x-api-key` / `cookie` (the token/secret) — belt AND
18
+ * suspenders, so widening the whitelist can never leak auth.
19
+ * - The outbound merge NEVER overwrites `authorization` / `content-type`
20
+ * (the auth strategy owns auth; content-type is fixed) and never overwrites a
21
+ * header the outbound build already set (case-insensitive).
22
+ * - Values are only ever REAL captured client headers — nothing here fabricates
23
+ * a `x-stainless-*` value. The only synthesizable piece is the operator-set UA
24
+ * baseline, applied in `applyFingerprint` ONLY when NOTHING was captured.
25
+ *
26
+ * @module provider-proxy/identity/fingerprintHeaders
27
+ */
28
+
29
+ /** Header-name prefix that marks a stainless (SDK-runtime) fingerprint header. */
30
+ declare const STAINLESS_PREFIX = "x-stainless-";
31
+ /** Whether a header name (any case) is a stainless fingerprint header. */
32
+ declare function isStainless(name: string): boolean;
33
+ /**
34
+ * Capture: extract the WHITELISTED fingerprint headers from an incoming client
35
+ * request's header bag (`http.IncomingHttpHeaders`-shaped). Array values (rare —
36
+ * duplicate headers) are joined with `, `. Keys are lowercased. The auth/secret
37
+ * exclusion is applied FIRST so it wins over any whitelist entry. Never throws.
38
+ */
39
+ declare function extractFingerprintHeaders(reqHeaders: Record<string, string | string[] | undefined>): Record<string, string>;
40
+ /**
41
+ * Ingress capture gate (subscription-client-fingerprint #7): extract the caller's
42
+ * fingerprint headers ONLY when replay is enabled — returns `undefined` when
43
+ * disabled so the ingress does NO extraction work on the default/BYO path (and
44
+ * threads nothing to the relay). Behavior when enabled is identical to calling
45
+ * `extractFingerprintHeaders` directly.
46
+ */
47
+ declare function captureCallerIdentity(store: SubscriptionIdentityStore, reqHeaders: Record<string, string | string[] | undefined>): Record<string, string> | undefined;
48
+ /**
49
+ * Store-normalize a header bag before freezing/seeding: lowercase keys, drop
50
+ * empty/non-string values, and HARD-EXCLUDE the auth/secret + protected-outbound
51
+ * sets. This is the second line of defense (after the capture whitelist) so a
52
+ * persisted/seeded identity can never carry a token even if a bad bag was handed
53
+ * in. Idempotent.
54
+ */
55
+ declare function sanitizeFrozenHeaders(headers: Record<string, string>): Record<string, string>;
56
+ /**
57
+ * TTL refresh split (P2, piece 2): produce the refreshed frozen set when a newer
58
+ * real capture is observed after the CC-header TTL. The STAINLESS set stays
59
+ * frozen-stable (only the original values survive — a real client keeps a stable
60
+ * stainless identity); the NON-stainless headers (user-agent / anthropic-beta /
61
+ * x-app / …) are refreshed from the newer observation, falling back to the frozen
62
+ * value when the new bag omits one. New stainless headers in the incoming bag are
63
+ * IGNORED (stainless never grows/changes after the first freeze).
64
+ */
65
+ declare function refreshNonStainless(frozen: Record<string, string>, incoming: Record<string, string>): Record<string, string>;
66
+ /**
67
+ * Merge a frozen identity into the outbound `headers` in place. NEVER overwrites
68
+ * `authorization` / `content-type`, and never overwrites a header already present
69
+ * (case-insensitive) — so a header the auth strategy or the relay already set
70
+ * always wins. The identity keys are already lowercased (`sanitizeFrozenHeaders`).
71
+ */
72
+ declare function mergeFrozenIdentity(headers: Record<string, string>, identity: Record<string, string>): void;
73
+ /**
74
+ * The ONE composition entrypoint the claude same-format relay calls, AFTER
75
+ * `applyHeaders` reported the selected account and BEFORE `fetchUpstream`.
76
+ *
77
+ * Disabled (default) OR no account id ⇒ a strict no-op — the `headers` object is
78
+ * left BYTE-IDENTICAL (the zero-regression guarantee). When enabled:
79
+ * 1. capture the caller's real fingerprint headers for this account (first-seen
80
+ * freeze; P2 TTL refresh) — per-account, keyed by the reported account id;
81
+ * 2. replay the frozen identity for the account into `headers` (never
82
+ * overwriting auth/content-type). On the FIRST request this is the client's
83
+ * own just-captured headers (honest); later requests replay the frozen set;
84
+ * 3. if NOTHING is captured for the account, apply ONLY the operator-configured
85
+ * UA baseline (never a fabricated stainless value).
86
+ */
87
+ declare function applyFingerprint(store: SubscriptionIdentityStore, headers: Record<string, string>, providerId: string, accountId: string | undefined, callerIdentity: Record<string, string> | undefined, now?: number): void;
88
+
89
+ export { STAINLESS_PREFIX, applyFingerprint, captureCallerIdentity, extractFingerprintHeaders, isStainless, mergeFrozenIdentity, refreshNonStainless, sanitizeFrozenHeaders };