@colixsystems/widget-sdk 0.141.0 → 0.142.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
@@ -70,7 +70,26 @@ See the design reference for the full architecture: [`docs/architecture/widget-m
70
70
 
71
71
  ## Status
72
72
 
73
- `v0.141.0` — pre-publish. The package surface (types, function names, export paths) is the v1 contract; runtime behaviour for some hooks is stubbed (each hook documents what's wired and what isn't). It is **not yet published to npm**.
73
+ `v0.142.0` — pre-publish. The package surface (types, function names, export paths) is the v1 contract; runtime behaviour for some hooks is stubbed (each hook documents what's wired and what isn't). It is **not yet published to npm**.
74
+
75
+ ### What's new in 0.142.0 (contract 1.110.0)
76
+
77
+ **An action script can finally tell WHO started the run — `triggeredBy` joins `CONTRACT.actionScriptGlobals` (sc-7885).** The identity was already captured (the run history has recorded an `actorId` since REQ-ACTION-RUNLOG) but never reached the sandbox, so a script could do the work and not attribute it: no "X submitted this" notification back to the submitter, no audit row naming the actor. Authors worked around it by writing the user id into a record first and switching to a `record_*` trigger — plumbing in the app's data model, and not available to a plain button press at all.
78
+
79
+ ```js
80
+ if (triggeredBy && triggeredBy.type === "app_user") {
81
+ await notifications.notifyUser(triggeredBy.id, {
82
+ title: "Request received",
83
+ body: "Thanks " + triggeredBy.name + ", we have started on it.",
84
+ });
85
+ }
86
+ ```
87
+
88
+ - The shape is `{ type, id, name, email, role }`, frozen, or **`null` when nothing initiated the run** — a `schedule` tick or a `record_*` event. `null` is the normal case for the automation triggers, so guard before reading it.
89
+ - **`type` is load-bearing, not decoration.** It is `"app_user"` on an `app` button press and an `http_post` webhook, and `"studio_user"` on an operator's Run now. One id column, two directories behind it: check `type` before handing the id to `notifications.notifyUser` or a USER column, or a studio user's id will silently resolve to nobody. `role` carries the app-user vocabulary (`USER` / `INTEGRATION`) and is `null` for a studio user, whose workspace role is a different axis entirely. `email` is likewise `null` for a studio user: nothing in a script can address an operator, so shipping their real address to an installed third-party Action would be PII with no consumer.
90
+ - **It grants nothing.** The script still runs as the Action's bound integration identity, exactly as before; `triggeredBy` describes the caller and does not widen the data the script can reach. Resolution is host-side and tenant-scoped, so a stale or foreign id resolves to `null` rather than leaking a row across workspaces.
91
+ - Actions never render, so this has **no effect on Player ↔ export parity** (CLAUDE.md §8).
92
+ - Also in this release: **`properties` was added to `CONTRACT.actionScriptGlobals`**, which the `@colixsystems/action-sdk` copy of the list had carried since 1.50.0 while this one had not — the two hand-mirrored lists had drifted. A parity test now pins them together. `CONTRACT.version` → `1.110.0`. Additive for every existing manifest and script.
74
93
 
75
94
  ### What's new in 0.141.0 (contract 1.109.0)
76
95
 
package/dist/contract.cjs CHANGED
@@ -1990,12 +1990,23 @@ const ACTION_TRIGGER_TYPES = [
1990
1990
  // Globals the action script runs against (the runner's surface) — distinct
1991
1991
  // from the React/SDK widget surface, so the component import/banned-API
1992
1992
  // linter does NOT scan action scripts.
1993
+ // sc-7877 deliberately does NOT add `directory` here. That global is
1994
+ // reachable only by a MARKETPLACE action whose install consented to a
1995
+ // `directory:` scope; a widget-declared action has no install, so
1996
+ // resolveForActionRow grants it nothing and the global is never defined.
1993
1997
  const ACTION_SCRIPT_GLOBALS = [
1994
1998
  "datastore",
1995
1999
  "secrets",
2000
+ // Was missing here while action-sdk listed it — the two hand-mirrored lists
2001
+ // had drifted. action-script-globals-parity.test.cjs now pins them together.
2002
+ "properties",
1996
2003
  "fetch",
1997
2004
  "connectors",
1998
2005
  "notifications",
2006
+ // Conditionally defined — only when the install consented to a `directory:`
2007
+ // scope. Added to the WIDGET-sdk copy here: sc-7891 put it in the action-sdk
2008
+ // list alone, the same drift this commit's parity test now catches.
2009
+ "directory",
1999
2010
  "console",
2000
2011
  "record",
2001
2012
  // sc-5366 — `{ body }` on a run fired by the inbound `http_post` trigger,
@@ -2004,6 +2015,8 @@ const ACTION_SCRIPT_GLOBALS = [
2004
2015
  "tenantId",
2005
2016
  "triggerType",
2006
2017
  "triggerTableId",
2018
+ // sc-7885 — who initiated the run; null on `schedule` / `record_*`.
2019
+ "triggeredBy",
2007
2020
  ];
2008
2021
  // Mirrors action.service.js SCRIPT_MAX_BYTES.
2009
2022
  const ACTION_SCRIPT_MAX_BYTES = 200 * 1024;
@@ -3970,7 +3983,16 @@ const CONTRACT = deepFreeze({
3970
3983
  // and the sc-7352 backfill deletes the stored key (a bottom-tabs app's
3971
3984
  // strip becomes the sidebar's quick bar) BEFORE this ships.
3972
3985
  // `menuItemCap` / `quickBarCap` keep their signatures.
3973
- version: "1.109.0",
3986
+ // 1.110.0: additive (sc-7885) — `triggeredBy` joins `actionScriptGlobals`:
3987
+ // WHO initiated this run, as `{ type, id, name, email, role }`, or `null`
3988
+ // on `schedule` / `record_*` where nothing did. `type` is `"app_user"` (an
3989
+ // `app` button press or an `http_post` webhook) or `"studio_user"` (an
3990
+ // operator's Run now) — load-bearing, because those are two different
3991
+ // directories behind one id. The script still runs as the Action's bound
3992
+ // integration identity; this describes the caller, it does not grant
3993
+ // anything. The same commit adds `properties` to this list, which the
3994
+ // action-sdk copy had carried since 1.50.0 while this one had not.
3995
+ version: "1.110.0",
3974
3996
  sharedTranslationKeys: SHARED_TRANSLATION_KEYS,
3975
3997
  hooks: HOOKS,
3976
3998
  primitives: PRIMITIVES,
package/dist/contract.js CHANGED
@@ -1993,9 +1993,16 @@ const ACTION_TRIGGER_TYPES = [
1993
1993
  const ACTION_SCRIPT_GLOBALS = [
1994
1994
  "datastore",
1995
1995
  "secrets",
1996
+ // Was missing here while action-sdk listed it — the two hand-mirrored lists
1997
+ // had drifted. action-script-globals-parity.test.cjs now pins them together.
1998
+ "properties",
1996
1999
  "fetch",
1997
2000
  "connectors",
1998
2001
  "notifications",
2002
+ // Conditionally defined — only when the install consented to a `directory:`
2003
+ // scope. Added to the WIDGET-sdk copy here: sc-7891 put it in the action-sdk
2004
+ // list alone, the same drift this commit's parity test now catches.
2005
+ "directory",
1999
2006
  "console",
2000
2007
  "record",
2001
2008
  // sc-5366 — `{ body }` on a run fired by the inbound `http_post` trigger,
@@ -2004,6 +2011,8 @@ const ACTION_SCRIPT_GLOBALS = [
2004
2011
  "tenantId",
2005
2012
  "triggerType",
2006
2013
  "triggerTableId",
2014
+ // sc-7885 — who initiated the run; null on `schedule` / `record_*`.
2015
+ "triggeredBy",
2007
2016
  ];
2008
2017
  // Mirrors action.service.js SCRIPT_MAX_BYTES.
2009
2018
  const ACTION_SCRIPT_MAX_BYTES = 200 * 1024;
@@ -3970,7 +3979,16 @@ const CONTRACT = deepFreeze({
3970
3979
  // and the sc-7352 backfill deletes the stored key (a bottom-tabs app's
3971
3980
  // strip becomes the sidebar's quick bar) BEFORE this ships.
3972
3981
  // `menuItemCap` / `quickBarCap` keep their signatures.
3973
- version: "1.109.0",
3982
+ // 1.110.0: additive (sc-7885) — `triggeredBy` joins `actionScriptGlobals`:
3983
+ // WHO initiated this run, as `{ type, id, name, email, role }`, or `null`
3984
+ // on `schedule` / `record_*` where nothing did. `type` is `"app_user"` (an
3985
+ // `app` button press or an `http_post` webhook) or `"studio_user"` (an
3986
+ // operator's Run now) — load-bearing, because those are two different
3987
+ // directories behind one id. The script still runs as the Action's bound
3988
+ // integration identity; this describes the caller, it does not grant
3989
+ // anything. The same commit adds `properties` to this list, which the
3990
+ // action-sdk copy had carried since 1.50.0 while this one had not.
3991
+ version: "1.110.0",
3974
3992
  sharedTranslationKeys: SHARED_TRANSLATION_KEYS,
3975
3993
  hooks: HOOKS,
3976
3994
  primitives: PRIMITIVES,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@colixsystems/widget-sdk",
3
- "version": "0.141.0",
3
+ "version": "0.142.0",
4
4
  "description": "Common widget interface for AppStudio. Implements WidgetManifest, WidgetContext, property schema, and helper hooks.",
5
5
  "homepage": "https://github.com/Colix-AB/AppStudio",
6
6
  "type": "module",