@proveanything/smartlinks 2.0.26 → 2.0.29

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.
package/docs/ai.md CHANGED
@@ -324,15 +324,40 @@ in `input`.
324
324
  | `image.searchStock` | Search real stock photos (Unsplash). |
325
325
  | `image.transform` | Resize / crop / rotate / grayscale / format-convert / compress → hosted URL. |
326
326
  | `pdf.create` | Render HTML → PDF → hosted URL. |
327
- | `pdf.fill` | Fill an AcroForm PDF's fields → hosted URL. |
328
- | `pdf.merge` | Merge several PDFs into one → hosted URL. |
327
+ | `pdf.fill` | Fill an AcroForm PDF's fields (`{ field: value }`) → hosted URL. |
328
+ | `pdf.merge` | Merge several PDFs into one, in order → hosted URL. |
329
+ | `pdf.inspect` | Cheap, no-AI introspection: page count/sizes, which pages have a real text layer, raster present, and a routing hint (`text` vs `vision`). |
330
+ | `pdf.render` | Rasterize one page to a PNG at a chosen DPI → hosted image URL (feed to vision, or screenshot a page). |
331
+ | `pdf.extract` | PDF → typed JSON in one call (schema and/or prompt). Auto-routes text vs vision. Optional per-field `confidence`/`source` (`includeConfidence`) and `bbox` (`includeBoxes`) in `fieldsMeta`. |
332
+ | `pdf.decodeBarcodes` | Deterministically decode barcodes/QR on a page (WASM, no AI) → value + symbology + page + bbox + confidence. Use this for barcode digits, never vision. |
333
+ | `pdf.inspectGraphics` | Prepress inspection: per-page path/image/outlined-text counts + colour spaces, plus named SPOT colours (e.g. "PANTONE 871 C"). No AI. |
329
334
  | `http.request` | SSRF-guarded outbound HTTP(S) to a public URL (call a REST API). |
330
335
  | `translate` | Translate text into one or more languages (generic, model-based). |
331
336
 
337
+ **Working with PDFs.** The PDF tools split into *read/analyse* and *produce*:
338
+
339
+ - **Read a whole PDF as text** → `document.read` (Firecrawl; good for prose/decks).
340
+ - **Turn a PDF into structured fields** → `pdf.extract` (give it a JSON schema and/or a prompt; it
341
+ returns typed JSON). It routes itself, but you can drive the route yourself: call `pdf.inspect`
342
+ first (deterministic, no AI) to see whether each page has a real text layer, then `pdf.extract`
343
+ (cheap text path) or `pdf.render` → `image.describe`/vision for curve-only or raster artwork.
344
+ - **Zoom in on small print** (INCI/allergen lists) → `pdf.render` at a high DPI (e.g. 300), then read
345
+ the PNG with vision.
346
+ - **Barcodes / QR** → `pdf.decodeBarcodes` (deterministic WASM decode) — never trust vision for barcode
347
+ digits; it hallucinates them.
348
+ - **Prepress / print QA** (spot colours, colour spaces, vector vs raster) → `pdf.inspectGraphics`.
349
+ - **A review UI that flags guessed fields** → `pdf.extract` with `includeConfidence` (per-field
350
+ confidence + source) and `includeBoxes` (per-field bbox on text-native pages) in `fieldsMeta`.
351
+ - **Produce a PDF** → `pdf.create` (HTML → PDF), `pdf.fill` (populate an AcroForm's fields),
352
+ `pdf.merge` (combine several). These return a hosted `hostedUrl`.
353
+
354
+ Every tool is also directly callable without the model loop via `ai.tools.run(collectionId, name,
355
+ args)` — e.g. render a page or extract fields straight from a UI, no agent round-trip.
356
+
332
357
  Discover tools two ways:
333
358
  - **Design time (typed):** import `BUILTIN_AI_TOOLS`, `AI_TOOL_NAMES`, and the per-tool arg types
334
- (`WebSearchArgs`, `DataExtractArgs`, …) from the SDK. This is the core set — stable, versioned,
335
- documented here.
359
+ (`WebSearchArgs`, `DataExtractArgs`, `PdfExtractArgs`, …) from the SDK. This is the core set —
360
+ stable, versioned, documented here.
336
361
  - **Runtime (live):** `await ai.catalog(collectionId)` returns the registry as the server sees it,
337
362
  including any future app-contributed tools. The built-in set above is always present.
338
363
 
@@ -271,6 +271,96 @@ name (a first-party builtin still wins). Always prefer an appId.
271
271
 
272
272
  ---
273
273
 
274
+ ## Exposing a function to the AI agent
275
+
276
+ An `http` function can be offered to the AI agent as a **callable tool**, alongside the built-in
277
+ tools. The model calls it, the server runs it, and the result is fed back into the loop. Opt in from
278
+ the manifest with an `agent` block (full reference: [agent-tools.md](agent-tools.md)):
279
+
280
+ ```jsonc
281
+ {
282
+ "name": "getLoyaltyBalance",
283
+ "trigger": { "type": "http" },
284
+ "visibility": "admin",
285
+ "authority": "caller",
286
+ "capabilities": ["sl:records:read"],
287
+ "agent": {
288
+ "tool": true,
289
+ "title": "Loyalty balance",
290
+ "description": "Look up a member's current loyalty points balance.",
291
+ "input": {
292
+ "type": "object",
293
+ "properties": { "memberId": { "type": "string" } },
294
+ "required": ["memberId"]
295
+ },
296
+ "approval": "auto" // 'require' = human confirms before each call
297
+ }
298
+ }
299
+ ```
300
+
301
+ The agent becomes **just another caller surface** — your function's `visibility`, `authority`, and
302
+ `capabilities` are enforced exactly as on the http route. Nothing new is granted. The agent's tool
303
+ arguments arrive as the function's request `body`, and whatever you return becomes the tool result the
304
+ model sees. `approval: "require"` tools are held back from the autonomous server-side loop until the
305
+ human-approval UX ships.
306
+
307
+ Include your app's functions in an agent run:
308
+
309
+ ```ts
310
+ // Agentic Responses:
311
+ await SL.ai.chat.responses.create(collectionId, {
312
+ model: 'balanced', input: 'What is member 42's balance?',
313
+ server_tools: true, // built-in tools
314
+ app_functions: { appId: 'my-loyalty-app' }, // + this app's ai.tool functions
315
+ })
316
+
317
+ // Or the one-shot agent loop:
318
+ await SL.ai.agent.run(collectionId, {
319
+ input: '…', appFunctions: { appId: 'my-loyalty-app' },
320
+ })
321
+ ```
322
+
323
+ On the **consumer surface**, a `visibility: "public"` function reaches a public assistant via the
324
+ public agent loop — the caller runs as the signed-in consumer (`'owner'`, send the authKit bearer) or
325
+ anonymous (`'public'`):
326
+
327
+ ```ts
328
+ await SL.ai.publicClient.agentRun(collectionId, {
329
+ input: '…',
330
+ appFunctions: { appId: 'my-app' }, // this app's public agent tools
331
+ server_tools: ['web.search'], // built-ins are an explicit allowlist on the public surface
332
+ })
333
+ ```
334
+
335
+ `channel` (default `'stable'`, pass `'dev'` to test a dev build) and `only: string[]` narrow which
336
+ functions are exposed. Only `http` functions with `agent.tool: true` are eligible; `event`/`cron`
337
+ functions never are. A built-in tool of the same name wins the clash.
338
+
339
+ ### One unified toolbelt
340
+
341
+ Rather than juggling `server_tools` + `app_functions`, declare everything in one `toolbelt` — built-in
342
+ tools, one **or several** apps' functions, and (reserved, staged) front-end client tools:
343
+
344
+ ```ts
345
+ await SL.ai.chat.responses.create(collectionId, {
346
+ input: '…',
347
+ toolbelt: {
348
+ builtins: ['web.search', 'document.read'], // true = all, [names] = subset, omit = none
349
+ appFunctions: [{ appId: 'loyalty' }, { appId: 'catalog' }], // several apps at once
350
+ // clientTools: [ … ] // reserved — the client-tool bridge is staged
351
+ },
352
+ })
353
+ ```
354
+
355
+ The same `toolbelt` works on `ai.agent.run` and `ai.publicClient.agentRun` (on the public surface
356
+ `builtins` is an explicit allowlist — `true` is treated as none). Precedence on a name clash: a
357
+ built-in wins, then earlier `appFunctions` sources win over later ones.
358
+
359
+ > Directly (no model): every function is also callable deterministically — `SL.functions.call` /
360
+ > `callAdmin` (above), the same way the built-in tools are callable via `SL.ai.tools.run`.
361
+
362
+ ---
363
+
274
364
  ## Runtime — what your function can use
275
365
 
276
366
  Your function runs in a **web-standard sandbox** (think Cloudflare Workers / Deno), **not
@@ -310,6 +400,12 @@ Prefer the platform primitives above over a dependency; when you do need one, pi
310
400
  | Schema validation of inputs | no | `zod` |
311
401
  | JWT (sign/verify for a third-party API) | Web Crypto can, verbosely | `jose` |
312
402
  | Hash / HMAC / encrypt | **native** — `crypto.subtle` | — |
403
+ | PDF **text** extraction (cheap first-pass, no AI) | no | `unpdf` — a serverless/WASM pdf.js build with no Node deps; `import { extractText } from 'unpdf'`. Text only. |
404
+
405
+ > **PDFs in a server function:** for a cheap text-layer check use `unpdf` (edge-safe, WASM). For
406
+ > anything heavier — rendering pages, vision extraction, **barcode/QR decode**, or prepress/spot-colour
407
+ > inspection — call the platform tools `pdf.render` / `pdf.extract` / `pdf.decodeBarcodes` /
408
+ > `pdf.inspectGraphics` via `ai.tools.run`; those run in the full platform runtime, not the sandbox.
313
409
 
314
410
  **The common actions, and how to do each:**
315
411
 
package/openapi.yaml CHANGED
@@ -16,6 +16,8 @@ tags:
16
16
  description: Chat completion generation.
17
17
  - name: agent
18
18
  description: Agent orchestration and tool-calling.
19
+ - name: tools
20
+ description: tools API
19
21
  - name: skills
20
22
  description: Reusable agent skills.
21
23
  - name: models
@@ -1239,6 +1241,45 @@ paths:
1239
1241
  description: Unauthorized
1240
1242
  404:
1241
1243
  description: Not found
1244
+ /admin/collection/{collectionId}/ai/tools/{name}/run:
1245
+ post:
1246
+ tags:
1247
+ - tools
1248
+ summary: tools.run
1249
+ operationId: tools_run
1250
+ security:
1251
+ - bearerAuth: []
1252
+ parameters:
1253
+ - name: collectionId
1254
+ in: path
1255
+ required: true
1256
+ schema:
1257
+ type: string
1258
+ - name: name
1259
+ in: path
1260
+ required: true
1261
+ schema:
1262
+ type: string
1263
+ responses:
1264
+ 200:
1265
+ description: Success
1266
+ content:
1267
+ application/json:
1268
+ schema:
1269
+ $ref: "#/components/schemas/ToolRunResult"
1270
+ 400:
1271
+ description: Bad request
1272
+ 401:
1273
+ description: Unauthorized
1274
+ 404:
1275
+ description: Not found
1276
+ requestBody:
1277
+ required: true
1278
+ content:
1279
+ application/json:
1280
+ schema:
1281
+ type: object
1282
+ additionalProperties: true
1242
1283
  /admin/collection/{collectionId}/ai/tts:
1243
1284
  post:
1244
1285
  tags:
@@ -10390,6 +10431,38 @@ paths:
10390
10431
  description: Unauthorized
10391
10432
  404:
10392
10433
  description: Not found
10434
+ /public/collection/{collectionId}/ai/agent/run:
10435
+ post:
10436
+ tags:
10437
+ - publicClient
10438
+ summary: Public agent loop — run the orchestration-neutral tool loop on the consumer surface.
10439
+ operationId: publicClient_agentRun
10440
+ security: []
10441
+ parameters:
10442
+ - name: collectionId
10443
+ in: path
10444
+ required: true
10445
+ schema:
10446
+ type: string
10447
+ responses:
10448
+ 200:
10449
+ description: Success
10450
+ content:
10451
+ application/json:
10452
+ schema:
10453
+ $ref: "#/components/schemas/AgentRunResult"
10454
+ 400:
10455
+ description: Bad request
10456
+ 401:
10457
+ description: Unauthorized
10458
+ 404:
10459
+ description: Not found
10460
+ requestBody:
10461
+ required: true
10462
+ content:
10463
+ application/json:
10464
+ schema:
10465
+ $ref: "#/components/schemas/PublicAgentRunRequest"
10393
10466
  /public/collection/{collectionId}/ai/chat:
10394
10467
  post:
10395
10468
  tags:
@@ -15499,6 +15572,10 @@ components:
15499
15572
  $ref: "#/components/schemas/AiToolName"
15500
15573
  maxSteps:
15501
15574
  type: number
15575
+ app_functions:
15576
+ $ref: "#/components/schemas/AgentAppFunctionsOption"
15577
+ toolbelt:
15578
+ $ref: "#/components/schemas/AgentToolbelt"
15502
15579
  required:
15503
15580
  - enabled
15504
15581
  ResponsesResult:
@@ -16530,6 +16607,162 @@ components:
16530
16607
  type: array
16531
16608
  items:
16532
16609
  type: string
16610
+ appFunctions:
16611
+ $ref: "#/components/schemas/AgentAppFunctionsOption"
16612
+ toolbelt:
16613
+ $ref: "#/components/schemas/AgentToolbelt"
16614
+ AgentAppFunctionsOption:
16615
+ type: object
16616
+ properties:
16617
+ appId:
16618
+ type: string
16619
+ channel:
16620
+ type: string
16621
+ only:
16622
+ type: array
16623
+ items:
16624
+ type: string
16625
+ required:
16626
+ - appId
16627
+ AgentToolbelt:
16628
+ type: object
16629
+ properties:
16630
+ builtins:
16631
+ type: array
16632
+ items:
16633
+ type: object
16634
+ additionalProperties: true
16635
+ appFunctions:
16636
+ type: array
16637
+ items:
16638
+ $ref: "#/components/schemas/AgentAppFunctionsOption"
16639
+ clientTools:
16640
+ type: array
16641
+ items:
16642
+ $ref: "#/components/schemas/ClientToolDeclaration"
16643
+ ClientToolDeclaration:
16644
+ type: object
16645
+ properties:
16646
+ name:
16647
+ type: string
16648
+ description:
16649
+ type: string
16650
+ input:
16651
+ type: object
16652
+ additionalProperties: true
16653
+ required:
16654
+ - name
16655
+ ClientToolCall:
16656
+ type: object
16657
+ properties:
16658
+ callId:
16659
+ type: string
16660
+ name:
16661
+ type: string
16662
+ args:
16663
+ type: object
16664
+ additionalProperties: true
16665
+ required:
16666
+ - callId
16667
+ - name
16668
+ - args
16669
+ RequiresActionResult:
16670
+ type: object
16671
+ properties:
16672
+ status:
16673
+ type: string
16674
+ enum:
16675
+ - requires_action
16676
+ client_tool_calls:
16677
+ type: array
16678
+ items:
16679
+ $ref: "#/components/schemas/ClientToolCall"
16680
+ items:
16681
+ type: array
16682
+ items: {}
16683
+ steps:
16684
+ type: number
16685
+ toolResults:
16686
+ type: array
16687
+ items:
16688
+ $ref: "#/components/schemas/AgentToolResult"
16689
+ availableTools:
16690
+ type: array
16691
+ items:
16692
+ type: string
16693
+ required:
16694
+ - status
16695
+ - client_tool_calls
16696
+ - items
16697
+ ClientTool:
16698
+ type: object
16699
+ properties:
16700
+ declaration:
16701
+ $ref: "#/components/schemas/ClientToolDeclaration"
16702
+ required:
16703
+ - declaration
16704
+ RunWithClientToolsOptions:
16705
+ type: object
16706
+ properties:
16707
+ input:
16708
+ type: string
16709
+ tools:
16710
+ type: array
16711
+ items:
16712
+ $ref: "#/components/schemas/ClientTool"
16713
+ surface:
16714
+ type: string
16715
+ enum:
16716
+ - admin
16717
+ - public
16718
+ instructions:
16719
+ type: string
16720
+ model:
16721
+ type: string
16722
+ maxSteps:
16723
+ type: number
16724
+ toolbelt:
16725
+ $ref: "#/components/schemas/AgentToolbelt"
16726
+ maxRounds:
16727
+ type: number
16728
+ required:
16729
+ - input
16730
+ - tools
16731
+ PublicAgentRunRequest:
16732
+ type: object
16733
+ properties:
16734
+ input:
16735
+ type: string
16736
+ prompt:
16737
+ type: string
16738
+ instructions:
16739
+ type: string
16740
+ model:
16741
+ type: string
16742
+ maxSteps:
16743
+ type: number
16744
+ server_tools:
16745
+ type: array
16746
+ items:
16747
+ $ref: "#/components/schemas/AiToolName"
16748
+ only:
16749
+ type: array
16750
+ items:
16751
+ $ref: "#/components/schemas/AiToolName"
16752
+ exclude:
16753
+ type: array
16754
+ items:
16755
+ $ref: "#/components/schemas/AiToolName"
16756
+ allowCapabilities:
16757
+ type: array
16758
+ items:
16759
+ $ref: "#/components/schemas/AiToolCapability"
16760
+ appFunctions:
16761
+ $ref: "#/components/schemas/AgentAppFunctionsOption"
16762
+ toolbelt:
16763
+ $ref: "#/components/schemas/AgentToolbelt"
16764
+ userId:
16765
+ type: string
16533
16766
  AgentToolResult:
16534
16767
  type: object
16535
16768
  properties:
@@ -16542,6 +16775,20 @@ components:
16542
16775
  - name
16543
16776
  - isError
16544
16777
  - result
16778
+ ToolRunResult:
16779
+ type: object
16780
+ properties:
16781
+ name:
16782
+ type: string
16783
+ isError:
16784
+ type: boolean
16785
+ result:
16786
+ type: object
16787
+ additionalProperties: true
16788
+ required:
16789
+ - name
16790
+ - isError
16791
+ - result
16545
16792
  AgentRunResult:
16546
16793
  type: object
16547
16794
  properties:
@@ -16793,6 +17040,46 @@ components:
16793
17040
  type: string
16794
17041
  required:
16795
17042
  - urls
17043
+ PdfInspectArgs:
17044
+ type: object
17045
+ properties:
17046
+ url:
17047
+ type: object
17048
+ additionalProperties: true
17049
+ required:
17050
+ - url
17051
+ PdfRenderArgs:
17052
+ type: object
17053
+ properties:
17054
+ url:
17055
+ type: object
17056
+ additionalProperties: true
17057
+ required:
17058
+ - url
17059
+ PdfExtractArgs:
17060
+ type: object
17061
+ properties:
17062
+ url:
17063
+ type: object
17064
+ additionalProperties: true
17065
+ required:
17066
+ - url
17067
+ PdfDecodeBarcodesArgs:
17068
+ type: object
17069
+ properties:
17070
+ url:
17071
+ type: object
17072
+ additionalProperties: true
17073
+ required:
17074
+ - url
17075
+ PdfInspectGraphicsArgs:
17076
+ type: object
17077
+ properties:
17078
+ url:
17079
+ type: object
17080
+ additionalProperties: true
17081
+ required:
17082
+ - url
16796
17083
  HttpRequestArgs:
16797
17084
  type: object
16798
17085
  properties:
@@ -16848,6 +17135,16 @@ components:
16848
17135
  $ref: "#/components/schemas/PdfFillArgs"
16849
17136
  pdf.merge:
16850
17137
  $ref: "#/components/schemas/PdfMergeArgs"
17138
+ pdf.inspect:
17139
+ $ref: "#/components/schemas/PdfInspectArgs"
17140
+ pdf.render:
17141
+ $ref: "#/components/schemas/PdfRenderArgs"
17142
+ pdf.extract:
17143
+ $ref: "#/components/schemas/PdfExtractArgs"
17144
+ pdf.decodeBarcodes:
17145
+ $ref: "#/components/schemas/PdfDecodeBarcodesArgs"
17146
+ pdf.inspectGraphics:
17147
+ $ref: "#/components/schemas/PdfInspectGraphicsArgs"
16851
17148
  http.request:
16852
17149
  $ref: "#/components/schemas/HttpRequestArgs"
16853
17150
  translate:
@@ -16868,6 +17165,11 @@ components:
16868
17165
  - pdf.create
16869
17166
  - pdf.fill
16870
17167
  - pdf.merge
17168
+ - pdf.inspect
17169
+ - pdf.render
17170
+ - pdf.extract
17171
+ - pdf.decodeBarcodes
17172
+ - pdf.inspectGraphics
16871
17173
  - http.request
16872
17174
  - translate
16873
17175
  WebSearchResultItem:
@@ -16944,6 +17246,90 @@ components:
16944
17246
  additionalProperties: true
16945
17247
  required:
16946
17248
  - translations
17249
+ PdfInspectPage:
17250
+ type: object
17251
+ properties:
17252
+ page:
17253
+ type: string
17254
+ enum:
17255
+ - text-native
17256
+ - text+raster
17257
+ - raster-only
17258
+ - curve-only
17259
+ required:
17260
+ - page
17261
+ PdfInspectResult:
17262
+ type: object
17263
+ properties:
17264
+ url:
17265
+ type: array
17266
+ items:
17267
+ type: string
17268
+ enum:
17269
+ - text
17270
+ - vision
17271
+ required:
17272
+ - url
17273
+ PdfRenderResult:
17274
+ type: object
17275
+ properties:
17276
+ url:
17277
+ type: object
17278
+ additionalProperties: true
17279
+ required:
17280
+ - url
17281
+ PdfFieldMeta:
17282
+ type: object
17283
+ properties:
17284
+ confidence:
17285
+ type: object
17286
+ additionalProperties: true
17287
+ PdfExtractResult:
17288
+ type: object
17289
+ properties:
17290
+ url:
17291
+ type: string
17292
+ enum:
17293
+ - text
17294
+ - vision
17295
+ required:
17296
+ - url
17297
+ PdfBarcode:
17298
+ type: object
17299
+ properties:
17300
+ type:
17301
+ type: object
17302
+ additionalProperties: true
17303
+ required:
17304
+ - type
17305
+ PdfDecodeBarcodesResult:
17306
+ type: object
17307
+ properties:
17308
+ url:
17309
+ type: array
17310
+ items:
17311
+ type: object
17312
+ additionalProperties: true
17313
+ required:
17314
+ - url
17315
+ PdfGraphicsPage:
17316
+ type: object
17317
+ properties:
17318
+ page:
17319
+ type: array
17320
+ items:
17321
+ type: object
17322
+ additionalProperties: true
17323
+ required:
17324
+ - page
17325
+ PdfInspectGraphicsResult:
17326
+ type: object
17327
+ properties:
17328
+ url:
17329
+ type: object
17330
+ additionalProperties: true
17331
+ required:
17332
+ - url
16947
17333
  ResponsesAgentTrace:
16948
17334
  type: object
16949
17335
  properties:
@@ -17022,6 +17408,11 @@ components:
17022
17408
  - pdf.create
17023
17409
  - pdf.fill
17024
17410
  - pdf.merge
17411
+ - pdf.inspect
17412
+ - pdf.render
17413
+ - pdf.extract
17414
+ - pdf.decodeBarcodes
17415
+ - pdf.inspectGraphics
17025
17416
  - http.request
17026
17417
  - translate
17027
17418
  AgentStreamEvent:
@@ -18264,9 +18655,30 @@ components:
18264
18655
  type: string
18265
18656
  handler:
18266
18657
  type: string
18658
+ agent:
18659
+ $ref: "#/components/schemas/AppFunctionAgentExposure"
18267
18660
  required:
18268
18661
  - name
18269
18662
  - trigger
18663
+ AppFunctionAgentExposure:
18664
+ type: object
18665
+ properties:
18666
+ tool:
18667
+ type: boolean
18668
+ title:
18669
+ type: string
18670
+ description:
18671
+ type: string
18672
+ input:
18673
+ type: object
18674
+ additionalProperties: true
18675
+ approval:
18676
+ type: string
18677
+ enum:
18678
+ - auto
18679
+ - require
18680
+ required:
18681
+ - tool
18270
18682
  AppManifestFunctions:
18271
18683
  type: object
18272
18684
  properties:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@proveanything/smartlinks",
3
- "version": "2.0.26",
3
+ "version": "2.0.29",
4
4
  "description": "Official JavaScript/TypeScript SDK for the Smartlinks API",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",