@domino-sdk/relay 1.53.1 → 1.55.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 (66) hide show
  1. package/CHANGELOG.md +1848 -0
  2. package/dist/analytics-URV-mxjH.d.ts +482 -0
  3. package/dist/{attempt-captures-QC4kTA44.d.ts → attempt-captures-CxxO7DeD.d.ts} +1 -1
  4. package/dist/authoring.d.ts +233 -78
  5. package/dist/authoring.js +112 -14
  6. package/dist/{automatic-outcomes-CVyZHxir.d.ts → automatic-outcomes-DxW_v5Wc.d.ts} +5 -2
  7. package/dist/avatar.d.ts +1 -1
  8. package/dist/browser.d.ts +8 -7
  9. package/dist/browser.js +14 -10
  10. package/dist/{capability-error-FQGGb5xS.d.ts → capability-error-DSd8EMQC.d.ts} +76 -2
  11. package/dist/{chunk-53JMTUWG.js → chunk-56DBFNR2.js} +1 -1
  12. package/dist/chunk-C7QZ4UBB.js +937 -0
  13. package/dist/chunk-F6HECAXA.js +661 -0
  14. package/dist/{chunk-VKHSC5MD.js → chunk-GL43VQ5D.js} +16 -16
  15. package/dist/{chunk-GTQJSDBS.js → chunk-IUF7DW76.js} +27 -16
  16. package/dist/{chunk-YBR4BUFK.js → chunk-IZRITLVV.js} +2 -2
  17. package/dist/chunk-KDR2VAJP.js +34 -0
  18. package/dist/{chunk-S2PMKZSX.js → chunk-SABMNPF2.js} +21 -2
  19. package/dist/{chunk-XFAYQFRO.js → chunk-TLK2MD4S.js} +1 -1
  20. package/dist/{chunk-ZJ3FVZRP.js → chunk-UY6KMLQG.js} +10 -3
  21. package/dist/{chunk-JYJAS4E3.js → chunk-VFBQVY4X.js} +1 -1
  22. package/dist/{chunk-YVC3B72P.js → chunk-WHG5WE43.js} +1 -1
  23. package/dist/chunk-WHMXXHPX.js +344 -0
  24. package/dist/{chunk-MP2ZF5U6.js → chunk-WUEQOKJH.js} +4 -4
  25. package/dist/{chunk-7BNCLWAO.js → chunk-XALIFNMD.js} +1 -1
  26. package/dist/{chunk-IELNFM3V.js → chunk-YCOKTQ4E.js} +96 -7
  27. package/dist/{chunk-LPHXTZDA.js → chunk-YE3XYB2F.js} +2 -2
  28. package/dist/{chunk-K6TVMNU4.js → chunk-YEVD4A5X.js} +1 -1
  29. package/dist/{client-CzNtl8UO.d.ts → client-C4zUZKpj.d.ts} +35 -7
  30. package/dist/{deployments-ovtqtAcx.d.ts → deployments-B32QS1CI.d.ts} +1060 -233
  31. package/dist/{groups-B5R1RCsl.d.ts → groups-O6onGPmC.d.ts} +131 -137
  32. package/dist/host-environment-FN4zg3hw.d.ts +30 -0
  33. package/dist/index.d.ts +8 -8
  34. package/dist/index.js +9 -9
  35. package/dist/integrations-C6_uUh-s.d.ts +584 -0
  36. package/dist/internal.d.ts +12 -10
  37. package/dist/internal.js +14 -8
  38. package/dist/{offers-CH1RZekg.d.ts → offers-BMDNcvwB.d.ts} +2 -2
  39. package/dist/{pages-BTlOg8sl.d.ts → pages-BFloMpyQ.d.ts} +25 -1
  40. package/dist/portal-proxy.d.ts +11 -1
  41. package/dist/portal-proxy.js +26 -5
  42. package/dist/{profiles-Cdv4BSd_.d.ts → profiles-BoOK03cR.d.ts} +2 -0
  43. package/dist/react/index.d.ts +488 -13
  44. package/dist/react/index.js +51 -15
  45. package/dist/runtime/authoring.js +1 -1
  46. package/dist/runtime/chunks/WKATKZXE.js +1 -0
  47. package/dist/runtime/manifest.json +3 -3
  48. package/dist/runtime/schema.js +1 -1
  49. package/dist/{schema-BJ9bOgpN.d.ts → schema-C4m9RhCR.d.ts} +166 -6
  50. package/dist/schema.d.ts +392 -334
  51. package/dist/schema.js +84 -40
  52. package/dist/server/index.d.ts +11 -10
  53. package/dist/server/index.js +1604 -838
  54. package/dist/{submission-input-BNah53go.d.ts → submission-input-BbdawqVy.d.ts} +2 -2
  55. package/dist/{telegram-browser-C36j_6v-.d.ts → telegram-browser-CwaxROAZ.d.ts} +1 -1
  56. package/dist/testing.d.ts +85 -12
  57. package/dist/testing.js +322 -37
  58. package/dist/{transport-DuB_fiA2.d.ts → transport-CZJOW5Sr.d.ts} +8018 -3150
  59. package/dist/vite.d.ts +54 -1
  60. package/dist/vite.js +35 -0
  61. package/dist/{x-BfQcsDp0.d.ts → x-1czZFVUW.d.ts} +1 -1
  62. package/package.json +3 -2
  63. package/dist/chunk-2NUD237O.js +0 -102
  64. package/dist/chunk-CCE2JWES.js +0 -1083
  65. package/dist/integrations-CllF-kWg.d.ts +0 -314
  66. package/dist/runtime/chunks/AVRVSLHX.js +0 -1
@@ -1,22 +1,26 @@
1
- import { x as xContentBodySchema, I as IdentityKind, n as customSourceSchema, W as WithRecordData, o as WithContent, p as WithAccountRoles, q as ResourceHandle, r as QuestHandle, L as LedgerReference, G as GroupHandle, u as TrackerSource, v as trackerDefinitionSchema, y as Tracker, z as TrackerData, B as SourceRoles, C as LedgerHandle, D as TrackerDataSchema, F as xSearchSourceSchema, X as XTweet, H as XContentMetric, J as TrackerTriggerPolicy, N as Where, P as MemberIdentity, U as TrackerTriggerContext, V as TrackerReader, Y as TextReviewInput, Z as TextResult, _ as PhotoResult, $ as Decision, a0 as rewardSchema, a1 as TrackerTriggerMode, a2 as RoleOf, a3 as WhereSetting, a4 as ContentBody, a5 as BadgeHandle, a6 as ContentMetricName, a7 as triggerSchema, d as QuestPresentation, e as QuestProfile, f as QuizEvidence, a8 as TieredRewardDefinition } from './schema-BJ9bOgpN.js';
2
- export { a9 as LedgerSetting, aa as TrackerPage, ab as TrackerReadQuery, ac as trackerDataSchema, ad as trackerTriggerContextSchema } from './schema-BJ9bOgpN.js';
1
+ import { x as xContentBodySchema, I as IdentityKind, y as customSourceSchema, W as WithRecordData, z as WithContent, B as WithAccountRoles, C as ResourceHandle, D as QuestHandle, L as LedgerReference, G as GroupHandle, F as pointLedgerDeclarationSchema, H as TrackerSource, J as trackerDefinitionSchema, N as Tracker, U as TrackerData, V as SourceRoles, X as LedgerHandle, Y as TrackerDataSchema, Z as xSearchSourceSchema, _ as XTweet, $ as XContentMetric, a0 as TrackerTriggerPolicy, a1 as Where, a2 as MemberIdentity, P as PointBalance, a3 as ReferralHandle, a4 as TrackerTriggerContext, a5 as TrackerReader, a6 as TextReviewInput, a7 as TextResult, a8 as PhotoResult, a9 as Decision, aa as rewardSchema, ab as TrackerTriggerMode, ac as RoleOf, ad as WhereSetting, ae as ContentBody, af as BadgeHandle, ag as ContentMetricName, ah as triggerSchema, k as QuestPresentation, l as QuestProfile, m as QuizEvidence, ai as TieredRewardDefinition } from './schema-C4m9RhCR.js';
2
+ export { aj as LedgerSetting, ak as TrackerPage, al as TrackerReadQuery, am as trackerDataSchema, an as trackerTriggerContextSchema } from './schema-C4m9RhCR.js';
3
+ import { M as MemberCompletion, B as Budget } from './capability-error-DSd8EMQC.js';
4
+ export { C as CapabilityError, a as CapabilityErrorCode, c as capabilityErrorCodes } from './capability-error-DSd8EMQC.js';
5
+ import { d as ProfileReferral } from './profiles-BoOK03cR.js';
3
6
  import * as z from 'zod';
4
7
  export { z } from 'zod';
5
- import { f as badgeDeclarationSchema, B as Badge } from './offers-CH1RZekg.js';
6
- export { g as defineOffer } from './offers-CH1RZekg.js';
7
- import { E as EngagementBudget, s as leaderboardDefinitionSchema, t as AuthoringIdentity, u as pointLedgerDeclarationSchema, v as referralAuthoringSchema, C as CampaignDefinition, A as AvailabilityWindow } from './groups-B5R1RCsl.js';
8
- export { w as defineCampaign, x as defineGroup } from './groups-B5R1RCsl.js';
8
+ import { f as badgeDeclarationSchema, B as Badge } from './offers-BMDNcvwB.js';
9
+ export { g as defineOffer } from './offers-BMDNcvwB.js';
10
+ import { E as EngagementBudget, l as leaderboardDefinitionSchema, m as AuthoringIdentity, r as referralAuthoringSchema, C as CampaignDefinition, A as AvailabilityWindow } from './groups-O6onGPmC.js';
11
+ export { n as defineCampaign, o as defineGroup } from './groups-O6onGPmC.js';
9
12
  import { d as discordMessagesSourceSchema, D as DiscordMessageData, c as DiscordMessageTextData, e as discordReactionsSourceSchema, f as DiscordReactionData, g as TelegramReader, h as DiscordReader } from './accounts-DRPENuZe.js';
10
13
  export { i as TelegramChatMember, j as TelegramChatMemberStatus, k as TelegramReactionData } from './accounts-DRPENuZe.js';
11
- import { Q as QuizContent, a as StreakPolicy } from './streaks-0YuipsUQ.js';
12
- import { R as ResourceSource, S as Setting, I as IntegrationModule, B as Budget, a as IntegerSettings } from './integrations-CllF-kWg.js';
13
- import { P as Prerequisite, T as TextEvidence, U as UrlEvidence, a as TextOptions, b as UrlOptions } from './submission-input-BNah53go.js';
14
- export { c as balanceAtLeast, d as completed, i as inGroup } from './submission-input-BNah53go.js';
15
- import { I as ImageReader, X as XReader } from './x-BfQcsDp0.js';
14
+ import { a as StreakPolicy, Q as QuizContent } from './streaks-0YuipsUQ.js';
15
+ import { R as ResourceSource, S as Setting, A as AmountSetting, B as BalanceChain, I as IntegrationModule, a as BoundSettings } from './integrations-C6_uUh-s.js';
16
+ export { D as DashboardInput, b as DashboardPanelInput, d as defineDashboard } from './integrations-C6_uUh-s.js';
17
+ import { P as Prerequisite, T as TextEvidence, U as UrlEvidence, a as TextOptions, b as UrlOptions } from './submission-input-BbdawqVy.js';
18
+ export { c as balanceAtLeast, d as completed, i as inGroup } from './submission-input-BbdawqVy.js';
19
+ import { I as ImageReader, X as XReader } from './x-1czZFVUW.js';
16
20
  import { h as WalletReader } from './wallet-Ac7OFpOr.js';
17
21
  export { i as CosmosDenom, a as CosmosNetwork, E as EvmChainId, j as WalletBalance, k as WalletBalanceQuery, l as cosmosDenomSchema, m as cosmosNetworkSchema, n as isEvmChainId } from './wallet-Ac7OFpOr.js';
18
- export { C as CapabilityError, a as CapabilityErrorCode, c as capabilityErrorCodes } from './capability-error-FQGGb5xS.js';
19
22
  export { f as formatUnits, p as parseUnits } from './units-CwgsPB_r.js';
23
+ import './analytics-URV-mxjH.js';
20
24
 
21
25
  declare function defineBadge(input: z.input<typeof badgeDeclarationSchema>): {
22
26
  name: string;
@@ -179,15 +183,6 @@ declare function defineReferral(input: Omit<ReferralInput, "qualification" | "in
179
183
  amount: number;
180
184
  })[];
181
185
  };
182
- qualification: {
183
- kind: "signup";
184
- } | {
185
- kind: "quest";
186
- quest: string;
187
- } | {
188
- kind: "external";
189
- };
190
- enabled: boolean;
191
186
  milestones: {
192
187
  id: string;
193
188
  count: number;
@@ -218,6 +213,15 @@ declare function defineReferral(input: Omit<ReferralInput, "qualification" | "in
218
213
  amount: number;
219
214
  })[];
220
215
  }[];
216
+ qualification: {
217
+ kind: "signup";
218
+ } | {
219
+ kind: "quest";
220
+ quest: string;
221
+ } | {
222
+ kind: "external";
223
+ };
224
+ enabled: boolean;
221
225
  bonuses: {
222
226
  id: string;
223
227
  balance: string;
@@ -253,15 +257,26 @@ declare function earned(options?: Omit<EarnedScore, "kind" | "quests"> & {
253
257
  quests?: QuestHandle[];
254
258
  kind: "earned";
255
259
  };
256
- declare function defineLeaderboard(input: Omit<LeaderboardInput, "key" | "id" | "balance" | "group" | "score"> & AuthoringIdentity & {
260
+ type SettlementInput = NonNullable<LeaderboardInput["settle"]>;
261
+ declare function defineLeaderboard(input: Omit<LeaderboardInput, "key" | "id" | "balance" | "group" | "score" | "settle"> & AuthoringIdentity & {
257
262
  ledger: LedgerReference;
258
263
  group?: GroupHandle;
259
264
  score?: Exclude<LeaderboardInput["score"], {
260
265
  kind: "earned";
261
266
  }> | ReturnType<typeof earned>;
267
+ /**
268
+ * A points pool's `ledger` takes a ledger handle or key. `prizes` may be left out when the
269
+ * settlement has a pool.
270
+ */
271
+ settle?: Omit<SettlementInput, "pool" | "prizes"> & {
272
+ prizes?: SettlementInput["prizes"];
273
+ pool?: Omit<NonNullable<SettlementInput["pool"]>, "ledger"> & {
274
+ ledger?: LedgerReference;
275
+ };
276
+ };
262
277
  }): {
263
- title: string;
264
278
  balance: string;
279
+ title: string;
265
280
  access: "participants" | "public";
266
281
  score: {
267
282
  kind: "balance";
@@ -331,6 +346,15 @@ declare function defineLeaderboard(input: Omit<LeaderboardInput, "key" | "id" |
331
346
  amount: number;
332
347
  })[];
333
348
  }[];
349
+ pool?: {
350
+ amount: string;
351
+ unit: "points" | {
352
+ code: string;
353
+ decimals: number;
354
+ };
355
+ ledger?: string | undefined;
356
+ minScore?: number | undefined;
357
+ } | undefined;
334
358
  } | undefined;
335
359
  group?: string | undefined;
336
360
  } & ResourceHandle<"leaderboard">;
@@ -450,7 +474,7 @@ declare const telegram: {
450
474
  reactions(): {
451
475
  kind: "custom";
452
476
  namespace: string;
453
- identities?: ("discord" | "member" | "wallet" | "x" | `app:${string}`)[] | undefined;
477
+ identities?: ("discord" | "wallet" | "x" | "member" | `app:${string}`)[] | undefined;
454
478
  accounts?: string[] | undefined;
455
479
  data?: TrackerDataSchema | undefined;
456
480
  content?: {
@@ -507,6 +531,23 @@ declare const settings: {
507
531
  telegramChat(options: Label & {
508
532
  default?: string;
509
533
  }): Setting<"text", z.ZodDefault<z.ZodString>>;
534
+ /**
535
+ * A non-negative token amount in base units, as an integer string such as `"1000000"`: exact at
536
+ * any scale, so an 18-decimal threshold fits. A tracker filter may compare with it
537
+ * (`gte: { setting }`). With `decimals`, Console shows and edits it in whole tokens.
538
+ */
539
+ amount(options: Label & {
540
+ default: string;
541
+ decimals?: number;
542
+ }): AmountSetting<z.ZodDefault<z.ZodString>>;
543
+ /**
544
+ * A chain `ctx.wallet.balance()` reads: `"solana"` (or Solana mainnet's CAIP-2 ID), or an EVM
545
+ * chain's CAIP-2 ID such as `"eip155:8453"`. Typed as the query's chain, so it passes to
546
+ * `ctx.wallet.balance({ chain })` as it is.
547
+ */
548
+ chain(options: Label & {
549
+ default: BalanceChain;
550
+ }): Setting<"text", z.ZodDefault<z.ZodPipe<z.ZodString, z.ZodTransform<"solana" | "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp" | `eip155:${number}`, string>>>>;
510
551
  integer(options: Label & {
511
552
  default: number;
512
553
  min: number;
@@ -769,7 +810,8 @@ type Supplied<G, K extends string, Present, Base> = unknown extends G ? Base | n
769
810
  type ContextTracker<G> = Supplied<G, "tracker", TrackerTriggerContext<TriggerData<G>, TriggerBody<G>>, TrackerTriggerContext>;
770
811
  /**
771
812
  * What a `keyed()` completion key reads. TypeScript cannot carry the trigger into a completion
772
- * built inline, so `tracker` stays nullable here; the evaluator's `ctx.tracker` is typed.
813
+ * built inline, so `tracker` stays nullable here; the builder form,
814
+ * `completion: ({ keyed }) => keyed((ctx) => …)`, reads a {@link QuestKeyedContext}.
773
815
  */
774
816
  type KeyedContext = {
775
817
  member: {
@@ -783,6 +825,15 @@ type KeyedContext = {
783
825
  /** The attempt's evaluation time; see {@link EvaluationContext.now}. */
784
826
  now: number;
785
827
  };
828
+ /**
829
+ * What a completion key reads in the builder form, `completion: ({ keyed }) => keyed((ctx) => …)`:
830
+ * a {@link KeyedContext} typed from quest `G`'s trigger, with its settings `S`.
831
+ */
832
+ type QuestKeyedContext<S, G> = Omit<KeyedContext, "tracker"> & {
833
+ settings: S;
834
+ /** The pinned tracker observation: non-null and typed for a tracker trigger, null for others. */
835
+ tracker: ContextTracker<G>;
836
+ };
786
837
  declare const budget: (definition: Omit<Budget, "id" | "cost"> & {
787
838
  key: string;
788
839
  cost: number | {
@@ -801,13 +852,14 @@ declare const keyed: (key: (ctx: KeyedContext) => string) => {
801
852
  kind: "keyed";
802
853
  key: (ctx: KeyedContext) => string;
803
854
  };
804
- /** Accepted evidence contributes once under its distinct key; Relay commits progress with rewards. */
805
- declare const progress: (definition: {
806
- distinct: (ctx: KeyedContext) => string;
855
+ type ProgressDefinition<C> = {
856
+ distinct: (ctx: C) => string;
807
857
  goal: ReturnType<typeof count>;
808
858
  window?: ReturnType<typeof calendar>;
809
859
  repeat?: "once" | "repeat";
810
- }) => {
860
+ };
861
+ /** Accepted evidence contributes once under its distinct key; Relay commits progress with rewards. */
862
+ declare const progress: (definition: ProgressDefinition<KeyedContext>) => {
811
863
  distinct: (ctx: KeyedContext) => string;
812
864
  kind: "progress";
813
865
  goal: {
@@ -868,12 +920,22 @@ declare function defineTieredReward<const T extends readonly {
868
920
  declare const once: () => {
869
921
  kind: "once";
870
922
  };
923
+ type CompletionKeyOption = {
924
+ /**
925
+ * The completion key for a `keyed(...)` quest, in place of its key callback. Other policies
926
+ * ignore it: `once()` and `streak(...)` key their own completions, `progress(...)` uses its
927
+ * `distinct(...)`, and a content quest uses its content item. `runQuest` reports an ignored key.
928
+ */
929
+ completionKey?: string;
930
+ };
871
931
  type Outcome = (Omit<Extract<Decision, {
872
932
  kind: "accept";
873
- }>, "rewards"> & {
933
+ }>, "rewards" | "completionKey"> & {
874
934
  rewards?: Reward[];
875
- }) | Exclude<Decision, {
876
- kind: "accept";
935
+ } & CompletionKeyOption) | (Omit<Extract<Decision, {
936
+ kind: "review";
937
+ }>, "completionKey"> & CompletionKeyOption) | Exclude<Decision, {
938
+ kind: "accept" | "review";
877
939
  }>;
878
940
  /**
879
941
  * A performance evaluator's answer. It gates the rewards content evaluation already selected, so
@@ -940,7 +1002,20 @@ declare const decision: {
940
1002
  };
941
1003
  review: typeof review;
942
1004
  };
943
- /** The member an attempt evaluates. */
1005
+ /** What `ctx.member.completions()` reads. */
1006
+ type MemberCompletionQuery = {
1007
+ /** Only this quest's completions: its handle or key. */
1008
+ quest?: QuestHandle | string;
1009
+ /** Only completions recorded at or after this time, in epoch milliseconds on the member's clock. */
1010
+ since?: number;
1011
+ /** At most this many, newest first: 100 by default, and never more than 100. */
1012
+ limit?: number;
1013
+ };
1014
+ /**
1015
+ * The member an attempt evaluates. Relay and the testing kit create it; quest code only reads it.
1016
+ *
1017
+ * @compat sealed
1018
+ */
944
1019
  type EvaluationMember = {
945
1020
  id: string;
946
1021
  /**
@@ -949,6 +1024,39 @@ type EvaluationMember = {
949
1024
  * this evaluation. Null when the member has none. `ctx.wallet.list()` reads wallets.
950
1025
  */
951
1026
  identities(): Promise<MemberIdentity[] | null>;
1027
+ /**
1028
+ * The member's balance in a point ledger of the project, by its handle or key, as
1029
+ * `relay.me.balances()` returns it. The member's balances are pinned once per evaluation run at
1030
+ * the first call: points awarded or spent afterwards, including this attempt's own reward, do not
1031
+ * change this evaluation. An unknown ledger fails with a `CapabilityError` of code `author-error`.
1032
+ */
1033
+ balance(ledger: LedgerHandle | string): Promise<PointBalance>;
1034
+ /**
1035
+ * The member's accepted, unrevoked quest completions in the project, newest first; completions
1036
+ * recorded without a time come last. Pinned once per evaluation run at the first call, like
1037
+ * `balance`. An unknown quest fails with a `CapabilityError` of code `author-error`.
1038
+ */
1039
+ completions(query?: MemberCompletionQuery): Promise<MemberCompletion[]>;
1040
+ /**
1041
+ * Keys of the project's unarchived groups the member belongs to, in byte order. Pinned once per
1042
+ * evaluation run at the first call, like `balance`.
1043
+ */
1044
+ groups(): Promise<string[]>;
1045
+ /**
1046
+ * Whether the member's enrollment in a campaign, by its definition or key, is active: false once
1047
+ * they withdraw and for a campaign they never enrolled in. Pinned once per evaluation run at the
1048
+ * first call, like `balance`. A campaign no active quest declares and the member never enrolled
1049
+ * in fails with a `CapabilityError` of code `author-error`.
1050
+ */
1051
+ enrolled(campaign: Pick<CampaignDefinition, "key"> | string): Promise<boolean>;
1052
+ /**
1053
+ * The member's progress as inviter in a referral program, by its handle or key, as
1054
+ * `relay.profiles.referral()` returns it: the members they invited, those who qualified in the
1055
+ * program and the milestones reached. Never codes or accounts. Pinned once per evaluation run at
1056
+ * the first call, like `balance`. An unknown program fails with a `CapabilityError` of code
1057
+ * `author-error`.
1058
+ */
1059
+ referrals(program: ReferralHandle | string): Promise<ProfileReferral>;
952
1060
  };
953
1061
  /** One project-calendar day, with epoch-millisecond bounds. */
954
1062
  type EvaluationCalendarDay = {
@@ -1051,16 +1159,24 @@ type QuestInput<T extends Trigger> = T extends {
1051
1159
  input: "url";
1052
1160
  } ? UrlEvidence : Record<string, never>;
1053
1161
  /**
1054
- * Rejects a trigger whose filter compares with settings that are not integer settings of the
1055
- * quest, naming them.
1162
+ * Rejects a trigger whose filter compares with settings that are not integer or amount settings
1163
+ * of the quest, naming them.
1056
1164
  */
1057
1165
  type IntegerSettingBounds<G, T> = [
1058
- Exclude<TriggerSettings<G>, IntegerSettings<T>>
1166
+ Exclude<TriggerSettings<G>, BoundSettings<T>>
1059
1167
  ] extends [never] ? unknown : {
1060
- readonly "The tracker filter compares with settings that are not integer settings of this quest": Exclude<TriggerSettings<G>, IntegerSettings<T>>;
1168
+ readonly "The tracker filter compares with settings that are not integer or amount settings of this quest": Exclude<TriggerSettings<G>, BoundSettings<T>>;
1169
+ };
1170
+ type CompletionPolicy = ReturnType<typeof once> | ReturnType<typeof keyed> | StreakPolicy | ReturnType<typeof progress>;
1171
+ /** The completion builders, with key callbacks reading quest `G`'s typed context. */
1172
+ type CompletionPolicies<S, G> = {
1173
+ once: typeof once;
1174
+ keyed: (key: (ctx: QuestKeyedContext<S, G>) => string) => ReturnType<typeof keyed>;
1175
+ streak: typeof streak;
1176
+ progress: (definition: ProgressDefinition<QuestKeyedContext<S, G>>) => ReturnType<typeof progress>;
1061
1177
  };
1062
1178
  /** How a quest completes: a content quest once per content item, so it takes no `completion`. */
1063
- type CompletionFor<G> = IsContent<G> extends true ? {
1179
+ type CompletionFor<G, S> = IsContent<G> extends true ? {
1064
1180
  /** A content quest completes once per content item; it takes no completion. */
1065
1181
  completion?: never;
1066
1182
  } : G extends {
@@ -1069,7 +1185,12 @@ type CompletionFor<G> = IsContent<G> extends true ? {
1069
1185
  } ? {
1070
1186
  completion: ReturnType<typeof once>;
1071
1187
  } : {
1072
- completion: ReturnType<typeof once> | ReturnType<typeof keyed> | StreakPolicy | ReturnType<typeof progress>;
1188
+ /**
1189
+ * A policy, or a function building one from the policies it receives:
1190
+ * `({ keyed }) => keyed((ctx) => ctx.tracker.record.data.messageId)` types `ctx` from the
1191
+ * quest's trigger and settings, which a policy built inline cannot.
1192
+ */
1193
+ completion: CompletionPolicy | ((policies: CompletionPolicies<S, G>) => CompletionPolicy);
1073
1194
  };
1074
1195
  /** What a content quest's performance stage reads: the declared metrics it chose, fresh. */
1075
1196
  type PerformanceContext<S, G, M extends string> = {
@@ -1085,7 +1206,7 @@ type PerformanceContext<S, G, M extends string> = {
1085
1206
  observedAt: number;
1086
1207
  };
1087
1208
  /** A concrete quest: prerequisite-only automatic triggers need at least one prerequisite. */
1088
- declare const defineQuest: <T extends Record<string, Setting>, const G extends Trigger, const D extends readonly IntegrationModule[] = readonly [], const M extends readonly [string, ...string[]] = readonly [string, ...string[]]>(definition: AuthoringIdentity & CompletionFor<G> & (G extends {
1209
+ declare const defineQuest: <T extends Record<string, Setting>, const G extends Trigger, const D extends readonly IntegrationModule[] = readonly [], const M extends readonly [string, ...string[]] = readonly [string, ...string[]]>(definition: AuthoringIdentity & CompletionFor<G, z.core.$InferObjectOutput<T, {}>> & (G extends {
1089
1210
  kind: "automatic";
1090
1211
  tracker?: never;
1091
1212
  } ? {
@@ -1116,6 +1237,13 @@ declare const defineQuest: <T extends Record<string, Setting>, const G extends T
1116
1237
  * Only for quests members submit. Omit it for no cooldown.
1117
1238
  */
1118
1239
  retryCooldownMs?: number;
1240
+ /**
1241
+ * Milliseconds a member waits after an accepted completion, of any key, before submitting
1242
+ * again: `5_400_000` makes a second story count only 90 minutes after the first was
1243
+ * accepted. Only for repeatable quests members submit; same bounds as `retryCooldownMs`.
1244
+ * Omit it for no cooldown.
1245
+ */
1246
+ completionCooldownMs?: number;
1119
1247
  /**
1120
1248
  * Whether staff can review this quest's attempts. Human review is on unless this returns
1121
1249
  * `{ enabled: false }`. With it off, `decision.review(...)` becomes a reject that keeps the
@@ -1148,15 +1276,15 @@ declare const defineQuest: <T extends Record<string, Setting>, const G extends T
1148
1276
  group?: string | undefined;
1149
1277
  };
1150
1278
  tier: string;
1279
+ } | {
1280
+ kind: "points";
1281
+ balance: string;
1282
+ amount: number;
1151
1283
  } | {
1152
1284
  kind: "integration";
1153
1285
  provider: "discord";
1154
1286
  action: "grant-role";
1155
1287
  roleId: string;
1156
- } | {
1157
- kind: "points";
1158
- balance: string;
1159
- amount: number;
1160
1288
  })[] | ((ctx: {
1161
1289
  settings: z.core.$InferObjectOutput<T, {}>;
1162
1290
  }) => Reward[]);
@@ -1231,6 +1359,9 @@ declare const defineQuest: <T extends Record<string, Setting>, const G extends T
1231
1359
  kind: "resource";
1232
1360
  default: string;
1233
1361
  source: {
1362
+ provider: "domino";
1363
+ resource: "point-ledger";
1364
+ } | {
1234
1365
  provider: "discord";
1235
1366
  resource: "channel";
1236
1367
  types: ("text" | "announcement")[];
@@ -1238,9 +1369,6 @@ declare const defineQuest: <T extends Record<string, Setting>, const G extends T
1238
1369
  provider: "discord";
1239
1370
  resource: "role";
1240
1371
  assignable: boolean;
1241
- } | {
1242
- provider: "domino";
1243
- resource: "point-ledger";
1244
1372
  };
1245
1373
  label: string;
1246
1374
  description?: string | undefined;
@@ -1265,6 +1393,7 @@ declare const defineQuest: <T extends Record<string, Setting>, const G extends T
1265
1393
  multiline: boolean;
1266
1394
  label: string;
1267
1395
  picker?: string | undefined;
1396
+ decimals?: number | undefined;
1268
1397
  description?: string | undefined;
1269
1398
  } | {
1270
1399
  kind: "integer";
@@ -1315,15 +1444,15 @@ declare const defineQuest: <T extends Record<string, Setting>, const G extends T
1315
1444
  group?: string | undefined;
1316
1445
  };
1317
1446
  tier: string;
1447
+ } | {
1448
+ kind: "points";
1449
+ balance: string;
1450
+ amount: number;
1318
1451
  } | {
1319
1452
  kind: "integration";
1320
1453
  provider: "discord";
1321
1454
  action: "grant-role";
1322
1455
  roleId: string;
1323
- } | {
1324
- kind: "points";
1325
- balance: string;
1326
- amount: number;
1327
1456
  })[];
1328
1457
  humanReview: boolean;
1329
1458
  trigger: {
@@ -1345,7 +1474,7 @@ declare const defineQuest: <T extends Record<string, Setting>, const G extends T
1345
1474
  actor?: "staff" | "member" | undefined;
1346
1475
  } | {
1347
1476
  kind: "manual";
1348
- input: "none" | "quiz" | "photo";
1477
+ input: "photo" | "quiz" | "none";
1349
1478
  actor?: "staff" | "member" | undefined;
1350
1479
  } | {
1351
1480
  kind: "automatic";
@@ -1389,9 +1518,9 @@ declare const defineQuest: <T extends Record<string, Setting>, const G extends T
1389
1518
  path: string;
1390
1519
  equals: string | number | boolean;
1391
1520
  })[] | undefined;
1392
- enrollment?: "none" | "required" | undefined;
1521
+ enrollment?: "required" | "none" | undefined;
1393
1522
  since?: "activation" | "window" | "enrollment" | undefined;
1394
- historical?: "staff" | "claim" | "automatic" | undefined;
1523
+ historical?: "automatic" | "staff" | "claim" | undefined;
1395
1524
  content?: true | undefined;
1396
1525
  } | undefined;
1397
1526
  };
@@ -1414,6 +1543,9 @@ declare const defineQuest: <T extends Record<string, Setting>, const G extends T
1414
1543
  title: string;
1415
1544
  })[];
1416
1545
  completion: {
1546
+ kind: "streak";
1547
+ days: number;
1548
+ } | {
1417
1549
  kind: "progress";
1418
1550
  goal: {
1419
1551
  kind: "count";
@@ -1430,9 +1562,6 @@ declare const defineQuest: <T extends Record<string, Setting>, const G extends T
1430
1562
  durationMs: number;
1431
1563
  };
1432
1564
  repeat: "repeat" | "once";
1433
- } | {
1434
- kind: "streak";
1435
- days: number;
1436
1565
  } | {
1437
1566
  kind: "once";
1438
1567
  } | {
@@ -1458,7 +1587,7 @@ declare const defineQuest: <T extends Record<string, Setting>, const G extends T
1458
1587
  campaign?: {
1459
1588
  key: string;
1460
1589
  title: string;
1461
- enrollment: "none" | "required";
1590
+ enrollment: "required" | "none";
1462
1591
  window?: {
1463
1592
  from: number;
1464
1593
  until: number;
@@ -1469,6 +1598,7 @@ declare const defineQuest: <T extends Record<string, Setting>, const G extends T
1469
1598
  until: number;
1470
1599
  } | undefined;
1471
1600
  retryCooldownMs?: number | undefined;
1601
+ completionCooldownMs?: number | undefined;
1472
1602
  };
1473
1603
  evaluate(ctx: {
1474
1604
  settings: unknown;
@@ -1519,11 +1649,19 @@ declare const defineQuest: <T extends Record<string, Setting>, const G extends T
1519
1649
  rewards: Reward[];
1520
1650
  humanReview: boolean;
1521
1651
  performance?: unknown;
1652
+ /**
1653
+ * The testing kit's: receives what the run did that had no effect, such as a
1654
+ * `completionKey` the completion policy ignores. Relay's hosted runtime does not pass it.
1655
+ */
1656
+ diagnose?: ((diagnostic: {
1657
+ code: string;
1658
+ message: string;
1659
+ }) => void) | undefined;
1522
1660
  }): Promise<Decision>;
1523
1661
  } & ResourceHandle<"quest">;
1524
1662
  /** Publish this artifact as a reusable type. Its key names the type;
1525
1663
  * Console instances receive independent quest identities and pinned versions. */
1526
- declare const defineQuestType: <T extends Record<string, Setting>, const G extends Trigger, const D extends readonly IntegrationModule[] = readonly [], const M extends readonly [string, ...string[]] = readonly [string, ...string[]]>(definition: AuthoringIdentity & CompletionFor<G> & {
1664
+ declare const defineQuestType: <T extends Record<string, Setting>, const G extends Trigger, const D extends readonly IntegrationModule[] = readonly [], const M extends readonly [string, ...string[]] = readonly [string, ...string[]]>(definition: AuthoringIdentity & CompletionFor<G, z.core.$InferObjectOutput<T, {}>> & {
1527
1665
  title: string | ((ctx: {
1528
1666
  settings: z.core.$InferObjectOutput<T, {}>;
1529
1667
  }) => string);
@@ -1549,6 +1687,13 @@ declare const defineQuestType: <T extends Record<string, Setting>, const G exten
1549
1687
  * Only for quests members submit. Omit it for no cooldown.
1550
1688
  */
1551
1689
  retryCooldownMs?: number;
1690
+ /**
1691
+ * Milliseconds a member waits after an accepted completion, of any key, before submitting
1692
+ * again: `5_400_000` makes a second story count only 90 minutes after the first was
1693
+ * accepted. Only for repeatable quests members submit; same bounds as `retryCooldownMs`.
1694
+ * Omit it for no cooldown.
1695
+ */
1696
+ completionCooldownMs?: number;
1552
1697
  /**
1553
1698
  * Whether staff can review this quest's attempts. Human review is on unless this returns
1554
1699
  * `{ enabled: false }`. With it off, `decision.review(...)` becomes a reject that keeps the
@@ -1581,15 +1726,15 @@ declare const defineQuestType: <T extends Record<string, Setting>, const G exten
1581
1726
  group?: string | undefined;
1582
1727
  };
1583
1728
  tier: string;
1729
+ } | {
1730
+ kind: "points";
1731
+ balance: string;
1732
+ amount: number;
1584
1733
  } | {
1585
1734
  kind: "integration";
1586
1735
  provider: "discord";
1587
1736
  action: "grant-role";
1588
1737
  roleId: string;
1589
- } | {
1590
- kind: "points";
1591
- balance: string;
1592
- amount: number;
1593
1738
  })[] | ((ctx: {
1594
1739
  settings: z.core.$InferObjectOutput<T, {}>;
1595
1740
  }) => Reward[]);
@@ -1664,6 +1809,9 @@ declare const defineQuestType: <T extends Record<string, Setting>, const G exten
1664
1809
  kind: "resource";
1665
1810
  default: string;
1666
1811
  source: {
1812
+ provider: "domino";
1813
+ resource: "point-ledger";
1814
+ } | {
1667
1815
  provider: "discord";
1668
1816
  resource: "channel";
1669
1817
  types: ("text" | "announcement")[];
@@ -1671,9 +1819,6 @@ declare const defineQuestType: <T extends Record<string, Setting>, const G exten
1671
1819
  provider: "discord";
1672
1820
  resource: "role";
1673
1821
  assignable: boolean;
1674
- } | {
1675
- provider: "domino";
1676
- resource: "point-ledger";
1677
1822
  };
1678
1823
  label: string;
1679
1824
  description?: string | undefined;
@@ -1698,6 +1843,7 @@ declare const defineQuestType: <T extends Record<string, Setting>, const G exten
1698
1843
  multiline: boolean;
1699
1844
  label: string;
1700
1845
  picker?: string | undefined;
1846
+ decimals?: number | undefined;
1701
1847
  description?: string | undefined;
1702
1848
  } | {
1703
1849
  kind: "integer";
@@ -1748,15 +1894,15 @@ declare const defineQuestType: <T extends Record<string, Setting>, const G exten
1748
1894
  group?: string | undefined;
1749
1895
  };
1750
1896
  tier: string;
1897
+ } | {
1898
+ kind: "points";
1899
+ balance: string;
1900
+ amount: number;
1751
1901
  } | {
1752
1902
  kind: "integration";
1753
1903
  provider: "discord";
1754
1904
  action: "grant-role";
1755
1905
  roleId: string;
1756
- } | {
1757
- kind: "points";
1758
- balance: string;
1759
- amount: number;
1760
1906
  })[];
1761
1907
  humanReview: boolean;
1762
1908
  trigger: {
@@ -1778,7 +1924,7 @@ declare const defineQuestType: <T extends Record<string, Setting>, const G exten
1778
1924
  actor?: "staff" | "member" | undefined;
1779
1925
  } | {
1780
1926
  kind: "manual";
1781
- input: "none" | "quiz" | "photo";
1927
+ input: "photo" | "quiz" | "none";
1782
1928
  actor?: "staff" | "member" | undefined;
1783
1929
  } | {
1784
1930
  kind: "automatic";
@@ -1822,9 +1968,9 @@ declare const defineQuestType: <T extends Record<string, Setting>, const G exten
1822
1968
  path: string;
1823
1969
  equals: string | number | boolean;
1824
1970
  })[] | undefined;
1825
- enrollment?: "none" | "required" | undefined;
1971
+ enrollment?: "required" | "none" | undefined;
1826
1972
  since?: "activation" | "window" | "enrollment" | undefined;
1827
- historical?: "staff" | "claim" | "automatic" | undefined;
1973
+ historical?: "automatic" | "staff" | "claim" | undefined;
1828
1974
  content?: true | undefined;
1829
1975
  } | undefined;
1830
1976
  };
@@ -1847,6 +1993,9 @@ declare const defineQuestType: <T extends Record<string, Setting>, const G exten
1847
1993
  title: string;
1848
1994
  })[];
1849
1995
  completion: {
1996
+ kind: "streak";
1997
+ days: number;
1998
+ } | {
1850
1999
  kind: "progress";
1851
2000
  goal: {
1852
2001
  kind: "count";
@@ -1863,9 +2012,6 @@ declare const defineQuestType: <T extends Record<string, Setting>, const G exten
1863
2012
  durationMs: number;
1864
2013
  };
1865
2014
  repeat: "repeat" | "once";
1866
- } | {
1867
- kind: "streak";
1868
- days: number;
1869
2015
  } | {
1870
2016
  kind: "once";
1871
2017
  } | {
@@ -1891,7 +2037,7 @@ declare const defineQuestType: <T extends Record<string, Setting>, const G exten
1891
2037
  campaign?: {
1892
2038
  key: string;
1893
2039
  title: string;
1894
- enrollment: "none" | "required";
2040
+ enrollment: "required" | "none";
1895
2041
  window?: {
1896
2042
  from: number;
1897
2043
  until: number;
@@ -1902,6 +2048,7 @@ declare const defineQuestType: <T extends Record<string, Setting>, const G exten
1902
2048
  until: number;
1903
2049
  } | undefined;
1904
2050
  retryCooldownMs?: number | undefined;
2051
+ completionCooldownMs?: number | undefined;
1905
2052
  };
1906
2053
  evaluate(ctx: {
1907
2054
  settings: unknown;
@@ -1952,7 +2099,15 @@ declare const defineQuestType: <T extends Record<string, Setting>, const G exten
1952
2099
  rewards: Reward[];
1953
2100
  humanReview: boolean;
1954
2101
  performance?: unknown;
2102
+ /**
2103
+ * The testing kit's: receives what the run did that had no effect, such as a
2104
+ * `completionKey` the completion policy ignores. Relay's hosted runtime does not pass it.
2105
+ */
2106
+ diagnose?: ((diagnostic: {
2107
+ code: string;
2108
+ message: string;
2109
+ }) => void) | undefined;
1955
2110
  }): Promise<Decision>;
1956
2111
  } & ResourceHandle<"quest">;
1957
2112
 
1958
- export { ContentBody, type ContentData, ContentMetricName, type ContentTrigger, type ContentTriggerInput, DiscordMessageData, DiscordMessageTextData, DiscordReactionData, DiscordReader, type EvaluationCalendar, type EvaluationCalendarDay, type EvaluationContext, type EvaluationMember, GroupHandle, IdentityKind, ImageReader, IntegrationModule, type KeyedContext, LedgerHandle, LedgerReference, MemberIdentity, type Outcome, type PerformanceContext, type PerformanceOutcome, QuestHandle, RoleOf, Setting, TelegramReader, Tracker, TrackerData, TrackerDataSchema, TrackerReader, type TrackerTrigger, TrackerTriggerContext, type TrackerTriggerInput, type TriggerAdmission, WalletReader, Where, type XContentBody, XReader, automatic, automaticFulfillment, badge, budget, calendar, content, count, customSource, decision, defineBadge, defineEngagementReward, defineLeaderboard, defineLedger, defineQuest, defineQuestType, defineReferral, defineTieredReward, defineTracker, discord, earned, evaluators, evidence, groupMembership, keyed, manual, once, pointLedgers, points, progress, questCompleted, rolling, settings, staffHandover, streak, telegram, untracked, x };
2113
+ export { AmountSetting, BalanceChain, ContentBody, type ContentData, ContentMetricName, type ContentTrigger, type ContentTriggerInput, DiscordMessageData, DiscordMessageTextData, DiscordReactionData, DiscordReader, type EvaluationCalendar, type EvaluationCalendarDay, type EvaluationContext, type EvaluationMember, GroupHandle, IdentityKind, ImageReader, IntegrationModule, type KeyedContext, LedgerHandle, LedgerReference, MemberCompletion, type MemberCompletionQuery, MemberIdentity, type Outcome, type PerformanceContext, type PerformanceOutcome, PointBalance, ProfileReferral, QuestHandle, type QuestKeyedContext, ReferralHandle, RoleOf, Setting, TelegramReader, Tracker, TrackerData, TrackerDataSchema, TrackerReader, type TrackerTrigger, TrackerTriggerContext, type TrackerTriggerInput, type TriggerAdmission, WalletReader, Where, type XContentBody, XReader, automatic, automaticFulfillment, badge, budget, calendar, content, count, customSource, decision, defineBadge, defineEngagementReward, defineLeaderboard, defineLedger, defineQuest, defineQuestType, defineReferral, defineTieredReward, defineTracker, discord, earned, evaluators, evidence, groupMembership, keyed, manual, once, pointLedgers, points, progress, questCompleted, rolling, settings, staffHandover, streak, telegram, untracked, x };