@naturali/cli 0.124.0 → 0.126.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 (2) hide show
  1. package/dist/index.mjs +233 -13
  2. package/package.json +2 -2
package/dist/index.mjs CHANGED
@@ -14,7 +14,7 @@ var __exportAll = (all, no_symbols) => {
14
14
  };
15
15
  //#endregion
16
16
  //#region package.json
17
- var version = "0.124.0";
17
+ var version = "0.126.0";
18
18
  //#endregion
19
19
  //#region ../sdk/src/generated/core/bodySerializer.gen.ts
20
20
  const serializeFormDataPair = (data, key, value) => {
@@ -756,6 +756,9 @@ var Actors = class {
756
756
  var Channels = class {
757
757
  /**
758
758
  * List addresses
759
+ *
760
+ * Every identifier this project has seen. An address appears the first time a message arrives from it, so this is what naturali has observed rather than a roster you maintain — most rows carry no `action` of their own and defer to the route table.
761
+ *
759
762
  */
760
763
  static listAddresses(options) {
761
764
  return (options.client ?? client).get({
@@ -777,6 +780,9 @@ var Channels = class {
777
780
  }
778
781
  /**
779
782
  * Get an address
783
+ *
784
+ * Reads one identifier's own action, if it has one. An identifier naturali has never seen is a `404`; to set an action without knowing whether it exists, use [`PUT /v1/projects/{project_id}/addresses/{identifier}`](/docs/api/addresses/set-address-action), which upserts.
785
+ *
780
786
  */
781
787
  static getAddress(options) {
782
788
  return (options.client ?? client).get({
@@ -826,6 +832,9 @@ var Channels = class {
826
832
  }
827
833
  /**
828
834
  * List a channel's routes
835
+ *
836
+ * One channel's routes, newest first, `disabled` ones included — only `active` routes take part in resolution. For every route in the project in one read, use [`GET /v1/projects/{project_id}/channel-routes`](/docs/api/channel-routes/list-project-channel-routes).
837
+ *
829
838
  */
830
839
  static listChannelRoutes(options) {
831
840
  return (options.client ?? client).get({
@@ -851,6 +860,9 @@ var Channels = class {
851
860
  }
852
861
  /**
853
862
  * Delete a route
863
+ *
864
+ * Conversations opened under this route keep its id and stay where they are; the next inbound resolves to the next most specific route, or the channel default, and opens a new conversation there. To stop a route from matching while keeping it readable, `PATCH` it to `status: disabled` instead.
865
+ *
854
866
  */
855
867
  static deleteChannelRoute(options) {
856
868
  return (options.client ?? client).delete({
@@ -860,6 +872,9 @@ var Channels = class {
860
872
  }
861
873
  /**
862
874
  * Get a route
875
+ *
876
+ * A route id is only meaningful inside its own channel: the same id under another `channel_id` is a `404`. A conversation's `route_id` may instead be one of the two sentinels for the address's own action and the channel default — those name no route and are not readable here.
877
+ *
863
878
  */
864
879
  static getChannelRoute(options) {
865
880
  return (options.client ?? client).get({
@@ -948,6 +963,9 @@ var Channels = class {
948
963
  }
949
964
  /**
950
965
  * Get a channel
966
+ *
967
+ * The channel's state, its transport modes and its default action. The access token is never returned — `has_credential` is all a read says about it.
968
+ *
951
969
  */
952
970
  static getChannel(options) {
953
971
  return (options.client ?? client).get({
@@ -1002,6 +1020,9 @@ var Channels = class {
1002
1020
  }
1003
1021
  /**
1004
1022
  * Get a conversation
1023
+ *
1024
+ * Where the conversation points: the address it belongs to, the route (or sentinel) whose action opened it, and the runtime session it maps 1:1 to. The messages are not here — read them with [`GET /v1/projects/{project_id}/channels/{channel_id}/conversations/{conversation_id}/messages`](/docs/api/channels/list-channel-conversation-messages).
1025
+ *
1005
1026
  */
1006
1027
  static getChannelConversation(options) {
1007
1028
  return (options.client ?? client).get({
@@ -3234,6 +3255,9 @@ var Models = class {
3234
3255
  }
3235
3256
  /**
3236
3257
  * Get a model
3258
+ *
3259
+ * `{model}` is naturali's own name for the model, the same value [`GET /v1/models`](/docs/api/models/list-models) returns — a vendor's invocation string is a `404`. A `deprecated` model still reads here, so a project already generating on one can see what happened to it.
3260
+ *
3237
3261
  */
3238
3262
  static getModel(options) {
3239
3263
  return (options.client ?? client).get({
@@ -3641,6 +3665,34 @@ var Projects = class {
3641
3665
  ...options
3642
3666
  });
3643
3667
  }
3668
+ /**
3669
+ * List project usage events
3670
+ *
3671
+ * The rows a rollup summed — one per metered occurrence, most recent first. Takes the same narrowings [the meter](/docs/api/projects/get-project-usage) does, so a query that produced a bucket answers here unchanged and reads back what went into it. This is the audit and reconciliation view: what was measured, when, against which agent, session, actor and provider, and what each component was priced at.
3672
+ *
3673
+ * An id naming nothing in this project yields an empty page rather than dropping the filter, so a mistyped narrowing can never widen the list past what was asked for.
3674
+ *
3675
+ */
3676
+ static listProjectUsageEvents(options) {
3677
+ return (options.client ?? client).get({
3678
+ url: "/v1/projects/{project_id}/usage/events",
3679
+ ...options
3680
+ });
3681
+ }
3682
+ /**
3683
+ * Get a generation or orchestration-run billing receipt
3684
+ *
3685
+ * What one occurrence was billed, line by line: per-event line items with their measured components and unit prices, a per-meter-type split, and the totals. Pass generation_id for one generation, or orchestration_run_id for a receipt summed across every event the run metered. Exactly one of the two is required.
3686
+ *
3687
+ * This is the itemisation behind a single number — where [the meter](/docs/api/projects/get-project-usage) says a window cost $12.40, a receipt says which components of which call made up one occurrence of it. On an orchestration-run receipt every line carries node_id, so grouping by it gives the per-node cost the total hides; a retried node contributes one line per attempt, which is the intended reading for spend.
3688
+ *
3689
+ */
3690
+ static getProjectUsageReceipt(options) {
3691
+ return (options.client ?? client).get({
3692
+ url: "/v1/projects/{project_id}/usage/receipt",
3693
+ ...options
3694
+ });
3695
+ }
3644
3696
  };
3645
3697
  var Quotas = class {
3646
3698
  /**
@@ -4375,9 +4427,11 @@ var Users = class {
4375
4427
  /**
4376
4428
  * Get the current account's billing standing
4377
4429
  *
4378
- * The plan the account is on, how long its projects may keep content, and the credit it has left — the figures the platform already enforces against, readable by the account they are enforced against.
4430
+ * The plan the account is on, how long its projects may keep content, how much indexed storage it is holding, and the credit it has left — the figures the platform already enforces against, readable by the account they are enforced against.
4431
+ *
4432
+ * A managed-model generation is refused with `402 insufficient_credit` while `credit_balance_usd` is negative, and a feature or a resource count outside the plan is refused with `403`, as is a retention window wider than `retention_days` or an ingest past `storage_limit_gb`. Every refusal names what is missing; this is where the numbers behind them are read.
4379
4433
  *
4380
- * A managed-model generation is refused with `402 insufficient_credit` while `credit_balance_usd` is negative, and a feature or a resource count outside the plan is refused with `403`, as is a retention window wider than `retention_days`. Every refusal names what is missing; this is where the numbers behind them are read.
4434
+ * Every figure here is a local read, which is what keeps this route cheap enough to poll — unlike `GET /v1/users/me/usage`, which asks the meter once per project.
4381
4435
  *
4382
4436
  * Answers for the caller's own account only, and always the account the credential resolves to — an API key answers for the user that minted it. The plan gating a *project* is that project's billing owner's, so a member of someone else's project reads their own rung here, not that project's.
4383
4437
  *
@@ -4455,6 +4509,9 @@ var Webhooks = class {
4455
4509
  }
4456
4510
  /**
4457
4511
  * Get a webhook
4512
+ *
4513
+ * The endpoint, the events it is subscribed to and whether deliveries are attempted. The signing secret is not returned: it is shown once by [`POST /v1/projects/{project_id}/webhooks`](/docs/api/webhooks/create-webhook) and again by [`POST /v1/projects/{project_id}/webhooks/{webhook_id}:rotate-secret`](/docs/api/webhooks/rotate-webhook-secret).
4514
+ *
4458
4515
  */
4459
4516
  static getWebhook(options) {
4460
4517
  return (options.client ?? client).get({
@@ -5588,7 +5645,7 @@ const routes = {
5588
5645
  "list-addresses": {
5589
5646
  serviceClass: "Channels",
5590
5647
  operationId: "listAddresses",
5591
- description: "List addresses",
5648
+ description: "Every identifier this project has seen. An address appears the first time a message arrives from it, so this is what naturali has observed rather than a roster you maintain — most rows carry no `action` of their own and defer to the route table.",
5592
5649
  moduleDocsUrl: "https://docs.naturali.ai/docs/modules/addresses",
5593
5650
  httpMethod: "get",
5594
5651
  pathParams: ["project_id"],
@@ -5620,7 +5677,7 @@ const routes = {
5620
5677
  "get-address": {
5621
5678
  serviceClass: "Channels",
5622
5679
  operationId: "getAddress",
5623
- description: "Get an address",
5680
+ description: "Reads one identifier's own action, if it has one. An identifier naturali has never seen is a `404`; to set an action without knowing whether it exists, use [`PUT /v1/projects/{project_id}/addresses/{identifier}`](/docs/api/addresses/set-address-action), which upserts.",
5624
5681
  moduleDocsUrl: "https://docs.naturali.ai/docs/modules/addresses",
5625
5682
  httpMethod: "get",
5626
5683
  pathParams: ["project_id", "identifier"],
@@ -7966,7 +8023,7 @@ const routes = {
7966
8023
  "list-channel-routes": {
7967
8024
  serviceClass: "Channels",
7968
8025
  operationId: "listChannelRoutes",
7969
- description: "List a channel's routes",
8026
+ description: "One channel's routes, newest first, `disabled` ones included — only `active` routes take part in resolution. For every route in the project in one read, use [`GET /v1/projects/{project_id}/channel-routes`](/docs/api/channel-routes/list-project-channel-routes).",
7970
8027
  moduleDocsUrl: "https://docs.naturali.ai/docs/modules/channel-routes",
7971
8028
  httpMethod: "get",
7972
8029
  pathParams: ["project_id", "channel_id"],
@@ -8100,7 +8157,7 @@ const routes = {
8100
8157
  "get-channel-route": {
8101
8158
  serviceClass: "Channels",
8102
8159
  operationId: "getChannelRoute",
8103
- description: "Get a route",
8160
+ description: "A route id is only meaningful inside its own channel: the same id under another `channel_id` is a `404`. A conversation's `route_id` may instead be one of the two sentinels for the address's own action and the channel default — those name no route and are not readable here.",
8104
8161
  moduleDocsUrl: "https://docs.naturali.ai/docs/modules/channel-routes",
8105
8162
  httpMethod: "get",
8106
8163
  pathParams: [
@@ -8242,7 +8299,7 @@ const routes = {
8242
8299
  "delete-channel-route": {
8243
8300
  serviceClass: "Channels",
8244
8301
  operationId: "deleteChannelRoute",
8245
- description: "Delete a route",
8302
+ description: "Conversations opened under this route keep its id and stay where they are; the next inbound resolves to the next most specific route, or the channel default, and opens a new conversation there. To stop a route from matching while keeping it readable, `PATCH` it to `status: disabled` instead.",
8246
8303
  moduleDocsUrl: "https://docs.naturali.ai/docs/modules/channel-routes",
8247
8304
  httpMethod: "delete",
8248
8305
  pathParams: [
@@ -8421,7 +8478,7 @@ const routes = {
8421
8478
  "get-channel": {
8422
8479
  serviceClass: "Channels",
8423
8480
  operationId: "getChannel",
8424
- description: "Get a channel",
8481
+ description: "The channel's state, its transport modes and its default action. The access token is never returned — `has_credential` is all a read says about it.",
8425
8482
  moduleDocsUrl: "https://docs.naturali.ai/docs/modules/channels",
8426
8483
  httpMethod: "get",
8427
8484
  pathParams: ["project_id", "channel_id"],
@@ -8621,7 +8678,7 @@ const routes = {
8621
8678
  "get-channel-conversation": {
8622
8679
  serviceClass: "Channels",
8623
8680
  operationId: "getChannelConversation",
8624
- description: "Get a conversation",
8681
+ description: "Where the conversation points: the address it belongs to, the route (or sentinel) whose action opened it, and the runtime session it maps 1:1 to. The messages are not here — read them with [`GET /v1/projects/{project_id}/channels/{channel_id}/conversations/{conversation_id}/messages`](/docs/api/channels/list-channel-conversation-messages).",
8625
8682
  moduleDocsUrl: "https://docs.naturali.ai/docs/modules/channels",
8626
8683
  httpMethod: "get",
8627
8684
  pathParams: [
@@ -12695,7 +12752,7 @@ const routes = {
12695
12752
  "get-model": {
12696
12753
  serviceClass: "Models",
12697
12754
  operationId: "getModel",
12698
- description: "Get a model",
12755
+ description: "`{model}` is naturali's own name for the model, the same value [`GET /v1/models`](/docs/api/models/list-models) returns — a vendor's invocation string is a `404`. A `deprecated` model still reads here, so a project already generating on one can see what happened to it.",
12699
12756
  moduleDocsUrl: "https://docs.naturali.ai/docs/modules/models",
12700
12757
  httpMethod: "get",
12701
12758
  pathParams: ["model"],
@@ -13742,6 +13799,169 @@ const routes = {
13742
13799
  }
13743
13800
  ]
13744
13801
  },
13802
+ "list-project-usage-events": {
13803
+ serviceClass: "Projects",
13804
+ operationId: "listProjectUsageEvents",
13805
+ description: "The rows a rollup summed — one per metered occurrence, most recent first. Takes the same narrowings [the meter](/docs/api/projects/get-project-usage) does, so a query that produced a bucket answers here unchanged and reads back what went into it. This is the audit and reconciliation view: what was measured, when, against which agent, session, actor and provider, and what each component was priced at. An id naming nothing in this project yields an empty page rather than dropping the filter, so a mistyped narrowing can never widen the list past what was asked for.",
13806
+ moduleDocsUrl: "https://docs.naturali.ai/docs/modules/projects",
13807
+ httpMethod: "get",
13808
+ pathParams: ["project_id"],
13809
+ queryParams: [
13810
+ "meter_type",
13811
+ "session_id",
13812
+ "actor_id",
13813
+ "agent_id",
13814
+ "ai_provider_id",
13815
+ "orchestration_run_id",
13816
+ "orchestration_id",
13817
+ "generation_id",
13818
+ "trace_id",
13819
+ "source",
13820
+ "trigger_id",
13821
+ "action_id",
13822
+ "limit",
13823
+ "offset"
13824
+ ],
13825
+ flags: [
13826
+ {
13827
+ "name": "project_id",
13828
+ "description": "Project public ID (proj_ prefix).",
13829
+ "required": true,
13830
+ "type": "string",
13831
+ "in": "path"
13832
+ },
13833
+ {
13834
+ "name": "meter_type",
13835
+ "description": "Narrow the rollup to one meter type (llm_tokens, compute_execution, api_request, storage). Omit to include every meter. Useful with group_by=model, whose dimension otherwise mixes model ids with platform SKUs. An unrecognized value yields an empty rollup, not an error.\n",
13836
+ "required": false,
13837
+ "type": "string",
13838
+ "in": "query"
13839
+ },
13840
+ {
13841
+ "name": "session_id",
13842
+ "description": "Narrow the whole rollup — every bucket and the top-level totals alike — to one session's traffic. Combines with group_by: group_by=day&session_id=... is one conversation's spend per day, group_by=model the same spend split by model. This is the figure behind the usage roll-up a single session read carries, broken down. An id naming no session in this project yields an empty rollup, never the project total.\n",
13843
+ "required": false,
13844
+ "type": "string",
13845
+ "in": "query"
13846
+ },
13847
+ {
13848
+ "name": "actor_id",
13849
+ "description": "The same narrowing, for one end user across every session they appear in — what a customer re-billing their own users charges each of them for. An id naming no actor in this project yields an empty rollup, never the project total.\n",
13850
+ "required": false,
13851
+ "type": "string",
13852
+ "in": "query"
13853
+ },
13854
+ {
13855
+ "name": "agent_id",
13856
+ "description": "Narrow to one agent's traffic, across every session, run and trigger that dispatched it.\n",
13857
+ "required": false,
13858
+ "type": "string",
13859
+ "in": "query"
13860
+ },
13861
+ {
13862
+ "name": "ai_provider_id",
13863
+ "description": "Narrow to the spend billed against one provider record — a routed generation's serving target, or the agent's pinned provider.\n",
13864
+ "required": false,
13865
+ "type": "string",
13866
+ "in": "query"
13867
+ },
13868
+ {
13869
+ "name": "orchestration_run_id",
13870
+ "description": "Narrow to the events one orchestration run metered.",
13871
+ "required": false,
13872
+ "type": "string",
13873
+ "in": "query"
13874
+ },
13875
+ {
13876
+ "name": "orchestration_id",
13877
+ "description": "Narrow to the runs of one orchestration — the ones it started itself, never the subtree a loop or sub-orchestration node started under it, which is metered against the child orchestration where it was incurred. Additive: summed across a project's orchestrations the figures reach the project total exactly once.\n",
13878
+ "required": false,
13879
+ "type": "string",
13880
+ "in": "query"
13881
+ },
13882
+ {
13883
+ "name": "generation_id",
13884
+ "description": "Narrow to one generation's events. A generation writes more than one when it meters several dimensions, such as tokens and compute.\n",
13885
+ "required": false,
13886
+ "type": "string",
13887
+ "in": "query"
13888
+ },
13889
+ {
13890
+ "name": "trace_id",
13891
+ "description": "Narrow to the events recorded under one trace.",
13892
+ "required": false,
13893
+ "type": "string",
13894
+ "in": "query"
13895
+ },
13896
+ {
13897
+ "name": "source",
13898
+ "description": "Narrow by what the spend was incurred for — eval and eval_judge are verification spend. Ordinary traffic carries no source, so it cannot be selected by this filter; omit the filter for everything.\n",
13899
+ "required": false,
13900
+ "type": "string",
13901
+ "in": "query"
13902
+ },
13903
+ {
13904
+ "name": "trigger_id",
13905
+ "description": "Narrow to the spend one trigger initiated. Matched as recorded rather than resolved, so it still selects the spend of a trigger that has since been deleted.\n",
13906
+ "required": false,
13907
+ "type": "string",
13908
+ "in": "query"
13909
+ },
13910
+ {
13911
+ "name": "action_id",
13912
+ "description": "Narrow to one caller-supplied action label, for per-action spend. Matched as recorded, like trigger_id.\n",
13913
+ "required": false,
13914
+ "type": "string",
13915
+ "in": "query"
13916
+ },
13917
+ {
13918
+ "name": "limit",
13919
+ "description": "Maximum number of events to return. A value above 100 is refused rather than clamped, so a caller paging by their own stride never silently skips a row.\n",
13920
+ "required": false,
13921
+ "type": "integer",
13922
+ "in": "query"
13923
+ },
13924
+ {
13925
+ "name": "offset",
13926
+ "description": "Number of events to skip.",
13927
+ "required": false,
13928
+ "type": "integer",
13929
+ "in": "query"
13930
+ }
13931
+ ]
13932
+ },
13933
+ "get-project-usage-receipt": {
13934
+ serviceClass: "Projects",
13935
+ operationId: "getProjectUsageReceipt",
13936
+ description: "What one occurrence was billed, line by line: per-event line items with their measured components and unit prices, a per-meter-type split, and the totals. Pass generation_id for one generation, or orchestration_run_id for a receipt summed across every event the run metered. Exactly one of the two is required. This is the itemisation behind a single number — where [the meter](/docs/api/projects/get-project-usage) says a window cost $12.40, a receipt says which components of which call made up one occurrence of it. On an orchestration-run receipt every line carries node_id, so grouping by it gives the per-node cost the total hides; a retried node contributes one line per attempt, which is the intended reading for spend.",
13937
+ moduleDocsUrl: "https://docs.naturali.ai/docs/modules/projects",
13938
+ httpMethod: "get",
13939
+ pathParams: ["project_id"],
13940
+ queryParams: ["generation_id", "orchestration_run_id"],
13941
+ flags: [
13942
+ {
13943
+ "name": "project_id",
13944
+ "description": "Project public ID (proj_ prefix).",
13945
+ "required": true,
13946
+ "type": "string",
13947
+ "in": "path"
13948
+ },
13949
+ {
13950
+ "name": "generation_id",
13951
+ "description": "Generation public ID. Mutually exclusive with orchestration_run_id.\n",
13952
+ "required": false,
13953
+ "type": "string",
13954
+ "in": "query"
13955
+ },
13956
+ {
13957
+ "name": "orchestration_run_id",
13958
+ "description": "Orchestration run public ID. Returns the receipt summed across every generation the run metered. Mutually exclusive with generation_id.\n",
13959
+ "required": false,
13960
+ "type": "string",
13961
+ "in": "query"
13962
+ }
13963
+ ]
13964
+ },
13745
13965
  "list-quotas": {
13746
13966
  serviceClass: "Quotas",
13747
13967
  operationId: "listQuotas",
@@ -15899,7 +16119,7 @@ const routes = {
15899
16119
  "get-current-user-billing": {
15900
16120
  serviceClass: "Users",
15901
16121
  operationId: "getCurrentUserBilling",
15902
- description: "The plan the account is on, how long its projects may keep content, and the credit it has left — the figures the platform already enforces against, readable by the account they are enforced against. A managed-model generation is refused with `402 insufficient_credit` while `credit_balance_usd` is negative, and a feature or a resource count outside the plan is refused with `403`, as is a retention window wider than `retention_days`. Every refusal names what is missing; this is where the numbers behind them are read. Answers for the caller's own account only, and always the account the credential resolves to — an API key answers for the user that minted it. The plan gating a *project* is that project's billing owner's, so a member of someone else's project reads their own rung here, not that project's.",
16122
+ description: "The plan the account is on, how long its projects may keep content, how much indexed storage it is holding, and the credit it has left — the figures the platform already enforces against, readable by the account they are enforced against. A managed-model generation is refused with `402 insufficient_credit` while `credit_balance_usd` is negative, and a feature or a resource count outside the plan is refused with `403`, as is a retention window wider than `retention_days` or an ingest past `storage_limit_gb`. Every refusal names what is missing; this is where the numbers behind them are read. Every figure here is a local read, which is what keeps this route cheap enough to poll — unlike `GET /v1/users/me/usage`, which asks the meter once per project. Answers for the caller's own account only, and always the account the credential resolves to — an API key answers for the user that minted it. The plan gating a *project* is that project's billing owner's, so a member of someone else's project reads their own rung here, not that project's.",
15903
16123
  moduleDocsUrl: "https://docs.naturali.ai/docs/modules/users",
15904
16124
  httpMethod: "get",
15905
16125
  pathParams: [],
@@ -15997,7 +16217,7 @@ const routes = {
15997
16217
  "get-webhook": {
15998
16218
  serviceClass: "Webhooks",
15999
16219
  operationId: "getWebhook",
16000
- description: "Get a webhook",
16220
+ description: "The endpoint, the events it is subscribed to and whether deliveries are attempted. The signing secret is not returned: it is shown once by [`POST /v1/projects/{project_id}/webhooks`](/docs/api/webhooks/create-webhook) and again by [`POST /v1/projects/{project_id}/webhooks/{webhook_id}:rotate-secret`](/docs/api/webhooks/rotate-webhook-secret).",
16001
16221
  moduleDocsUrl: "https://docs.naturali.ai/docs/modules/webhooks",
16002
16222
  httpMethod: "get",
16003
16223
  pathParams: ["project_id", "webhook_id"],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@naturali/cli",
3
- "version": "0.124.0",
3
+ "version": "0.126.0",
4
4
  "description": "Command-line interface for the naturali.ai API, generated from its OpenAPI specs",
5
5
  "type": "module",
6
6
  "bin": {
@@ -30,7 +30,7 @@
30
30
  "tsx": "^4.23.1",
31
31
  "typescript": "~6.0.3",
32
32
  "vitest": "^4.1.10",
33
- "@naturali/sdk": "0.124.0"
33
+ "@naturali/sdk": "0.126.0"
34
34
  },
35
35
  "scripts": {
36
36
  "generate": "tsx scripts/generate.ts",