@jinn-network/client 0.1.2-canary.d6e72dfd → 0.1.2

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 (218) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/README.md +3 -0
  3. package/dist/adapters/adapter.d.ts +7 -0
  4. package/dist/adapters/mech/adapter.d.ts +4 -0
  5. package/dist/adapters/mech/adapter.js +140 -19
  6. package/dist/adapters/mech/adapter.js.map +1 -1
  7. package/dist/adapters/mech/contracts.d.ts +17 -1
  8. package/dist/adapters/mech/contracts.js +55 -1
  9. package/dist/adapters/mech/contracts.js.map +1 -1
  10. package/dist/adapters/mech/ipfs.d.ts +30 -5
  11. package/dist/adapters/mech/ipfs.js +162 -17
  12. package/dist/adapters/mech/ipfs.js.map +1 -1
  13. package/dist/adapters/mech/safe.js +8 -6
  14. package/dist/adapters/mech/safe.js.map +1 -1
  15. package/dist/adapters/mech/types.d.ts +2 -0
  16. package/dist/adapters/mech/types.js.map +1 -1
  17. package/dist/api/balance-build.js +3 -3
  18. package/dist/api/balance-build.js.map +1 -1
  19. package/dist/api/fleet-build.js +35 -40
  20. package/dist/api/fleet-build.js.map +1 -1
  21. package/dist/api/gather-status.d.ts +5 -0
  22. package/dist/api/gather-status.js +158 -7
  23. package/dist/api/gather-status.js.map +1 -1
  24. package/dist/api/history-build.d.ts +5 -1
  25. package/dist/api/history-build.js +51 -26
  26. package/dist/api/history-build.js.map +1 -1
  27. package/dist/api/portfolio-v0-build.d.ts +3 -1
  28. package/dist/api/portfolio-v0-build.js +12 -10
  29. package/dist/api/portfolio-v0-build.js.map +1 -1
  30. package/dist/api/rewards-build.js +29 -13
  31. package/dist/api/rewards-build.js.map +1 -1
  32. package/dist/api/status-build.d.ts +32 -6
  33. package/dist/api/status-build.js +2 -1
  34. package/dist/api/status-build.js.map +1 -1
  35. package/dist/api/status-rollup-build.d.ts +2 -0
  36. package/dist/api/status-rollup-build.js +30 -3
  37. package/dist/api/status-rollup-build.js.map +1 -1
  38. package/dist/build-meta.json +1 -1
  39. package/dist/cli/commands/auth.js +27 -5
  40. package/dist/cli/commands/auth.js.map +1 -1
  41. package/dist/cli/commands/balance.js +8 -1
  42. package/dist/cli/commands/balance.js.map +1 -1
  43. package/dist/cli/commands/bootstrap.js +22 -0
  44. package/dist/cli/commands/bootstrap.js.map +1 -1
  45. package/dist/cli/commands/doctor.js +33 -3
  46. package/dist/cli/commands/doctor.js.map +1 -1
  47. package/dist/cli/commands/fleet.js +10 -1
  48. package/dist/cli/commands/fleet.js.map +1 -1
  49. package/dist/cli/commands/history.js +25 -6
  50. package/dist/cli/commands/history.js.map +1 -1
  51. package/dist/cli/commands/logs.js +35 -11
  52. package/dist/cli/commands/logs.js.map +1 -1
  53. package/dist/cli/commands/quickstart.js +39 -1
  54. package/dist/cli/commands/quickstart.js.map +1 -1
  55. package/dist/cli/commands/run.js +38 -0
  56. package/dist/cli/commands/run.js.map +1 -1
  57. package/dist/cli/commands/status.js +11 -1
  58. package/dist/cli/commands/status.js.map +1 -1
  59. package/dist/cli/commands/submit-intent.js +62 -99
  60. package/dist/cli/commands/submit-intent.js.map +1 -1
  61. package/dist/cli/intent-registry-access.d.ts +3 -5
  62. package/dist/cli/intent-registry-access.js +12 -34
  63. package/dist/cli/intent-registry-access.js.map +1 -1
  64. package/dist/cli/introspection-context.js +11 -8
  65. package/dist/cli/introspection-context.js.map +1 -1
  66. package/dist/config.d.ts +28 -1
  67. package/dist/config.js +29 -0
  68. package/dist/config.js.map +1 -1
  69. package/dist/daemon/balance-topup-loop.js +32 -4
  70. package/dist/daemon/balance-topup-loop.js.map +1 -1
  71. package/dist/daemon/creator.d.ts +6 -9
  72. package/dist/daemon/creator.js +45 -51
  73. package/dist/daemon/creator.js.map +1 -1
  74. package/dist/daemon/daemon.d.ts +9 -20
  75. package/dist/daemon/daemon.js +34 -27
  76. package/dist/daemon/daemon.js.map +1 -1
  77. package/dist/daemon/delivery-watcher.d.ts +3 -1
  78. package/dist/daemon/delivery-watcher.js +19 -1
  79. package/dist/daemon/delivery-watcher.js.map +1 -1
  80. package/dist/daemon/reward-claim-loop.js +38 -1
  81. package/dist/daemon/reward-claim-loop.js.map +1 -1
  82. package/dist/dashboard/index.html +71 -496
  83. package/dist/discovery/registry.d.ts +54 -0
  84. package/dist/discovery/registry.js +73 -0
  85. package/dist/discovery/registry.js.map +1 -1
  86. package/dist/earning/bootstrap.js +8 -38
  87. package/dist/earning/bootstrap.js.map +1 -1
  88. package/dist/earning/stolas-claim.d.ts +6 -0
  89. package/dist/earning/stolas-claim.js +7 -0
  90. package/dist/earning/stolas-claim.js.map +1 -1
  91. package/dist/intents/kinds/constants.d.ts +5 -0
  92. package/dist/intents/kinds/constants.js +6 -0
  93. package/dist/intents/kinds/constants.js.map +1 -0
  94. package/dist/intents/kinds/index.d.ts +28 -0
  95. package/dist/intents/kinds/index.js +50 -0
  96. package/dist/intents/kinds/index.js.map +1 -0
  97. package/dist/intents/kinds/portfolio-v0.d.ts +2 -0
  98. package/dist/intents/kinds/portfolio-v0.js +13 -0
  99. package/dist/intents/kinds/portfolio-v0.js.map +1 -0
  100. package/dist/intents/kinds/prediction-apy-v0.d.ts +3 -0
  101. package/dist/intents/kinds/prediction-apy-v0.js +21 -0
  102. package/dist/intents/kinds/prediction-apy-v0.js.map +1 -0
  103. package/dist/intents/kinds/prediction-v0.d.ts +3 -0
  104. package/dist/intents/kinds/prediction-v0.js +32 -0
  105. package/dist/intents/kinds/prediction-v0.js.map +1 -0
  106. package/dist/intents/kinds/spec-kind.d.ts +38 -0
  107. package/dist/intents/kinds/spec-kind.js +6 -0
  108. package/dist/intents/kinds/spec-kind.js.map +1 -0
  109. package/dist/intents/posting-service.d.ts +26 -0
  110. package/dist/intents/posting-service.js +218 -0
  111. package/dist/intents/posting-service.js.map +1 -0
  112. package/dist/intents/prediction-apy-v0-auto.js +1 -1
  113. package/dist/intents/prediction-apy-v0-auto.js.map +1 -1
  114. package/dist/intents/prediction-v0-template.d.ts +8 -3
  115. package/dist/intents/prediction-v0-template.js +21 -1
  116. package/dist/intents/prediction-v0-template.js.map +1 -1
  117. package/dist/intents/sources.d.ts +39 -0
  118. package/dist/intents/sources.js +42 -0
  119. package/dist/intents/sources.js.map +1 -0
  120. package/dist/main.js +89 -65
  121. package/dist/main.js.map +1 -1
  122. package/dist/mcp/server.js +8 -4
  123. package/dist/mcp/server.js.map +1 -1
  124. package/dist/observability/emit-event.d.ts +12 -0
  125. package/dist/observability/emit-event.js +27 -0
  126. package/dist/observability/emit-event.js.map +1 -0
  127. package/dist/preflight/api-port.d.ts +13 -0
  128. package/dist/preflight/api-port.js +32 -0
  129. package/dist/preflight/api-port.js.map +1 -0
  130. package/dist/preflight/rpc-network.d.ts +44 -0
  131. package/dist/preflight/rpc-network.js +121 -0
  132. package/dist/preflight/rpc-network.js.map +1 -0
  133. package/dist/restorer/engine/engine.d.ts +10 -0
  134. package/dist/restorer/engine/engine.js +60 -44
  135. package/dist/restorer/engine/engine.js.map +1 -1
  136. package/dist/restorer/impls/claude-mcp-hyperliquid/index.d.ts +7 -4
  137. package/dist/restorer/impls/claude-mcp-hyperliquid/index.js +12 -1
  138. package/dist/restorer/impls/claude-mcp-hyperliquid/index.js.map +1 -1
  139. package/dist/restorer/impls/claude-mcp-prediction/index.d.ts +2 -1
  140. package/dist/restorer/impls/claude-mcp-prediction/index.js +9 -0
  141. package/dist/restorer/impls/claude-mcp-prediction/index.js.map +1 -1
  142. package/dist/restorer/impls/claude-mcp-prediction/types.d.ts +2 -0
  143. package/dist/restorer/impls/claude-mcp-prediction-apy/index.d.ts +34 -0
  144. package/dist/restorer/impls/claude-mcp-prediction-apy/index.js +233 -0
  145. package/dist/restorer/impls/claude-mcp-prediction-apy/index.js.map +1 -0
  146. package/dist/restorer/impls/claude-mcp-prediction-apy/mcp-tools.d.ts +18 -0
  147. package/dist/restorer/impls/claude-mcp-prediction-apy/mcp-tools.js +136 -0
  148. package/dist/restorer/impls/claude-mcp-prediction-apy/mcp-tools.js.map +1 -0
  149. package/dist/restorer/impls/claude-mcp-prediction-apy/prompt.d.ts +7 -0
  150. package/dist/restorer/impls/claude-mcp-prediction-apy/prompt.js +46 -0
  151. package/dist/restorer/impls/claude-mcp-prediction-apy/prompt.js.map +1 -0
  152. package/dist/restorer/impls/claude-mcp-prediction-apy/session-orchestrator.d.ts +27 -0
  153. package/dist/restorer/impls/claude-mcp-prediction-apy/session-orchestrator.js +128 -0
  154. package/dist/restorer/impls/claude-mcp-prediction-apy/session-orchestrator.js.map +1 -0
  155. package/dist/restorer/impls/claude-mcp-prediction-apy/types.d.ts +64 -0
  156. package/dist/restorer/impls/claude-mcp-prediction-apy/types.js +6 -0
  157. package/dist/restorer/impls/claude-mcp-prediction-apy/types.js.map +1 -0
  158. package/dist/restorer/impls/evaluation-context.d.ts +16 -0
  159. package/dist/restorer/impls/evaluation-context.js +18 -0
  160. package/dist/restorer/impls/evaluation-context.js.map +1 -0
  161. package/dist/restorer/impls/index.d.ts +46 -0
  162. package/dist/restorer/impls/index.js +88 -0
  163. package/dist/restorer/impls/index.js.map +1 -0
  164. package/dist/restorer/impls/legacy-claude/index.d.ts +8 -1
  165. package/dist/restorer/impls/legacy-claude/index.js +79 -10
  166. package/dist/restorer/impls/legacy-claude/index.js.map +1 -1
  167. package/dist/restorer/impls/portfolio-v0-evaluator/index.d.ts +2 -1
  168. package/dist/restorer/impls/portfolio-v0-evaluator/index.js +9 -0
  169. package/dist/restorer/impls/portfolio-v0-evaluator/index.js.map +1 -1
  170. package/dist/restorer/impls/portfolio-v0-evaluator/types.d.ts +2 -0
  171. package/dist/restorer/impls/prediction-apy-v0-baseline/index.d.ts +1 -0
  172. package/dist/restorer/impls/prediction-apy-v0-baseline/index.js +12 -3
  173. package/dist/restorer/impls/prediction-apy-v0-baseline/index.js.map +1 -1
  174. package/dist/restorer/impls/prediction-apy-v0-evaluator/canonical-metrics.d.ts +4 -0
  175. package/dist/restorer/impls/prediction-apy-v0-evaluator/canonical-metrics.js +4 -0
  176. package/dist/restorer/impls/prediction-apy-v0-evaluator/canonical-metrics.js.map +1 -1
  177. package/dist/restorer/impls/prediction-apy-v0-evaluator/index.d.ts +6 -3
  178. package/dist/restorer/impls/prediction-apy-v0-evaluator/index.js +55 -33
  179. package/dist/restorer/impls/prediction-apy-v0-evaluator/index.js.map +1 -1
  180. package/dist/restorer/impls/prediction-apy-v0-evaluator/parse-submission.d.ts +7 -0
  181. package/dist/restorer/impls/prediction-apy-v0-evaluator/parse-submission.js +29 -0
  182. package/dist/restorer/impls/prediction-apy-v0-evaluator/parse-submission.js.map +1 -0
  183. package/dist/restorer/impls/prediction-apy-v0-evaluator/types.d.ts +1 -1
  184. package/dist/restorer/impls/prediction-v0-baseline/index.d.ts +2 -0
  185. package/dist/restorer/impls/prediction-v0-baseline/index.js +6 -0
  186. package/dist/restorer/impls/prediction-v0-baseline/index.js.map +1 -1
  187. package/dist/restorer/impls/prediction-v0-evaluator/checks/integrity.d.ts +6 -0
  188. package/dist/restorer/impls/prediction-v0-evaluator/checks/integrity.js +19 -1
  189. package/dist/restorer/impls/prediction-v0-evaluator/checks/integrity.js.map +1 -1
  190. package/dist/restorer/impls/prediction-v0-evaluator/index.d.ts +6 -3
  191. package/dist/restorer/impls/prediction-v0-evaluator/index.js +30 -4
  192. package/dist/restorer/impls/prediction-v0-evaluator/index.js.map +1 -1
  193. package/dist/restorer/impls/prediction-v0-evaluator/types.d.ts +1 -1
  194. package/dist/restorer/types.d.ts +17 -0
  195. package/dist/restorer/types.js +22 -1
  196. package/dist/restorer/types.js.map +1 -1
  197. package/dist/rpc-error-context.d.ts +10 -0
  198. package/dist/rpc-error-context.js +26 -0
  199. package/dist/rpc-error-context.js.map +1 -0
  200. package/dist/store/store.d.ts +98 -0
  201. package/dist/store/store.js +331 -4
  202. package/dist/store/store.js.map +1 -1
  203. package/dist/trajectory/schema.d.ts +510 -0
  204. package/dist/trajectory/schema.js +74 -0
  205. package/dist/trajectory/schema.js.map +1 -0
  206. package/dist/types/prediction-apy.d.ts +21 -10
  207. package/dist/types/prediction-apy.js +17 -5
  208. package/dist/types/prediction-apy.js.map +1 -1
  209. package/dist/types/prediction.d.ts +11 -10
  210. package/dist/types/prediction.js +3 -2
  211. package/dist/types/prediction.js.map +1 -1
  212. package/dist/venues/aave-v3/client.d.ts +6 -2
  213. package/dist/venues/aave-v3/client.js +14 -5
  214. package/dist/venues/aave-v3/client.js.map +1 -1
  215. package/package.json +4 -3
  216. package/dist/daemon/restorer.d.ts +0 -19
  217. package/dist/daemon/restorer.js +0 -82
  218. package/dist/daemon/restorer.js.map +0 -1
@@ -0,0 +1,32 @@
1
+ import { BASE_SEPOLIA_FEEDS } from '../../venues/chainlink/feeds.js';
2
+ import { predictionV0TemplateNeedsReadCurrent, resolvePredictionV0Template, } from '../prediction-v0-template.js';
3
+ import { makePredictionV0Generator } from '../prediction-v0-auto.js';
4
+ import { PREDICTION_V0_KIND } from './constants.js';
5
+ export const predictionV0 = {
6
+ kind: PREDICTION_V0_KIND,
7
+ async parseSpec(raw, deps) {
8
+ if (predictionV0TemplateNeedsReadCurrent(raw) && !deps?.readCurrent) {
9
+ throw new Error('prediction.v0 parseSpec requires readCurrent (Chainlink) when the template uses a current[±…] threshold sentinel');
10
+ }
11
+ const intent = await resolvePredictionV0Template(raw, {
12
+ readCurrent: deps?.readCurrent,
13
+ });
14
+ return { window: intent.window, spec: intent.spec, eligibility: intent.eligibility };
15
+ },
16
+ buildGenerator: (config) => makePredictionV0Generator(config),
17
+ getTestnetAutoConfig: (ctx) => {
18
+ if (ctx.network !== 'testnet')
19
+ return undefined;
20
+ return {
21
+ feed: BASE_SEPOLIA_FEEDS['ETH / USD'],
22
+ feedDescription: 'ETH / USD',
23
+ venue: 'chainlink-base-sepolia',
24
+ rpcUrl: ctx.rpcUrl,
25
+ };
26
+ },
27
+ ui: {
28
+ description: 'Price threshold prediction (Chainlink oracle)',
29
+ category: 'prediction',
30
+ },
31
+ };
32
+ //# sourceMappingURL=prediction-v0.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prediction-v0.js","sourceRoot":"","sources":["../../../src/intents/kinds/prediction-v0.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,EACL,oCAAoC,EACpC,2BAA2B,GAC5B,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,yBAAyB,EAA+B,MAAM,0BAA0B,CAAC;AAElG,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEpD,MAAM,CAAC,MAAM,YAAY,GAAqC;IAC5D,IAAI,EAAE,kBAAkB;IACxB,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI;QACvB,IAAI,oCAAoC,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,EAAE,CAAC;YACpE,MAAM,IAAI,KAAK,CACb,kHAAkH,CACnH,CAAC;QACJ,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,2BAA2B,CAAC,GAAG,EAAE;YACpD,WAAW,EAAE,IAAI,EAAE,WAAW;SAC/B,CAAC,CAAC;QACH,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE,CAAC;IACvF,CAAC;IACD,cAAc,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,yBAAyB,CAAC,MAAM,CAAC;IAC7D,oBAAoB,EAAE,CAAC,GAAG,EAAE,EAAE;QAC5B,IAAI,GAAG,CAAC,OAAO,KAAK,SAAS;YAAE,OAAO,SAAS,CAAC;QAChD,OAAO;YACL,IAAI,EAAE,kBAAkB,CAAC,WAAW,CAAC;YACrC,eAAe,EAAE,WAAW;YAC5B,KAAK,EAAE,wBAAwB;YAC/B,MAAM,EAAE,GAAG,CAAC,MAAM;SACnB,CAAC;IACJ,CAAC;IACD,EAAE,EAAE;QACF,WAAW,EAAE,+CAA+C;QAC5D,QAAQ,EAAE,YAAY;KACvB;CACF,CAAC"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * SpecKind manifest — one entry per in-repo intent kind (parse + optional auto-gen).
3
+ * See jinn-mono-6q1.1.
4
+ */
5
+ import type { IntentGenerator } from '../sources.js';
6
+ /** Overlay fields merged into DesiredState when posting from --spec-file. */
7
+ export type ParsedSpecOverlay = {
8
+ window: unknown;
9
+ spec: unknown;
10
+ eligibility: unknown;
11
+ };
12
+ /** Optional deps for kinds that resolve sentinels at parse time (e.g. Chainlink). */
13
+ export interface ParseDeps {
14
+ readCurrent?: (args: {
15
+ feed: `0x${string}`;
16
+ venue: 'chainlink-base' | 'chainlink-base-sepolia';
17
+ }) => Promise<string>;
18
+ }
19
+ /** Context for optional testnet auto-intent registration (see {@link collectTestnetAutoIntentGenerators}). */
20
+ export interface TestnetAutoContext {
21
+ network: 'mainnet' | 'testnet';
22
+ rpcUrl: string;
23
+ env: NodeJS.ProcessEnv;
24
+ }
25
+ export interface SpecKind<GenConfig = unknown> {
26
+ kind: string;
27
+ parseSpec: (raw: unknown, deps?: ParseDeps) => Promise<ParsedSpecOverlay>;
28
+ buildGenerator?: (config: GenConfig) => IntentGenerator;
29
+ /**
30
+ * If this returns a config object, the daemon may register `buildGenerator(config)` on testnet.
31
+ * Return `undefined` to skip (default for kinds without auto-gen or not enabled on testnet).
32
+ */
33
+ getTestnetAutoConfig?: (ctx: TestnetAutoContext) => GenConfig | undefined;
34
+ ui?: {
35
+ description: string;
36
+ category: string;
37
+ };
38
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * SpecKind manifest — one entry per in-repo intent kind (parse + optional auto-gen).
3
+ * See jinn-mono-6q1.1.
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=spec-kind.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spec-kind.js","sourceRoot":"","sources":["../../../src/intents/kinds/spec-kind.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
@@ -0,0 +1,26 @@
1
+ import type { ExecutionAdapter } from '../adapters/adapter.js';
2
+ import type { Store } from '../store/store.js';
3
+ import { type DesiredState, type RequestId } from '../types/index.js';
4
+ import type { IntentCandidate } from './sources.js';
5
+ import type { Registry8004 } from '../discovery/registry.js';
6
+ export interface IntentPostResult {
7
+ requestId: RequestId;
8
+ desiredState: DesiredState;
9
+ attemptNumber: number;
10
+ attemptId: string;
11
+ idempotent: boolean;
12
+ source: 'store' | 'legacy_config' | 'posted';
13
+ }
14
+ export interface PostIntentCandidateOptions {
15
+ creatorSafeAddress?: string;
16
+ legacyConfigKeys?: string[];
17
+ }
18
+ export declare class IntentPostingService {
19
+ private readonly adapter;
20
+ private readonly store;
21
+ private readonly registry?;
22
+ constructor(adapter: ExecutionAdapter, store: Store, registry?: Registry8004 | undefined);
23
+ postCandidate(candidate: IntentCandidate, opts?: PostIntentCandidateOptions): Promise<IntentPostResult>;
24
+ private tryImportLegacyRecord;
25
+ private buildIdempotentResult;
26
+ }
@@ -0,0 +1,218 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { getAddress } from 'viem';
3
+ import { emitEvent } from '../observability/emit-event.js';
4
+ import { TransientError } from '../types/index.js';
5
+ const GLOBAL_CREATOR_SCOPE = '__global__';
6
+ const POST_LOCK_STALE_AFTER_MS = 60_000;
7
+ function normalizeCreatorSafeAddress(safeAddress) {
8
+ return safeAddress ? getAddress(safeAddress) : GLOBAL_CREATOR_SCOPE;
9
+ }
10
+ function policyTypeOf(policy) {
11
+ return policy.kind;
12
+ }
13
+ function scopeKeyOf(policy) {
14
+ switch (policy.kind) {
15
+ case 'once_per_safe':
16
+ return '';
17
+ case 'once_per_bucket':
18
+ return policy.bucketKey;
19
+ case 'interval':
20
+ return policy.scopeKey ?? '';
21
+ }
22
+ }
23
+ function shouldSkipPost(record, policy, nowMs) {
24
+ if (policy.kind !== 'interval')
25
+ return true;
26
+ const lastPostedAt = Date.parse(record.lastPostedAt);
27
+ return Number.isFinite(lastPostedAt) && (nowMs - lastPostedAt) < policy.intervalMs;
28
+ }
29
+ export class IntentPostingService {
30
+ adapter;
31
+ store;
32
+ registry;
33
+ constructor(adapter, store, registry) {
34
+ this.adapter = adapter;
35
+ this.store = store;
36
+ this.registry = registry;
37
+ }
38
+ async postCandidate(candidate, opts = {}) {
39
+ const creatorSafeAddress = normalizeCreatorSafeAddress(opts.creatorSafeAddress);
40
+ const policyType = policyTypeOf(candidate.postingPolicy);
41
+ const scopeKey = scopeKeyOf(candidate.postingPolicy);
42
+ const now = new Date();
43
+ const nowIso = now.toISOString();
44
+ const nowMs = now.getTime();
45
+ const existing = this.store.getIntentPostRecord({
46
+ creatorSafeAddress,
47
+ sourceKey: candidate.sourceKey,
48
+ policyType,
49
+ scopeKey,
50
+ });
51
+ if (existing && shouldSkipPost(existing, candidate.postingPolicy, nowMs)) {
52
+ return this.buildIdempotentResult(candidate, existing, 'store');
53
+ }
54
+ const migrated = this.tryImportLegacyRecord(candidate, {
55
+ creatorSafeAddress,
56
+ policyType,
57
+ scopeKey,
58
+ nowIso,
59
+ legacyConfigKeys: opts.legacyConfigKeys ?? [],
60
+ });
61
+ if (migrated) {
62
+ return this.buildIdempotentResult(candidate, migrated, 'legacy_config');
63
+ }
64
+ const ownerToken = randomUUID();
65
+ const lockAcquired = this.store.acquireIntentPostLock({
66
+ creatorSafeAddress,
67
+ sourceKey: candidate.sourceKey,
68
+ policyType,
69
+ scopeKey,
70
+ ownerToken,
71
+ lockedAt: nowIso,
72
+ staleAfterMs: POST_LOCK_STALE_AFTER_MS,
73
+ });
74
+ if (!lockAcquired) {
75
+ throw new TransientError(`Intent post already in progress for ${candidate.sourceKey} (${candidate.desiredState.id})`);
76
+ }
77
+ try {
78
+ const lockedExisting = this.store.getIntentPostRecord({
79
+ creatorSafeAddress,
80
+ sourceKey: candidate.sourceKey,
81
+ policyType,
82
+ scopeKey,
83
+ });
84
+ if (lockedExisting && shouldSkipPost(lockedExisting, candidate.postingPolicy, nowMs)) {
85
+ return this.buildIdempotentResult(candidate, lockedExisting, 'store');
86
+ }
87
+ const lockedMigrated = this.tryImportLegacyRecord(candidate, {
88
+ creatorSafeAddress,
89
+ policyType,
90
+ scopeKey,
91
+ nowIso,
92
+ legacyConfigKeys: opts.legacyConfigKeys ?? [],
93
+ });
94
+ if (lockedMigrated) {
95
+ return this.buildIdempotentResult(candidate, lockedMigrated, 'legacy_config');
96
+ }
97
+ const previousPostCount = lockedExisting?.postCount ?? 0;
98
+ const attemptNumber = previousPostCount + 1;
99
+ const attemptId = `${candidate.desiredState.id}/${attemptNumber}`;
100
+ const desiredState = {
101
+ ...candidate.desiredState,
102
+ type: 'restoration',
103
+ attemptId,
104
+ attemptNumber,
105
+ };
106
+ const requestId = await this.adapter.postDesiredState(desiredState);
107
+ // ERC-8004 Intent registration (Plan E Task 10). Best-effort: a failure here
108
+ // does NOT roll back the post. Registration fires only when a registry is
109
+ // injected and the adapter surfaces the intent CID (IPFS-backed adapters only).
110
+ if (this.registry && candidate.desiredState.spec?.kind) {
111
+ const intentCid = this.adapter.getLastPostedIntentCid?.();
112
+ if (intentCid) {
113
+ const creator = opts.creatorSafeAddress
114
+ ? getAddress(opts.creatorSafeAddress)
115
+ : creatorSafeAddress === GLOBAL_CREATOR_SCOPE
116
+ ? ''
117
+ : creatorSafeAddress;
118
+ try {
119
+ await this.registry.registerIntent({
120
+ intentCid,
121
+ kind: candidate.desiredState.spec.kind,
122
+ creator,
123
+ createdAt: nowMs,
124
+ requestId: requestId,
125
+ });
126
+ }
127
+ catch (err) {
128
+ // Registration is best-effort; a failure here should not prevent the
129
+ // intent from being posted. Log + emit but don't throw.
130
+ console.warn(`[posting-service] registerIntent failed: ${err instanceof Error ? err.message : err}`);
131
+ emitEvent(this.store, {
132
+ kind: 'intent_registry_failed',
133
+ requestId,
134
+ specKind: candidate.desiredState.spec?.kind,
135
+ outcome: 'failed',
136
+ detail: err instanceof Error ? err.message : String(err),
137
+ }, 'creator');
138
+ }
139
+ }
140
+ }
141
+ this.store.recordOwnActivity(requestId, 'created');
142
+ emitEvent(this.store, {
143
+ kind: 'intent_posted',
144
+ requestId,
145
+ specKind: candidate.desiredState.spec?.kind,
146
+ outcome: 'ok',
147
+ detail: `Posted intent for desired state ${candidate.desiredState.id} via ${candidate.sourceKey}`,
148
+ }, 'creator');
149
+ this.store.upsertIntentPostRecord({
150
+ creatorSafeAddress,
151
+ sourceKey: candidate.sourceKey,
152
+ policyType,
153
+ scopeKey,
154
+ desiredStateId: candidate.desiredState.id,
155
+ requestId,
156
+ firstPostedAt: lockedExisting?.firstPostedAt ?? nowIso,
157
+ lastPostedAt: nowIso,
158
+ postCount: attemptNumber,
159
+ });
160
+ return {
161
+ requestId,
162
+ desiredState,
163
+ attemptNumber,
164
+ attemptId,
165
+ idempotent: false,
166
+ source: 'posted',
167
+ };
168
+ }
169
+ finally {
170
+ this.store.releaseIntentPostLock({
171
+ creatorSafeAddress,
172
+ sourceKey: candidate.sourceKey,
173
+ policyType,
174
+ scopeKey,
175
+ ownerToken,
176
+ });
177
+ }
178
+ }
179
+ tryImportLegacyRecord(candidate, args) {
180
+ for (const key of args.legacyConfigKeys) {
181
+ const requestId = this.store.getConfigValue(key);
182
+ if (!requestId)
183
+ continue;
184
+ const record = {
185
+ creatorSafeAddress: args.creatorSafeAddress,
186
+ sourceKey: candidate.sourceKey,
187
+ policyType: args.policyType,
188
+ scopeKey: args.scopeKey,
189
+ desiredStateId: candidate.desiredState.id,
190
+ requestId,
191
+ firstPostedAt: args.nowIso,
192
+ lastPostedAt: args.nowIso,
193
+ postCount: 1,
194
+ };
195
+ this.store.upsertIntentPostRecord(record);
196
+ return record;
197
+ }
198
+ return null;
199
+ }
200
+ buildIdempotentResult(candidate, record, source) {
201
+ const attemptNumber = Math.max(1, record.postCount);
202
+ const attemptId = `${candidate.desiredState.id}/${attemptNumber}`;
203
+ return {
204
+ requestId: record.requestId,
205
+ desiredState: {
206
+ ...candidate.desiredState,
207
+ type: 'restoration',
208
+ attemptId,
209
+ attemptNumber,
210
+ },
211
+ attemptNumber,
212
+ attemptId,
213
+ idempotent: true,
214
+ source,
215
+ };
216
+ }
217
+ }
218
+ //# sourceMappingURL=posting-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"posting-service.js","sourceRoot":"","sources":["../../src/intents/posting-service.ts"],"names":[],"mappings":"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"}
@@ -34,7 +34,7 @@ export function makePredictionApyV0Generator(config = {}) {
34
34
  },
35
35
  question: { resolveTs },
36
36
  },
37
- eligibility: { maxSubmissionDelayMs: 60_000 },
37
+ eligibility: { maxSubmissionDelayMs: windowDurationMs },
38
38
  });
39
39
  return intent;
40
40
  }
@@ -1 +1 @@
1
- {"version":3,"file":"prediction-apy-v0-auto.js","sourceRoot":"","sources":["../../src/intents/prediction-apy-v0-auto.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,8BAA8B,EAAE,MAAM,iCAAiC,CAAC;AACjF,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAa9D,MAAM,UAAU,4BAA4B,CAAC,SAAoC,EAAE;IACjF,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,sBAAsB,CAAC;IACrD,MAAM,KAAK,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;IAClC,MAAM,gBAAgB,GAAG,MAAM,CAAC,gBAAgB,IAAI,OAAO,CAAC;IAC5D,MAAM,YAAY,GAAG,MAAM,CAAC,YAAY,IAAI,OAAO,CAAC;IACpD,MAAM,gBAAgB,GAAG,MAAM,CAAC,gBAAgB,IAAI,KAAK,CAAC;IAC1D,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,IAAI,EAAE,CAAC;IAC7C,MAAM,YAAY,GAAG,MAAM,CAAC,YAAY,IAAI,EAAE,CAAC;IAE/C,OAAO,KAAK,IAAkC,EAAE;QAC9C,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,gBAAgB,CAAC,GAAG,gBAAgB,CAAC;QACtE,MAAM,KAAK,GAAG,OAAO,GAAG,gBAAgB,CAAC;QACzC,MAAM,SAAS,GAAG,KAAK,GAAG,YAAY,CAAC;QACvC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,8BAA8B,CAAC;gBAClD,EAAE,EAAE,oBAAoB,OAAO,EAAE;gBACjC,WAAW,EAAE,+CAA+C,KAAK,CAAC,MAAM,OAAO,KAAK,EAAE;gBACtF,MAAM,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE;gBAC1B,IAAI,EAAE;oBACJ,IAAI,EAAE,mBAAmB;oBACzB,MAAM,EAAE;wBACN,KAAK;wBACL,IAAI,EAAE,KAAK,CAAC,IAAI;wBAChB,OAAO,EAAE,KAAK,CAAC,OAAO;wBACtB,aAAa,EAAE,KAAK,CAAC,MAAM;qBAC5B;oBACD,MAAM,EAAE;wBACN,IAAI,EAAE,oBAAoB;wBAC1B,gBAAgB;wBAChB,WAAW;wBACX,YAAY;qBACb;oBACD,QAAQ,EAAE,EAAE,SAAS,EAAE;iBACxB;gBACD,WAAW,EAAE,EAAE,oBAAoB,EAAE,MAAM,EAAE;aAC9C,CAAC,CAAC;YACH,OAAO,MAAiC,CAAC;QAC3C,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"prediction-apy-v0-auto.js","sourceRoot":"","sources":["../../src/intents/prediction-apy-v0-auto.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,8BAA8B,EAAE,MAAM,iCAAiC,CAAC;AACjF,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAa9D,MAAM,UAAU,4BAA4B,CAAC,SAAoC,EAAE;IACjF,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,sBAAsB,CAAC;IACrD,MAAM,KAAK,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;IAClC,MAAM,gBAAgB,GAAG,MAAM,CAAC,gBAAgB,IAAI,OAAO,CAAC;IAC5D,MAAM,YAAY,GAAG,MAAM,CAAC,YAAY,IAAI,OAAO,CAAC;IACpD,MAAM,gBAAgB,GAAG,MAAM,CAAC,gBAAgB,IAAI,KAAK,CAAC;IAC1D,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,IAAI,EAAE,CAAC;IAC7C,MAAM,YAAY,GAAG,MAAM,CAAC,YAAY,IAAI,EAAE,CAAC;IAE/C,OAAO,KAAK,IAAkC,EAAE;QAC9C,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,gBAAgB,CAAC,GAAG,gBAAgB,CAAC;QACtE,MAAM,KAAK,GAAG,OAAO,GAAG,gBAAgB,CAAC;QACzC,MAAM,SAAS,GAAG,KAAK,GAAG,YAAY,CAAC;QACvC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,8BAA8B,CAAC;gBAClD,EAAE,EAAE,oBAAoB,OAAO,EAAE;gBACjC,WAAW,EAAE,+CAA+C,KAAK,CAAC,MAAM,OAAO,KAAK,EAAE;gBACtF,MAAM,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE;gBAC1B,IAAI,EAAE;oBACJ,IAAI,EAAE,mBAAmB;oBACzB,MAAM,EAAE;wBACN,KAAK;wBACL,IAAI,EAAE,KAAK,CAAC,IAAI;wBAChB,OAAO,EAAE,KAAK,CAAC,OAAO;wBACtB,aAAa,EAAE,KAAK,CAAC,MAAM;qBAC5B;oBACD,MAAM,EAAE;wBACN,IAAI,EAAE,oBAAoB;wBAC1B,gBAAgB;wBAChB,WAAW;wBACX,YAAY;qBACb;oBACD,QAAQ,EAAE,EAAE,SAAS,EAAE;iBACxB;gBACD,WAAW,EAAE,EAAE,oBAAoB,EAAE,gBAAgB,EAAE;aACxD,CAAC,CAAC;YACH,OAAO,MAAiC,CAAC;QAC3C,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
@@ -30,10 +30,10 @@ export declare function isCurrentSentinel(value: unknown): boolean;
30
30
  export interface TemplateReaderDeps {
31
31
  /**
32
32
  * Read the current price of the Chainlink feed referenced in the template.
33
- * The helper passes `{feed, venue}` so the reader can build the right client.
34
- * Returns a decimal string (scaled from int256 via scaleToDecimal).
33
+ * Required only when the template uses a `current[±…]` threshold sentinel
34
+ * (see {@link predictionV0TemplateNeedsReadCurrent}).
35
35
  */
36
- readCurrent: (args: {
36
+ readCurrent?: (args: {
37
37
  feed: `0x${string}`;
38
38
  venue: 'chainlink-base' | 'chainlink-base-sepolia';
39
39
  }) => Promise<string>;
@@ -53,6 +53,11 @@ export interface TemplateReaderDeps {
53
53
  export declare const DEFAULT_WINDOW_DURATION_MS = 600000;
54
54
  /** Default resolve gap for the startTs-sentinel fill. Tuned for fast-test. */
55
55
  export declare const DEFAULT_RESOLVE_GAP_MS = 300000;
56
+ /**
57
+ * True if {@link resolvePredictionV0Template} will call `readCurrent` for this
58
+ * template (Chainlink). `window.startTs === 0` does not need `readCurrent`.
59
+ */
60
+ export declare function predictionV0TemplateNeedsReadCurrent(template: unknown): boolean;
56
61
  /**
57
62
  * Resolve all supported sentinels in a raw prediction.v0 template + return a
58
63
  * parsed, validated PredictionV0Intent.
@@ -25,6 +25,7 @@
25
25
  * future auto-generator (jinn-mono-9ew) call through this helper.
26
26
  */
27
27
  import { PredictionV0IntentSchema, } from '../types/prediction.js';
28
+ import { PREDICTION_V0_KIND } from './kinds/constants.js';
28
29
  // ── Sentinel parsers ──────────────────────────────────────────────────────────
29
30
  /**
30
31
  * Parse a `current[±N[%]]` sentinel. Returns a function that takes the current
@@ -66,6 +67,22 @@ export function isCurrentSentinel(value) {
66
67
  export const DEFAULT_WINDOW_DURATION_MS = 600_000;
67
68
  /** Default resolve gap for the startTs-sentinel fill. Tuned for fast-test. */
68
69
  export const DEFAULT_RESOLVE_GAP_MS = 300_000;
70
+ /**
71
+ * True if {@link resolvePredictionV0Template} will call `readCurrent` for this
72
+ * template (Chainlink). `window.startTs === 0` does not need `readCurrent`.
73
+ */
74
+ export function predictionV0TemplateNeedsReadCurrent(template) {
75
+ if (typeof template !== 'object' || template === null)
76
+ return false;
77
+ const t = template;
78
+ const spec = t['spec'];
79
+ if (spec?.kind !== PREDICTION_V0_KIND)
80
+ return false;
81
+ if (spec.question?.kind === 'threshold' && typeof spec.question.threshold === 'string') {
82
+ return isCurrentSentinel(spec.question.threshold);
83
+ }
84
+ return false;
85
+ }
69
86
  /**
70
87
  * Resolve all supported sentinels in a raw prediction.v0 template + return a
71
88
  * parsed, validated PredictionV0Intent.
@@ -96,11 +113,14 @@ export async function resolvePredictionV0Template(template, deps) {
96
113
  }
97
114
  // ── (2) spec.question.threshold sentinel → absolute price ──────────────────
98
115
  const spec = stub['spec'];
99
- if (spec?.kind === 'prediction.v0' &&
116
+ if (spec?.kind === PREDICTION_V0_KIND &&
100
117
  spec.question?.kind === 'threshold' &&
101
118
  typeof spec.question.threshold === 'string') {
102
119
  const t = spec.question.threshold;
103
120
  if (isCurrentSentinel(t)) {
121
+ if (!deps.readCurrent) {
122
+ throw new Error('resolvePredictionV0Template: readCurrent is required when spec.question.threshold uses a current[±…] sentinel');
123
+ }
104
124
  if (!spec.oracle?.feed || !spec.oracle.venue) {
105
125
  throw new Error('cannot resolve threshold sentinel: spec.oracle.feed and spec.oracle.venue are required');
106
126
  }
@@ -1 +1 @@
1
- {"version":3,"file":"prediction-v0-template.js","sourceRoot":"","sources":["../../src/intents/prediction-v0-template.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"prediction-v0-template.js","sourceRoot":"","sources":["../../src/intents/prediction-v0-template.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EACL,wBAAwB,GAEzB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE1D,iFAAiF;AAEjF;;;;GAIG;AACH,SAAS,oBAAoB,CAAC,QAAgB;IAC5C,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC;IAC9B,CAAC;IACD,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;IACnE,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CACb,+BAA+B,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI;YAC3D,2EAA2E,CAC5E,CAAC;IACJ,CAAC;IACD,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,GAAG,KAAK,CAAC;IACpC,MAAM,KAAK,GAAG,UAAU,CAAC,MAAO,CAAC,CAAC;IAClC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QACzC,MAAM,IAAI,KAAK,CAAC,yCAAyC,MAAM,EAAE,CAAC,CAAC;IACrE,CAAC;IACD,OAAO,CAAC,OAAe,EAAE,EAAE;QACzB,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;QACnC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3C,MAAM,IAAI,KAAK,CAAC,kDAAkD,OAAO,EAAE,CAAC,CAAC;QAC/E,CAAC;QACD,MAAM,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QACpD,MAAM,MAAM,GAAG,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;QAC/C,MAAM,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;QAC/B,kEAAkE;QAClE,kDAAkD;QAClD,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IACjD,CAAC,CAAC;AACJ,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,iBAAiB,CAAC,KAAc;IAC9C,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,+BAA+B,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAClF,CAAC;AA2BD,kFAAkF;AAClF,MAAM,CAAC,MAAM,0BAA0B,GAAG,OAAO,CAAC;AAClD,8EAA8E;AAC9E,MAAM,CAAC,MAAM,sBAAsB,GAAG,OAAO,CAAC;AAE9C;;;GAGG;AACH,MAAM,UAAU,oCAAoC,CAAC,QAAiB;IACpE,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IACpE,MAAM,CAAC,GAAG,QAAmC,CAAC;IAC9C,MAAM,IAAI,GAAG,CAAC,CAAC,MAAM,CAKR,CAAC;IACd,IAAI,IAAI,EAAE,IAAI,KAAK,kBAAkB;QAAE,OAAO,KAAK,CAAC;IACpD,IAAI,IAAI,CAAC,QAAQ,EAAE,IAAI,KAAK,WAAW,IAAI,OAAO,IAAI,CAAC,QAAQ,CAAC,SAAS,KAAK,QAAQ,EAAE,CAAC;QACvF,OAAO,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IACpD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAC/C,QAAiB,EACjB,IAAwB;IAExB,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QACtD,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAC;IAC7E,CAAC;IACD,mDAAmD;IACnD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAA4B,CAAC;IAE7E,8EAA8E;IAC9E,MAAM,QAAQ,GAAG,IAAI,CAAC,gBAAgB,IAAI,0BAA0B,CAAC;IACrE,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,IAAI,sBAAsB,CAAC;IAC9D,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAqD,CAAC;IAC/E,IAAI,GAAG,IAAI,GAAG,CAAC,OAAO,KAAK,CAAC,EAAE,CAAC;QAC7B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,GAAG,CAAC,OAAO,GAAG,GAAG,CAAC;QAClB,GAAG,CAAC,KAAK,GAAG,GAAG,GAAG,QAAQ,CAAC;QAC3B,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAsD,CAAC;QAC/E,IAAI,IAAI,EAAE,QAAQ,EAAE,CAAC;YACnB,IAAI,CAAC,QAAQ,CAAC,SAAS,GAAG,GAAG,GAAG,QAAQ,GAAG,SAAS,CAAC;QACvD,CAAC;IACH,CAAC;IAED,8EAA8E;IAC9E,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAMX,CAAC;IAEd,IACE,IAAI,EAAE,IAAI,KAAK,kBAAkB;QACjC,IAAI,CAAC,QAAQ,EAAE,IAAI,KAAK,WAAW;QACnC,OAAO,IAAI,CAAC,QAAQ,CAAC,SAAS,KAAK,QAAQ,EAC3C,CAAC;QACD,MAAM,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC;QAClC,IAAI,iBAAiB,CAAC,CAAC,CAAC,EAAE,CAAC;YACzB,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;gBACtB,MAAM,IAAI,KAAK,CACb,+GAA+G,CAChH,CAAC;YACJ,CAAC;YACD,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;gBAC7C,MAAM,IAAI,KAAK,CACb,wFAAwF,CACzF,CAAC;YACJ,CAAC;YACD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC;gBACrC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI;gBACtB,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK;aACzB,CAAC,CAAC;YACH,MAAM,SAAS,GAAG,oBAAoB,CAAC,CAAC,CAAC,CAAC;YAC1C,IAAI,CAAC,QAAQ,CAAC,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;QAC/C,CAAC;aAAM,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YACjD,6EAA6E;YAC7E,2EAA2E;YAC3E,MAAM,IAAI,KAAK,CACb,+BAA+B,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI;gBACpD,4EAA4E;gBAC5E,sFAAsF,CACvF,CAAC;QACJ,CAAC;IACH,CAAC;IAED,8EAA8E;IAC9E,OAAO,wBAAwB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AAC9C,CAAC"}
@@ -0,0 +1,39 @@
1
+ import type { DesiredState } from '../types/desired-state.js';
2
+ /** Returns a freshly-built DesiredState for this tick, or null to skip. */
3
+ export type IntentGenerator = () => Promise<DesiredState | null>;
4
+ export type IntentPostingPolicy = {
5
+ kind: 'once_per_safe';
6
+ } | {
7
+ kind: 'once_per_bucket';
8
+ bucketKey: string;
9
+ } | {
10
+ kind: 'interval';
11
+ intervalMs: number;
12
+ scopeKey?: string;
13
+ };
14
+ export interface IntentCandidate {
15
+ desiredState: DesiredState;
16
+ sourceKey: string;
17
+ postingPolicy: IntentPostingPolicy;
18
+ sourceMeta?: {
19
+ kind?: string;
20
+ bucketKey?: string;
21
+ note?: string;
22
+ };
23
+ }
24
+ export interface IntentSource {
25
+ sourceKey: string;
26
+ collect(now: Date): Promise<IntentCandidate[]>;
27
+ }
28
+ export declare class StaticConfiguredIntentSource implements IntentSource {
29
+ private readonly desiredStates;
30
+ readonly sourceKey = "configured";
31
+ constructor(desiredStates: DesiredState[]);
32
+ collect(_now: Date): Promise<IntentCandidate[]>;
33
+ }
34
+ export declare class GeneratedIntentSource implements IntentSource {
35
+ readonly sourceKey: string;
36
+ private readonly generator;
37
+ constructor(sourceKey: string, generator: IntentGenerator);
38
+ collect(_now: Date): Promise<IntentCandidate[]>;
39
+ }
@@ -0,0 +1,42 @@
1
+ export class StaticConfiguredIntentSource {
2
+ desiredStates;
3
+ sourceKey = 'configured';
4
+ constructor(desiredStates) {
5
+ this.desiredStates = desiredStates;
6
+ }
7
+ async collect(_now) {
8
+ return this.desiredStates.map((desiredState) => ({
9
+ desiredState,
10
+ sourceKey: `${this.sourceKey}:${desiredState.id}`,
11
+ postingPolicy: { kind: 'once_per_safe' },
12
+ sourceMeta: { kind: desiredState.spec?.kind, note: 'configured' },
13
+ }));
14
+ }
15
+ }
16
+ export class GeneratedIntentSource {
17
+ sourceKey;
18
+ generator;
19
+ constructor(sourceKey, generator) {
20
+ this.sourceKey = sourceKey;
21
+ this.generator = generator;
22
+ }
23
+ async collect(_now) {
24
+ const desiredState = await this.generator();
25
+ if (!desiredState)
26
+ return [];
27
+ const bucketKey = desiredState.window
28
+ ? `${desiredState.window.startTs}:${desiredState.window.endTs}`
29
+ : desiredState.id;
30
+ return [{
31
+ desiredState,
32
+ sourceKey: this.sourceKey,
33
+ postingPolicy: { kind: 'once_per_bucket', bucketKey },
34
+ sourceMeta: {
35
+ kind: desiredState.spec?.kind,
36
+ bucketKey,
37
+ note: 'generated',
38
+ },
39
+ }];
40
+ }
41
+ }
42
+ //# sourceMappingURL=sources.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sources.js","sourceRoot":"","sources":["../../src/intents/sources.ts"],"names":[],"mappings":"AA0BA,MAAM,OAAO,4BAA4B;IAGV;IAFpB,SAAS,GAAG,YAAY,CAAC;IAElC,YAA6B,aAA6B;QAA7B,kBAAa,GAAb,aAAa,CAAgB;IAAG,CAAC;IAE9D,KAAK,CAAC,OAAO,CAAC,IAAU;QACtB,OAAO,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;YAC/C,YAAY;YACZ,SAAS,EAAE,GAAG,IAAI,CAAC,SAAS,IAAI,YAAY,CAAC,EAAE,EAAE;YACjD,aAAa,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE;YACxC,UAAU,EAAE,EAAE,IAAI,EAAE,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,YAAY,EAAE;SAClE,CAAC,CAAC,CAAC;IACN,CAAC;CACF;AAED,MAAM,OAAO,qBAAqB;IAErB;IACQ;IAFnB,YACW,SAAiB,EACT,SAA0B;QADlC,cAAS,GAAT,SAAS,CAAQ;QACT,cAAS,GAAT,SAAS,CAAiB;IAC1C,CAAC;IAEJ,KAAK,CAAC,OAAO,CAAC,IAAU;QACtB,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;QAC5C,IAAI,CAAC,YAAY;YAAE,OAAO,EAAE,CAAC;QAC7B,MAAM,SAAS,GAAG,YAAY,CAAC,MAAM;YACnC,CAAC,CAAC,GAAG,YAAY,CAAC,MAAM,CAAC,OAAO,IAAI,YAAY,CAAC,MAAM,CAAC,KAAK,EAAE;YAC/D,CAAC,CAAC,YAAY,CAAC,EAAE,CAAC;QACpB,OAAO,CAAC;gBACN,YAAY;gBACZ,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,aAAa,EAAE,EAAE,IAAI,EAAE,iBAAiB,EAAE,SAAS,EAAE;gBACrD,UAAU,EAAE;oBACV,IAAI,EAAE,YAAY,CAAC,IAAI,EAAE,IAAI;oBAC7B,SAAS;oBACT,IAAI,EAAE,WAAW;iBAClB;aACF,CAAC,CAAC;IACL,CAAC;CACF"}