@checkstack/automation-common 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/CHANGELOG.md ADDED
@@ -0,0 +1,442 @@
1
+ # @checkstack/automation-common
2
+
3
+ ## 0.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - e2d6f25: feat(automation): connection picker for integration actions + restore Integrations menu
8
+
9
+ Connection-backed automation actions (Jira, Teams, Webex) now render a
10
+ working connection picker plus cascading provider dropdowns in the
11
+ visual editor, and the Integrations entry is back in the user menu.
12
+
13
+ **Contract.** `ActionDefinition` gained an optional
14
+ `connectionProviderId` (and it is surfaced on `ActionInfoSchema` and
15
+ mapped in the `listActions` router). It carries the integration
16
+ provider's fully-qualified id, derived from the provider plugin's own
17
+ `pluginMetadata.pluginId` (never a hardcoded string), so the editor
18
+ knows which provider backs an action's dropdowns and it matches the
19
+ `qualifiedId` the integration provider registry assigns.
20
+
21
+ **Providers.** Jira, Teams and Webex each export
22
+ `*_PROVIDER_LOCAL_ID` / `*_PROVIDER_QUALIFIED_ID`, register their
23
+ provider with the local id, and add a `CONNECTION_OPTIONS`
24
+ (`"connectionOptions"`) resolver name. Their `post_message` /
25
+ issue actions set `connectionProviderId` and expose `connectionId`
26
+ as an `x-options-resolver` dropdown instead of a hidden field.
27
+
28
+ **Frontend bridge.** A new `useConnectionOptionResolvers` hook
29
+ (`@checkstack/automation-frontend`, which now depends on
30
+ `@checkstack/integration-common`) turns an action's
31
+ `x-options-resolver` schema fields into live data: the
32
+ `connectionOptions` resolver lists the provider's connections via
33
+ `listConnections`, and every other resolver name is forwarded to
34
+ `getConnectionOptions` for the selected `connectionId`, passing the
35
+ live form values as `context` for dependent fields. `ProviderActionBody`
36
+ now passes this map to `DynamicForm` (it was previously missing
37
+ entirely, so connection-backed actions had no working dropdowns).
38
+
39
+ **frontend-api.** `usePluginClient` procedures now also expose a typed
40
+ imperative `.call(input)` alongside `.useQuery` / `.useMutation`, for
41
+ async callbacks that cannot host a hook (such as a `DynamicForm`
42
+ options resolver). Additive, non-breaking.
43
+
44
+ **Integrations menu.** Re-added `IntegrationMenuItem` and a new
45
+ `IntegrationsLandingPage`, wired into `integration-frontend` as a list
46
+ route and a `UserMenuItemsSlot` entry under the "Configuration" group.
47
+
48
+ **Action card polish.** The action editor's secondary metadata (id,
49
+ description, failure behaviour) is now grouped into one quiet settings
50
+ panel with consistent small uppercase "eyebrow" labels, so the action's
51
+ own configuration stays the focal point. The raw failure checkbox was
52
+ replaced with the standard `Checkbox` control, and the provider action
53
+ picker / configuration sections gained consistent section headers and a
54
+ divider. The per-step "type" dropdown was removed: an action's kind is
55
+ fixed at creation, so changing it now means adding a new step and
56
+ deleting the old one (avoids the surprising full-config reset that
57
+ switching kinds used to trigger).
58
+
59
+ **Add-step picker.** Adding a step now opens a Home-Assistant-style
60
+ dialog where the operator decides the step type up front: an "Actions"
61
+ tab lists the registered provider actions grouped by category
62
+ (searchable; picking one presets the step's `action`), and a "Blocks"
63
+ tab lists the structural building blocks (choose / parallel / repeat /
64
+ etc.). Because the concrete action is chosen here, the in-card action
65
+ switcher was removed - a step's action is fixed once created. Composite
66
+ blocks now start with an empty child list (filled via the nested
67
+ add-step picker) instead of seeding an unconfigurable empty action.
68
+
69
+ - e1a2077: feat(automation): reference artifacts by explicit action id (`artifacts.<id>.<name>`)
70
+
71
+ Multiple actions of the same type (e.g. two "create Jira issue" steps) used
72
+ to collide: both produced the artifact type `integration-jira.issue`, so a
73
+ template could only ever reach "the most recent one of that type". Artifacts
74
+ are now addressed by the producing action's instance `id` instead.
75
+
76
+ - Templates reference a produced artifact solely as
77
+ `{{ artifacts.<actionId>.<localArtifactName>.<field> }}`, e.g.
78
+ `{{ artifacts.open_jira.issue.issueKey }}`. The local artifact name is the
79
+ producing action's `produces` id with the owning plugin prefix stripped
80
+ (`integration-jira.issue` -> `issue`).
81
+ - `@checkstack/automation-backend`: the dispatch engine nests each produced
82
+ artifact under `artifacts[actionId][localName]` in the template scope and
83
+ records the `actionId` on the artifact row. `validate-definition` now
84
+ enforces that action ids are unique within an automation and that every
85
+ artifact-producing action carries an id.
86
+ - `@checkstack/automation-common`: action `id` is constrained to an
87
+ identifier (`/^[a-zA-Z_][a-zA-Z0-9_]*$/`) so it is always usable as a
88
+ plain template segment. The variable-scope resolver surfaces
89
+ `artifacts.<id>.<name>` (with full field completion) in the editor.
90
+ - `@checkstack/automation-frontend`: the action editor now has editable `Id`
91
+ and `Description` inputs (previously settable only via the YAML view), and
92
+ new steps get an auto-assigned, unique, log-friendly default id that the
93
+ operator can rename. Action ids are recorded on every run step, so run
94
+ logs are parseable by id regardless of kind.
95
+
96
+ **BREAKING (beta):** the previous flat, type-keyed scope form
97
+ `{{ artifacts["integration-jira.issue"] }}` is removed. Reference artifacts
98
+ by the producing action's id instead. Action ids may no longer contain
99
+ hyphens or dots (identifier characters only). Artifacts are per-run and
100
+ ephemeral, so no stored-data migration is needed.
101
+
102
+ - 41c77f4: feat(automation): native per-editor context for script actions (typed `context` for TS, `$ENV` for shell)
103
+
104
+ Script action editors had a confusing dual system: the TypeScript editor
105
+ type-checked `{{ }}` template text as code (so `{{ artifact.x }}` errored
106
+ with "Cannot find name"), and the runtime never actually populated the
107
+ `context` object. This standardises on a single, native context-access
108
+ mechanism per editor kind.
109
+
110
+ **Run scope reaches actions.** `ActionExecutionContext` gains a `scope`
111
+ (`{ trigger, artifacts, vars, repeat? }`), populated by the dispatch
112
+ engine from the same scope it already uses for `{{ }}` rendering. Actions
113
+ that need broad context (the script actions) read from it instead of
114
+ having to declare every artifact type in `consumes`. Additive and
115
+ optional, so existing actions are unaffected.
116
+
117
+ **TypeScript / JavaScript → typed `context`.** `run_script` now builds
118
+ `context` from the run scope, so `context.trigger.payload`,
119
+ `context.artifacts`, `context.var`, `context.repeat`, and
120
+ `context.automation` are populated at run time (previously
121
+ `context.trigger` was always empty). The editor types match via
122
+ `generateAutomationContextTypes`.
123
+
124
+ **Shell → `$CHECKSTACK_*` env vars.** `run_shell` flattens the run scope
125
+ into environment variables (e.g. `$CHECKSTACK_TRIGGER_PAYLOAD_TITLE`,
126
+ `$CHECKSTACK_ARTIFACT_INTEGRATION_JIRA_ISSUE_ISSUEKEY`). Arrays become a
127
+ single newline-separated var (iterate with `while IFS= read -r x; do …;
128
+ done <<< "$VAR"`). Every value is a plain string — no JSON blob, since
129
+ the container has no `jq` to parse one. A shared `toShellEnvKey`
130
+ helper (in `@checkstack/automation-common`) derives the names so the
131
+ shell editor's `$` autocomplete lists exactly what the runtime injects.
132
+
133
+ **One syntax per field kind (editor + runtime).** `MultiTypeEditorField`
134
+ no longer offers `{{ }}` autocomplete in `typescript` / `javascript` /
135
+ `shell` editors, and the dispatch engine no longer template-renders
136
+ native-code config fields (those whose `x-editor-types` is a code type) —
137
+ so `{{ }}` can't be used in a script by accident. Text / markup editors
138
+ (`raw`, `json`, `yaml`, `xml`, `markdown`, `formdata`) and plain string
139
+ fields keep `{{ }}` as before. Because both the automation and
140
+ health-check editors share `MultiTypeEditorField`, they behave
141
+ identically.
142
+
143
+ **Script-editor IntelliSense polish.** The code editors got a few
144
+ ergonomic fixes so the typed context is actually usable: the suggestion
145
+ **details panel auto-opens** (so long completion names are legible
146
+ on-focus, not hidden behind the chevron); word-based keyword noise is
147
+ disabled in favour of language-service + provider completions; and a
148
+ TS/JS completion provider makes `context.artifacts.` list the in-scope
149
+ artifact ids and **auto-convert the dot to bracket notation** —
150
+ `context.artifacts["integration-jira.issue"]` — since those ids aren't
151
+ valid identifiers. (Driven by a new opt-in `dottedKeyCompletions` prop on
152
+ the editor / `DynamicForm`.)
153
+
154
+ **BREAKING (beta):** `{{ }}` interpolation inside a script action's
155
+ `script` field (shell or TypeScript) is no longer expanded at run time —
156
+ read run data via the typed `context` object (TS) or `$CHECKSTACK_*` env
157
+ vars (shell) instead. Non-script config fields are unchanged.
158
+
159
+ Also fixes: switching a provider action in the visual editor now resets
160
+ its config, so the validator no longer reports the previous action's keys
161
+ as unrecognised.
162
+
163
+ - 41c77f4: feat(automation): Phase 11 — editor primitives + context type generation
164
+
165
+ Lays the UI + type-generation groundwork for Phase 12's visual automation
166
+ editor. Every primitive reuses the existing Monaco wrapper / template
167
+ engine / `jsonSchemaToTypeScript` helper rather than building parallel
168
+ infrastructure.
169
+
170
+ **`@checkstack/automation-common` — `resolveVariableScope`**
171
+
172
+ Pure walker that returns the in-scope `{{ … }}` paths at a given action
173
+ position. Conservative scoping rules: linear-upstream variables /
174
+ artifacts only (no leaking across `choose` / `parallel` / `repeat`
175
+ branches), `repeat.index` / `repeat.item` exposed only inside a `repeat`,
176
+ and trigger.payload modelled as a **discriminated union over
177
+ `trigger.event`** — every payload field surfaces; ones that come from a
178
+ subset of subscribed triggers carry a `conditionalOnTriggers` annotation
179
+ so the picker can render an "Only when …" hint. Earlier draft used
180
+ schema-intersection; switched to discriminated unions per review
181
+ feedback so Monaco can narrow correctly inside event-gated branches.
182
+
183
+ **Condition-aware narrowing.** When the path descends through a
184
+ `choose-when`, the resolver parses the branch's `when:` expression and
185
+ statically pins `trigger.event` to the set the condition allows —
186
+ patterns covered are `trigger.event == "X"` (either operand order),
187
+ `trigger.event != "X"`, `||`/`&&` of those, and `{ and: [...] }` /
188
+ `{ or: [...] }` combinators. So an action inside
189
+ `when: 'trigger.event == "incident.created"'` sees only the
190
+ `incident.created` variant in scope, the `conditionalOnTriggers`
191
+ annotation disappears, and other-trigger fields drop out entirely.
192
+ Nested choose branches compound (intersection). Anything outside the
193
+ covered patterns falls back to the full union — better to show every
194
+ field than guess wrong.
195
+
196
+ **`@checkstack/template-engine`**
197
+
198
+ The expression AST (`Expr`, `BinaryExpr`, `MemberExpr`, etc.) is now a
199
+ public export — the resolver's condition-narrowing walker needs to
200
+ inspect parsed condition trees. `ParsedCondition.root` is tightened
201
+ from `unknown` to `Expr` so consumers don't need to cast.
202
+
203
+ **`@checkstack/automation-frontend` — `generateAutomationContextTypes`**
204
+
205
+ Consumes `resolveVariableScope`'s output + the trigger / artifact
206
+ registries and emits the `declare const context: { … }` TS declaration
207
+ that `integration-script.run_script`'s Monaco editor injects via
208
+ `addExtraLib`. The emitted shape:
209
+
210
+ ```ts
211
+ type AutomationTrigger =
212
+ | { event: "incident.created"; payload: { … } }
213
+ | { event: "incident.resolved"; payload: { … } };
214
+
215
+ declare const context: {
216
+ trigger: AutomationTrigger;
217
+ artifacts: { "jira.issue"?: { key: string; … }; … };
218
+ var: { foo?: string; … };
219
+ repeat: { index: number; item: unknown }; // only when inside a repeat
220
+ };
221
+ ```
222
+
223
+ `jsonSchemaToTypeScript` from `@checkstack/ui` is reused via a deep
224
+ import (rather than the barrel) so the bun test runner doesn't try to
225
+ load Monaco's Vite-only `?worker` modules during unit tests.
226
+
227
+ **`@checkstack/ui` — new editor primitives**
228
+
229
+ - `TemplateValueInput` — single-line `{{ }}` autocomplete input.
230
+ Extracted from `DynamicForm/KeyValueEditor`'s previously-private
231
+ `TemplateInput` so other editor surfaces can share it without
232
+ rebuilding the picker UX. `KeyValueEditor` is now a one-line
233
+ delegation; `detectTemplateContext` is also exported.
234
+ - `VariablePicker` — hierarchical popover for the explicit "fx" /
235
+ "Insert variable" workflow. Renders a filterable tree of
236
+ `VariableNode`s with type chips and `Only when …` hints sourced from
237
+ the resolver's `conditionalOnTriggers`. Defaults to a small "fx" pill
238
+ trigger; callers can pass a custom one.
239
+ - `TemplateInput` — high-level mode switcher: `text` mode delegates to
240
+ `TemplateValueInput`, all other modes (`code` / `bash` / `json` /
241
+ `yaml`) delegate to `CodeEditor` with the matching language so the
242
+ action editor can swap widgets purely from the action's
243
+ `x-editor-types` annotation without touching the consuming code.
244
+ - `TemplateInputToggle` — the small "fx" pill that flips a typed input
245
+ (number / select / date / …) into template mode and back. Auto-infers
246
+ template mode when the saved value already starts with `{{`, so
247
+ round-tripping a previously-templated automation works out of the
248
+ box. Render-prop API for the typed editor so consumers keep control
249
+ over their own input shape.
250
+ - `ActionCard` — collapsible card that hosts a single action in the
251
+ visual editor. Decoupled from `DynamicForm` so container blocks
252
+ (`ChooseBlock` / `ParallelBlock` / `RepeatBlock` in Phase 12) can use
253
+ it as a structural shell over their own children. Toggle / delete /
254
+ drag handle are conditionally rendered on their callback's presence.
255
+
256
+ Storybook stories shipped for each of the new primitives.
257
+
258
+ **`@checkstack/integration-script-backend`**
259
+
260
+ `ScriptContext` docstring and the `scriptRunConfigSchema.script` field
261
+ description now point at `generateAutomationContextTypes` so the Phase
262
+ 12 editor wiring is unambiguous — the runtime payload type stays
263
+ `Record<string, unknown>` (the runner can't know the trigger schema),
264
+ but the **editor** narrows it per-automation from the subscribed
265
+ triggers' payload schemas.
266
+
267
+ - 41c77f4: feat(automation): backend RPC router with the full 15-endpoint contract
268
+
269
+ Wires up `core/automation-backend/src/router.ts` covering automation CRUD,
270
+ definition validation, manual runs, run history, registry introspection,
271
+ and a template playground. The contract is refactored to use the
272
+ project's `proc()` pattern so `autoAuthMiddleware` enforces `read` /
273
+ `manage` access automatically, and `AutomationApi` is exported via
274
+ `createClientDefinition` for the frontend client.
275
+
276
+ - 41c77f4: feat(automation): one-time migration of webhook subscriptions + remove legacy integration backend
277
+
278
+ **BREAKING CHANGES** (platform is in BETA — no major bump):
279
+
280
+ - `IntegrationProvider` no longer carries `config` (subscription
281
+ config) or `deliver`. The interface now models a connection provider
282
+ only: connection schema + `getConnectionOptions` + `testConnection`.
283
+ - The legacy subscription / delivery-log / event endpoints
284
+ (`listSubscriptions`, `createSubscription`, `getDeliveryLogs`,
285
+ `listEventTypes`, …) are removed from `integrationContract`.
286
+ - `delivery-coordinator`, `hook-subscriber`, `event-registry`, and the
287
+ `integrationEventExtensionPoint` are deleted. Plugins that
288
+ previously called `integrationEvents.registerEvent(...)` now
289
+ register their hooks as automation triggers via
290
+ `automationTriggerExtensionPoint.registerTrigger(...)`.
291
+ - Frontend pages `IntegrationsPage` and `DeliveryLogsPage` are gone;
292
+ the integration plugin's only remaining UI is connection
293
+ management. Subscription management lives under `/automation/...`.
294
+ - `webhook_subscriptions` and `delivery_logs` tables stay in the
295
+ database for one release as a safety net (no code reads or writes
296
+ them), and will be dropped in a follow-up migration.
297
+
298
+ **New**:
299
+
300
+ - `jira.create_issue`, `teams.post_message`, `webex.post_message`,
301
+ `webhook.send`, `integration-script.run_shell`, and
302
+ `integration-script.run_script` actions registered against the
303
+ Automation Platform with matching `*.message`, `*.delivery`,
304
+ `shell.result`, and `script.result` artifact types. The script
305
+ plugin exposes **two** actions — `run_shell` runs bash via the
306
+ shared `ShellScriptRunner` (Monaco `shell` editor), `run_script`
307
+ runs an ESM module in a Bun subprocess via `EsmScriptRunner`
308
+ (Monaco `typescript` editor + `defineIntegration` helper) — to
309
+ preserve the legacy provider split. `jira.create_issue` keeps the
310
+ dynamic field-mapping dropdown (driven by
311
+ `JIRA_RESOLVERS.FIELD_OPTIONS`).
312
+ - One-time data migration runs on boot in
313
+ `automation-backend.afterPluginsReady`. It reads
314
+ `webhook_subscriptions` via a new service RPC
315
+ `IntegrationApi.listLegacySubscriptions`, translates each row into
316
+ a single-trigger / single-action automation (marked with
317
+ `managed_by = "migrated-subscription:<id>"`), and is idempotent
318
+ across restarts.
319
+ - Failed translations are recorded in a new
320
+ `automation_migration_failures` table and surfaced via
321
+ `AutomationApi.listMigrationFailures` /
322
+ `acknowledgeMigrationFailure` so admins can review and re-create
323
+ failed entries by hand.
324
+
325
+ - 4832e33: fix(automation): insert runtime-parseable `templateRef` from editor autocomplete + variable picker, with array indexing
326
+
327
+ The automation editor's `{{ }}` autocomplete and the `fx` variable picker
328
+ previously inserted the canonical dotted path (e.g.
329
+ `artifact.integration-jira.issue.issueKey`), which the template engine
330
+ cannot parse when an artifact id contains dots or hyphens, and which used
331
+ the singular `artifact`/`var` namespaces the runtime template context does
332
+ not expose. They now insert the runtime-parseable `templateRef` form -
333
+ plural top-level namespace (`artifacts`/`variables`) plus bracket notation
334
+ for non-identifier segments, e.g. `artifacts["integration-jira.issue"].issueKey`.
335
+
336
+ - `@checkstack/automation-common`: `VariableEntry` gains `templateRef`
337
+ (runtime-parseable insertion form) and `referenceable`, alongside the
338
+ unchanged canonical `path`. New exported helpers `isTemplateIdentifier`,
339
+ `appendTemplateSegment`, and `appendArrayIndex` build the form. Scope
340
+ derivation now descends into `array` schemas, offering both the whole
341
+ array and a representative element subtree (`tags[0]`, `comments[0].author`,
342
+ nested `matrix[0][0]`).
343
+ - `CompletionField` / `TemplateProperty` / `VariableNode` carry a
344
+ `templateRef` alongside the canonical `path`.
345
+ - The staged completion provider's field label, filter/match, insert text,
346
+ and value-stage field lookup all operate in `templateRef` space. The
347
+ expression tokenizer now emits bracket tokens and reconstructs the full
348
+ `foo["bar"].baz` / `foo["bar"].list[0]` access chain (normalising single
349
+ quotes to the stored double-quoted form, and supporting bare numeric array
350
+ indices) so value-stage enum suggestions resolve for bracket-notation and
351
+ indexed fields.
352
+ - `VariablePicker` and the `DynamicForm` template inserters write the
353
+ `templateRef` (falling back to `path` when absent).
354
+ - Shell-env (`$CHECKSTACK_*`) name derivation deliberately keeps using the
355
+ canonical dotted `path`, so the suggested env names stay byte-identical
356
+ to the backend's path-based injection. Script-context type generation is
357
+ unchanged.
358
+ - `@checkstack/integration-script-backend`: shell-script actions now also
359
+ expose array elements as indexed `$CHECKSTACK_*_<i>` env vars (and
360
+ `$CHECKSTACK_*_<i>_<field>` for object elements), alongside the existing
361
+ whole-array newline-joined var, so the runtime injects exactly the
362
+ array-element names the editor now suggests.
363
+
364
+ - 6d52276: feat(automation): expose `trigger.actor` so automations can filter on who/what caused an event
365
+
366
+ Every platform event now carries an **actor** - the user, application (API
367
+ client), service (backend-to-backend), or `system` (background /
368
+ unauthenticated) that caused it - and the automation engine surfaces it to
369
+ automations as `trigger.actor`. This lets a trigger filter gate on the
370
+ origin of the event it reacts to:
371
+
372
+ ```text
373
+ {{ trigger.actor.type == "system" }} # auto-created by the platform
374
+ {{ trigger.actor.type == "user" }} # a human
375
+ {{ trigger.actor.id == "app-deploybot" }} # a specific application
376
+ ```
377
+
378
+ `trigger.actor` is available on **every** trigger - it is injected by the
379
+ platform, not declared per trigger - and editor autocomplete + Run Script
380
+ context types include `trigger.actor.{type,id,name}`.
381
+
382
+ How it works:
383
+
384
+ - **`@checkstack/common`** adds the canonical `Actor` type / `ActorSchema`
385
+ and `SYSTEM_ACTOR`.
386
+ - **`@checkstack/backend-api`** adds `resolveActor(user)` and a
387
+ `HookEventMeta` envelope. The hook listener / `onHook` signature gains an
388
+ optional second `meta` argument (additive, backward compatible).
389
+ - **`@checkstack/backend`** wraps emitted hooks in an envelope so the actor
390
+ travels with the payload through the distributed queue, unwrapping it
391
+ before delivery. The RPC emit path captures the authenticated caller;
392
+ background emits default to the system actor. Raw/legacy queue data is
393
+ treated as a system-actor payload, so delivery stays backward compatible.
394
+ - **`@checkstack/automation-backend`** threads the actor into the dispatch
395
+ scope (`trigger.actor`), available to trigger filters, top-level
396
+ conditions, and all run templates, and persisted in the run's scope
397
+ snapshot. Manual runs are attributed to the invoking user.
398
+ - **`@checkstack/automation-common`** / **`@checkstack/automation-frontend`**
399
+ expose `trigger.actor` in the editor variable scope and the generated
400
+ Run Script `context.trigger.actor` types.
401
+
402
+ No database migration and no per-trigger schema changes: the actor rides as
403
+ event-envelope metadata and in the run scope snapshot.
404
+
405
+ - 6d52276: feat(automation): expose `trigger.id` and reconcile the trigger scope so multiple triggers are distinguishable
406
+
407
+ Automations with more than one trigger could not tell which trigger fired:
408
+ the trigger id wasn't queryable, and scripts only received `trigger.event`
409
+ (so two triggers on the same event were indistinguishable). This exposes a
410
+ consistent trigger contract everywhere - `trigger.id`, `trigger.event`,
411
+ `trigger.actor`, `trigger.payload` - in templates, shell, and TypeScript
412
+ scripts.
413
+
414
+ - **`trigger.id` is now available** in templates (`{{ trigger.id }}`) and in
415
+ the script context (`context.trigger.id`). It is typed as the **literal
416
+ union** of the automation's trigger ids, so it discriminates triggers -
417
+ including two subscribed to the same `event`.
418
+ - **Auto-generated trigger ids.** The editor now assigns a unique, log-
419
+ friendly id to every trigger (derived from its event, e.g.
420
+ `incident_created`, deduped as `incident_created_2`), mirroring action ids:
421
+ seeded on the starter automation, assigned on add, and re-filled on blur.
422
+ - **Scripts now receive `trigger.id` and `trigger.actor`.** The
423
+ `ActionRunScope` projection previously dropped both (it only forwarded
424
+ `event` + `payload`), so `context.trigger.actor` was typed but never
425
+ populated - that gap is fixed.
426
+ - **Scope key reconciled.** The internal dispatch scope now exposes
427
+ `trigger.event` as the canonical key (matching the editor and script
428
+ contract) instead of leaking `trigger.eventId`; `trigger.eventId` is kept
429
+ as a back-compat alias, so `{{ trigger.event }}` now resolves in template
430
+ fields where it previously returned `undefined`.
431
+
432
+ No database migration: the actor and id ride in the run scope snapshot. A
433
+ shared `deriveTriggerId` is exported from `@checkstack/automation-common` so
434
+ the editor, generated script types, and the runtime all agree on derived ids.
435
+
436
+ ### Patch Changes
437
+
438
+ - Updated dependencies [41c77f4]
439
+ - Updated dependencies [6d52276]
440
+ - @checkstack/template-engine@0.2.0
441
+ - @checkstack/common@0.12.0
442
+ - @checkstack/signal-common@0.2.5
package/package.json ADDED
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "@checkstack/automation-common",
3
+ "version": "0.2.0",
4
+ "license": "Elastic-2.0",
5
+ "type": "module",
6
+ "exports": {
7
+ ".": {
8
+ "types": "./src/index.ts",
9
+ "import": "./src/index.ts"
10
+ }
11
+ },
12
+ "dependencies": {
13
+ "@checkstack/common": "0.11.0",
14
+ "@checkstack/signal-common": "0.2.4",
15
+ "@checkstack/template-engine": "0.1.0",
16
+ "@orpc/contract": "^1.13.14",
17
+ "zod": "^4.0.0"
18
+ },
19
+ "devDependencies": {
20
+ "@checkstack/scripts": "0.3.3",
21
+ "@checkstack/tsconfig": "0.0.7",
22
+ "typescript": "^5.7.2"
23
+ },
24
+ "scripts": {
25
+ "typecheck": "tsgo -b",
26
+ "lint": "bun run lint:code",
27
+ "lint:code": "eslint . --max-warnings 0",
28
+ "test": "bun test"
29
+ },
30
+ "checkstack": {
31
+ "type": "common"
32
+ }
33
+ }
package/src/access.ts ADDED
@@ -0,0 +1,32 @@
1
+ import { access } from "@checkstack/common";
2
+
3
+ /**
4
+ * Access rules for the Automation plugin.
5
+ */
6
+ export const automationAccess = {
7
+ /**
8
+ * Read access to automations and run history. Required to list automations
9
+ * and inspect past runs.
10
+ */
11
+ read: access(
12
+ "automation",
13
+ "read",
14
+ "View automations and run history",
15
+ ),
16
+ /**
17
+ * Manage automations: create, edit, enable/disable, delete, manually run.
18
+ */
19
+ manage: access(
20
+ "automation",
21
+ "manage",
22
+ "Create, edit, enable, disable, delete, and manually run automations",
23
+ ),
24
+ };
25
+
26
+ /**
27
+ * All access rules for registration with the plugin system.
28
+ */
29
+ export const automationAccessRules = [
30
+ automationAccess.read,
31
+ automationAccess.manage,
32
+ ];
package/src/index.ts ADDED
@@ -0,0 +1,8 @@
1
+ export * from "./access";
2
+ export * from "./plugin-metadata";
3
+ export * from "./routes";
4
+ export * from "./schemas";
5
+ export * from "./rpc-contract";
6
+ export * from "./signals";
7
+ export * from "./variable-scope";
8
+ export * from "./shell-env";
@@ -0,0 +1,9 @@
1
+ import { definePluginMetadata } from "@checkstack/common";
2
+
3
+ /**
4
+ * Plugin metadata for the automation plugin.
5
+ * Exported from the common package so both backend and frontend can reference it.
6
+ */
7
+ export const pluginMetadata = definePluginMetadata({
8
+ pluginId: "automation",
9
+ });
package/src/routes.ts ADDED
@@ -0,0 +1,19 @@
1
+ import { createRoutes } from "@checkstack/common";
2
+
3
+ /**
4
+ * Route definitions for the automation plugin.
5
+ */
6
+ export const automationRoutes = createRoutes("automation", {
7
+ /** Automation list page */
8
+ list: "/",
9
+ /** Create new automation */
10
+ create: "/new",
11
+ /** Edit a single automation */
12
+ edit: "/:automationId",
13
+ /** Run history for a single automation */
14
+ runs: "/:automationId/runs",
15
+ /** Drill into a single run */
16
+ runDetail: "/:automationId/runs/:runId",
17
+ /** Template playground (live preview of templates with sample payloads) */
18
+ playground: "/playground",
19
+ });