@mortar-ai/skill 0.1.0 → 0.2.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 CHANGED
@@ -1,8 +1,8 @@
1
1
  # @mortar-ai/skill
2
2
 
3
- [Claude Code](https://claude.ai/code) skill package for building on
4
- **Mortar** (the BaaS that AI bundles talk to). Drop it into your skills
5
- directory + Claude becomes instantly Mortar-fluent: knows the SDK
3
+ [Agent Skills](https://agentskills.io/) package for building on **Mortar** (the
4
+ BaaS that AI bundles talk to). Install the canonical `SKILL.md` into a compatible
5
+ agent's skill directory to teach it the SDK
6
6
  accessors, CLI commands, MCP tools, and — most importantly — the
7
7
  tenant-isolation + `auth.tenant_id()` RLS rules that are the easiest
8
8
  thing to get wrong.
@@ -17,6 +17,12 @@ mortar-skill-install
17
17
 
18
18
  Then restart Claude Code (or `/skill reload`).
19
19
 
20
+ The same versioned `SKILL.md` is packaged into Fabric Harness. `manifest.json`
21
+ binds the npm version and Harness preinstall to its SHA-256 digest; the Fabric
22
+ Server rejects a Market install when the running Harness reports different
23
+ bytes. npm is an external distribution channel and is not required by Fabric at
24
+ runtime.
25
+
20
26
  Pairs naturally with the [Mortar MCP server](../mcp) — the skill teaches Claude
21
27
  *how* to think about Mortar; the MCP gives it live tools to *act* on a
22
28
  project. Install both for the full Supabase-plugin-equivalent
@@ -56,6 +62,19 @@ Useful for team-shared skill repositories or in-repo skill packs.
56
62
  Re-run `mortar-skill-install` after `npm update @mortar-ai/skill`.
57
63
  Idempotent — overwrites in place.
58
64
 
65
+ ## Maintainer release
66
+
67
+ `SKILL.md` is the only hand-edited instruction source. Regenerate the manifest
68
+ and Harness copy before testing or publishing:
69
+
70
+ ```bash
71
+ npm run sync
72
+ npm run check
73
+ npm pack --dry-run
74
+ ```
75
+
76
+ Never edit `fabric/harness/internal/skills/preinstalled/mortar/` directly.
77
+
59
78
  ## License
60
79
 
61
80
  Apache-2.0 (same as the rest of Mortar).
@@ -62,12 +62,6 @@ below; if platform provisioning fails, report that platform failure.
62
62
  code using the injected singleton.
63
63
  5. Type-check and build. Handle every `{ data, error }` result in UI code.
64
64
 
65
- Example schema operations (the tool schema is authoritative for all fields):
66
-
67
- ```json
68
- {"kind":"create_table","table":"todos","access":"private","columns":[{"name":"title","type":"text","required":true},{"name":"done","type":"bool"},{"name":"user_id","type":"uuid","required":true}]}
69
- ```
70
-
71
65
  Supported migration kinds are `create_table`, `drop_table`, `set_table_access`,
72
66
  `add_column`, `drop_column`, `create_index`, `set_bucket_access`, `deploy_function`, `delete_function`,
73
67
  `upsert_cron`, and `delete_cron`. Destructive and backend-changing operations
@@ -110,20 +104,11 @@ const { data: created, error: insertError } = await mortar
110
104
  .select()
111
105
  .single();
112
106
 
113
- const { data: updated, error: updateError } = await mortar
114
- .from('todos')
115
- .update({ done: true })
116
- .eq('id', todoId)
117
- .select();
118
-
119
- const { error: deleteError } = await mortar
120
- .from('todos')
121
- .delete()
122
- .eq('id', todoId);
123
107
  ```
124
108
 
125
- Useful chaining includes `eq`, `neq`, `gt/gte`, `lt/lte`, `like/ilike`, `in`,
126
- `is`, `order`, `range`, `limit`, `single`, and `maybeSingle`.
109
+ Updates and deletes use the same filter chain. Useful operators include `eq`,
110
+ `neq`, ranges, `like/ilike`, `in`, `is`, `order`, `limit`, `single`, and
111
+ `maybeSingle`.
127
112
 
128
113
  ## App-user authentication
129
114
 
@@ -139,15 +124,12 @@ const verified = await mortar.auth.verifyOtp({ email, token });
139
124
 
140
125
  const { data: sessionData } = await mortar.auth.getSession();
141
126
  const { data: userData, error: userError } = await mortar.auth.getUser();
142
-
143
- const { data: listener } = mortar.auth.onAuthStateChange((event, session) => {
144
- // INITIAL_SESSION | SIGNED_IN | SIGNED_OUT | TOKEN_REFRESHED
145
- });
146
- listener.subscription.unsubscribe();
147
-
148
127
  await mortar.auth.signOut();
149
128
  ```
150
129
 
130
+ Use `onAuthStateChange` when UI must react to session changes, and unsubscribe
131
+ the returned subscription during cleanup.
132
+
151
133
  Password reset starts with `mortar.auth.resetPasswordForEmail(email)`; confirm via
152
134
  `passwordResetConfirm(email, token, newPassword)`. Never store or pass session
153
135
  tokens manually unless the user explicitly needs a server integration.
@@ -180,16 +162,9 @@ budget, but clients should still lazy-load visible media and cache/reuse each
180
162
  URL instead of signing again on every render. Signing authorizes a possible
181
163
  download; it does not prove bytes were served and must never be described or
182
164
  modeled as an object-egress charge. Only provider-observed access-log or billing
183
- reconciliation may record actual object egress. Use the third
184
- `createSignedUrl` argument to bound only the signing request when the UI needs
185
- a deadline:
186
-
187
- ```ts
188
- const { data: signed, error } = await bucket.createSignedUrl(path, 900, {
189
- signal: controller.signal,
190
- timeoutMs: 10_000,
191
- });
192
- ```
165
+ reconciliation may record actual object egress. The optional third
166
+ `createSignedUrl` argument (`{ signal, timeoutMs }`) bounds only the signing
167
+ request when the UI needs a deadline.
193
168
 
194
169
  `bucket.download(path)` uses JavaScript `fetch()` against the object store and
195
170
  therefore needs a matching bucket CORS rule in browsers. Appunvs-managed Mortar
@@ -223,26 +198,10 @@ realtime only notifies peers.
223
198
 
224
199
  ## Compute and analytics
225
200
 
226
- Invoke only functions already deployed through `mortar_migrate`:
227
-
228
- ```ts
229
- const response = await mortar.compute.invoke({
230
- name: 'summarize',
231
- method: 'POST',
232
- body: JSON.stringify({ text }),
233
- contentType: 'application/json',
234
- });
235
- if (!response.ok) throw new Error(await response.text());
236
- ```
237
-
238
- Analytics calls are fire-and-forget except `flush`:
239
-
240
- ```ts
241
- mortar.analytics.track('pageview', { path: location.pathname });
242
- mortar.analytics.identify(user.id, { plan: 'free' });
243
- mortar.analytics.captureError(error, { screen: 'checkout' });
244
- await mortar.analytics.flush();
245
- ```
201
+ Invoke only functions already deployed through `mortar_migrate`; check
202
+ `response.ok` and read the response body. Analytics provides `track`,
203
+ `identify`, `captureError`, and `flush`; events are fire-and-forget except
204
+ `flush`.
246
205
 
247
206
  ## Boundary for non-Fabric development
248
207
 
package/bin/install.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * mortar-skill-install — copies mortar-skill.md into the user's Claude
3
+ * mortar-skill-install — copies the canonical SKILL.md into the user's Claude
4
4
  * Code skills directory.
5
5
  *
6
6
  * Default destination: `~/.claude/skills/mortar/SKILL.md`. Override
@@ -26,7 +26,7 @@ function parseFlags(argv) {
26
26
 
27
27
  function main() {
28
28
  const flags = parseFlags(process.argv);
29
- const src = resolve(__dirname, '..', 'mortar-skill.md');
29
+ const src = resolve(__dirname, '..', 'SKILL.md');
30
30
  if (!existsSync(src)) {
31
31
  console.error(`mortar-skill: source missing at ${src}`);
32
32
  process.exit(1);
package/index.js CHANGED
@@ -9,7 +9,8 @@
9
9
  const { readFileSync } = require('node:fs');
10
10
  const { resolve } = require('node:path');
11
11
 
12
- const SKILL_PATH = resolve(__dirname, 'mortar-skill.md');
12
+ const SKILL_PATH = resolve(__dirname, 'SKILL.md');
13
+ const MANIFEST_PATH = resolve(__dirname, 'manifest.json');
13
14
 
14
15
  module.exports = {
15
16
  /**
@@ -20,5 +21,9 @@ module.exports = {
20
21
  skillContents() {
21
22
  return readFileSync(SKILL_PATH, 'utf8');
22
23
  },
24
+ manifest() {
25
+ return JSON.parse(readFileSync(MANIFEST_PATH, 'utf8'));
26
+ },
23
27
  SKILL_PATH,
28
+ MANIFEST_PATH,
24
29
  };
package/manifest.json ADDED
@@ -0,0 +1,16 @@
1
+ {
2
+ "schema_version": 1,
3
+ "id": "mortar",
4
+ "version": "0.2.0",
5
+ "content_sha256": "sha256:dd11d5e635f47e64303927fd4af21b0f8a9aef8836a17c3a592eecb69cc75325",
6
+ "source_repo": "liamxujia/appunvs",
7
+ "source_path": "mortar/skill/SKILL.md",
8
+ "distributions": [
9
+ "harness_preinstalled",
10
+ "npm"
11
+ ],
12
+ "npm": {
13
+ "package": "@mortar-ai/skill",
14
+ "version": "0.2.0"
15
+ }
16
+ }
package/package.json CHANGED
@@ -1,12 +1,16 @@
1
1
  {
2
2
  "name": "@mortar-ai/skill",
3
- "version": "0.1.0",
4
- "description": "Claude Code skill package for building on Mortar (BaaS). Drop `mortar-skill.md` into ~/.claude/skills/mortar/ to give Claude expert-level guidance about the Mortar SDK / CLI / MCP, tenant isolation + auth.tenant_id() RLS, and the 9 primitive × feature model.",
3
+ "version": "0.2.0",
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
- "files": ["mortar-skill.md", "index.js", "README.md"],
6
+ "files": ["SKILL.md", "manifest.json", "index.js", "README.md"],
7
7
  "bin": {
8
8
  "mortar-skill-install": "bin/install.js"
9
9
  },
10
+ "scripts": {
11
+ "sync": "node scripts/sync-distributions.js",
12
+ "check": "node scripts/sync-distributions.js --check"
13
+ },
10
14
  "publishConfig": { "access": "public" },
11
15
  "license": "Apache-2.0"
12
16
  }