@mitralab.io/functions-sdk 0.1.1 → 0.2.0-beta.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.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,29 @@
2
2
 
3
3
  All notable changes to this project are documented in this file.
4
4
 
5
+ ## 0.2.0-beta.0
6
+
7
+ This working tree prepares the `0.2.0-beta.0` package. The immutable Core source pin
8
+ and npm lock integrity are finalized after `@mitralab.io/sdk-core@0.2.0-beta.0` is
9
+ published and before this package is released.
10
+
11
+ - Re-export exactly the runtime and type surface of `mitra-sdk@1.0.63-beta.39`,
12
+ marked `@deprecated`, without adding browser-only interactions exports.
13
+ - Configure the legacy SDK from the same environment `createClient` resolves.
14
+ - Expose the complete native `sdk-core` module surface through direct service transports.
15
+ - Add authenticated Code Studio, Copilot, and Messenger transports.
16
+ - Add native live Agent sessions over authenticated HTTP input and SSE output channels.
17
+ - Forward Core Agent session transport preferences to the runtime SSE adapter.
18
+ - Add an anonymous Public Functions transport that omits authorization and app headers.
19
+ - Add anonymous polling for executions created by the public async Function route.
20
+ - Align the deprecated bridge with the `mitra-sdk` beta.39 version baked into the E2B runtime.
21
+ - Restrict Code Studio operations to the configured runtime app and add a `currentApp` facade.
22
+ - Align stable page and record envelopes with Core 0.2, bind app context to the configured app,
23
+ and execute Custom Queries without a caller-selected Data Source.
24
+ - Leave request deadlines to the Server Function runtime by default while preserving opt-in
25
+ `timeoutMs` deadlines.
26
+ - Document runtime authorization gaps and the pending Core 0.2.0-beta.0 release gate.
27
+
5
28
  ## 0.1.0
6
29
 
7
30
  - Add environment-based Server Function client configuration.
package/README.md CHANGED
@@ -1,10 +1,10 @@
1
1
  # Mitra Functions SDK for JavaScript
2
2
 
3
- JavaScript and TypeScript SDK for code running inside Mitra Server Functions. It exposes the application-scoped Platform APIs that a function commonly needs without bringing browser authentication into the runtime.
3
+ JavaScript and TypeScript SDK for code running inside Mitra Server Functions. Its native surface exposes the application-scoped Platform APIs that a function commonly needs without requiring browser authentication in the runtime.
4
4
 
5
5
  The SDK uses the short-lived platform access token injected into the function runtime. It does not log in users, persist credentials, refresh tokens, use API keys, or retry requests automatically.
6
6
 
7
- Shared API contracts and modules come from `@mitralab.io/sdk-core`. This package owns only the Server Function runtime adapter: environment configuration, token headers, timeout, credential redaction, redirect refusal, and one-attempt request policy. The core never receives or stores the token.
7
+ Shared API contracts and modules come from `@mitralab.io/sdk-core`. This package owns only the Server Function runtime adapter: environment configuration, token headers, optional request deadlines, credential redaction, redirect refusal, and one-attempt request policy. The core never receives or stores the token.
8
8
 
9
9
  ## Installation
10
10
 
@@ -14,16 +14,26 @@ npm install @mitralab.io/functions-sdk
14
14
 
15
15
  Node.js 18 or newer is required.
16
16
 
17
- ## Runtime integration status
17
+ ## Runtime integration
18
18
 
19
- The SDK is ready for the target runtime contract, but Functions and Sandbox do not inject it yet. Until that integration is delivered, these variables must be supplied explicitly in local or controlled execution environments:
19
+ The SDK accepts the existing Server Function runtime variables:
20
+
21
+ - `MITRA_BASE_URL`
22
+ - `MITRA_TOKEN`
23
+ - `MITRA_PROJECT_ID`
24
+
25
+ It also accepts the canonical aliases:
20
26
 
21
27
  - `MITRA_API_URL`
22
28
  - `MITRA_PLATFORM_ACCESS_TOKEN`
23
29
  - `MITRA_APP_ID`
24
- - `MITRA_DATA_SOURCE_ID`, when already resolved by the runtime
30
+ - `MITRA_DATA_SOURCE_ID`, retained for runtime compatibility when already resolved
25
31
 
26
- Do not treat user-defined function secrets as the runtime credential channel. The pending runtime integration must inject the platform access token separately from user secrets.
32
+ When only the existing names are present, the SDK removes a trailing `/legacy` from
33
+ `MITRA_BASE_URL` and calls the owning services from that gateway root. It forwards `MITRA_TOKEN`
34
+ unchanged as the bearer token and uses `MITRA_PROJECT_ID` as the app identifier. It does not
35
+ exchange, refresh, inspect, or alter the token. The deprecated bridge still receives the original
36
+ base URL. Neither token name represents a user-defined Function secret.
27
37
 
28
38
  ## Quick start
29
39
 
@@ -53,9 +63,13 @@ const mitra = createClient({
53
63
 
54
64
  ## Initialization
55
65
 
56
- Entity operations use the app identity from the token and `X-App-Id`, so they are available immediately. Custom queries require a data source ID.
66
+ Entity and Custom Query operations use the app identity from the token and `X-App-Id`, so they are
67
+ available immediately. Custom Query execution sends only `parameters`; Data Manager resolves its
68
+ Data Source from the authenticated app.
57
69
 
58
- If `MITRA_DATA_SOURCE_ID` or `dataSourceId` is not configured, call `init()` once before executing queries. It resolves the data source from Code Studio and is safe to call concurrently.
70
+ `init()` and the optional `dataSourceId` configuration remain available for source compatibility.
71
+ When no Data Source is configured, `init()` resolves the nullable value from Code Studio and is
72
+ safe to call concurrently, but native Queries and Entities do not depend on it.
59
73
 
60
74
  ```typescript
61
75
  const mitra = createClient()
@@ -86,8 +100,8 @@ type Task = {
86
100
  }
87
101
 
88
102
  const tasks = mitra.entities.getTable<Task>("Task")
89
- const recent = await tasks.list({ sort: "-created_at", limit: 20 })
90
- const pending = await tasks.filter({ status: "pending" })
103
+ const { data: recent } = await tasks.list({ sort: "-created_at", limit: 20 })
104
+ const { data: pending } = await tasks.filter({ status: "pending" })
91
105
  const created = await tasks.create({ title: "Review order" })
92
106
  await tasks.update(created.id, { status: "done" })
93
107
  await tasks.delete(created.id)
@@ -100,7 +114,6 @@ Available methods are `list`, `filter`, `get`, `create`, `bulkCreate`, `update`,
100
114
  ### Custom queries
101
115
 
102
116
  ```typescript
103
- await mitra.init()
104
117
  const result = await mitra.queries.execute("5df41c69-2a74-4db6-9cca-4af2b473941f", {
105
118
  customerId: "customer-id",
106
119
  })
@@ -133,6 +146,162 @@ const proxy = await mitra.integration.execute("config-id", {
133
146
 
134
147
  Credentials configured for an integration are injected by the Integration service. Do not pass provider credentials through function input.
135
148
 
149
+ Use `integrationAdmin.list()` as the native equivalent of `listIntegrationsMitra`. It calls
150
+ `GET /integration/api/v1/template-configs`; the service filters app-scoped runtime tokens to the
151
+ current app and returns its real paginated `TemplateConfigSummary` values.
152
+
153
+ Native entity methods target the public Data Manager records API, which resolves the app Data
154
+ Source from the runtime token. That API does not accept the legacy `jdbcConnectionConfigId`
155
+ selector, so records that depend on it remain available only through the deprecated bridge. The
156
+ SDK does not emulate that selection with raw SQL.
157
+
158
+ ### Native modules
159
+
160
+ The native client exposes all 24 application runtime and authoring modules from
161
+ `@mitralab.io/sdk-core` directly against the owning services. `currentApp` is an additional
162
+ Functions-specific convenience facade over the Core `apps` module:
163
+
164
+ | Area | Modules | Service |
165
+ | ------------------------ | --------------------------------------------------------------------------------- | --------------------------------------- |
166
+ | Identity and members | `auth`, `members` | IAM |
167
+ | Data | `dataSources`, `schema`, `entities`, `customQueries`, `queries`, `sql`, `imports` | Data Manager |
168
+ | Functions and automation | `functions`, `functionsAdmin`, `agents`, `workflows` | Functions |
169
+ | Apps | `apps`, `currentApp`, `context` | Code Studio and composed native modules |
170
+ | Agent runtime | `agentTasks`, `agentCredentials`, `agentConnections` | Copilot |
171
+ | Integrations | `integration`, `integrationAdmin`, `integrationTemplates`, `integrationResources` | Integration |
172
+ | Notifications | `messenger` | Messenger |
173
+ | Anonymous execution | `publicFunctions` | Functions public API |
174
+
175
+ These modules do not use the BFF gateway. The BFF remains only behind the deprecated
176
+ `mitra-sdk` compatibility exports described below.
177
+
178
+ Single-Function `functionsAdmin.create()` and `functionsAdmin.patch()` expose
179
+ `cronExpression`, `cronInputJson`, and `cronEnabled` as one composed scheduling unit. On create,
180
+ omit all three for no schedule; supplying any one requires a non-blank expression. The new schedule
181
+ uses `UTC` and starts `ACTIVE` unless `cronEnabled` is `false`. On patch, null or omitted schedule
182
+ fields preserve their stored values, an empty input object clears the scheduled input, and a blank
183
+ expression removes the schedule. A non-blank expression can create a missing schedule in `UTC`,
184
+ while `cronEnabled` explicitly pauses or resumes it. Schedule composition requires
185
+ `SCHEDULE_WRITE` and `FUNCTION_EXECUTE` in addition to the Function write permission.
186
+
187
+ Function `get()` and `list()` include all three cron fields when the caller has `SCHEDULE_READ`.
188
+ Without it, the fields are all null without consulting Scheduler. A Function with no schedule has
189
+ the same all-null shape, so those responses alone cannot distinguish absence from missing read
190
+ permission. Function bulk create, update, and patch prohibit all three cron fields; use the
191
+ single-Function methods for composed scheduling.
192
+
193
+ The native SDK deliberately has no separate schedule lifecycle methods. Create, patch, get, and
194
+ list keep Function state and its composed cron fields in one contract.
195
+
196
+ ### Live Agent sessions over HTTP
197
+
198
+ `agentTasks.session()` adds the Core session state machine to the native Copilot task module. The
199
+ Functions adapter uses the direct HTTP channel because Server Functions do not provide a browser
200
+ WebSocket runtime:
201
+
202
+ ```typescript
203
+ const session = mitra.agentTasks.session({
204
+ create: true,
205
+ agentType: "CODEX",
206
+ transport: "http",
207
+ })
208
+
209
+ session.on("delta", ({ delta, kind }) => {
210
+ console.log(kind, delta)
211
+ })
212
+
213
+ const result = await session.sendAndWait("Summarize today's orders")
214
+ console.log(result.content)
215
+ session.close()
216
+ ```
217
+
218
+ Existing tasks use `mitra.agentTasks.session({ taskId })`. The adapter opens
219
+ `GET /copilot/api/v1/tasks/{taskId}/events` as a Server-Sent Events (SSE) stream before it sends
220
+ input to `POST /inputs`. Both calls use the fixed runtime token in `Authorization` plus
221
+ `X-App-Id`; credentials are never placed in the URL. `transport: "auto"` and `"http"` use this
222
+ channel, while `"websocket"` rejects locally.
223
+
224
+ When `timeoutMs` is configured, it applies only while waiting for the SSE response headers. Once
225
+ the handshake succeeds, the body remains open until the session closes, its abort signal fires, or
226
+ the server disconnects. The parser ignores `hello` and `ping` keepalives and forwards `message`
227
+ events to the Core session manager. Core performs one reconnect and reconciles persisted messages
228
+ after an unexpected disconnect.
229
+
230
+ ### App-scoped Code Studio access
231
+
232
+ The Functions runtime is fixed to the configured `appId`. `apps.list()` and `apps.create()`
233
+ reject locally because they are tenant-level operations. Every other `apps` method rejects
234
+ an app ID different from the configured runtime app before making a request.
235
+
236
+ Use `currentApp` when possible. It exposes the same current-app lifecycle without repeating
237
+ the app ID:
238
+
239
+ ```typescript
240
+ const app = await mitra.currentApp.get()
241
+ const published = await mitra.currentApp.get({ version: "PUBLISHED" })
242
+ await mitra.currentApp.update({ name: "Orders" })
243
+ await mitra.currentApp.mergeFiles({ "src/generated.ts": "export const ready = true" })
244
+ const previewDeploy = await mitra.currentApp.build()
245
+ await mitra.currentApp.publish({ externalAccess: true })
246
+ ```
247
+
248
+ `build()` returns the `AppDeploy` created for preview polling. `get()` preserves the Core
249
+ `AppGetOptions`, and `publish()` preserves `AppPublishOptions`.
250
+
251
+ The client-side check prevents accidental cross-app calls, but it is not a security boundary.
252
+ Code Studio must also enforce the JWT `app_id` claim in the backend. Until that enforcement is
253
+ deployed, the access token must be treated as sensitive even though this SDK fixes the app ID.
254
+
255
+ ### Public Functions
256
+
257
+ `publicFunctions` calls `/functions/public/v1` with a dedicated anonymous transport. It never
258
+ sends `Authorization` or `X-App-Id`.
259
+
260
+ ```typescript
261
+ const result = await mitra.publicFunctions.execute("public-function-id", { value: 1 })
262
+ const queued = await mitra.publicFunctions.executeAsync("public-function-id", { value: 1 })
263
+ ```
264
+
265
+ An asynchronous public execution returns its ID and initial status as fire-and-forget. The public
266
+ API does not expose anonymous polling or cancellation. Use synchronous `execute` when the caller
267
+ needs the result, or authenticated `functions.executeAsync` plus `functions.getExecution` when the
268
+ caller has an app-scoped token.
269
+
270
+ ## Runtime authorization
271
+
272
+ The JWT `app_id` claim is the authority for application scope. `X-App-Id` carries runtime
273
+ context for protected service requests and must not be used by a backend as the authorization
274
+ boundary.
275
+
276
+ Against the current `origin/alpha` service and IAM policies, 109 of the 120 MCP capabilities
277
+ are usable or authorizable from an app-scoped Server Function. The `dataSources.bulk*` methods
278
+ compose the existing singular Data Manager endpoints, so they do not require a coordinated
279
+ service rollout. The remaining capabilities have these known constraints:
280
+
281
+ | Capability | Runtime behavior | Reason |
282
+ | ------------------------------------- | ----------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
283
+ | Member reads through `members.list()` | `403 INSUFFICIENT_PERMISSIONS` | `MEMBER_READ` is deliberately absent from the SF token policy. App context excludes members. |
284
+ | Function secret list/create/delete | `403 INSUFFICIENT_PERMISSIONS` | `FUNCTION_SECRET_READ`, `FUNCTION_SECRET_WRITE`, and `FUNCTION_SECRET_DELETE` are absent from the SF token policy. |
285
+ | Agent runtime operations | Configuration or service rejection without an agent context | The runtime must inject or otherwise provide the applicable `agent_id`. |
286
+ | `apps.list()` and `apps.create()` | Local `MitraConfigurationError` | Tenant-level app collection operations are not applicable to an app-scoped runtime. |
287
+ | `messenger.notify()` | Depends on the authenticated user's channel | The call is authorized, but delivery requires a configured notification channel. |
288
+
289
+ The methods remain part of the typed API so clients with a different authorized token can use
290
+ the shared contract. This SDK does not broaden IAM permissions or retry a rejected operation.
291
+
292
+ ### Core and legacy type names
293
+
294
+ The deprecated `AgentConnection`, `AgentMessage`, `AgentModel`, and `ListTablesOptions` names keep
295
+ their original `mitra-sdk` meanings for source compatibility. Import the native Core contracts as
296
+ `CoreAgentConnection`, `CoreAgentMessage`, `CoreAgentModel`, and `CoreListTablesOptions`.
297
+
298
+ The deprecated package also owns `AgentTaskSession`, `AgentTimelineItem`, and `AgentToolEvent`.
299
+ Their native equivalents are exported as `CoreAgentTaskSession`, `CoreAgentTimelineItem`, and
300
+ `CoreAgentToolEvent`. New session options and results are available as
301
+ `CoreAgentTaskSessionOptions`, `AgentSendOptions`, `AgentSendAndWaitOptions`, and `AgentTurnResult`.
302
+ `sendAndWait()` rejects Agent turn failures with `AgentTaskTurnError`, preserving the service error
303
+ code when one is present.
304
+
136
305
  ## Errors and request behavior
137
306
 
138
307
  API, timeout, invalid response, and network failures throw `MitraApiError`. The error exposes `status`, `code`, `details`, `requestId`, and `retryable`, preserving API metadata when it is provided. Configuration failures throw `MitraConfigurationError`.
@@ -143,16 +312,20 @@ only. The SDK still makes one attempt and never retries a request automatically.
143
312
 
144
313
  The Python package uses idiomatic specialized names for local failures. JavaScript `REQUEST_TIMEOUT` and `NETWORK_ERROR` map to Python `MitraNetworkError`, while JavaScript `INVALID_RESPONSE` maps to Python `MitraResponseError`. API responses use `MitraApiError` in both packages.
145
314
 
146
- Every request sends `Authorization: Bearer <token>` and `X-App-Id`. The default timeout is 10 seconds. Requests are never retried automatically, which avoids replaying writes with unknown idempotency.
315
+ Every protected request sends `Authorization: Bearer <token>` and `X-App-Id`. Public Function
316
+ requests send neither header. Requests have no adapter-level deadline by default, so normal
317
+ long-running platform operations remain governed by the Server Function runtime. Set `timeoutMs`
318
+ to opt into a per-request deadline. Requests are never retried automatically, which avoids
319
+ replaying writes with unknown idempotency.
147
320
 
148
321
  The access token is redacted from API error messages and error details.
149
322
 
150
323
  ## Contract parity
151
324
 
152
- The test suite reads SDK-PARITY-001 directly from the installed
153
- `@mitralab.io/sdk-core` package. The source manifest pins Core version 0.1.0,
154
- the SHA-256 digest, and the full source commit
155
- `b513454d0d1f7344a4656cd9c0e1e32530c5ea90`. It does not duplicate the corpus.
325
+ The test suite reads SDK-PARITY-001 version 0.2.0-beta.0 directly from the installed
326
+ `@mitralab.io/sdk-core` package. The `sdk-core-v0.2.0-beta.0` manifest pins the expected package
327
+ version, contract path, SHA-256 digest, and immutable source commit. The release gate rejects
328
+ publication unless the installed corpus matches its raw GitHub source byte for byte.
156
329
 
157
330
  The JavaScript consumer requirement is exactly `httpAdapterCases: all`. Tests
158
331
  execute all recorded 404, 503, and timeout cases through the public client and
@@ -163,7 +336,44 @@ at the pinned commit and compare it byte for byte with the installed package.
163
336
 
164
337
  ## Scope
165
338
 
166
- Version 0.1 includes application runtime operations: current user, entity CRUD, custom query execution, Server Function execution management, and integrations. Administrative control-plane methods and the legacy messenger API are intentionally excluded.
339
+ The current draft expands the native client from the initial runtime operations to the complete
340
+ Core 0.2.0-beta.0 module surface listed above. Availability still depends on the runtime token resources
341
+ and the service constraints in the authorization matrix.
342
+
343
+ ## Legacy compatibility
344
+
345
+ The runtime and type surface of `mitra-sdk@1.0.63-beta.39` is re-exported so existing Server
346
+ Function code can adopt `@mitralab.io/functions-sdk` without an import rewrite. Browser-only
347
+ bindings that exist only in `mitra-interactions-sdk`, including login and token refresh, are not
348
+ part of this package. Every re-export is the legacy binding itself, unchanged, and is marked
349
+ `@deprecated` with the new equivalent when one exists. Native raw SQL is available through `sql`;
350
+ app authoring and Agent runtime modules cover most builder and Agent SDK operations. Builder-specific
351
+ Git and direct-S3 flows have no one-to-one replacement and remain supported through the legacy
352
+ exports. Live Agent sessions have a native HTTP and SSE replacement through
353
+ `agentTasks.session()`.
354
+
355
+ `getGitConfigMitra` remains legacy-only because credential minting is an internal Sandbox POST
356
+ authenticated between services and is not published for app tokens. The Sandbox already owns Git
357
+ setup and token renewal for Agent workspaces; the native Functions client does not expose that
358
+ secret-producing endpoint.
359
+
360
+ ```typescript
361
+ import { createClient, listProjectsMitra } from "@mitralab.io/functions-sdk"
362
+
363
+ createClient()
364
+ const projects = await listProjectsMitra()
365
+ ```
366
+
367
+ `createClient()` and `createClientFromEnvironment()` configure the deprecated SDK with
368
+ `MITRA_BASE_URL`, the resolved access token, and the app ID, so legacy code does not read the
369
+ environment itself. Native modules use the canonical API root directly and never route through the
370
+ BFF, even when that root was derived from an existing `MITRA_BASE_URL` value.
371
+ For explicit local configuration, `legacyBaseUrl` selects the deprecated BFF base; it falls back to
372
+ `apiUrl` only when omitted. The deprecated SDK receives `appId` as its `projectId` and accepts the
373
+ access token with or without a `Bearer` prefix.
374
+
375
+ The direct legacy dependency is pinned to the exact `mitra-sdk` version. Nothing in it is modified
376
+ or published by this package.
167
377
 
168
378
  ## Development
169
379
 
@@ -172,15 +382,59 @@ npm install
172
382
  npm run check
173
383
  ```
174
384
 
175
- `@mitralab.io/sdk-core@0.1.0` is resolved from the public npm registry and
176
- locked by integrity in `package-lock.json`. Do not replace it with a `file:`
177
- dependency or a local tarball.
385
+ The adapter pins `@mitralab.io/sdk-core@0.2.0-beta.0` exactly. Until that version is published,
386
+ validate
387
+ against a supplied tarball without changing dependency metadata or the final lockfile:
388
+
389
+ ```bash
390
+ npm install --no-save --package-lock=false /path/to/mitralab.io-sdk-core-0.2.0-beta.0.tgz
391
+ npm run lint && npm run typecheck && npm test && npm run build
392
+ MITRA_SDK_CORE_TARBALL=/path/to/mitralab.io-sdk-core-0.2.0-beta.0.tgz npm run smoke:package
393
+ git diff --exit-code -- package-lock.json
394
+ ```
395
+
396
+ Do not use a `file:` dependency or `npm link`. After Core 0.2.0-beta.0 is published, install it from
397
+ the public npm registry and commit the registry `resolved` URL and integrity generated in
398
+ `package-lock.json`.
399
+
400
+ The checked-in lock records the intended Core `0.2.0-beta.0` package without a false `0.1.x`
401
+ registry
402
+ resolution. It is provisional until Core is published. `npm ci` is therefore not expected to work
403
+ from the registry before the Core release.
404
+
405
+ ## Release order
406
+
407
+ 1. Merge and publish `@mitralab.io/sdk-core@0.2.0-beta.0` under npm's `beta` dist-tag from its
408
+ immutable source commit.
409
+ 2. Add that full commit SHA to `contracts/sdk-core-v0.2.0-beta.0.manifest.json` as:
410
+
411
+ ```json
412
+ {
413
+ "source": {
414
+ "repository": "https://github.com/mitralab-dev/mitra-core-sdk",
415
+ "commit": "<full-core-commit-sha>",
416
+ "path": "contracts/v0.2.0-beta.0/sdk-parity.json"
417
+ }
418
+ }
419
+ ```
420
+
421
+ 3. Run `npm install --package-lock-only`, then verify that the Core lock entry is exactly
422
+ `0.2.0-beta.0` with an npm registry URL and integrity.
423
+ 4. Run `npm ci`, `npm run check`, and `npm run check:contracts:source`.
424
+ 5. Publish `@mitralab.io/functions-sdk@0.2.0-beta.0` under npm's `beta` dist-tag and run the
425
+ tarball smoke against the registry.
426
+
427
+ Stable `X.Y.Z` releases use npm's default `latest` dist-tag. The workflow accepts only that stable
428
+ form or the prerelease form `X.Y.Z-beta.N`.
429
+
430
+ `prepublishOnly` repeats the immutable-source check, so a direct `npm publish` cannot bypass the
431
+ pending Core provenance.
178
432
 
179
433
  The contract source can be checked explicitly without changing the manifest or
180
434
  lockfile:
181
435
 
182
436
  ```bash
183
- npm run check:contracts -- --canonical /path/to/sdk-parity.json
437
+ node scripts/check-contract-corpus.mjs --canonical /path/to/sdk-parity.json
184
438
  ```
185
439
 
186
440
  The package builds ESM, CommonJS, and TypeScript declarations in `dist/`. Tests enforce at least 80 percent coverage for lines, functions, branches, and statements.
@@ -0,0 +1,15 @@
1
+ {
2
+ "contract": "SDK-PARITY-001",
3
+ "version": "0.2.0-beta.0",
4
+ "dependency": {
5
+ "package": "@mitralab.io/sdk-core",
6
+ "version": "0.2.0-beta.0",
7
+ "contractPath": "contracts/v0.2.0-beta.0/sdk-parity.json"
8
+ },
9
+ "sha256": "0f41764eedce0945b0b696b6f95af4d76c31a63df169b088b8a6f65d0aa841d4",
10
+ "source": {
11
+ "repository": "https://github.com/mitralab-dev/mitra-core-sdk",
12
+ "commit": "3ae71aaa9fe21e2a918934082f769bb4bed0faf1",
13
+ "path": "contracts/v0.2.0-beta.0/sdk-parity.json"
14
+ }
15
+ }