softr-vibe-coding 2.14.4 → 2.14.5
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 +4 -0
- package/README.md +6 -1
- package/datasources/hubspot.md +4 -1
- package/package.json +1 -1
- package/references/softr-mcp.md +57 -3
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,10 @@ 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.14.5] - 2026-10-07
|
|
8
|
+
- Release 2.14.5
|
|
9
|
+
- Document condition-based user groups over the MCP
|
|
10
|
+
|
|
7
11
|
## [2.14.4] - 2026-10-07
|
|
8
12
|
- Release 2.14.4
|
|
9
13
|
- Add the Safari focus rule to the Combo reference
|
package/README.md
CHANGED
|
@@ -208,7 +208,12 @@ softr-vibe-coding/
|
|
|
208
208
|
│ │ # alone, DATETIME create shape, offset paging;
|
|
209
209
|
│ │ # OAuth grant per ticked workspace, email
|
|
210
210
|
│ │ # senders, formulas fixed at creation, loop
|
|
211
|
-
│ │ # counter, workflow time zone and publish state
|
|
211
|
+
│ │ # counter, workflow time zone and publish state;
|
|
212
|
+
│ │ # Oct 7 2026: condition-based user groups over
|
|
213
|
+
│ │ # MCP (subject USER:<field id>, not USER:::),
|
|
214
|
+
│ │ # list_users omits conditional membership,
|
|
215
|
+
│ │ # reading userGroups in the preview iframe,
|
|
216
|
+
│ │ # what __softr_current_user carries
|
|
212
217
|
│ ├── browser-checks.md # Checking a pushed block in a browser with
|
|
213
218
|
│ │ # the agent-browser CLI (ask before installing):
|
|
214
219
|
│ │ # preview cookie, shadow-DOM refs grepped in the
|
package/datasources/hubspot.md
CHANGED
|
@@ -452,7 +452,10 @@ page ([details](multi-datasource.md#one-connection--one-read-payload-the-union-o
|
|
|
452
452
|
HubSpot: anyone who can edit that property there can grant the group's access.
|
|
453
453
|
- **`application_list_users` is not a membership check.** It showed `userGroups: []` for every
|
|
454
454
|
user, including members of condition groups that demonstrably applied (verified 2026-10-05).
|
|
455
|
-
Test membership by what the user can reach, e.g. preview as them against a group-gated block
|
|
455
|
+
Test membership by what the user can reach, e.g. preview as them against a group-gated block, or
|
|
456
|
+
read their groups in the preview
|
|
457
|
+
([how](../references/softr-mcp.md#testing-as-any-app-user-without-logins--the-preview-as-switcher);
|
|
458
|
+
same result on Softr Database, 2026-10-07).
|
|
456
459
|
|
|
457
460
|
## Audit trail
|
|
458
461
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "softr-vibe-coding",
|
|
3
|
-
"version": "2.14.
|
|
3
|
+
"version": "2.14.5",
|
|
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"
|
package/references/softr-mcp.md
CHANGED
|
@@ -19,7 +19,7 @@ The official Softr MCP server (`https://mcp.softr.io/mcp`) gives an AI assistant
|
|
|
19
19
|
- [Vibe coding block tools](#vibe-coding-block-tools) — incl. [what the server enforces on a block's data endpoints](#what-the-server-enforces-on-a-blocks-data-endpoints)
|
|
20
20
|
- [Adopting Studio-AI-generated code](#adopting-studio-ai-generated-code)
|
|
21
21
|
- [Vibe coding gotchas (official)](#vibe-coding-gotchas-official)
|
|
22
|
-
- [Application management tools](#application-management-tools) — incl. [testing as any user via "Preview as"](#testing-as-any-app-user-without-logins--the-preview-as-switcher)
|
|
22
|
+
- [Application management tools](#application-management-tools) — incl. [condition-based user groups](#condition-based-user-groups) and [testing as any user via "Preview as"](#testing-as-any-app-user-without-logins--the-preview-as-switcher)
|
|
23
23
|
- [Browsing integrations (external data sources)](#browsing-integrations-external-data-sources)
|
|
24
24
|
- [Softr Database tools](#softr-database-tools)
|
|
25
25
|
- [Workflows](#workflows)
|
|
@@ -536,14 +536,19 @@ verified on HubSpot on 2026-10-05, the same way.* There are two forms, and **the
|
|
|
536
536
|
**It fails closed:** a user whose field is empty, or who has no record in the users' data source,
|
|
537
537
|
gets 0 rows, and a by-id request for a record outside the condition returns 404 (on HubSpot;
|
|
538
538
|
Softr Database answers HTTP 200 with an empty body).
|
|
539
|
+
- **Do not confuse it with the user-group syntax.** A user group's condition names the user field
|
|
540
|
+
as its **subject**, `USER:<field id>`: one colon, no braces (verified 2026-10-07, see
|
|
541
|
+
[Condition-based user groups](#condition-based-user-groups)). A Source condition names it in the
|
|
542
|
+
**value**, `USER:::<field id>`: three colons. The user-group form returned HTTP 400 in a Source
|
|
543
|
+
condition (below); the Source-condition form has not been tried in a user group.
|
|
539
544
|
- **Use AND between rules.** With one rule OR and AND behave the same, but a second rule added
|
|
540
545
|
under OR widens access (2026-10-05).
|
|
541
546
|
- **The braced user-field spellings fail.** On 2026-09-18, on Softr Database, eleven spellings were
|
|
542
547
|
tried, including `{USER:::<fieldId>}`, `{USER:<fieldId>}` and `{USER:::FIELD:<fieldId>}`. Each
|
|
543
548
|
silently matched nothing. All eleven had braces, so the braceless form is untested on Softr
|
|
544
549
|
Database, not disproved. A subject of `USER:<fieldId>`, the syntax user-group rules use, returned
|
|
545
|
-
HTTP 400 "Field not found": the user field goes in the value, never the subject. No token
|
|
546
|
-
user group has been found.
|
|
550
|
+
HTTP 400 "Field not found": the user field goes in the value, never the subject. No token that
|
|
551
|
+
tests whether the user is in a group has been found.
|
|
547
552
|
- Studio's conditional-filter UI offers the logged-in user's Email and Email-Domain, plus every
|
|
548
553
|
users-table field once users sync from a data source (documented). For a value not listed here,
|
|
549
554
|
pick it in a block's Source tab, save, and read `dataSources[].condition` back with
|
|
@@ -641,6 +646,37 @@ Combined with the database tools (`database_create` / `database_create_table` /
|
|
|
641
646
|
no zone designator and nine fractional digits (`2026-09-09T22:34:11.157881061`). They were UTC, so
|
|
642
647
|
read any older logged value as UTC, never as local time.
|
|
643
648
|
|
|
649
|
+
### Condition-based user groups
|
|
650
|
+
|
|
651
|
+
*Verified 2026-10-07 on Softr Database, with users synced from a Softr Database table and the user
|
|
652
|
+
connection's field reference key set to `id`. The HubSpot version (2026-10-05) is in
|
|
653
|
+
[../datasources/hubspot.md](../datasources/hubspot.md#user-sync).*
|
|
654
|
+
|
|
655
|
+
- **`application_update_user_group` sets a group's condition.** It returned the condition exactly as
|
|
656
|
+
sent. This one, on a "Volunteer" group, tests two single-line text fields of the users table:
|
|
657
|
+
|
|
658
|
+
```json
|
|
659
|
+
{
|
|
660
|
+
"logicalOperator": "AND",
|
|
661
|
+
"expressions": [
|
|
662
|
+
{ "subject": { "field": "USER:YB2ot", "type": "TEXT" }, "operator": "IS_NOT_EMPTY", "value": [] },
|
|
663
|
+
{ "subject": { "field": "USER:uo0TW", "type": "TEXT" }, "operator": "IS", "value": ["Active"] }
|
|
664
|
+
]
|
|
665
|
+
}
|
|
666
|
+
```
|
|
667
|
+
|
|
668
|
+
- **The subject is `USER:<field id>`: one colon, no braces.** A block's Source condition uses a
|
|
669
|
+
different form, `USER:::<field id>` with three colons, and puts it in the value
|
|
670
|
+
([Logged-in-user values in Source conditions](#logged-in-user-values-in-source-conditions)). Do not
|
|
671
|
+
copy one into the other.
|
|
672
|
+
- **`application_list_users` does not show condition-based membership.** Right after the update, the
|
|
673
|
+
one user whose record matched (login email set, status Active) still listed `userGroups: []`. The
|
|
674
|
+
tool shows only manual memberships, such as a user added to Administrator through `userEmails`.
|
|
675
|
+
Softr evaluates conditions at runtime, so an empty `userGroups` there is not evidence that a
|
|
676
|
+
condition fails. HubSpot behaved the same way.
|
|
677
|
+
- **Check membership by running the app as that user** and reading the groups the app gives them
|
|
678
|
+
([how](#testing-as-any-app-user-without-logins--the-preview-as-switcher), below).
|
|
679
|
+
|
|
644
680
|
### Testing as any app user without logins — the "Preview as" switcher
|
|
645
681
|
|
|
646
682
|
*Verified live 2026-09-18.* The `application_preview` link does not open the app directly: it opens a
|
|
@@ -666,6 +702,24 @@ passwords, no test accounts to create:
|
|
|
666
702
|
`fetch('/studio/impersonate/<softrUserId>')` makes the preview run as that user. The id is the
|
|
667
703
|
user's Softr id from `application_list_users`. It works from a fresh preview link, so it needs no
|
|
668
704
|
Studio session in the browser.
|
|
705
|
+
- **Read a user's groups from the app itself** (verified 2026-10-07, read-only). Mint a fresh
|
|
706
|
+
`application_preview` link and open it, run the impersonate call above, reload the app iframe,
|
|
707
|
+
then read `iframe.contentWindow.__softr_current_user.userGroups`.
|
|
708
|
+
- The link carries `?show-toolbar=true`, so the top document is the toolbar shell and the app runs
|
|
709
|
+
in `document.querySelector('iframe')` (the `#preview-iframe` of
|
|
710
|
+
[browser-checks.md](browser-checks.md)). `window.__softr_current_user` exists only in that
|
|
711
|
+
iframe's `contentWindow`. The top window has no user globals at all.
|
|
712
|
+
- To reload, set the iframe's `src` again with a fresh `t=<timestamp>` query parameter, after the
|
|
713
|
+
impersonate call.
|
|
714
|
+
- Observed group names: a user who matched the Volunteer condition above read
|
|
715
|
+
`["Logged in users", "All users", "Volunteer"]`; a user with no login email read
|
|
716
|
+
`["Logged in users", "All users"]`.
|
|
717
|
+
- **`window.__softr_current_user` carries only `name`, `email`, `avatar` and `userGroups`**
|
|
718
|
+
(verified 2026-10-07). None of the users-table record's other fields were there, on a users table
|
|
719
|
+
with notes, phone and emergency-contact fields. For a privacy review: syncing a users table does
|
|
720
|
+
not by itself expose the record's other fields through this global. A block can still ask for
|
|
721
|
+
them with `useCurrentUser({ properties })`
|
|
722
|
+
([../datasources/reading.md](../datasources/reading.md#current-user)).
|
|
669
723
|
- **Press the preview's own `#refresh-button` after a push.** An open preview kept serving the old
|
|
670
724
|
block version until it was pressed (verified 2026-10-05). Minting a fresh link does too (see the
|
|
671
725
|
version note above).
|