primitive-admin 1.1.0-alpha.74 → 1.1.0-alpha.76

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 (128) hide show
  1. package/dist/bin/primitive.js +110 -21
  2. package/dist/bin/primitive.js.map +1 -1
  3. package/dist/src/commands/collection-type-configs.js +1 -1
  4. package/dist/src/commands/collection-type-configs.js.map +1 -1
  5. package/dist/src/commands/config.js +8 -4
  6. package/dist/src/commands/config.js.map +1 -1
  7. package/dist/src/commands/database-type-configs.js +1 -1
  8. package/dist/src/commands/database-type-configs.js.map +1 -1
  9. package/dist/src/commands/databases.js +25 -31
  10. package/dist/src/commands/databases.js.map +1 -1
  11. package/dist/src/commands/documents.js +9 -24
  12. package/dist/src/commands/documents.js.map +1 -1
  13. package/dist/src/commands/env.d.ts +1 -1
  14. package/dist/src/commands/env.js +14 -11
  15. package/dist/src/commands/env.js.map +1 -1
  16. package/dist/src/commands/functions.js +173 -4
  17. package/dist/src/commands/functions.js.map +1 -1
  18. package/dist/src/commands/groups.js +1 -1
  19. package/dist/src/commands/groups.js.map +1 -1
  20. package/dist/src/commands/init.d.ts +12 -15
  21. package/dist/src/commands/init.js +36 -77
  22. package/dist/src/commands/init.js.map +1 -1
  23. package/dist/src/commands/prompts.js +54 -39
  24. package/dist/src/commands/prompts.js.map +1 -1
  25. package/dist/src/commands/rule-sets.js +1 -1
  26. package/dist/src/commands/rule-sets.js.map +1 -1
  27. package/dist/src/commands/scripts.js +17 -4
  28. package/dist/src/commands/scripts.js.map +1 -1
  29. package/dist/src/commands/sync-app-settings.js +2 -4
  30. package/dist/src/commands/sync-app-settings.js.map +1 -1
  31. package/dist/src/commands/sync.d.ts +41 -2
  32. package/dist/src/commands/sync.js +635 -364
  33. package/dist/src/commands/sync.js.map +1 -1
  34. package/dist/src/commands/workflows.js +62 -31
  35. package/dist/src/commands/workflows.js.map +1 -1
  36. package/dist/src/lib/api-client.d.ts +23 -2
  37. package/dist/src/lib/api-client.js +24 -5
  38. package/dist/src/lib/api-client.js.map +1 -1
  39. package/dist/src/lib/app-match-guard.d.ts +44 -0
  40. package/dist/src/lib/app-match-guard.js +72 -0
  41. package/dist/src/lib/app-match-guard.js.map +1 -0
  42. package/dist/src/lib/block-selector.d.ts +58 -0
  43. package/dist/src/lib/block-selector.js +92 -0
  44. package/dist/src/lib/block-selector.js.map +1 -0
  45. package/dist/src/lib/codegen-shared/resolveCodegenSourceDir.d.ts +11 -8
  46. package/dist/src/lib/codegen-shared/resolveCodegenSourceDir.js +108 -54
  47. package/dist/src/lib/codegen-shared/resolveCodegenSourceDir.js.map +1 -1
  48. package/dist/src/lib/config-object-descriptor.js +1 -3
  49. package/dist/src/lib/config-object-descriptor.js.map +1 -1
  50. package/dist/src/lib/config.d.ts +2 -2
  51. package/dist/src/lib/config.js +2 -2
  52. package/dist/src/lib/credentials-store.d.ts +3 -3
  53. package/dist/src/lib/credentials-store.js +3 -3
  54. package/dist/src/lib/credentials-store.js.map +1 -1
  55. package/dist/src/lib/document-export-permissions.d.ts +30 -0
  56. package/dist/src/lib/document-export-permissions.js +54 -0
  57. package/dist/src/lib/document-export-permissions.js.map +1 -0
  58. package/dist/src/lib/env-resolver-core.d.ts +41 -9
  59. package/dist/src/lib/env-resolver-core.js +84 -13
  60. package/dist/src/lib/env-resolver-core.js.map +1 -1
  61. package/dist/src/lib/env-resolver.d.ts +3 -3
  62. package/dist/src/lib/env-resolver.js +2 -2
  63. package/dist/src/lib/function-bundle.d.ts +11 -1
  64. package/dist/src/lib/function-bundle.js +13 -1
  65. package/dist/src/lib/function-bundle.js.map +1 -1
  66. package/dist/src/lib/function-collect.d.ts +123 -0
  67. package/dist/src/lib/function-collect.js +463 -0
  68. package/dist/src/lib/function-collect.js.map +1 -0
  69. package/dist/src/lib/function-db-types.d.ts +149 -0
  70. package/dist/src/lib/function-db-types.js +587 -0
  71. package/dist/src/lib/function-db-types.js.map +1 -0
  72. package/dist/src/lib/function-grants-preflight.d.ts +64 -0
  73. package/dist/src/lib/function-grants-preflight.js +100 -0
  74. package/dist/src/lib/function-grants-preflight.js.map +1 -0
  75. package/dist/src/lib/function-sync.d.ts +23 -0
  76. package/dist/src/lib/function-sync.js +65 -1
  77. package/dist/src/lib/function-sync.js.map +1 -1
  78. package/dist/src/lib/function-triggers.d.ts +6 -0
  79. package/dist/src/lib/function-triggers.js +63 -4
  80. package/dist/src/lib/function-triggers.js.map +1 -1
  81. package/dist/src/lib/generated-config-surfaces.d.ts +340 -0
  82. package/dist/src/lib/generated-config-surfaces.js +669 -17
  83. package/dist/src/lib/generated-config-surfaces.js.map +1 -1
  84. package/dist/src/lib/generated-sdk-types.d.ts +12 -0
  85. package/dist/src/lib/generated-sdk-types.js +13 -0
  86. package/dist/src/lib/generated-sdk-types.js.map +1 -0
  87. package/dist/src/lib/init-adopt.js +2 -2
  88. package/dist/src/lib/init-adopt.js.map +1 -1
  89. package/dist/src/lib/init-assets.js +3 -3
  90. package/dist/src/lib/init-config.d.ts +1 -1
  91. package/dist/src/lib/init-ios-links.js +1 -1
  92. package/dist/src/lib/init-ios-links.js.map +1 -1
  93. package/dist/src/lib/init-plan.d.ts +1 -1
  94. package/dist/src/lib/init-plan.js +1 -1
  95. package/dist/src/lib/init-xcode.d.ts +2 -2
  96. package/dist/src/lib/init-xcode.js +6 -5
  97. package/dist/src/lib/init-xcode.js.map +1 -1
  98. package/dist/src/lib/local-state.d.ts +1 -1
  99. package/dist/src/lib/local-state.js +1 -1
  100. package/dist/src/lib/local-test-cases.d.ts +1 -1
  101. package/dist/src/lib/local-test-cases.js +2 -1
  102. package/dist/src/lib/local-test-cases.js.map +1 -1
  103. package/dist/src/lib/migration-nag.d.ts +2 -2
  104. package/dist/src/lib/migration-nag.js +4 -3
  105. package/dist/src/lib/migration-nag.js.map +1 -1
  106. package/dist/src/lib/project-config.d.ts +23 -20
  107. package/dist/src/lib/project-config.js +27 -45
  108. package/dist/src/lib/project-config.js.map +1 -1
  109. package/dist/src/lib/snapshots.d.ts +2 -2
  110. package/dist/src/lib/snapshots.js +2 -2
  111. package/dist/src/lib/swift-codegen/generator.d.ts +1 -1
  112. package/dist/src/lib/swift-codegen/generator.js +1 -1
  113. package/dist/src/lib/sync-dir-selector.d.ts +1 -1
  114. package/dist/src/lib/sync-dir-selector.js +1 -1
  115. package/dist/src/lib/sync-paths.d.ts +52 -16
  116. package/dist/src/lib/sync-paths.js +68 -22
  117. package/dist/src/lib/sync-paths.js.map +1 -1
  118. package/dist/src/lib/sync-resource-types.d.ts +2 -2
  119. package/dist/src/lib/sync-resource-types.js +2 -2
  120. package/dist/src/lib/template.d.ts +2 -2
  121. package/dist/src/lib/template.js +2 -2
  122. package/dist/src/lib/test-case-keys.d.ts +1 -1
  123. package/dist/src/lib/test-case-keys.js +1 -1
  124. package/dist/src/lib/toml-database-config.js +19 -2
  125. package/dist/src/lib/toml-database-config.js.map +1 -1
  126. package/dist/src/lib/workflow-codegen/generator.d.ts +1 -1
  127. package/dist/src/lib/workflow-codegen/generator.js +1 -1
  128. package/package.json +3 -3
@@ -578,6 +578,346 @@ export interface RetiredConfigKey {
578
578
  export declare const RETIRED_CONFIG_KEYS: Record<string, Record<string, RetiredConfigKey>>;
579
579
  /** The retired-key entry for `key` under `prefix`, or null when it is simply unknown. */
580
580
  export declare function retiredConfigKey(prefix: string, key: string): RetiredConfigKey | null;
581
+ /**
582
+ * The capability grammar for server functions — #3182 phase 1, rewritten by
583
+ * #3279 (project `server-functions` phase 3).
584
+ *
585
+ * A function declares in its own TOML what it may CONFIGURE:
586
+ *
587
+ * capabilities = ["integration:stripe", "secret:STRIPE_KEY", "databases:delete"]
588
+ *
589
+ * ── Why the grammar is this small ────────────────────────────────────────
590
+ *
591
+ * The intent's decision (2026-09-09, "Authorization inside a function?"):
592
+ * function code acts as the system. The invocation gate is the authorization,
593
+ * and inside a function every platform call carries the app's own authority in
594
+ * every family. A capability is therefore never a statement about DATA — a
595
+ * model, a prompt, a channel, a member — because the function may reach all of
596
+ * it. It is declared only where it configures something:
597
+ *
598
+ * `integration:<key>` the egress allowlist — which upstream hosts the
599
+ * function's outbound calls may reach;
600
+ * `secret:<NAME>` credential least privilege — which secret VALUES may
601
+ * cross into the sandbox at all;
602
+ * the high-blast list {@link HIGH_BLAST_CAPABILITIES} — the operations
603
+ * whose blast radius the intent keeps opt-in.
604
+ *
605
+ * Every other string a function used to declare is RETIRED, and the grammar
606
+ * says so by name: an author who still writes `database:orders/Order:read`
607
+ * is told the model changed and what stays, not "unknown family", which would
608
+ * send them to check their spelling.
609
+ *
610
+ * ── Why the components have a charset ────────────────────────────────────
611
+ *
612
+ * A keyed grant's key must match `[A-Za-z0-9_-]+`, so neither `:` nor `/` can
613
+ * enter a component and the string is INJECTIVE — one string, one object. An
614
+ * integration or secret whose key carries a delimiter is simply unreachable
615
+ * from functions, with an error that says why (D3182-001's argument, kept).
616
+ *
617
+ * ── Why this module is pure ──────────────────────────────────────────────
618
+ *
619
+ * Capabilities are validated twice — by `config push`'s preflight, so an
620
+ * author sees the error against their own file, and by the server, which is
621
+ * authoritative because the raw admin API exists. Two enforcement points must
622
+ * not be two grammars, so the grammar lives here, in the dependency-free
623
+ * `src/config-surface/` tree the CLI vendors at build time
624
+ * (`cli/scripts/gen-config-surfaces.mjs`). The server imports this module; the
625
+ * CLI imports the generated copy; the drift guard fails if they differ.
626
+ */
627
+ /** Every component of a grant. Injectivity depends on this. */
628
+ export declare const GRANT_COMPONENT_PATTERN: RegExp;
629
+ /** `ServerFunctionConfig.capabilities` is a StringSet with these bounds. */
630
+ export declare const MAX_CAPABILITY_ENTRIES = 100;
631
+ export declare const MAX_CAPABILITY_ENTRY_LENGTH = 200;
632
+ /**
633
+ * The two keyed families the intent keeps: one component under
634
+ * {@link GRANT_COMPONENT_PATTERN}, naming a single object. Every key format the
635
+ * platform issues fits: an integration key is `^[a-z0-9][a-z0-9-_]{2,}$` and a
636
+ * secret name is `^[A-Z][A-Z0-9_]{0,63}$`.
637
+ */
638
+ export declare const KEYED_GRANT_FAMILIES: readonly ["integration", "secret"];
639
+ /**
640
+ * The high-blast-radius opt-ins — #3279, criterion 5 (CR3279-001, D3279-003).
641
+ *
642
+ * Since function code acts as the system, admission to a family is no longer
643
+ * an authority statement: everything the gateway lets through runs with the
644
+ * app's own authority. Most operations are fine that way — that is the whole
645
+ * decision. A short list is not, and the intent names its categories: delete a
646
+ * database, app or user; role changes; secret changes; resource provisioning.
647
+ * Those stay opt-in, so a function that can do them says so in a reviewable
648
+ * line of its TOML.
649
+ *
650
+ * The strings are EXACT and 1:1 with the operation id, so there is nothing to
651
+ * look up: `users.setRole` needs `users:setRole`. They parse with the verb as
652
+ * their KEY, because two exact capabilities in one family must not cover each
653
+ * other — `databases:create` is not permission to delete a database.
654
+ *
655
+ * The database ROLE mutations are here because they hand out persistent
656
+ * authority: a group grant assigns the manager role (D3279-003). App deletion
657
+ * and secret writes have no app-API route today; they are recorded, not gated,
658
+ * and the profile generator refuses to admit a future such route without a row
659
+ * here (`HIGH_BLAST_WATCH` in `scripts/lib/function-profile.mjs`).
660
+ */
661
+ export declare const HIGH_BLAST_CAPABILITIES: readonly ["databases:create", "databases:delete", "databases:transferOwnership", "databases:addManager", "databases:revokePermission", "databases:grantGroupPermission", "databases:revokeGroupPermission", "users:remove", "users:setRole", "blobBuckets:createBucket", "blobBuckets:deleteBucket"];
662
+ /** The exact strings, which since #3279 are exactly the high-blast list. */
663
+ export declare const EXACT_GRANT_STRINGS: readonly ["databases:create", "databases:delete", "databases:transferOwnership", "databases:addManager", "databases:revokePermission", "databases:grantGroupPermission", "databases:revokeGroupPermission", "users:remove", "users:setRole", "blobBuckets:createBucket", "blobBuckets:deleteBucket"];
664
+ export type GrantFamily = (typeof KEYED_GRANT_FAMILIES)[number] | "databases" | "users" | "blobBuckets";
665
+ /**
666
+ * The retired FAMILIES (#3279), each with the reason it is gone.
667
+ *
668
+ * The value is what the family used to authorize, phrased as what a function
669
+ * now reaches without it. A refusal names the authored string, says it is
670
+ * retired, gives this reason, tells the author to delete the entry, and lists
671
+ * what stays.
672
+ */
673
+ export declare const RETIRED_GRANT_FAMILIES: Record<string, string>;
674
+ /** The retired EXACT strings (#3279), on the same terms. */
675
+ export declare const RETIRED_GRANT_STRINGS: Record<string, string>;
676
+ /**
677
+ * The retirement sentence for one authored string, or null when the string is
678
+ * not a retired one.
679
+ *
680
+ * Exported so the enforcement-time reader (`loadConfigGrants`) can tell a
681
+ * retired string on a pre-change row — tolerated, logged — from a string that
682
+ * was never a grant at all, which still authorizes nothing.
683
+ */
684
+ export declare function retiredGrantRefusal(raw: string): string | null;
685
+ /**
686
+ * Any grant, in one flat shape.
687
+ *
688
+ * Flat rather than a discriminated union because this module is vendored into
689
+ * the CLI, which compiles with `strict: false`: a caller reads `family` and
690
+ * then `key`, and the fields another family would have used are simply absent.
691
+ */
692
+ export interface FunctionGrant {
693
+ family: GrantFamily;
694
+ /**
695
+ * The single component of a keyed family — the integration key or the
696
+ * secret name — or the VERB of a high-blast string (`delete` for
697
+ * `databases:delete`), so that no two exact capabilities in one family read
698
+ * as the same grant.
699
+ */
700
+ key: string;
701
+ /** The authored string, so an error or a log line can quote it. */
702
+ raw: string;
703
+ }
704
+ export interface ParsedFunctionGrant {
705
+ grant?: FunctionGrant;
706
+ error?: string;
707
+ }
708
+ /**
709
+ * A channel name's ceiling, and the reason it has one.
710
+ *
711
+ * The name rides in a `ConnectionMapping` row's document-id slot as
712
+ * `ch:<appId>:<channel>` and in every grant token's claims, so an unbounded
713
+ * name would be an unbounded key and an unbounded credential. 200 characters
714
+ * is {@link MAX_CAPABILITY_ENTRY_LENGTH}, kept for continuity with the rows
715
+ * #3184 already wrote.
716
+ */
717
+ export declare const MAX_CHANNEL_NAME_LENGTH = 200;
718
+ export interface ParsedChannelName {
719
+ /** The segment before the first `:`. Absent when the name is refused. */
720
+ namespace?: string;
721
+ error?: string;
722
+ }
723
+ /**
724
+ * A channel NAME, and its namespace.
725
+ *
726
+ * The grammar is the grant component charset applied per segment: one or more
727
+ * `[A-Za-z0-9_-]+` segments joined by `:`. The `channel:<namespace>` GRANT
728
+ * that used to cover a name is retired (#3279); the name grammar stays because
729
+ * the authorize and publish routes answer 400 about a name outside it before
730
+ * anything else, and the connection worker keys membership by it.
731
+ *
732
+ * Refusals name the segment that failed, because "channel name is invalid" on
733
+ * a name like `orders:a::b` tells an author nothing they cannot already see.
734
+ */
735
+ export declare function parseChannelName(value: unknown): ParsedChannelName;
736
+ /**
737
+ * One capability entry as a grant, or the reason it is not one.
738
+ *
739
+ * The single entry point the enforcement path and both preflights use: a
740
+ * caller holds one authored string and asks what it grants, without having to
741
+ * know which of the shapes to try. Every diagnosis is specific — a retired
742
+ * string gets the retirement and what stays; a near miss in a kept family gets
743
+ * the family's own strings; a keyed family gets its charset rule.
744
+ */
745
+ export declare function parseFunctionGrant(entry: unknown): ParsedFunctionGrant;
746
+ /**
747
+ * One shape rather than a discriminated union: this module is vendored into
748
+ * the CLI, which compiles with `strict: false`, where narrowing on a boolean
749
+ * literal discriminant does not hold. Both callers read `ok` and then the
750
+ * field they want, and the unused half is empty rather than absent.
751
+ */
752
+ export interface ParsedCapabilities {
753
+ ok: boolean;
754
+ /** Deduped, in authored order — what the config row stores. Empty when refused. */
755
+ capabilities: string[];
756
+ /** Every grant, in authored order. */
757
+ allGrants: FunctionGrant[];
758
+ /**
759
+ * The retired strings that were SKIPPED, in authored order — populated only
760
+ * under `tolerateRetired` (see {@link parseCapabilities}); a strict parse
761
+ * refuses them instead and leaves this empty.
762
+ */
763
+ retired: string[];
764
+ /** Empty when accepted. */
765
+ errors: string[];
766
+ }
767
+ export interface ParseCapabilitiesOptions {
768
+ /**
769
+ * Skip retired strings instead of refusing them — #3279 edge 25.
770
+ *
771
+ * The PUSH path is strict: a file that still declares a retired grant is
772
+ * refused with the retirement, because a line that is accepted and ignored
773
+ * is a line the author believes means something. The ENFORCEMENT path is
774
+ * tolerant: a config version pushed before #3279 carries retired strings in
775
+ * a row that can never be re-pushed to fix (its envelope is immutable), and
776
+ * refusing it there would break every function pushed before the change.
777
+ * Such a row authorizes exactly what it keeps, and the skipped strings are
778
+ * reported in `retired` so the caller can log them.
779
+ */
780
+ tolerateRetired?: boolean;
781
+ }
782
+ /**
783
+ * A whole `capabilities` list: shape, bounds, grammar, duplicates.
784
+ *
785
+ * The model's own caps are checked HERE rather than left to the StringSet
786
+ * field, so an over-long entry is a named push error instead of a late model
787
+ * throw after the R2 object has already been written (principle 6).
788
+ */
789
+ export declare function parseCapabilities(value: unknown, options?: ParseCapabilitiesOptions): ParsedCapabilities;
790
+ /**
791
+ * The config-tree objects an `integration:` grant may name.
792
+ *
793
+ * Only the one family whose target is CONFIG-TREE state. `secret:` is absent
794
+ * on purpose (D3183-002): its values are provisioned per environment, out of
795
+ * band, and are not part of the reviewed tree at all, so the ordinary order of
796
+ * work is to push the function and then provision the value. Refusing an
797
+ * unprovisioned name at push would break that; a missing value at CALL time is
798
+ * a structured runtime error instead. The high-blast strings name no object.
799
+ *
800
+ * `null` means "this enforcement point could not find out". The CLI reads the
801
+ * tree and, when it can, a live listing; when neither is available it defers
802
+ * rather than guessing, because a preflight that refused a valid tree for
803
+ * being offline would be worse than one that lets the server have the last
804
+ * word. The server never passes null — it can always read its own rows.
805
+ */
806
+ export interface KnownGrantTargets {
807
+ /** Non-archived integration keys, or null when unknown. */
808
+ integrations: ReadonlySet<string> | null;
809
+ }
810
+ /**
811
+ * Grants naming an integration the app does not have.
812
+ *
813
+ * One message per offending grant, quoting the whole authored string AND the
814
+ * key on its own, so an operator reading the line knows both what to fix in
815
+ * the file and what to create in the app.
816
+ *
817
+ * The rule is here, beside the grammar, for the reason the whole module
818
+ * exists: `config push`'s preflight and the authoritative server check read
819
+ * different sources for the same facts — a `.toml` in the tree versus a row
820
+ * in DynamoDB — and it is the RULE that must not differ between them.
821
+ */
822
+ export declare function validateKeyedGrantsAgainstTargets(grants: readonly FunctionGrant[], known: KnownGrantTargets): string[];
823
+ /**
824
+ * The query manifest's grammar, and the read rule it unlocks — #3187, project
825
+ * `server-functions` phase 5.
826
+ *
827
+ * A pushed config version may carry a MANIFEST: the queries and mutations the
828
+ * tree registered at module scope, collected by the CLI (`function-collect.ts`)
829
+ * by running the tree with `primitive-functions` aliased to a recording stub.
830
+ *
831
+ * ── What the manifest is for ─────────────────────────────────────────────
832
+ *
833
+ * Observability, and nothing else. `primitive functions get` and the admin
834
+ * get list what a version registered, so an operator can see it without
835
+ * reading the bundle (principle 8). The read rule it used to be decided from
836
+ * (#3187's `$caller` relaxation of `unscopedReads`) is retired by #3279:
837
+ * function code acts as the system, so there is no per-model grant for a
838
+ * binding to waive. The intent says so in as many words — "the models a
839
+ * function touches are collected at push as a reviewable manifest, not an
840
+ * authorization".
841
+ *
842
+ * It is HONEST-CODE evidence and the design doc says so: a hostile bundle can
843
+ * register whatever it likes, because the collector runs the tenant's own
844
+ * code. Nothing security-relevant at runtime reads it — parameter injection
845
+ * and cache verification happen in the platform-owned SDK inside the isolate,
846
+ * and the invocation gate remains the adversarial boundary.
847
+ *
848
+ * ── Why the grammar is here ──────────────────────────────────────────────
849
+ *
850
+ * Same reason as `function-grants.ts`: the CLI validates at push preflight so
851
+ * an author sees the error against their own tree, and the server validates
852
+ * authoritatively because the raw admin API exists. Two enforcement points,
853
+ * one rule, in the dependency-free tree the CLI vendors.
854
+ */
855
+ /**
856
+ * The manifest encoding, versioned with the envelope that carries it.
857
+ *
858
+ * Version 2 (#3279 behavior 10) adds what a function TOUCHES beside what it
859
+ * registers: the deduplicated `models` its code names and the `families` of
860
+ * `ctx.api` and the ctx helpers it reaches, collected by a static scan of the
861
+ * built bundle, plus a `dynamicModels` marker for a model name the scan
862
+ * could not resolve — distinct from an empty list, which means "names none".
863
+ * A version-1 manifest still parses: it records registrations only.
864
+ */
865
+ export declare const FUNCTION_MANIFEST_SCHEMA_VERSION = 2;
866
+ export declare const FUNCTION_MANIFEST_SCHEMA_VERSIONS: readonly [1, 2];
867
+ /** Bounds, so a manifest cannot be a way to store an unbounded blob. */
868
+ export declare const MAX_MANIFEST_QUERIES = 200;
869
+ export declare const MAX_MANIFEST_NAME_LENGTH = 120;
870
+ export declare const MAX_MANIFEST_MODELS = 200;
871
+ export declare const MAX_MANIFEST_FAMILIES = 40;
872
+ export interface ManifestParam {
873
+ type?: string;
874
+ caller?: boolean;
875
+ optional?: boolean;
876
+ default?: unknown;
877
+ }
878
+ export interface ManifestQuery {
879
+ name: string;
880
+ kind: "query" | "mutation";
881
+ models: string[];
882
+ params: Record<string, ManifestParam>;
883
+ cache: {
884
+ ttlMs: number;
885
+ } | null;
886
+ /** True when a `$caller` binding scopes this registration. */
887
+ callerScoped: boolean;
888
+ }
889
+ export interface FunctionManifest {
890
+ schemaVersion: number;
891
+ queries: ManifestQuery[];
892
+ /**
893
+ * Every model name the bundle names, deduplicated and sorted: registration
894
+ * declarations, literal `.model("…")` calls, and literal `modelName`/`model`
895
+ * arguments of the direct records and documents calls (#3279). Empty for a
896
+ * version-1 manifest, and for a function that names none.
897
+ */
898
+ models: string[];
899
+ /** Every `ctx.api.<family>` and ctx-helper family the bundle reaches. */
900
+ families: string[];
901
+ /**
902
+ * The scan met a model name it could not resolve — a computed
903
+ * `modelName`, a `.model(variable)`. Says "and possibly more", which an
904
+ * empty `models` list does not.
905
+ */
906
+ dynamicModels: boolean;
907
+ }
908
+ export interface ParsedManifest {
909
+ ok: boolean;
910
+ manifest: FunctionManifest | null;
911
+ errors: string[];
912
+ }
913
+ /**
914
+ * Validate a manifest's grammar and normalize it.
915
+ *
916
+ * Deliberately strict about SHAPE and silent about meaning: whether the models
917
+ * exist, whether the queries are the ones the sandbox will really register,
918
+ * and whether the author meant any of it are questions this cannot answer.
919
+ */
920
+ export declare function parseFunctionManifest(value: unknown): ParsedManifest;
581
921
  export declare const WORKFLOW_SURFACE: ConfigObjectSurface;
582
922
  export declare const PROMPT_SURFACE: ConfigObjectSurface;
583
923
  export declare const INTEGRATION_SURFACE: ConfigObjectSurface;