effect-cursor-sdk 0.1.1 → 0.2.1
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/DEPRECATIONS.md +88 -0
- package/README.md +153 -60
- package/dist/index.d.ts +259 -154
- package/dist/index.js +211 -158
- package/dist/index.js.map +1 -1
- package/package.json +11 -6
package/DEPRECATIONS.md
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# Deprecations
|
|
2
|
+
|
|
3
|
+
This document lists deprecated `effect-cursor-sdk` APIs, what to use instead today, and how names are expected to change in the **next major** release. Deprecated APIs remain available until that major; follow [CHANGELOG.md](./CHANGELOG.md) and release notes when upgrading.
|
|
4
|
+
|
|
5
|
+
## Status definitions
|
|
6
|
+
|
|
7
|
+
| Status | Meaning |
|
|
8
|
+
| ---------------------- | ---------------------------------------------------------------------------------------------------- |
|
|
9
|
+
| **Deprecated** | Still supported; avoid in new code. May show IDE warnings via TSDoc `@deprecated`. |
|
|
10
|
+
| **Preferred now** | Current recommended API; use with [`loadCursorConfig`](./README.md#quick-start) and related helpers. |
|
|
11
|
+
| **Planned next major** | Intended replacement names after deprecated overloads and `*FromConfig` suffixes are removed. |
|
|
12
|
+
|
|
13
|
+
## Agent entry: plain `AgentOptions` vs config-first
|
|
14
|
+
|
|
15
|
+
Passing raw [`AgentOptions`](https://cursor.com/docs/sdk/typescript) (including a plain `apiKey` string) directly to `CursorAgentService` agent entry points is **deprecated**. Prefer loading `CursorConfig` with `loadCursorConfig` (exported from this package) and using the `*FromConfig` methods so secrets stay [`Redacted`](https://effect.website/docs/schema/redacted/) until merged for the SDK boundary.
|
|
16
|
+
|
|
17
|
+
### API mapping
|
|
18
|
+
|
|
19
|
+
| Deprecated (`CursorAgentService`) | Preferred now | Planned next major (same signatures as “Preferred now”) |
|
|
20
|
+
| --------------------------------- | ----------------------------------------------- | ------------------------------------------------------- |
|
|
21
|
+
| `create(options)` | `createFromConfig(config, overrides?)` | `create(config, overrides?)` |
|
|
22
|
+
| `resume(agentId, options?)` | `resumeFromConfig(agentId, config, overrides?)` | `resume(agentId, config, overrides?)` |
|
|
23
|
+
| `prompt(message, options?)` | `promptFromConfig(message, config, overrides?)` | `prompt(message, config, overrides?)` |
|
|
24
|
+
| `scoped(options)` | `scopedFromConfig(config, overrides?)` | `scoped(config, overrides?)` |
|
|
25
|
+
|
|
26
|
+
The `*FromConfig` suffixes exist today to keep deprecated plain-`AgentOptions` entry points without breaking callers. After removal of the legacy forms, the shorter names above are the intended stable surface.
|
|
27
|
+
|
|
28
|
+
### Migrate `create`
|
|
29
|
+
|
|
30
|
+
**Before (deprecated):**
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
const agent =
|
|
34
|
+
yield *
|
|
35
|
+
agents.create({
|
|
36
|
+
apiKey: process.env.CURSOR_API_KEY,
|
|
37
|
+
model: { id: "composer-2" },
|
|
38
|
+
local: { cwd: process.cwd() },
|
|
39
|
+
});
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
**After (preferred):**
|
|
43
|
+
|
|
44
|
+
```ts
|
|
45
|
+
const config = yield * loadCursorConfig;
|
|
46
|
+
const agent =
|
|
47
|
+
yield *
|
|
48
|
+
agents.createFromConfig(config, {
|
|
49
|
+
model: { id: "composer-2" },
|
|
50
|
+
local: { cwd: process.cwd() },
|
|
51
|
+
});
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
If you need full control over merging into SDK options, call `agentOptionsFromConfig(config, overrides)` and pass the result only through internal or transitional code paths; application code should still prefer `createFromConfig`.
|
|
55
|
+
|
|
56
|
+
### Migrate `prompt`
|
|
57
|
+
|
|
58
|
+
**Before (deprecated):**
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
const result =
|
|
62
|
+
yield *
|
|
63
|
+
agents.prompt("Summarize the README", {
|
|
64
|
+
apiKey: process.env.CURSOR_API_KEY,
|
|
65
|
+
model: { id: "composer-2" },
|
|
66
|
+
});
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
**After (preferred):**
|
|
70
|
+
|
|
71
|
+
```ts
|
|
72
|
+
const config = yield * loadCursorConfig;
|
|
73
|
+
const result =
|
|
74
|
+
yield *
|
|
75
|
+
agents.promptFromConfig("Summarize the README", config, {
|
|
76
|
+
model: { id: "composer-2" },
|
|
77
|
+
});
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Other deprecations
|
|
81
|
+
|
|
82
|
+
`CursorSdkFactory` exposes raw SDK-style `create` / `resume` / `prompt` helpers for tests and advanced wiring; those are **deprecated for application code** in favor of `CursorAgentService` with the config-first flow above. See TSDoc on `CursorSdkFactory` in the published types.
|
|
83
|
+
|
|
84
|
+
## Where else this is documented
|
|
85
|
+
|
|
86
|
+
- [README.md](./README.md) — quick summary and link here.
|
|
87
|
+
- Package root ships this file next to `README.md` on npm (see `package.json` `files`).
|
|
88
|
+
- Per-symbol `@deprecated` tags on `CursorAgentService` and related exports in the TypeScript declarations.
|
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# effect-cursor-sdk
|
|
2
2
|
|
|
3
|
+
   
|
|
4
|
+
|
|
3
5
|
Effect-native access to the new [Cursor SDK](https://cursor.com/docs/sdk/typescript).
|
|
4
6
|
|
|
5
7
|
`effect-cursor-sdk` wraps `@cursor/sdk` with Effect services, layers, scoped resource management, tagged errors, observability hooks, deterministic mocks, and ready-made runtimes. The upstream SDK remains the source of truth for Cursor-owned types; this package adds Effect ergonomics without creating a parallel model that can drift.
|
|
@@ -27,7 +29,7 @@ Effect-native access to the new [Cursor SDK](https://cursor.com/docs/sdk/typescr
|
|
|
27
29
|
| `Agent.list`, `get`, `listRuns`, `getRun`, messages | `CursorInspectionService` |
|
|
28
30
|
| `Agent.archive`, `unarchive`, `delete` | `CursorInspectionService` |
|
|
29
31
|
| `Cursor.me`, models, repositories | `CursorInspectionService` |
|
|
30
|
-
| MCP servers, sub-agents, local/cloud options, model options | SDK
|
|
32
|
+
| MCP servers, sub-agents, local/cloud options, model options | Defaults via `CursorConfig` / `loadCursorConfig`; merged SDK `AgentOptions` ([deprecated](./DEPRECATIONS.md) at agent entry) |
|
|
31
33
|
| Local run event helpers and platform helpers | Re-exported from `@cursor/sdk` |
|
|
32
34
|
|
|
33
35
|
## Install
|
|
@@ -44,18 +46,44 @@ bun run typecheck
|
|
|
44
46
|
bun run test
|
|
45
47
|
```
|
|
46
48
|
|
|
49
|
+
## Examples
|
|
50
|
+
|
|
51
|
+
The [`examples`](./examples) directory contains a guided learning path from a
|
|
52
|
+
minimal first script to production-style Effect composition:
|
|
53
|
+
|
|
54
|
+
| Example | What it demonstrates |
|
|
55
|
+
| --- | --- |
|
|
56
|
+
| [`quickstart`](./examples/quickstart) | First config-first local agent call with `loadCursorConfig`, `agentOptionsFromConfig`, and `collectText`. |
|
|
57
|
+
| [`cli`](./examples/cli) | A small terminal app with `liveRuntime`, offline `makeMockRuntime`, CLI overrides, and tagged error handling. |
|
|
58
|
+
| [`basic-agent-workflow`](./examples/basic-agent-workflow) | Scoped agents, run status listeners, streaming, capability checks, and artifact listing/downloads. |
|
|
59
|
+
| [`advanced-ops-dashboard`](./examples/advanced-ops-dashboard) | Inspection APIs, confirmation-gated lifecycle operations, parallel Effect composition, retries/timeouts, telemetry, redaction, and rich mocks. |
|
|
60
|
+
|
|
61
|
+
Run all example typechecks from the repo root:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
bun run examples:typecheck
|
|
65
|
+
```
|
|
66
|
+
|
|
47
67
|
## Quick Start
|
|
48
68
|
|
|
69
|
+
Load environment defaults with `loadCursorConfig`, then create agents with `createFromConfig` (and `scopedFromConfig`, `promptFromConfig`, `resumeFromConfig` as needed). The API key stays in `Redacted` form until the merge step; `AgentOptions.apiKey` remains a plain string at the SDK boundary.
|
|
70
|
+
|
|
49
71
|
```ts
|
|
50
|
-
import {
|
|
51
|
-
|
|
72
|
+
import {
|
|
73
|
+
CursorAgentService,
|
|
74
|
+
CursorRunService,
|
|
75
|
+
loadCursorConfig,
|
|
76
|
+
liveLayer,
|
|
77
|
+
} from "effect-cursor-sdk";
|
|
78
|
+
import { Effect } from "effect";
|
|
52
79
|
|
|
53
80
|
const program = Effect.gen(function* () {
|
|
54
81
|
const agents = yield* CursorAgentService;
|
|
55
82
|
const runs = yield* CursorRunService;
|
|
56
83
|
|
|
57
|
-
const
|
|
58
|
-
|
|
84
|
+
const config = yield* loadCursorConfig;
|
|
85
|
+
const agent = yield* agents.createFromConfig(config, {
|
|
86
|
+
// Override the given config optionally with custom values
|
|
59
87
|
model: { id: "composer-2" },
|
|
60
88
|
local: { cwd: process.cwd() },
|
|
61
89
|
});
|
|
@@ -68,56 +96,50 @@ const program = Effect.gen(function* () {
|
|
|
68
96
|
}).pipe(Effect.provide(liveLayer));
|
|
69
97
|
```
|
|
70
98
|
|
|
71
|
-
`AgentOptions.apiKey` is a plain string at the SDK boundary. To keep the key in `Redacted` form until that boundary, read `CURSOR_API_KEY` (and optional `CURSOR_MODEL`, `CURSOR_LOCAL_CWD`) with `loadCursorConfig`, then merge into `AgentOptions` with `agentOptionsFromConfig`.
|
|
72
|
-
In a future version, we might drop the plain `AgentOptions` boundary and require all options to be passed through `CursorConfig` / `loadCursorConfig` / `agentOptionsFromConfig`.
|
|
73
|
-
|
|
74
99
|
Effect’s default `ConfigProvider` reads `process.env`, so you usually do not need to install a custom provider for this.
|
|
75
100
|
|
|
76
|
-
|
|
101
|
+
If you need full control over the merge into SDK options, you can still call `agentOptionsFromConfig` yourself and pass the result to deprecated `create`; prefer `createFromConfig` in application code.
|
|
102
|
+
|
|
103
|
+
## Plain `AgentOptions` at the agent boundary (deprecated)
|
|
104
|
+
|
|
105
|
+
Passing raw `AgentOptions` (for example `apiKey: process.env.CURSOR_API_KEY`) to `create`, `resume`, `prompt`, or `scoped` is **deprecated**. It still works for compatibility, but prefer the config flow above.
|
|
77
106
|
|
|
78
107
|
```ts
|
|
79
|
-
import {
|
|
80
|
-
CursorAgentService,
|
|
81
|
-
CursorRunService,
|
|
82
|
-
agentOptionsFromConfig,
|
|
83
|
-
loadCursorConfig,
|
|
84
|
-
liveLayer,
|
|
85
|
-
} from "effect-cursor-sdk";
|
|
108
|
+
import { CursorAgentService, CursorRunService, liveLayer } from "effect-cursor-sdk";
|
|
86
109
|
import { Effect } from "effect";
|
|
87
110
|
|
|
88
|
-
const
|
|
111
|
+
const legacyProgram = Effect.gen(function* () {
|
|
89
112
|
const agents = yield* CursorAgentService;
|
|
90
113
|
const runs = yield* CursorRunService;
|
|
91
114
|
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
local: { cwd: process.cwd() },
|
|
98
|
-
}),
|
|
99
|
-
);
|
|
115
|
+
const agent = yield* agents.create({
|
|
116
|
+
apiKey: process.env.CURSOR_API_KEY,
|
|
117
|
+
model: { id: "composer-2" },
|
|
118
|
+
local: { cwd: process.cwd() },
|
|
119
|
+
});
|
|
100
120
|
|
|
101
121
|
const run = yield* agents.send(agent, "Explain this repository");
|
|
102
122
|
const text = yield* runs.collectText(run);
|
|
103
|
-
|
|
104
123
|
yield* agents.dispose(agent);
|
|
105
124
|
return text;
|
|
106
125
|
}).pipe(Effect.provide(liveLayer));
|
|
107
126
|
```
|
|
108
127
|
|
|
128
|
+
Migrate by replacing `agents.create({ ... })` with `const config = yield* loadCursorConfig` and `agents.createFromConfig(config, { ... })` (or the other `*FromConfig` helpers).
|
|
129
|
+
|
|
109
130
|
## Scoped Agents
|
|
110
131
|
|
|
111
|
-
Prefer `
|
|
132
|
+
Prefer `scopedFromConfig` when an agent should be disposed automatically:
|
|
112
133
|
|
|
113
134
|
```ts
|
|
114
|
-
import { CursorAgentService, liveLayer } from "effect-cursor-sdk";
|
|
135
|
+
import { CursorAgentService, loadCursorConfig, liveLayer } from "effect-cursor-sdk";
|
|
115
136
|
import { Effect } from "effect";
|
|
116
137
|
|
|
117
138
|
const program = Effect.scoped(
|
|
118
139
|
Effect.gen(function* () {
|
|
119
140
|
const agents = yield* CursorAgentService;
|
|
120
|
-
const
|
|
141
|
+
const config = yield* loadCursorConfig;
|
|
142
|
+
const agent = yield* agents.scopedFromConfig(config, {
|
|
121
143
|
model: { id: "composer-2" },
|
|
122
144
|
local: { cwd: process.cwd() },
|
|
123
145
|
});
|
|
@@ -129,19 +151,19 @@ const program = Effect.scoped(
|
|
|
129
151
|
|
|
130
152
|
## Cloud Agents
|
|
131
153
|
|
|
132
|
-
Cloud options are
|
|
154
|
+
Cloud options are merged as SDK overrides on top of loaded config:
|
|
133
155
|
|
|
134
156
|
```ts
|
|
135
|
-
const
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
157
|
+
const config = yield* loadCursorConfig;
|
|
158
|
+
const agent = yield* agents.createFromConfig(config, {
|
|
159
|
+
model: { id: "composer-2" },
|
|
160
|
+
cloud: {
|
|
161
|
+
repos: [
|
|
162
|
+
{ url: "https://github.com/your-org/your-repo", startingRef: "main" },
|
|
163
|
+
],
|
|
164
|
+
autoCreatePR: true,
|
|
165
|
+
},
|
|
166
|
+
});
|
|
145
167
|
```
|
|
146
168
|
|
|
147
169
|
## Streaming
|
|
@@ -149,18 +171,24 @@ const agent =
|
|
|
149
171
|
`CursorRunService.streamEvents` preserves SDK event shapes and returns an Effect `Stream`.
|
|
150
172
|
|
|
151
173
|
```ts
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
yield
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
174
|
+
import { Effect, Stream } from "effect";
|
|
175
|
+
|
|
176
|
+
const run = yield* agents.send(agent, "Refactor the auth module");
|
|
177
|
+
|
|
178
|
+
yield* runs.streamEvents(run).pipe(
|
|
179
|
+
Stream.runForEach((event) => {
|
|
180
|
+
if (event.type !== "assistant") {
|
|
181
|
+
return Effect.void;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const text = event.message.content
|
|
185
|
+
.filter((block) => block.type === "text")
|
|
186
|
+
.map((block) => block.text)
|
|
187
|
+
.join("");
|
|
188
|
+
|
|
189
|
+
return Effect.sync(() => console.log(text));
|
|
190
|
+
}),
|
|
191
|
+
);
|
|
164
192
|
```
|
|
165
193
|
|
|
166
194
|
## Inspection And Metadata
|
|
@@ -168,13 +196,73 @@ yield *
|
|
|
168
196
|
Use `CursorInspectionService` for agent/run listings, messages, lifecycle operations, account metadata, model discovery, and connected repositories.
|
|
169
197
|
|
|
170
198
|
```ts
|
|
171
|
-
const inspection = yield
|
|
199
|
+
const inspection = yield* CursorInspectionService;
|
|
200
|
+
|
|
201
|
+
const agents = yield* inspection.listAgents({ runtime: "cloud", includeArchived: true });
|
|
202
|
+
const models = yield* inspection.listModels();
|
|
203
|
+
const repos = yield* inspection.listRepositories();
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
## Integrate deeper with Effect
|
|
207
|
+
|
|
208
|
+
Because every Cursor call is an `Effect`, you compose it like the rest of your program: parallel requests, timeouts, retries, logging, and layers all work the same way.
|
|
209
|
+
|
|
210
|
+
This agent garden snapshot loads your catalog in parallel, adds a resilient boundary around the batch, logs a safe summary (counts and IDs only — never log API keys), then asks Cursor for a one-shot triage opinion via `promptFromConfig`:
|
|
211
|
+
|
|
212
|
+
```ts
|
|
213
|
+
import {
|
|
214
|
+
CursorAgentService,
|
|
215
|
+
CursorInspectionService,
|
|
216
|
+
loadCursorConfig,
|
|
217
|
+
liveLayer,
|
|
218
|
+
} from "effect-cursor-sdk";
|
|
219
|
+
import { Effect, Schedule } from "effect";
|
|
172
220
|
|
|
173
|
-
const
|
|
174
|
-
const
|
|
175
|
-
const
|
|
221
|
+
const agentGardenSnapshot = Effect.gen(function* () {
|
|
222
|
+
const inspection = yield* CursorInspectionService;
|
|
223
|
+
const agents = yield* CursorAgentService;
|
|
224
|
+
const config = yield* loadCursorConfig;
|
|
225
|
+
|
|
226
|
+
const catalog = yield* Effect.all(
|
|
227
|
+
{
|
|
228
|
+
cloud: inspection.listAgents({ runtime: "cloud", includeArchived: false }),
|
|
229
|
+
models: inspection.listModels(),
|
|
230
|
+
repos: inspection.listRepositories(),
|
|
231
|
+
},
|
|
232
|
+
{ concurrency: "unbounded" },
|
|
233
|
+
).pipe(
|
|
234
|
+
Effect.retry(
|
|
235
|
+
Schedule.exponential("150 millis").pipe(Schedule.both(Schedule.recurs(3))),
|
|
236
|
+
),
|
|
237
|
+
Effect.timeout("45 seconds"),
|
|
238
|
+
);
|
|
239
|
+
|
|
240
|
+
yield* Effect.logInfo("Cursor catalog loaded", {
|
|
241
|
+
cloudAgents: catalog.cloud.items.length,
|
|
242
|
+
models: catalog.models.length,
|
|
243
|
+
repos: catalog.repos.length,
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
const triage = yield* agents.promptFromConfig(
|
|
247
|
+
[
|
|
248
|
+
"You are helping on-call. Here is non-secret inventory:",
|
|
249
|
+
`- Cloud agents (ids): ${catalog.cloud.items.map((a) => a.agentId).join(", ") || "(none)"}`,
|
|
250
|
+
`- Models (ids): ${catalog.models.map((m) => m.id).join(", ") || "(none)"}`,
|
|
251
|
+
`- Repos (urls): ${catalog.repos.map((r) => r.url).join(", ") || "(none)"}`,
|
|
252
|
+
"In two short sentences: what should we verify first before trusting automation here?",
|
|
253
|
+
].join("\n"),
|
|
254
|
+
config,
|
|
255
|
+
{
|
|
256
|
+
model: { id: "composer-2" },
|
|
257
|
+
},
|
|
258
|
+
);
|
|
259
|
+
|
|
260
|
+
return triage.result;
|
|
261
|
+
}).pipe(Effect.provide(liveLayer));
|
|
176
262
|
```
|
|
177
263
|
|
|
264
|
+
Swap `liveLayer` for `mockLayer({ ... })` in tests and the same program shape exercises your orchestration without the network.
|
|
265
|
+
|
|
178
266
|
## Errors
|
|
179
267
|
|
|
180
268
|
SDK failures are mapped into tagged errors such as `CursorAuthenticationError`, `CursorRateLimitError`, `CursorConfigurationError`, `CursorNetworkError`, and `CursorUnsupportedOperationError`. The original SDK error is preserved as `cause`, with safe operation context and retryability where available.
|
|
@@ -201,12 +289,13 @@ Never log API keys, MCP credentials, authorization headers, or prompt image data
|
|
|
201
289
|
Use `mockLayer` for deterministic tests:
|
|
202
290
|
|
|
203
291
|
```ts
|
|
204
|
-
import { CursorAgentService, mockLayer } from "effect-cursor-sdk";
|
|
292
|
+
import { CursorAgentService, loadCursorConfig, mockLayer } from "effect-cursor-sdk";
|
|
205
293
|
import { Effect } from "effect";
|
|
206
294
|
|
|
207
295
|
const testProgram = Effect.gen(function* () {
|
|
208
296
|
const agents = yield* CursorAgentService;
|
|
209
|
-
const
|
|
297
|
+
const config = yield* loadCursorConfig;
|
|
298
|
+
const agent = yield* agents.createFromConfig(config, { model: { id: "composer-2" } });
|
|
210
299
|
return yield* agents.send(agent, "Hello");
|
|
211
300
|
}).pipe(
|
|
212
301
|
Effect.provide(
|
|
@@ -221,11 +310,11 @@ const testProgram = Effect.gen(function* () {
|
|
|
221
310
|
|
|
222
311
|
The main exports are:
|
|
223
312
|
|
|
224
|
-
- `CursorAgentService`
|
|
313
|
+
- `CursorAgentService` (prefer `createFromConfig`, `scopedFromConfig`, `promptFromConfig`, `resumeFromConfig` with `loadCursorConfig`; plain `AgentOptions` at the agent boundary is [deprecated](./DEPRECATIONS.md))
|
|
225
314
|
- `CursorRunService`
|
|
226
315
|
- `CursorArtifactService`
|
|
227
316
|
- `CursorInspectionService`
|
|
228
|
-
- `CursorSdkFactory`
|
|
317
|
+
- `CursorSdkFactory` ([deprecated for application code](./DEPRECATIONS.md#other-deprecations); low-level tests and overrides)
|
|
229
318
|
- `liveLayer`, `mockLayer`, `liveRuntime`, `makeMockRuntime`
|
|
230
319
|
- `CursorConfig`, `cursorConfig`, `agentOptionsFromConfig`, `loadCursorConfig`
|
|
231
320
|
- tagged Cursor error classes and `mapCursorError`
|
|
@@ -247,6 +336,10 @@ bun run lint:package
|
|
|
247
336
|
|
|
248
337
|
Coverage is measured with Vitest v8 coverage. The suite focuses on deterministic wrapper behavior; live SDK network paths should be validated separately with credentials and a disposable repository.
|
|
249
338
|
|
|
339
|
+
## Deprecations
|
|
340
|
+
|
|
341
|
+
Whenever you need a single place for what is deprecated, what to use instead, how to migrate, and what may change in the next major (when that is already decided), read **[DEPRECATIONS.md](./DEPRECATIONS.md)**. Pair it with **[CHANGELOG.md](./CHANGELOG.md)** for release-by-release notes; `@deprecated` tags on exported symbols mirror the same intent for day-to-day coding.
|
|
342
|
+
|
|
250
343
|
## Versioning and Publishing
|
|
251
344
|
|
|
252
345
|
Use conventional commits for readable history and changelog context:
|