softr-vibe-coding 2.11.0 → 2.11.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/CHANGELOG.md CHANGED
@@ -4,6 +4,9 @@ All notable changes to this skill are documented here. Versions follow [Semantic
4
4
 
5
5
  Entries from 1.3.1 onward are generated automatically from git commit subjects between version bumps (see `.github/workflows/publish.yml`). Entries before 1.3.1 were backfilled by hand from the existing commit history.
6
6
 
7
+ ## [2.11.1] - 2026-10-01
8
+ - Correct four 2.11.0 statements after an independent fact-check of the transcripts
9
+
7
10
  ## [2.11.0] - 2026-10-01
8
11
  - Track Softr's 2026-10-01 MCP release: renamed tools, sourceSha256 push checks, stub-tool root cause
9
12
 
package/README.md CHANGED
@@ -195,8 +195,8 @@ softr-vibe-coding/
195
195
  │ │ # enforces on block data endpoints, "Preview as"
196
196
  │ │ # role testing, search-replace on 100KB+ blocks
197
197
  │ │ # (Sep 18 2026); Oct 1 2026: tool rename map,
198
- │ │ # push verification by sourceSha256, stub-tool
199
- │ │ # root cause, update_field/update_table fixes
198
+ │ │ # push verification by sourceSha256, stub tools
199
+ │ │ # after a resume, update_field/update_table fixes
200
200
  │ ├── advanced-integrations.md # Shadow DOM CSS isolation
201
201
  │ │ # Leaflet, Mapbox, TinyMCE, Quill, FullCalendar
202
202
  │ ├── native-chrome-styling.md # Restyle Softr's native shell (header, footer,
package/SKILL.md CHANGED
@@ -570,8 +570,9 @@ Non-negotiable rules. Most are enforced by the Softr platform (compiler, validat
570
570
  everyone can see it comes back `ALL_USERS`, i.e. writable by logged-OUT visitors (UPDATE/DELETE
571
571
  reset to logged-in users). The MCP call that re-tightens it (`vibe_coding_block_set_action_visibility`)
572
572
  can itself fail with no fallback. It fails when the client holds only a stub of the tool
573
- (name-only description, no properties), which happens after a session resume, so check the
574
- loaded definition and start a fresh session if it is a stub (see
573
+ (name-only description, no properties), which has happened after a session was resumed. Check
574
+ the loaded definition; if it is a stub, start a fresh top-level session (a subagent inherits the
575
+ stubs) (see
575
576
  [references/softr-mcp.md](references/softr-mcp.md#the-array-argument-rejection-and-why-it-is-a-security-issue)).
576
577
  A push that returns `errors: null` can still have left public write access on the block.
577
578
  **If any action is still broader than intended, report it WITH its severity and let the builder decide.**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "softr-vibe-coding",
3
- "version": "2.11.0",
3
+ "version": "2.11.1",
4
4
  "description": "Claude Code skill for generating production-ready Softr Vibe Coding blocks (JSX). Installs into ~/.claude/skills/ and auto-updates on each Claude Code session.",
5
5
  "bin": {
6
6
  "softr-vibe-coding": "./bin/cli.js"
@@ -44,7 +44,7 @@ Run through this catalog before delivering any block. Every row is a violation o
44
44
  | Tightening Actions-tab permissions before the block's final redeploy | Every code recompile **resets the auto-registered Actions to default permissions** (verified live 2026-08-25). Tighten permissions after the LAST redeploy, and re-check after any future one |
45
45
  | Assuming a comment-only edit is "safe" and leaves Action permissions alone | There is no cosmetic-edit exemption. Any save recompiles, and every recompile rebuilds the Actions at default visibility — a `search_replace` changing nothing but a code comment resets them exactly like a rewrite (verified live 2026-09-09, on two blocks at once). Re-check after EVERY push, including cosmetic ones |
46
46
  | Treating the permission-restore call as done because you issued it | Read the permissions back with `vibe_coding_block_get_settings` and confirm each one changed. `vibe_coding_block_set_action_visibility` can fail outright on the array-argument rejection (the client holding only a stub of the tool, typically after a session resume), and it has **no fallback** — the default for ADD_RECORD follows the block's own visibility, so on a block everyone can see, a routine push silently leaves it publicly writable while returning `errors: null`. Verified live 2026-09-09: four ADD_RECORD actions left open across two blocks. Report the list with its severity — check the page's VIEW permission with `application_page_get_permissions`, since a logged-in-gated page makes this housekeeping while a public page makes it a real hole — and let the builder decide whether it holds their release. A human sets them on the block's Actions tab |
47
- | Calling an array-argument MCP tool (`vibe_coding_block_set_action_visibility`, `vibe_coding_block_update_code_search_replace`) when its loaded definition is a stub — description identical to the tool name, schema `{"type":"object"}` with no properties | A stub declares no types, so the array is sent as a JSON string and rejected (since 2026-10-01 the error reads "Parameter '…' must be an array of objects, but a string was sent"). Stubs appear after a session resume. Start a fresh session, which reloads the real definitions, then call. Root cause established 2026-10-01 — see [softr-mcp.md](softr-mcp.md#the-array-argument-rejection-and-why-it-is-a-security-issue) |
47
+ | Calling an array-argument MCP tool (`vibe_coding_block_set_action_visibility`, `vibe_coding_block_update_code_search_replace`) when its loaded definition is a stub — description identical to the tool name, schema `{"type":"object"}` with no properties | A stub declares no types, so the array is sent as a JSON string and rejected (since 2026-10-01 the error reads "Parameter '…' must be an array of objects, but a string was sent"). Stubs have appeared after a session was resumed, and subagents spawned from that session inherit them. Start a fresh top-level session, which reloaded the real definitions when we tried it, then call. Found 2026-10-01 — see [softr-mcp.md](softr-mcp.md#the-array-argument-rejection-and-why-it-is-a-security-issue) |
48
48
  | Verifying a push by pulling the whole block source back into the model's context | Compare `sourceSha256` from the push result (or from `vibe_coding_block_get_code` with `includeCode: false`) with `shasum -a 256` of the file you sent; fetch the full source only when the digest is missing or differs. Available since 2026-10-01 — see [softr-mcp.md](softr-mcp.md#verifying-a-push--the-deployed-source-is-the-only-proof) |
49
49
  | Splitting one table's writes across several `useRecordUpdate` hooks (or across two connections of the same table) to get separately-permissioned Actions | Actions register per **TABLE**: the hooks merge into ONE UPDATE_RECORD action whose field list is the union, and a hook pointed at a second connection of the table is still filed under the FIRST connection's dataSourceId (verified live 2026-09-18). Point writes at the table's first connection; expect one action per table + operation when re-tightening permissions. See [datasources/writing.md](../datasources/writing.md#actions-register-per-table-not-per-hook-or-connection) |
50
50
  | Treating Studio's Actions tab as a separately-managed configuration to keep in sync with code | Actions auto-derive from your `useRecordCreate`/`useRecordUpdate`/`useRecordDelete` + `q.select` on every save. The Actions tab is a read-only inspector; there is no manual delete control. To change an Action, change the code |
@@ -35,13 +35,13 @@ The official Softr MCP server (`https://mcp.softr.io/mcp`) gives an AI assistant
35
35
  | Applications | **Create whole apps**; manage app users and login settings; swap an app's data source; read apps, pages, blocks, permissions, user groups; preview; publish — see [Application management tools](#application-management-tools) | https://docs.softr.io/mcp/apps |
36
36
  | Vibe coding blocks | Create and edit blocks, manage settings, visibility, versions, data source connections | https://docs.softr.io/mcp/vibe-coding |
37
37
  | Integrations | Browse external data sources connected to the workspace, down to field level | https://docs.softr.io/mcp/integrations |
38
- | Workflows | Build, wire, test, and publish workflows — 26 tools and a 418-node trigger/action catalog; see [Workflows](#workflows) | https://docs.softr.io/mcp/workflows |
38
+ | Workflows | Build, wire, test, and publish workflows — 28 tools and a 418-node trigger/action catalog; see [Workflows](#workflows) | https://docs.softr.io/mcp/workflows |
39
39
 
40
40
  `workspace_list` is often the first call — it turns "my Sales workspace" into the workspace ID every other tool needs. The server's own instructions now start from `application_list` (applications and their workspace IDs) and `database_list` (databases), and keep `workspace_list` for turning a workspace name into an ID.
41
41
 
42
42
  ## Tool names — the 2026-10-01 rename
43
43
 
44
- On 2026-10-01 Softr renamed every workspace-server tool outside Workflows to **area first, then verb**:
44
+ On 2026-10-01 Softr renamed the workspace-server tools outside Workflows to **area first, then verb**:
45
45
  `vibe_coding_block_*`, `application_*` (pages are `application_page_*`), `database_*`,
46
46
  `integration_*` and `workspace_*`. 79 tools were renamed and one was added
47
47
  (`application_update_pwa_settings`); the 28 Workflows tools and `get_workspace_integrations` kept their names. The
@@ -264,9 +264,10 @@ unverified until the deployed source is proven identical to your file.
264
264
  search-replace) and `vibe_coding_block_get_code` carry `sourceSha256` and `sourceBytes`: the SHA-256
265
265
  of the UTF-8 source Softr persisted, and its length in bytes. A failed compile stores nothing and
266
266
  reports neither field. With `includeCode: false`, `vibe_coding_block_get_code` returns the digest and
267
- `sourceCode: null`. Verified live 2026-10-01: a deployed block's `sourceSha256` equalled
268
- `shasum -a 256` of the file last pushed to it, and the read came back at about 1 KB for a 15 KB
269
- block. (The digest on push results is per Softr's release notes; no push of ours has shown it yet.)
267
+ `sourceCode: null`. Verified live 2026-10-01: a deployed block's `sourceSha256` equalled the SHA-256
268
+ of the exact source last pushed to it (taken from the push call), and the read came back at about
269
+ 1 KB for a 15 KB block. The same check showed that block's local mirror had picked up three comment
270
+ edits since that push, which is exactly what step 1 below exists to catch. (The digest on push results is per Softr's release notes; no push of ours has shown it yet.)
270
271
  Right after that release our client's copy of the tool definition did not declare `includeCode`, so
271
272
  the argument went out as the string `"false"` and the server still honoured it. Whatever the loaded
272
273
  definition says, check that `sourceCode` came back `null`.
@@ -293,7 +294,7 @@ definition says, check that `sourceCode` came back `null`.
293
294
  by eye.
294
295
 
295
296
  **Hash the exact bytes, trailing newline included.** Softr stores exactly what it receives: across
296
- 58 push→fetch pairs between 2026-08-26 and 2026-09-10 (14 blocks, 16–161 KB each) the fetched
297
+ 112 push→fetch pairs between 2026-09-09 and 2026-09-30 the fetched
297
298
  `sourceCode` was byte- and MD5-identical to the text sent, including two pushes sent *without* a
298
299
  final newline and stored without one. The "deployed block is one byte shorter" we chased on
299
300
  2026-09-09 was our own read: an agent that reads a large file in chunks can drop the final
@@ -347,19 +348,23 @@ from String value (token `JsonToken.VALUE_STRING`)
347
348
  | `vibe_coding_block_update_code_search_replace` | `operations` | Start a fresh session (below) | Use `vibe_coding_block_update_code` (full replace) |
348
349
  | `vibe_coding_block_set_action_visibility` | `updates` | Start a fresh session (below) | **NONE — a human must fix it in Studio** |
349
350
 
350
- **Where the string comes from — root cause found 2026-10-01: tool stubs in a resumed session.**
351
- When Claude Code resumes a session, MCP connector tools it already knew can come back as **stubs**:
352
- the description is just the tool name and the input schema is `{"type":"object"}`, with no
353
- properties. They stay stubs until the connector delivers its definitions again, which a fresh session
354
- does (so did reconnecting the connector, once). A stub declares no types, so an array argument
355
- goes out as a JSON string and Softr rejects it. Nothing is written, so the failure is safe, but no
356
- amount of care on the caller's side gets an array through a stub. The evidence, from the complete
357
- transcripts of one build:
351
+ **Where the string comes from: tool stubs on the client side (found 2026-10-01).** In the sessions
352
+ we examined, our client (Claude Code) at times held the Softr tools as **stubs**: the description is
353
+ just the tool name and the input schema is `{"type":"object"}`, with no properties. A stub declares
354
+ no types, so an array argument goes out as a JSON string and Softr rejects it. Nothing is written,
355
+ so the failure is safe, but no amount of care on the caller's side gets an array through a stub.
356
+ The evidence, from the complete transcripts of one build:
358
357
 
359
358
  - On 2026-09-09 every successful array call came before that session was resumed, and every
360
359
  rejected one came after.
361
- - On 2026-09-30, in a resumed session, every Softr tool definition the client recorded was a stub.
362
- - A fresh session on 2026-10-01 loaded the full definitions.
360
+ - On 2026-09-30, after the session was picked up again, every Softr tool definition the client
361
+ recorded was a stub: in the session itself and in all 47 subagents it spawned. A live tool-list
362
+ update from the server that day did not change that.
363
+ - Only two things ever replaced the stubs with real definitions: re-adding the connector (once) and
364
+ a fresh session (2026-10-01).
365
+ - Not every pick-up produced stubs: a session picked up on the morning of 2026-09-09 held real
366
+ definitions. So the trigger is not fully understood. The stubs most likely come from our side
367
+ rather than Softr's server, since a fresh session got full definitions from the same server.
363
368
 
364
369
  This replaces two earlier explanations in this file: that the model "had not loaded the tool
365
370
  definitions" (2026-09-10), and that the workspace server's tools "can arrive schema-less"
@@ -370,7 +375,8 @@ publish full schemas.
370
375
 
371
376
  **The rule:** before any array-argument call, look at the tool's loaded definition (ToolSearch shows
372
377
  it). If the description is just the tool name and there are no `properties`, do not make the call:
373
- start a fresh session first. That matters most for `vibe_coding_block_set_action_visibility`, which
378
+ start a fresh top-level session first. A subagent is not a fresh session; it inherits the stubs.
379
+ That matters most for `vibe_coding_block_set_action_visibility`, which
374
380
  has no fallback. For a code edit, a full replace is an acceptable stopgap: one file per subagent for
375
381
  a large block, hash-verified.
376
382
 
@@ -378,8 +384,8 @@ a large block, hash-verified.
378
384
  block's auto-registered Actions at Softr's default permissions. Per Softr (2026-10-01), the default
379
385
  for **ADD_RECORD follows the block's own visibility**. On a block everyone can see, it comes back
380
386
  `ALL_USERS`, writable by logged-OUT visitors. UPDATE_RECORD and DELETE_RECORD are always reset to
381
- `LOGGED_IN_USERS`. That is what we saw on 2026-09-09, when one push left four ADD_RECORD actions
382
- open across two blocks. The remedy is to re-apply the permissions with
387
+ `LOGGED_IN_USERS`. That is what we saw on 2026-09-09, when one round of pushes (two saves, one per
388
+ block) left four ADD_RECORD actions open across two blocks and every restore call was rejected. The remedy is to re-apply the permissions with
383
389
  `vibe_coding_block_set_action_visibility`. When that call is the one that fails, a routine cosmetic
384
390
  push silently leaves public write access on the block. Nothing in the push result says so: the push
385
391
  itself returns `errors: null, warnings: null`.
@@ -522,8 +528,8 @@ Combined with the database tools (`database_create` / `database_create_table` /
522
528
  blocks yet. Softr has said placement will come later. Until then, a human drags it into place in
523
529
  Studio. Say so when you hand the block over.
524
530
  - **Timestamps are UTC with a `Z`.** Since 2026-10-01, timestamps such as `publishedAt` or a
525
- version's `createdAt` are ISO-8601 UTC with millisecond precision on both server kinds (verified
526
- on `vibe_coding_block_list_versions` that day). Before then, studio-side timestamps came back with
531
+ version's `createdAt` are ISO-8601 UTC with millisecond precision, studio-side and tables-side
532
+ alike (per Softr; verified on `vibe_coding_block_list_versions` that day). Before then, studio-side timestamps came back with
527
533
  no zone designator and nine fractional digits (`2026-09-09T22:34:11.157881061`). They were UTC, so
528
534
  read any older logged value as UTC, never as local time.
529
535
 
@@ -602,7 +608,7 @@ For Softr's native databases the MCP goes far beyond browsing: `database_get_fie
602
608
 
603
609
  **Call economy (from the server's own instructions):** `database_get_table` returns a table's metadata AND all its field definitions in one call; `database_list_fields` returns the fields alone. Call ONE of them once per table and reuse the result — never both — and re-fetch only after you changed the table's fields yourself.
604
610
 
605
- **`database_get_field_reference` (was `get_schema`).** It describes the whole product, not one table: it takes no table ID and returns the same content every time. Live-confirmed 2026-08-31: `readOnlyFieldTypes` = AUTONUMBER, COUNT, CREATED_AT, CREATED_BY, FORMULA, LOOKUP, RECORD_ID, ROLLUP, UPDATED_AT, UPDATED_BY. On 2026-10-01 the list was the same without COUNT, which no longer appears in either the read-only list or the field types. The `LINKED_RECORD` value example is `["record-id-1", "record-id-2"]` — independently corroborating the verified string-array write shape in [../datasources/softr-database.md](../datasources/softr-database.md). On 2026-10-01 it listed `allowMultipleEntries` among the available options of SELECT and LINKED_RECORD. Operator families include relative-date `IS_WITHIN` / `IS_NOT_WITHIN` ("last 7 days"), ternary `IS_BETWEEN` / `IS_NOT_BETWEEN`, and `AND`/`OR` composites. **Schema-drift caution:** this reference and the [per-application servers'](#per-application-mcp-servers) `get_schema` have drifted. The per-app catalog lists creatable types the workspace one omits: ADDRESS, PROGRESS, TIME, DATE_RANGE and BUTTON were still absent from the workspace reference on 2026-10-01, although, per Softr, the workspace server returns fields of those types. The operator NAMES differed too (workspace `GREATER_THAN` / `DOES_NOT_CONTAIN` vs per-app `GT` / `DOES_NOT_CONTAINS`, observed 2026-08-31); per Softr the per-app names were realigned on 2026-09-09, which we have not re-checked. Do not assume a filter payload is portable between the two kinds: call the reference of the server you are actually using.
611
+ **`database_get_field_reference` (was `get_schema`).** It describes the whole product, not one table: it takes no table ID and returns the same content every time. Live-confirmed 2026-08-31 (and in reads of 2026-08-26 and 2026-09-09): `readOnlyFieldTypes` = AUTONUMBER, COUNT, CREATED_AT, CREATED_BY, FORMULA, LOOKUP, RECORD_ID, ROLLUP, UPDATED_AT, UPDATED_BY. On 2026-10-01 the list was the same without COUNT, which no longer appears in either the read-only list or the field types. The `LINKED_RECORD` value example is `["record-id-1", "record-id-2"]` — independently corroborating the verified string-array write shape in [../datasources/softr-database.md](../datasources/softr-database.md). On 2026-10-01 it listed `allowMultipleEntries` among the available options of SELECT and LINKED_RECORD. Operator families include relative-date `IS_WITHIN` / `IS_NOT_WITHIN` ("last 7 days"), ternary `IS_BETWEEN` / `IS_NOT_BETWEEN`, and `AND`/`OR` composites. **Schema-drift caution:** this reference and the [per-application servers'](#per-application-mcp-servers) `get_schema` have drifted. The per-app catalog lists creatable types the workspace one omits: ADDRESS, PROGRESS, TIME, DATE_RANGE and BUTTON were still absent from the workspace reference on 2026-10-01, although, per Softr, the workspace server returns fields of those types. The operator NAMES differed too (workspace `GREATER_THAN` / `DOES_NOT_CONTAIN` vs per-app `GT` / `DOES_NOT_CONTAINS`, observed 2026-08-31); per Softr the per-app names were realigned on 2026-09-09, which we have not re-checked. Do not assume a filter payload is portable between the two kinds: call the reference of the server you are actually using.
606
612
 
607
613
  Known limits and behaviors (per official docs):
608
614
 
@@ -694,7 +700,7 @@ A separate product class from the workspace server (live-observed 2026-08-31 on
694
700
 
695
701
  **Tools (12):** `list_tables`, `describe_table`, `get_schema`, `get_records`, `get_record`, `get_linked_records`, `get_current_user`, `create_record`, `update_record`, `delete_record`, `batch_update_records`, `batch_delete_records`. These are this server's own names, last enumerated by us in late August 2026; the 2026-10-01 rename of the workspace server did not touch them.
696
702
 
697
- **If the tool definitions arrive empty, do not conclude the server sent them that way.** Every definition of these tools our client ever recorded had a name-only description and an `{"type":"object"}` schema, the same signature as the stubs described [above](#the-array-argument-rejection-and-why-it-is-a-security-issue). Unlike the workspace stubs, these were stubs even at times when the same client held real workspace definitions, so their cause is not settled. Per Softr, these servers publish full schemas and descriptions. A tool with no arguments (`list_tables`, `get_schema`, `get_current_user`) works either way; before relying on one that takes arguments, start a fresh session and check the loaded definition again.
703
+ **If the tool definitions arrive empty, do not conclude the server sent them that way.** Every definition of these tools our client ever recorded had a name-only description and an `{"type":"object"}` schema, the same signature as the stubs described [above](#the-array-argument-rejection-and-why-it-is-a-security-issue). Unlike the workspace stubs, these were stubs even at times when the same client held real workspace definitions, so their cause is not settled. Per Softr, these servers publish full schemas and descriptions. A tool with no arguments (`list_tables`, `get_schema`, `get_current_user`) works either way; before relying on one that takes arguments, start a fresh top-level session and check the loaded definition again.
698
704
 
699
705
  **Live-observed semantics:**
700
706