@jaypie/mcp 0.8.30 → 0.8.31

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.
@@ -9,7 +9,7 @@ import { gt } from 'semver';
9
9
  /**
10
10
  * Docs Suite - Documentation services (skill, version, release_notes)
11
11
  */
12
- const BUILD_VERSION_STRING = "@jaypie/mcp@0.8.30#e4c15172"
12
+ const BUILD_VERSION_STRING = "@jaypie/mcp@0.8.31#0d902410"
13
13
  ;
14
14
  const __filename$1 = fileURLToPath(import.meta.url);
15
15
  const __dirname$1 = path.dirname(__filename$1);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jaypie/mcp",
3
- "version": "0.8.30",
3
+ "version": "0.8.31",
4
4
  "description": "Jaypie MCP",
5
5
  "repository": {
6
6
  "type": "git",
@@ -0,0 +1,42 @@
1
+ ---
2
+ version: 0.6.0
3
+ date: 2026-04-13
4
+ summary: Replace `putEntity` with `createEntity` (conditional `attribute_not_exists(id)`) to remove the silent-clobber footgun
5
+ ---
6
+
7
+ ## Breaking changes
8
+
9
+ - **Removed `putEntity`.** The unconditional `PutCommand` it issued was a
10
+ silent-clobber footgun: callers using it as "ensure exists" overwrote
11
+ embedded fields (e.g., `messages: []`) on every call. `putEntity` was also
12
+ semantically identical to `updateEntity`, so it was dead weight as well as
13
+ a trap. Migrate based on intent:
14
+ - "I want this row to exist, do nothing if it already does" → `createEntity`
15
+ - "I want this row to be exactly these values, replacing any prior state" → `updateEntity`
16
+
17
+ ## New
18
+
19
+ - **`createEntity({ entity })`**: writes with
20
+ `ConditionExpression: "attribute_not_exists(id)"`. On
21
+ `ConditionalCheckFailedException`, returns `null` instead of throwing.
22
+ Other errors propagate normally. Return type is `StorableEntity | null`.
23
+
24
+ ## MCP
25
+
26
+ - The `dynamodb_put` tool is renamed to `dynamodb_create` and now wraps
27
+ `createEntity`.
28
+
29
+ ## Migration
30
+
31
+ ```ts
32
+ // Before
33
+ await putEntity({ entity }); // silently overwrote on second call
34
+
35
+ // After — pick the verb that matches intent
36
+ await createEntity({ entity }); // ensure exists; null if id taken
37
+ await updateEntity({ entity }); // overwrite (was putEntity's actual behavior)
38
+ ```
39
+
40
+ Internal callers in `seedExport` (`seedEntityIfNotExists`, `seedEntities`)
41
+ were migrated: the create paths use `createEntity`; the `replace: true`
42
+ path uses `updateEntity`.
@@ -0,0 +1,14 @@
1
+ ---
2
+ version: 0.3.1
3
+ date: 2026-04-13
4
+ summary: FabricData create service uses `createEntity` (was `putEntity`) from `@jaypie/dynamodb` 0.6.0
5
+ ---
6
+
7
+ ## Changes
8
+
9
+ - `createCreateService` (the POST `/{model}` handler in FabricData) now
10
+ imports `createEntity` instead of `putEntity`. Behavior is unchanged in
11
+ practice: the create service generates a fresh UUID for `id`, so the new
12
+ conditional write never collides; if a caller supplies a colliding `id`
13
+ via a custom transform, the service now returns `null` instead of
14
+ silently overwriting.
@@ -0,0 +1,12 @@
1
+ ---
2
+ version: 0.8.31
3
+ date: 2026-04-13
4
+ summary: Update dynamodb skill docs and pull `@jaypie/dynamodb` 0.6.0 (`createEntity` replaces `putEntity`)
5
+ ---
6
+
7
+ ## Changes
8
+
9
+ - `dynamodb` skill updated: `putEntity` examples and table entry replaced
10
+ with `createEntity`.
11
+ - Pulls `@jaypie/dynamodb` 0.6.0 with renamed MCP tool `dynamodb_create`
12
+ (was `dynamodb_put`).
@@ -0,0 +1,11 @@
1
+ ---
2
+ version: 1.2.33
3
+ date: 2026-04-13
4
+ summary: Replace `putEntity` mock with `createEntity` to match `@jaypie/dynamodb` 0.6.0
5
+ ---
6
+
7
+ ## Changes
8
+
9
+ - Removed `putEntity` mock; added `createEntity` mock that returns the
10
+ indexed entity (or `null` to simulate `ConditionalCheckFailedException`,
11
+ via `mockResolvedValueOnce(null)`).
@@ -33,7 +33,7 @@ The runtime package provides entity operations, GSI-based queries, key builders,
33
33
  import {
34
34
  APEX,
35
35
  initClient,
36
- putEntity,
36
+ createEntity,
37
37
  getEntity,
38
38
  deleteEntity,
39
39
  queryByScope,
@@ -44,7 +44,7 @@ import {
44
44
  Or through the main package:
45
45
 
46
46
  ```typescript
47
- import { APEX, initClient, putEntity, queryByScope } from "jaypie";
47
+ import { APEX, initClient, createEntity, queryByScope } from "jaypie";
48
48
  ```
49
49
 
50
50
  ### Client Initialization
@@ -121,10 +121,10 @@ interface StorableEntity {
121
121
  ### Entity Operations
122
122
 
123
123
  ```typescript
124
- import { APEX, putEntity, getEntity, updateEntity, deleteEntity, archiveEntity, destroyEntity } from "@jaypie/dynamodb";
124
+ import { APEX, createEntity, getEntity, updateEntity, deleteEntity, archiveEntity, destroyEntity } from "@jaypie/dynamodb";
125
125
 
126
126
  // Create entity — indexEntity auto-populates GSI keys, createdAt, updatedAt
127
- const record = await putEntity({
127
+ const record = await createEntity({
128
128
  entity: {
129
129
  model: "record",
130
130
  id: crypto.randomUUID(),
@@ -157,7 +157,7 @@ await destroyEntity({ id: "abc-123" });
157
157
 
158
158
  | Function | Description |
159
159
  |----------|-------------|
160
- | `putEntity({ entity })` | Create or replace (auto-indexes GSI keys, auto-timestamps) |
160
+ | `createEntity({ entity })` | Create entity; returns `null` if `id` exists (conditional `attribute_not_exists(id)`) |
161
161
  | `getEntity({ id })` | Get by primary key (id only) |
162
162
  | `updateEntity({ entity })` | Update (sets `updatedAt`, re-indexes) |
163
163
  | `deleteEntity({ id })` | Soft delete (`deletedAt`, `#deleted` suffix on GSI pk) |
@@ -169,16 +169,16 @@ await destroyEntity({ id: "abc-123" });
169
169
  The `scope` field enables parent-child relationships:
170
170
 
171
171
  ```typescript
172
- import { APEX, calculateScope, putEntity, queryByScope } from "@jaypie/dynamodb";
172
+ import { APEX, calculateScope, createEntity, queryByScope } from "@jaypie/dynamodb";
173
173
 
174
174
  // Root-level entity: scope = APEX ("@")
175
- await putEntity({ entity: { model: "chat", scope: APEX, ... } });
175
+ await createEntity({ entity: { model: "chat", scope: APEX, ... } });
176
176
 
177
177
  // Child entity: scope = "{parent.model}#{parent.id}"
178
178
  const chat = { model: "chat", id: "abc-123" };
179
179
  const messageScope = calculateScope(chat); // "chat#abc-123"
180
180
 
181
- await putEntity({
181
+ await createEntity({
182
182
  entity: { model: "message", scope: messageScope, ... },
183
183
  });
184
184
 
@@ -394,7 +394,7 @@ Mock `@jaypie/dynamodb` via testkit. Key builders and `indexEntity` work correct
394
394
  import {
395
395
  APEX,
396
396
  indexEntity,
397
- putEntity,
397
+ createEntity,
398
398
  queryByScope,
399
399
  seedEntities,
400
400
  } from "@jaypie/testkit/mock";