@mortar-ai/skill 0.2.0 → 0.3.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/README.md +6 -0
- package/SKILL.md +108 -9
- package/manifest.json +3 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -35,6 +35,12 @@ The skill teaches Claude:
|
|
|
35
35
|
- **SDK surface** — the `mortar.from()` / `auth` / `storage` /
|
|
36
36
|
`realtime` / `compute` / `usage` / `cron` / `queue` / `comms`
|
|
37
37
|
accessors + the account-scope `AccountClient`; which one to reach for
|
|
38
|
+
- **Transaction boundaries** — atomic row batches and filtered mutations,
|
|
39
|
+
trusted cross-table row + PostgreSQL queue transactions, and why privileged
|
|
40
|
+
transaction clients must never enter browser/mobile bundles
|
|
41
|
+
- **Storage consistency** — immutable physical object versions, atomic metadata
|
|
42
|
+
pointer switches, durable cleanup, and why object storage is not part of a
|
|
43
|
+
PostgreSQL ACID transaction
|
|
38
44
|
- **CLI commands** — `mortar login / use / db / storage / compute /
|
|
39
45
|
cron / queue / domains / comms / keys / tokens / topup / usage`
|
|
40
46
|
- **MCP tools** — the 40 `mortar_*` tools and when an agent should use
|
package/SKILL.md
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
3
|
-
description:
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
name: mortar
|
|
3
|
+
description: Build or change Fabric applications that use Mortar for database, auth, storage, realtime, compute, or analytics. Use for Mortar schema and provisioning, SDK integration, RLS, transactions, or storage consistency; not for Fabric's own control plane or a different backend.
|
|
4
|
+
metadata:
|
|
5
|
+
activation: auto
|
|
6
|
+
priority: high
|
|
7
|
+
triggers:
|
|
8
|
+
- keywords: [database, 数据库, backend, 后端, auth, authentication, 登录, 认证, persistence, 持久化, transaction, 事务, ACID, storage, upload, 文件, realtime, 实时, collaboration, compute, cloud, 云端]
|
|
8
9
|
---
|
|
9
10
|
|
|
10
11
|
# Mortar for Fabric applications
|
|
@@ -59,8 +60,16 @@ below; if platform provisioning fails, report that platform failure.
|
|
|
59
60
|
tenant. Do not edit or create `mortar.config.json`. Do not edit generated
|
|
60
61
|
`integrations/mortar/types.ts`; Fabric regenerates it from the live schema.
|
|
61
62
|
4. Run `npm install @mortar-ai/client` if the dependency is absent, then write app
|
|
62
|
-
code using the injected singleton.
|
|
63
|
-
|
|
63
|
+
code using the injected singleton. Atomic batches, server-side filtered
|
|
64
|
+
mutations, and `DatabaseTransactions` require `@mortar-ai/client` 0.8.0 or
|
|
65
|
+
newer. If an existing project needs one of those capabilities and pins an
|
|
66
|
+
older version, update that dependency with npm and let npm update its lockfile;
|
|
67
|
+
do not rewrite unrelated dependencies.
|
|
68
|
+
5. Before writing a multi-step mutation, choose the supported consistency
|
|
69
|
+
boundary: one-table batches and filtered mutations can use the bundle-safe
|
|
70
|
+
singleton; cross-table row + queue transactions require trusted server code;
|
|
71
|
+
object storage and external services never join a PostgreSQL transaction.
|
|
72
|
+
6. Type-check and build. Handle every `{ data, error }` result in UI code.
|
|
64
73
|
|
|
65
74
|
Supported migration kinds are `create_table`, `drop_table`, `set_table_access`,
|
|
66
75
|
`add_column`, `drop_column`, `create_index`, `set_bucket_access`, `deploy_function`, `delete_function`,
|
|
@@ -103,13 +112,87 @@ const { data: created, error: insertError } = await mortar
|
|
|
103
112
|
.insert({ title: 'Ship', done: false, user_id: userId })
|
|
104
113
|
.select()
|
|
105
114
|
.single();
|
|
106
|
-
|
|
107
115
|
```
|
|
108
116
|
|
|
109
117
|
Updates and deletes use the same filter chain. Useful operators include `eq`,
|
|
110
118
|
`neq`, ranges, `like/ilike`, `in`, `is`, `order`, `limit`, `single`, and
|
|
111
119
|
`maybeSingle`.
|
|
112
120
|
|
|
121
|
+
### Atomic row mutations
|
|
122
|
+
|
|
123
|
+
Pass an array when every insert or upsert must succeed or fail together. Mortar
|
|
124
|
+
sends at most 200 rows in one request and executes the batch in one
|
|
125
|
+
tenant-scoped PostgreSQL transaction. For upsert, a row with an `id` replaces
|
|
126
|
+
that row's data; a row without an `id` inserts. Do not use a loop or
|
|
127
|
+
`Promise.all` when partial completion would break an invariant.
|
|
128
|
+
|
|
129
|
+
```ts
|
|
130
|
+
const { data: createdTodos, error: batchError } = await mortar
|
|
131
|
+
.from('todos')
|
|
132
|
+
.insert([
|
|
133
|
+
{ title: 'Prepare', done: false, user_id: userId },
|
|
134
|
+
{ title: 'Ship', done: false, user_id: userId },
|
|
135
|
+
])
|
|
136
|
+
.select();
|
|
137
|
+
if (batchError) throw new Error(batchError.message);
|
|
138
|
+
|
|
139
|
+
const { data: changedTodos, error: updateError } = await mortar
|
|
140
|
+
.from('todos')
|
|
141
|
+
.update({ done: true })
|
|
142
|
+
.eq('user_id', userId)
|
|
143
|
+
.eq('archived', false)
|
|
144
|
+
.select();
|
|
145
|
+
if (updateError) throw new Error(updateError.message);
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Filtered `update` and `delete` select and mutate all matching rows inside one
|
|
149
|
+
server-side transaction. Do not pre-select IDs and then update/delete them one
|
|
150
|
+
at a time: that creates a race and loses the all-or-nothing guarantee. Chain
|
|
151
|
+
`.select()` only when the app needs the affected rows returned.
|
|
152
|
+
|
|
153
|
+
### Cross-table transactions are server-only
|
|
154
|
+
|
|
155
|
+
`DatabaseTransactions` can atomically combine up to 200 cross-table row
|
|
156
|
+
`insert` / by-ID `update` / by-ID `delete` operations and PostgreSQL-backed
|
|
157
|
+
queue `enqueue` operations. It is intentionally not attached to the injected
|
|
158
|
+
`mortar` singleton and requires an `app` or `admin` key. Its `execute` method
|
|
159
|
+
throws on failure, so use `try`/`catch`, not a `{ data, error }` envelope.
|
|
160
|
+
|
|
161
|
+
```ts
|
|
162
|
+
import { DatabaseTransactions } from '@mortar-ai/client';
|
|
163
|
+
|
|
164
|
+
const transactions = new DatabaseTransactions(serverOnlyMortarOptions);
|
|
165
|
+
|
|
166
|
+
try {
|
|
167
|
+
const results = await transactions.execute([
|
|
168
|
+
{ op: 'insert', table: 'orders', data: { customer_id: customerId, total } },
|
|
169
|
+
{ op: 'enqueue', type: 'send_receipt', payload: { customer_id: customerId } },
|
|
170
|
+
]);
|
|
171
|
+
console.log(results);
|
|
172
|
+
} catch (error) {
|
|
173
|
+
// Nothing committed. Report or retry the whole idempotent operation.
|
|
174
|
+
throw error;
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Never instantiate `DatabaseTransactions` in Web, Desktop renderer,
|
|
179
|
+
Keel/React Native, or WeChat client code. Never add an app/admin key to a
|
|
180
|
+
client-side environment variable or source file. Use this API only in an
|
|
181
|
+
already-approved trusted server environment that holds the key. If a Fabric
|
|
182
|
+
project has no such path, report cross-table ACID as unsupported instead of
|
|
183
|
+
simulating it with several public-client calls. A transactional queue enqueue
|
|
184
|
+
also requires Mortar's PostgreSQL queue backend; otherwise the whole request
|
|
185
|
+
fails without committing row changes.
|
|
186
|
+
|
|
187
|
+
### Exact ACID boundary
|
|
188
|
+
|
|
189
|
+
Mortar provides true ACID only for work executed in the same tenant-scoped
|
|
190
|
+
PostgreSQL transaction: atomic row batches, filtered row mutations, and the
|
|
191
|
+
trusted cross-table row + PostgreSQL queue API above. Object storage,
|
|
192
|
+
compute/functions, communications providers, analytics delivery, and other
|
|
193
|
+
external systems do not participate in that transaction. Never describe a
|
|
194
|
+
workflow spanning them as one ACID transaction or claim two-phase commit.
|
|
195
|
+
|
|
113
196
|
## App-user authentication
|
|
114
197
|
|
|
115
198
|
Auth sessions are persisted and attached to later database, storage, realtime,
|
|
@@ -153,6 +236,22 @@ const { data: signed, error: signError } = await bucket.createSignedUrl(path, 36
|
|
|
153
236
|
const { error: removeError } = await bucket.remove([path]);
|
|
154
237
|
```
|
|
155
238
|
|
|
239
|
+
Applications address files by their stable logical `path`. Mortar stores new
|
|
240
|
+
uploads under immutable internal physical versions, then atomically switches
|
|
241
|
+
its PostgreSQL metadata pointer and durably schedules orphan/replaced versions
|
|
242
|
+
for retryable cleanup. Never construct, persist, or expose Mortar's internal
|
|
243
|
+
physical object key. Existing logical paths remain compatible, and application
|
|
244
|
+
projects do not run or author the platform storage migration.
|
|
245
|
+
|
|
246
|
+
This protocol keeps Mortar's own file metadata from pointing at a partial
|
|
247
|
+
upload, but it does not make a separate application row and an object upload
|
|
248
|
+
one transaction. When a business row must reference a file, generate an
|
|
249
|
+
unguessable logical key. For a simple workflow, upload first and write the
|
|
250
|
+
business row only after upload succeeds. For recoverable workflows, create a
|
|
251
|
+
row with a stable idempotency key and `pending` state, upload, then mark it
|
|
252
|
+
`ready`; reconcile stale rows to `failed` or retry them. Do not issue a database
|
|
253
|
+
write and `bucket.upload()` concurrently and call the result atomic.
|
|
254
|
+
|
|
156
255
|
Downloads mint a short-lived URL and fetch the object directly from the storage
|
|
157
256
|
backend. Reuse `signed.signedUrl` until it nears expiry when rendering media.
|
|
158
257
|
Prefer the signed URL directly in `<img src>`, `<video src>`, or `<audio src>`;
|
package/manifest.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema_version": 1,
|
|
3
3
|
"id": "mortar",
|
|
4
|
-
"version": "0.
|
|
5
|
-
"content_sha256": "sha256:
|
|
4
|
+
"version": "0.3.0",
|
|
5
|
+
"content_sha256": "sha256:c69dab74ad4a377086c0c883c4d400770600738de2741778fad21ec27e925f27",
|
|
6
6
|
"source_repo": "liamxujia/appunvs",
|
|
7
7
|
"source_path": "mortar/skill/SKILL.md",
|
|
8
8
|
"distributions": [
|
|
@@ -11,6 +11,6 @@
|
|
|
11
11
|
],
|
|
12
12
|
"npm": {
|
|
13
13
|
"package": "@mortar-ai/skill",
|
|
14
|
-
"version": "0.
|
|
14
|
+
"version": "0.3.0"
|
|
15
15
|
}
|
|
16
16
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mortar-ai/skill",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Agent skill package for building Fabric applications on Mortar (BaaS), distributed from one versioned SKILL.md with a content-addressed manifest.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"files": ["SKILL.md", "manifest.json", "index.js", "README.md"],
|