@checkstack/ui 1.10.0 → 1.12.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.
Files changed (72) hide show
  1. package/.storybook/main.ts +43 -0
  2. package/CHANGELOG.md +565 -0
  3. package/package.json +15 -7
  4. package/scripts/generate-stdlib-types.ts +25 -2
  5. package/src/components/ActionCard.tsx +309 -0
  6. package/src/components/CodeEditor/CodeEditor.tsx +132 -9
  7. package/src/components/CodeEditor/TypefoxEditor.tsx +1024 -0
  8. package/src/components/CodeEditor/bracketKeyGroups.test.ts +120 -0
  9. package/src/components/CodeEditor/bracketKeyGroups.ts +205 -0
  10. package/src/components/CodeEditor/generateTypeDefinitions.ts +4 -4
  11. package/src/components/CodeEditor/generated/builtin-modules.json +1 -0
  12. package/src/components/CodeEditor/importSpecifiers.test.ts +286 -0
  13. package/src/components/CodeEditor/importSpecifiers.ts +267 -0
  14. package/src/components/CodeEditor/index.ts +26 -0
  15. package/src/components/CodeEditor/monacoTsService.ts +217 -0
  16. package/src/components/CodeEditor/popoutTitle.test.ts +37 -0
  17. package/src/components/CodeEditor/popoutTitle.ts +31 -0
  18. package/src/components/CodeEditor/scriptContext.test.ts +41 -0
  19. package/src/components/CodeEditor/scriptContext.ts +76 -1
  20. package/src/components/CodeEditor/scriptDiagnostics.test.ts +135 -0
  21. package/src/components/CodeEditor/scriptDiagnostics.ts +172 -0
  22. package/src/components/CodeEditor/templateValidation.ts +51 -0
  23. package/src/components/CodeEditor/types.ts +168 -0
  24. package/src/components/CodeEditor/validateJsonTemplate.test.ts +61 -0
  25. package/src/components/CodeEditor/validateJsonTemplate.ts +26 -0
  26. package/src/components/CodeEditor/validateScripts.ts +132 -0
  27. package/src/components/CodeEditor/validateXmlTemplate.test.ts +34 -0
  28. package/src/components/CodeEditor/validateXmlTemplate.ts +35 -0
  29. package/src/components/CodeEditor/validateYamlTemplate.test.ts +39 -0
  30. package/src/components/CodeEditor/validateYamlTemplate.ts +28 -0
  31. package/src/components/Dialog.tsx +32 -11
  32. package/src/components/DurationInput.tsx +121 -0
  33. package/src/components/DynamicForm/DynamicForm.tsx +27 -1
  34. package/src/components/DynamicForm/FormField.tsx +138 -10
  35. package/src/components/DynamicForm/KeyValueEditor.tsx +2 -169
  36. package/src/components/DynamicForm/MultiTypeEditorField.tsx +83 -9
  37. package/src/components/DynamicForm/SecretEnvEditor.tsx +315 -0
  38. package/src/components/DynamicForm/index.ts +6 -0
  39. package/src/components/DynamicForm/secretEnv.logic.test.ts +126 -0
  40. package/src/components/DynamicForm/secretEnv.logic.ts +87 -0
  41. package/src/components/DynamicForm/types.ts +83 -1
  42. package/src/components/DynamicForm/utils.ts +32 -0
  43. package/src/components/Popover.tsx +6 -1
  44. package/src/components/ScriptTestPanel.logic.test.ts +139 -0
  45. package/src/components/ScriptTestPanel.logic.ts +137 -0
  46. package/src/components/ScriptTestPanel.tsx +394 -0
  47. package/src/components/Sheet.tsx +21 -6
  48. package/src/components/TemplateInput.tsx +104 -0
  49. package/src/components/TemplateInputToggle.tsx +111 -0
  50. package/src/components/TemplateValueInput.test.ts +98 -0
  51. package/src/components/TemplateValueInput.tsx +470 -0
  52. package/src/components/TimeOfDayInput.tsx +116 -0
  53. package/src/components/VariablePicker.tsx +271 -0
  54. package/src/components/comboboxInteraction.ts +39 -0
  55. package/src/components/portalContainer.ts +24 -0
  56. package/src/hooks/useInitOnceForKey.test.ts +27 -0
  57. package/src/hooks/useInitOnceForKey.ts +21 -18
  58. package/src/index.ts +9 -0
  59. package/stories/ActionCard.stories.tsx +122 -0
  60. package/stories/Alert.stories.tsx +5 -5
  61. package/stories/CodeEditor.stories.tsx +47 -2
  62. package/stories/DurationInput.stories.tsx +59 -0
  63. package/stories/ScriptTestPanel.stories.tsx +106 -0
  64. package/stories/SecretEnvEditor.stories.tsx +80 -0
  65. package/stories/TemplateInputToggle.stories.tsx +77 -0
  66. package/stories/TemplateValueInput.stories.tsx +65 -0
  67. package/stories/TimeOfDayInput.stories.tsx +34 -0
  68. package/stories/VariablePicker.stories.tsx +109 -0
  69. package/tsconfig.json +1 -0
  70. package/src/components/CodeEditor/MonacoEditor.tsx +0 -616
  71. package/src/components/CodeEditor/monacoStdlib.ts +0 -62
  72. package/src/components/CodeEditor/monacoWorkers.ts +0 -118
@@ -1,4 +1,31 @@
1
1
  import type { StorybookConfig } from "@storybook/react-vite";
2
+ import { createRequire } from "node:module";
3
+ import path from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { mergeConfig } from "vite";
6
+
7
+ const storybookDir = path.dirname(fileURLToPath(import.meta.url));
8
+ const uiRoot = path.resolve(storybookDir, "..");
9
+ const localRequire = createRequire(import.meta.url);
10
+
11
+ // Resolve the `vscode` npm-alias (= @codingame/monaco-vscode-extension-api) to
12
+ // an absolute path so Vite/Rolldown can alias it. This mirrors the same fix in
13
+ // core/frontend/vite.config.ts.
14
+ //
15
+ // `CodeEditor` (via @typefox/monaco-editor-react + monaco-languageclient) pulls
16
+ // in the @codingame/monaco-vscode-* stack, whose runtime package does
17
+ // `require("vscode")`. Under bun's isolated node_modules the `"vscode":
18
+ // "npm:@codingame/monaco-vscode-extension-api"` alias only exists inside the
19
+ // typefox / monaco-languageclient scopes, so the Storybook build can't resolve
20
+ // a bare `vscode` import and fails with "Rolldown failed to resolve import
21
+ // 'vscode'". We resolve the alias *through* @typefox so the path follows bun's
22
+ // store layout on any machine/CI rather than being hardcoded.
23
+ const typefoxDir = path.dirname(
24
+ localRequire.resolve("@typefox/monaco-editor-react", { paths: [uiRoot] }),
25
+ );
26
+ const vscodeApiDir = path.dirname(
27
+ localRequire.resolve("vscode", { paths: [typefoxDir] }),
28
+ );
2
29
 
3
30
  const config: StorybookConfig = {
4
31
  stories: [
@@ -17,6 +44,22 @@ const config: StorybookConfig = {
17
44
  typescript: {
18
45
  reactDocgen: "react-docgen",
19
46
  },
47
+ viteFinal: (viteConfig) =>
48
+ mergeConfig(viteConfig, {
49
+ // The @typefox/monaco-editor-react + @codingame/monaco-vscode-* stack
50
+ // loads its language services in ES module workers.
51
+ worker: {
52
+ format: "es",
53
+ },
54
+ resolve: {
55
+ alias: {
56
+ // Alias the `vscode` npm-alias to its real package dir so @codingame's
57
+ // CJS `require("vscode")` resolves under bun's isolated store instead
58
+ // of failing the build.
59
+ vscode: vscodeApiDir,
60
+ },
61
+ },
62
+ }),
20
63
  };
21
64
 
22
65
  export default config;
package/CHANGELOG.md CHANGED
@@ -1,5 +1,570 @@
1
1
  # @checkstack/ui
2
2
 
3
+ ## 1.12.0
4
+
5
+ ### Minor Changes
6
+
7
+ - b995afb: Redesign the automation visual editor to a Home-Assistant-style collapsed-card UX.
8
+
9
+ Every item in all three sections (actions, triggers, conditions) now renders as a compact summary row by default - icon, title, and a one-line summary derived from its config. Clicking the row opens the item's full configuration in a right-side sheet that edits the same live definition (no draft/commit step), so closing the sheet keeps the changes. The saved `definition` is unchanged - only the editor presentation - so the visual and YAML views still round-trip losslessly.
10
+
11
+ - `@checkstack/ui` `ActionCard` gains three optional, backward-compatible props: `onOpenSheet` (turns the card into a non-expanding summary row that opens a host-supplied sheet on header click), `summary` (the compact one-line hint shown under the title), and `actions` (a typed `ActionCardMenuItem[]` rendered as a three-dot overflow menu). The new `ActionCardMenuItem` type is exported. Existing inline-expand usages are unaffected when the new props are omitted.
12
+ - Per-card commands move into the overflow menu: Disable/Enable, a new Duplicate, and Delete. The drag grip stays on the action card header; actions keep dnd-kit reordering and the parallel id array. Triggers and conditions remain non-reorderable.
13
+ - Duplicate clones an item with fresh, unique ids (via the existing id helpers) and inserts it directly after the original, keeping the editor's parallel id array in sync.
14
+ - Composite actions (choose / parallel / repeat / sequence) keep nesting: a child card inside a parent's sheet opens its OWN sheet, stacking via Radix Dialog's portal + overlay.
15
+ - Cards with validation errors auto-open their sheet and show an error badge on the collapsed row, so problems are never hidden behind a collapsed row plus a closed sheet.
16
+
17
+ - 270ef29: Add the sensing-layer editor UX (Wave 2 Phase 19) - the visual widgets for the duration-aware and structured-condition building blocks from Phases 15-18.
18
+
19
+ - New `@checkstack/ui` components (each with a Storybook story):
20
+ - `DurationInput` - number + unit (`seconds` / `minutes` / `hours`) picker emitting the single-unit `Duration` object the backend accepts, so it round-trips losslessly through YAML.
21
+ - `TimeOfDayInput` - HH:MM (24h) input emitting the `"HH:mm"` string the `time` condition's `after` / `before` accept. Both are plain inputs (no animations), so no `usePerformance` gating is needed.
22
+ - `DynamicForm`'s `FormField` gains an additive `x-duration` / `format: "duration"` branch that renders `DurationInput` for schema-driven duration configs. (Additive alongside the existing dispatch; reconciles cleanly with the parallel branch's `FormField` edits.)
23
+ - The `ConditionEditor` kind selector gains `numeric_state` / `time` / `state` structured branches: an operator dropdown (above / below / between) + threshold for numeric, `TimeOfDayInput` + weekday toggles + timezone for time, and a status dropdown + optional `DurationInput` dwell for state. The raw-expression escape hatch is kept. Pure `kindOf` / `defaultForKind` helpers are split into a UI-free `condition-kind` module so they unit-test under bun (the UI barrel drags Monaco).
24
+ - The trigger card gains a `for:` dwell toggle + `DurationInput` (Phase 15's schema was already round-tripping in YAML).
25
+
26
+ Visual and YAML views stay lossless; structured conditions authored in either are editable in the other.
27
+
28
+ - b995afb: Surface inline-script type errors as automation action badges.
29
+
30
+ Every inline `run_script` action in the automation editor is now type-checked
31
+ against its generated `context` types continuously - including actions whose
32
+ cards are collapsed - and any errors show up as the action card's error badge
33
+ (and in the definition issue list), the same surface structural validation
34
+ uses. Previously a type error was only visible as a red squiggle inside the
35
+ open Monaco editor, so a broken script behind a collapsed card (or one
36
+ invalidated by adding a new trigger) went unnoticed until runtime, where the
37
+ bad property access silently read `undefined`.
38
+
39
+ Validation runs entirely in the browser via the same standalone TypeScript
40
+ worker the editor uses (new `validateTypeScriptSources` export on
41
+ `@checkstack/ui`), so there is no backend round-trip. Each script is checked by
42
+ prepending its generated `context.d.ts` to the source, which keeps the
43
+ `context` global scoped to that one off-screen file and avoids colliding with
44
+ any open editor. When an automation already contains scripts, a hidden editor
45
+ boots the shared editor services on open so validation runs immediately rather
46
+ than only after the first script card is expanded.
47
+
48
+ This covers the automation currently open in the editor. Scripts in other
49
+ automations, or definitions authored via YAML/API, are not type-checked here -
50
+ that platform-wide coverage remains future work for a backend typecheck.
51
+
52
+ Also: action cards no longer auto-open their detail sheet when they have
53
+ validation issues; issues now surface only as the card badge, so multiple
54
+ flagged actions no longer pop several sheets open at once.
55
+
56
+ - b995afb: Improve the automation Run Script secret → env mapping editor and script IntelliSense.
57
+
58
+ - **Searchable secret picker with existence validation.** The secret → env mapping editor (`SecretEnvEditor`) now uses a searchable, keyboard-navigable combobox (modeled on `VariablePicker` / `PackageNameCombobox`, `isLowPower`-aware) populated from the secrets plugin's `listSecretNames`, replacing the plain `<input>` + `<datalist>`. A free-typed name still round-trips (a secret may be created later). When a row references a name that the loaded list does not contain, the row shows a non-blocking warning (red border + message); save is not prevented. The existence check lives in a pure, unit-tested `unknownSecretNames` helper.
59
+ - **Clearer field description.** The `secretEnv` field descriptions on the `run_script` / `run_shell` actions no longer show the stored `${{ secrets.NAME }}` template (which is confusing in a UI that takes a bare name); they now describe the actual UI behavior and how the value is injected (`process.env.<ENV_NAME>` / `$<ENV_NAME>`) and masked.
60
+ - **`process.env.<ENV_NAME>` autocomplete.** Declared `secretEnv` env-var names now autocomplete under `process.env.` in the Run Script (TypeScript) Monaco editor and are typed `string`, via an ambient `NodeJS.ProcessEnv` augmentation merged into the editor type definitions. New pure, unit-tested generators `generateSecretEnvTypes` and `secretEnvEnvNames` (exported from `@checkstack/automation-frontend`) drive this; the augmentation coexists with `@types/node`'s existing index signature.
61
+ - **Shared combobox-interaction helper.** The "opens-then-immediately-closes" popover guard (`comboboxAnchorProps` / `isAnchorInteraction`) is promoted from `@checkstack/script-packages-frontend` into `@checkstack/ui` so the new secret picker and the existing package/version comboboxes share one implementation; the package comboboxes now import it from `@checkstack/ui` and the local copy is removed.
62
+
63
+ - b995afb: Add an "expand to overlay" popout to the shared `CodeEditor` so big scripts (shell / TypeScript / JavaScript) can be edited comfortably in a large full-screen overlay.
64
+
65
+ Every consumer of `CodeEditor` (automation Run Script, healthcheck collectors, etc.) now gets a subtle "Expand editor" affordance (a `Maximize2` icon button) in the editor's top-right corner. Clicking it opens the shared `Dialog` at `size="full"` containing a large editor that fills the dialog.
66
+
67
+ - The overlay editor is a second `TypefoxEditor` instance bound to the SAME `value` / `onChange` and all the same completion props (`typeDefinitions`, `templateProperties`, `shellEnvVars`, `markers`, `acquireTypes`, `acquireResetKey`, `importablePackages`, `language`, `readOnly`, `placeholder`), so IntelliSense / ATA / import-name / shell-var completion all work in the overlay exactly as inline. Both editors are controlled on the same value, so edits stay in sync and closing the dialog keeps them.
68
+ - The overlay editor only MOUNTS while the dialog is open (lazy), so there is no second Monaco instance cost when closed. It uses a distinct `${id}-popout` model id so the two Monaco models don't fight over the same URI.
69
+ - New opt-in `TypefoxEditor` prop `fillHeight`: when true the editor container uses `height: 100%` (with `minHeight` as a floor) instead of a fixed px height, so it fills the tall flex dialog body and Monaco's `automaticLayout` resizes to fit. Inline behaviour is unchanged when `fillHeight` is absent/false.
70
+ - `CodeEditorProps` gains two additive optional props: `allowPopout` (default `true`; set `false` to hide the affordance) and `title` (override the overlay dialog title, which otherwise derives from `language`, e.g. "Edit script - TypeScript").
71
+ - `TypefoxEditor` is now properly controlled: external `value` changes are applied to the live model (guarded by an equality check so a user's own edit is a no-op and there's no loop). This is what keeps the inline and popout editors in sync — editing one updates the other — and also fixes external resets (YAML→Visual, loaded definitions) reflecting in the editor.
72
+ - `DialogContent`'s inner content wrapper gains `min-h-0 flex-1` so it fills the height when a consumer makes `DialogContent` a tall flex column (e.g. the popout body). Inert for the default non-flex dialog, so existing dialogs are unaffected.
73
+
74
+ The `Dialog` already degrades its own animations under `usePerformance` / `isLowPower`; the popout button adds no heavy effects.
75
+
76
+ - b995afb: Suggest Node and Bun built-in modules in script-editor import-name completion.
77
+
78
+ The import-specifier completion now also offers the always-available runtime built-ins (`node:fs`, bare `fs`, `bun`, `bun:test`, `node:crypto`, ...) alongside the installed allowlist packages. These are importable in the script sandbox regardless of the allowlist (the sandbox is a Bun subprocess, which provides Node's builtins plus its own `bun:` modules), and their types are already loaded ambiently, so completing one needs no lazy acquisition.
79
+
80
+ - The built-in name list is DERIVED authoritatively at build time from the same bundled `@types/node` + `bun-types` declarations the editor injects: every importable built-in is a top-level `declare module "<spec>"`, so the generator (`scripts/generate-stdlib-types.ts`) now also parses those names (via the new pure `extractBuiltinModuleSpecifiers`) and emits `generated/builtin-modules.json`. No hand-maintained list - it auto-updates whenever the bundled types are regenerated. Wildcard / asset-glob ambient shims (names containing a star, e.g. asset globs or a `bun.lock` path glob) are filtered out.
81
+ - The completion provider merges built-ins with the injected installed packages (deduped + sorted via the pure `mergeImportCompletionEntries`), labelling each via `detail` ("Node.js" / "Bun built-in" / "installed package"). Built-ins appear even when the allowlist is empty; the provider still only fires inside an import-string position and coexists with the TS worker's own completions.
82
+
83
+ The existing node/bun stdlib TYPE hosting is unchanged (still injected from the separately code-split `stdlib-types.json` asset), so global completions (`process.*`, `Buffer`, ...) and member completions (`import * as fs from "node:fs"`) are unaffected. New pure helpers are fully unit-tested; the Monaco glue is untested per the no-DOM rule.
84
+
85
+ - 270ef29: Add in-UI script testing for automation `run_script` / `run_shell` actions.
86
+
87
+ A new `testScript` RPC runs a TypeScript or shell script against an
88
+ editable, auto-seeded sample context using the same sandboxed runner the
89
+ real action uses, so operators can test scripts directly in the editor
90
+ without dispatching a whole automation. Surfaces beneath any script field
91
+ flagged `x-script-testable` via the new `ScriptTestPanel` /
92
+ `ContextSampleEditor` components in `@checkstack/ui` and the
93
+ `scriptTestRenderer` prop threaded through `DynamicForm`.
94
+
95
+ - `@checkstack/automation-common`: adds the `testScript` contract +
96
+ `ScriptTest*` schemas (gated by `automation.manage`).
97
+ - `@checkstack/automation-backend`: implements `testScript` reusing the
98
+ shared ESM / shell runners; central-only, time-bounded.
99
+ - `@checkstack/backend-api`: new `x-script-testable` config-schema
100
+ metadata propagated to the frontend JSON Schema.
101
+ - `@checkstack/ui`: new `ScriptTestPanel` + `ContextSampleEditor`
102
+ components and a `scriptTestRenderer` prop on `DynamicForm`.
103
+ - `@checkstack/automation-frontend`: wires the test panel into the action
104
+ editor.
105
+ - `@checkstack/integration-script-backend`: marks the `run_script` /
106
+ `run_shell` script fields as testable.
107
+
108
+ - b995afb: Autocomplete the import specifier itself in script editors.
109
+
110
+ Lazy type acquisition only loads a package's types once its name is already in the buffer, so while you were still typing the import specifier (`import {} from "lod"`) there were no suggestions - the lazy-ATA catch-22. Script editors now suggest installed package names directly in import-specifier position; selecting one (e.g. `lodash`) inserts the name, and the existing ATA loop then loads its `@types/lodash` closure so members complete.
111
+
112
+ - `@checkstack/ui`: `CodeEditor`/`TypefoxEditor` gained an injected `importablePackages?: string[]` prop and a dedicated Monaco completion provider (registered once per `typescript`/`javascript` language, scoped to the editor's model, disposed on unmount). It fires ONLY when the cursor is inside an import/require module-specifier string - detected by a new pure, unit-tested helper `importSpecifierCompletionContext(lineUpToCursor)` that handles `from "…"`, bare `import "…"`, `require("…")`, and dynamic `import("…")`, returns the partial specifier + the replace range, and returns null once the string is closed or outside an import. Items are `kind: Module`, insert the bare name without touching the quotes, and coexist with (do not replace) the TS worker's own completions. Trigger characters: `"`, `'`, and `/` (for scoped subpaths); manual invoke (Ctrl+Space) also works. A new pure helper `importablePackageNames` filters a raw manifest name list (excludes `@types/*`, dedupes, sorts).
113
+ - `@checkstack/script-packages-frontend`: `useScriptPackageTypeAcquisition()` now also returns `importablePackages`, derived from the installed manifest (what is actually resolvable at runtime) with `@types/*` companions excluded - you import `lodash`, never `@types/lodash` (the `@types` package still backs the closure types).
114
+ - `@checkstack/automation-frontend` / `@checkstack/healthcheck-frontend`: pass `importablePackages` into `DynamicForm` alongside the existing `acquireTypes` wiring, so both the Run Script action editor and healthcheck collector editors get import-name completion.
115
+
116
+ The completion list is plugin-agnostic in `@checkstack/ui` (the names are injected); it never fires outside import-string positions, so normal completions are unaffected.
117
+
118
+ - b995afb: Fix package IntelliSense in script editors: lazy Automatic Type Acquisition (ATA) with proper `@types/*` resolution.
119
+
120
+ Script editors (automation "Run Script (TypeScript)" and healthcheck collectors) now provide real autocomplete for installed npm packages. Importing a package whose types live in DefinitelyTyped - e.g. `import { debounce } from "lodash"` (lodash ships no own types; `@types/lodash` does) - now yields member completions. Previously no package completions appeared at all.
121
+
122
+ Root cause: the old rollup wrapped each package's raw, multi-file `.d.ts` (with `export =`, `export as namespace`, and triple-slash `/// <reference path>` chains) inside a single `declare module "<name>" { ... }`, which the TypeScript worker silently rejected, and it truncated large type sets (lodash is ~866 KB across ~700 files) at a 256 KB cap.
123
+
124
+ The fix registers the REAL declaration files at their `node_modules/...` virtual paths and lets TypeScript's own NodeJs + `@types` resolution do the work:
125
+
126
+ - `@checkstack/script-packages-backend`: replaced `rollupPackageTypes` with a tree-driven closure extractor (`resolvePackageTypeClosure`). Given a bare specifier, it resolves against the materialized tree - own types via `package.json` `types`/`typings`/`exports` (bundled-types packages like `zod`/`dayjs`), the `@types/<mangled>` companion when it exists (`lodash` -> `@types/lodash`, scoped `@babel/core` -> `@types/babel__core`), or both, or neither (graceful empty, never a throw). It follows `/// <reference path|types>` and relative imports, includes each package's `package.json`, leaves every file UNWRAPPED, and surfaces a `truncated` flag instead of silently capping. Served from a new raw, HTTP-cacheable route `GET /api/script-packages/types/:lockfileHash/:specifier` (`Cache-Control: private, max-age=1y, immutable`), auth-gated by `script-packages.read`.
127
+ - `@checkstack/script-packages-common`: **BREAKING** - replaced the `listPackageTypes` RPC procedure and `PackageTypesSchema { name, version, dts }` with `PackageTypeClosureSchema` (a `{ path, content }` file-map plus `hasOwnTypes`/`hasAtTypes`/`notFound`/`truncated`) served over the cacheable HTTP route. Added a shared `buildTypeAcquisitionPath`/`parseTypeAcquisitionPath` path contract.
128
+ - `@checkstack/ui`: `CodeEditor`/`TypefoxEditor` gained an injected `acquireTypes` resolver + `acquireResetKey`. On debounced buffer change it parses bare `import`/`require` specifiers (pure, unit-tested) and lazily fetches + registers each NEW package's closure via `addExtraLib` at `file:///node_modules/...`, deduped by a shared acquired-set that resets when the install hash changes. Compiler options set `moduleResolution: NodeJs`, `baseUrl: "file:///"`, and `typeRoots` so a bare import resolves to its `@types` companion. The `context` ambient global keeps working unchanged.
129
+ - `@checkstack/script-packages-frontend`: replaced the old `useScriptPackageTypes` (which concatenated the broken `dts`) with `useScriptPackageTypeAcquisition()`, returning the `acquireTypes` resolver (targets the cacheable route, zod-validates the response) and the current `lockfileHash` as `acquireResetKey`.
130
+ - `@checkstack/automation-frontend` / `@checkstack/healthcheck-frontend`: wired the resolver into the Run Script and collector editors.
131
+
132
+ State & scale: the type closure is derived on read from the materialized package tree (no new durable state). The editor's acquired-set is pod-local UI bookkeeping; the route is keyed by the cluster-wide `lockfileHash`, so the browser HTTP cache is correct across pods and only refetches after a new install changes the hash.
133
+
134
+ - b995afb: Fix the automation Run Script action's `secretEnv` (secret → env mapping) test wiring and tolerate bare secret names.
135
+
136
+ - `@checkstack/ui` `ScriptTestPanel` now accepts the script field's declared `secretEnv` and renders an optional per-secret test-override input. The `ScriptTestRenderer` callback (DynamicForm) receives the SIBLING `x-secret-env` mapping value, located by annotation (not by field name), so a testable script field forwards it to the panel. Previously the test path never sent `secretEnv`, so `buildTestSecretEnv` got `undefined` and `process.env.<env>` was undefined in an in-UI test. Now an override-less test injects `__SECRET_<NAME>__` placeholders, and any operator override is masked from the output. Real secret values are still NEVER resolved in the test path.
137
+ - `@checkstack/automation-frontend` forwards the action's `secretEnv` and the collected overrides to `testScript`.
138
+ - `@checkstack/secrets-common`: the `secretEnv` mapping VALUE now accepts EITHER a `${{ secrets.NAME }}` template OR a bare secret name, normalizing a bare name to the canonical `${{ secrets.NAME }}` template on parse. This is a forgiving / NARROWING input change (more inputs accepted; stored/output form is unchanged and still the template), not a breaking change. Existing data and YAML shorthand like `secretEnv: { secret: SECRET }` now pass config validation instead of failing with "Must contain a ${{ secrets.NAME }} reference". Partial inline interpolation (e.g. `u:${{ secrets.pw }}@host`) keeps working unchanged; values that are neither a secret reference nor a valid secret name are still rejected.
139
+ - `@checkstack/ui` `parseSecretName` tolerates a legacy bare secret name for display so the picker shows the same name for both the template and the bare form.
140
+
141
+ The healthcheck collector test panel was checked: its config has no `x-secret-env` field, so it needed no secret wiring (only the `onRun` signature change, which is backward compatible).
142
+
143
+ - 270ef29: Secrets platform Phase 2: secret -> env-var mapping with central resolve, inject, and mask.
144
+
145
+ - Script consumers declare a least-privilege `secretEnv` allowlist
146
+ (`{ ENV_NAME: "${{ secrets.NAME }}" }`). The automation `run_script` /
147
+ `run_shell` actions resolve ONLY the declared secrets via
148
+ `secretResolverRef.resolveForRun`, inject them into the runner env for
149
+ that run (memory-only; the ESM runner gained a per-run `env` option), and
150
+ mask their values out of stdout/stderr/result/error via the run-scoped
151
+ masking context. A missing required secret fails the run clearly. No
152
+ ambient secret access.
153
+ - Test panel: `testScript` / `testCollectorScript` inject named
154
+ `__SECRET_<NAME>__` placeholders by default, or user-supplied per-secret
155
+ overrides; real production values are never resolved in the test path,
156
+ and overrides are masked out of the result.
157
+ - Healthcheck collectors carry the `secretEnv` field for authoring +
158
+ the test panel; runtime injection on satellites lands in Phase 3.
159
+ - Editor UX: a new `@checkstack/ui` `SecretEnvEditor` renders `x-secret-env`
160
+ record fields with `${{ secrets.* }}` name autocomplete (from
161
+ `listSecretNames`), wired into the automation action editor and the
162
+ healthcheck collector editor. New `withConfigMeta` helper +
163
+ `x-secret-env` config-meta key in `@checkstack/backend-api`.
164
+
165
+ - b995afb: fix(ui): make Popover/combobox lists scrollable inside a Sheet or Dialog
166
+
167
+ A `Popover` (and the comboboxes built on it, e.g. the automation trigger Event
168
+ picker, the secret-name picker, the package picker) portals its content to
169
+ `document.body`. When opened inside a modal `Sheet`/`Dialog`, the dialog's
170
+ `react-remove-scroll` scroll-lock blocked wheel/touch scrolling on that
171
+ body-portaled content, so a long list's `overflow-y-auto` could not scroll.
172
+
173
+ `SheetContent` and `DialogContent` now publish their content element through a
174
+ `PortalContainerContext`, and `PopoverContent` portals INTO it when present.
175
+ That keeps the popover inside the dialog's allowed-scroll subtree, so its lists
176
+ scroll again. Radix positions popovers with `position: fixed`, so placement and
177
+ clipping are unaffected; outside a Sheet/Dialog the popover still portals to
178
+ `body` as before.
179
+
180
+ - 270ef29: Collapse `ScriptTestPanel` behind a compact disclosure by default.
181
+
182
+ The inline script-test panel previously expanded its sample-context editor and results under every testable script field. It now defaults to collapsed: a compact "Test script" affordance shows, and the panel expands on demand. Running a test still auto-expands the results, and the last run's outcome surfaces as a badge while collapsed. A new `defaultOpen` prop opts back into the always-expanded behaviour.
183
+
184
+ ## 1.11.0
185
+
186
+ ### Minor Changes
187
+
188
+ - 41c77f4: feat(automation): deep + live definition validation surfaces invalid values, keys and ids — marked inline
189
+
190
+ Previously `validateDefinition` only checked the structural shape via
191
+ `AutomationDefinitionSchema`, where an action's `config` is typed as
192
+ `z.record(z.unknown())`. So a bad config value (e.g. `level:
193
+ debugthisiswrong` on `automation.log`) passed validation, and switching
194
+ to the visual editor just showed an empty dropdown with no explanation.
195
+
196
+ **Backend — deep validation.** New `collectDefinitionIssues` walker
197
+ validates the whole definition semantically, not just structurally:
198
+
199
+ - unknown trigger `event` / action `action` ids,
200
+ - each provider action's `config` against the registered action's own
201
+ schema (wrong enum value, missing required field, wrong type),
202
+ - each trigger's `config` against the trigger's `configSchema`,
203
+ - **unknown / typo'd config keys** — object configs are validated in
204
+ strict mode, so `levle: "info"` is reported rather than silently
205
+ stripped,
206
+ - recurses through `choose` / `parallel` / `repeat` / `sequence` so
207
+ nested action configs are covered too.
208
+
209
+ Issues come back with a dot-joinable `path` (e.g.
210
+ `actions.0.config.level`, `triggers.1.event`). The `validateDefinition`
211
+ RPC now returns these.
212
+
213
+ **Frontend — live + inline.** The automation editor re-validates on
214
+ every edit (debounced ~400ms) in BOTH tabs, and marks the offending
215
+ content in place rather than in a separate alert panel:
216
+
217
+ - **YAML tab** — issues (and YAML syntax errors) are squiggled at the
218
+ exact node. `@checkstack/ui`'s `CodeEditor` gained a `markers` prop;
219
+ the editor maps each issue's `path` onto the YAML document's node
220
+ range via a new `computeYamlMarkers` helper (walking up to the
221
+ nearest existing ancestor when a key is absent, e.g. a missing
222
+ required field).
223
+ - **Visual tab** — the specific card carrying an issue is marked: a
224
+ destructive border + warning icon + the field-level messages. A
225
+ `ValidationProvider` context partitions issues by owner (action card
226
+ / trigger card / condition / top-level) using the action-node path
227
+ grammar, so a nested action's config error attaches to the nested
228
+ card, and a `choose`'s own `when` error attaches to the choose card.
229
+ `ActionCard` gained an `errors` prop. So importing YAML with a bad
230
+ value (the empty-dropdown case) now visibly flags the card instead of
231
+ being silent.
232
+
233
+ The big error alert is gone; the only residual panel is a slim fallback
234
+ for the rare top-level issue that can't attach to any card.
235
+
236
+ Note: strict config validation means an action whose config schema
237
+ intentionally allowed extra keys would now flag them; action configs
238
+ across the platform declare all their fields, so this only catches
239
+ genuine typos.
240
+
241
+ - 41c77f4: fix(automation): editor UI fixes — action-config autocomplete, popup edge clamping + scroll, de-misleading action icon
242
+
243
+ Four fixes to the automation editor's visual mode:
244
+
245
+ - **Template autocomplete on action config fields.** A provider
246
+ action's config form (e.g. `automation.log`'s `message`) rendered
247
+ plain string fields with no `{{ … }}` autocomplete — only the
248
+ condition/expression fields had it. `DynamicForm` gains a
249
+ `templateCompletionProvider` prop; when supplied, default single-line
250
+ string fields render a `TemplateValueInput` wired to it instead of a
251
+ bare `Input`. The automation editor passes the staged template-mode
252
+ provider, so config fields now get the same field / comparator / value
253
+ / filter completion as conditions. Other `DynamicForm` consumers are
254
+ unaffected (the prop is opt-in; without it string fields stay plain).
255
+
256
+ - **Autocomplete popup no longer overflows the window.** The popup is
257
+ now edge-aware: it flips above the input when there isn't room below,
258
+ anchors to the input's right edge when a left-anchored popup would
259
+ spill past the right edge, and caps its height to the available space
260
+ (the list scrolls within it). The placement decision is extracted into
261
+ a pure, unit-tested `computePopupPlacement` helper.
262
+
263
+ - **Keyboard navigation scrolls the popup.** Arrowing through a list
264
+ taller than the popup now scrolls the highlighted row into view
265
+ (`scrollIntoView({ block: "nearest" })`) instead of leaving the
266
+ selection off-screen.
267
+
268
+ - **Action card icon no longer looks like a run button.** The "action"
269
+ kind used a `Play` triangle, which reads as a test/run control but
270
+ actually sits inside the card's expand toggle (so clicking it just
271
+ collapsed the card). Swapped to `Zap`, the conventional
272
+ automation-action glyph, which carries no "click to run" affordance.
273
+
274
+ - **Inline-script actions get their typed runtime context.** The Monaco
275
+ editor for `Run Script (TypeScript)` was falling back to an untyped
276
+ default context because the editor never received type definitions.
277
+ `useVariableScope` now also returns the `declare const context: …`
278
+ declarations from `generateAutomationContextTypes` (already built, but
279
+ never wired), and the provider action body forwards them to
280
+ `DynamicForm` so `context.trigger.payload` is typed as the discriminated
281
+ union over the automation's subscribed triggers, with
282
+ `context.artifacts` / `context.var` / `context.repeat` in scope at the
283
+ action's position. Shell scripts get their context the same way every
284
+ other config string does: `{{ … }}` templates are expanded by the
285
+ dispatch engine (`renderValue`) before the script runs, with the same
286
+ field autocomplete as other template fields.
287
+
288
+ - 41c77f4: feat(automation): native per-editor context for script actions (typed `context` for TS, `$ENV` for shell)
289
+
290
+ Script action editors had a confusing dual system: the TypeScript editor
291
+ type-checked `{{ }}` template text as code (so `{{ artifact.x }}` errored
292
+ with "Cannot find name"), and the runtime never actually populated the
293
+ `context` object. This standardises on a single, native context-access
294
+ mechanism per editor kind.
295
+
296
+ **Run scope reaches actions.** `ActionExecutionContext` gains a `scope`
297
+ (`{ trigger, artifacts, vars, repeat? }`), populated by the dispatch
298
+ engine from the same scope it already uses for `{{ }}` rendering. Actions
299
+ that need broad context (the script actions) read from it instead of
300
+ having to declare every artifact type in `consumes`. Additive and
301
+ optional, so existing actions are unaffected.
302
+
303
+ **TypeScript / JavaScript → typed `context`.** `run_script` now builds
304
+ `context` from the run scope, so `context.trigger.payload`,
305
+ `context.artifacts`, `context.var`, `context.repeat`, and
306
+ `context.automation` are populated at run time (previously
307
+ `context.trigger` was always empty). The editor types match via
308
+ `generateAutomationContextTypes`.
309
+
310
+ **Shell → `$CHECKSTACK_*` env vars.** `run_shell` flattens the run scope
311
+ into environment variables (e.g. `$CHECKSTACK_TRIGGER_PAYLOAD_TITLE`,
312
+ `$CHECKSTACK_ARTIFACT_INTEGRATION_JIRA_ISSUE_ISSUEKEY`). Arrays become a
313
+ single newline-separated var (iterate with `while IFS= read -r x; do …;
314
+ done <<< "$VAR"`). Every value is a plain string — no JSON blob, since
315
+ the container has no `jq` to parse one. A shared `toShellEnvKey`
316
+ helper (in `@checkstack/automation-common`) derives the names so the
317
+ shell editor's `$` autocomplete lists exactly what the runtime injects.
318
+
319
+ **One syntax per field kind (editor + runtime).** `MultiTypeEditorField`
320
+ no longer offers `{{ }}` autocomplete in `typescript` / `javascript` /
321
+ `shell` editors, and the dispatch engine no longer template-renders
322
+ native-code config fields (those whose `x-editor-types` is a code type) —
323
+ so `{{ }}` can't be used in a script by accident. Text / markup editors
324
+ (`raw`, `json`, `yaml`, `xml`, `markdown`, `formdata`) and plain string
325
+ fields keep `{{ }}` as before. Because both the automation and
326
+ health-check editors share `MultiTypeEditorField`, they behave
327
+ identically.
328
+
329
+ **Script-editor IntelliSense polish.** The code editors got a few
330
+ ergonomic fixes so the typed context is actually usable: the suggestion
331
+ **details panel auto-opens** (so long completion names are legible
332
+ on-focus, not hidden behind the chevron); word-based keyword noise is
333
+ disabled in favour of language-service + provider completions; and a
334
+ TS/JS completion provider makes `context.artifacts.` list the in-scope
335
+ artifact ids and **auto-convert the dot to bracket notation** —
336
+ `context.artifacts["integration-jira.issue"]` — since those ids aren't
337
+ valid identifiers. (Driven by a new opt-in `dottedKeyCompletions` prop on
338
+ the editor / `DynamicForm`.)
339
+
340
+ **BREAKING (beta):** `{{ }}` interpolation inside a script action's
341
+ `script` field (shell or TypeScript) is no longer expanded at run time —
342
+ read run data via the typed `context` object (TS) or `$CHECKSTACK_*` env
343
+ vars (shell) instead. Non-script config fields are unchanged.
344
+
345
+ Also fixes: switching a provider action in the visual editor now resets
346
+ its config, so the validator no longer reports the previous action's keys
347
+ as unrecognised.
348
+
349
+ - 41c77f4: feat(automation): Phase 11 — editor primitives + context type generation
350
+
351
+ Lays the UI + type-generation groundwork for Phase 12's visual automation
352
+ editor. Every primitive reuses the existing Monaco wrapper / template
353
+ engine / `jsonSchemaToTypeScript` helper rather than building parallel
354
+ infrastructure.
355
+
356
+ **`@checkstack/automation-common` — `resolveVariableScope`**
357
+
358
+ Pure walker that returns the in-scope `{{ … }}` paths at a given action
359
+ position. Conservative scoping rules: linear-upstream variables /
360
+ artifacts only (no leaking across `choose` / `parallel` / `repeat`
361
+ branches), `repeat.index` / `repeat.item` exposed only inside a `repeat`,
362
+ and trigger.payload modelled as a **discriminated union over
363
+ `trigger.event`** — every payload field surfaces; ones that come from a
364
+ subset of subscribed triggers carry a `conditionalOnTriggers` annotation
365
+ so the picker can render an "Only when …" hint. Earlier draft used
366
+ schema-intersection; switched to discriminated unions per review
367
+ feedback so Monaco can narrow correctly inside event-gated branches.
368
+
369
+ **Condition-aware narrowing.** When the path descends through a
370
+ `choose-when`, the resolver parses the branch's `when:` expression and
371
+ statically pins `trigger.event` to the set the condition allows —
372
+ patterns covered are `trigger.event == "X"` (either operand order),
373
+ `trigger.event != "X"`, `||`/`&&` of those, and `{ and: [...] }` /
374
+ `{ or: [...] }` combinators. So an action inside
375
+ `when: 'trigger.event == "incident.created"'` sees only the
376
+ `incident.created` variant in scope, the `conditionalOnTriggers`
377
+ annotation disappears, and other-trigger fields drop out entirely.
378
+ Nested choose branches compound (intersection). Anything outside the
379
+ covered patterns falls back to the full union — better to show every
380
+ field than guess wrong.
381
+
382
+ **`@checkstack/template-engine`**
383
+
384
+ The expression AST (`Expr`, `BinaryExpr`, `MemberExpr`, etc.) is now a
385
+ public export — the resolver's condition-narrowing walker needs to
386
+ inspect parsed condition trees. `ParsedCondition.root` is tightened
387
+ from `unknown` to `Expr` so consumers don't need to cast.
388
+
389
+ **`@checkstack/automation-frontend` — `generateAutomationContextTypes`**
390
+
391
+ Consumes `resolveVariableScope`'s output + the trigger / artifact
392
+ registries and emits the `declare const context: { … }` TS declaration
393
+ that `integration-script.run_script`'s Monaco editor injects via
394
+ `addExtraLib`. The emitted shape:
395
+
396
+ ```ts
397
+ type AutomationTrigger =
398
+ | { event: "incident.created"; payload: { … } }
399
+ | { event: "incident.resolved"; payload: { … } };
400
+
401
+ declare const context: {
402
+ trigger: AutomationTrigger;
403
+ artifacts: { "jira.issue"?: { key: string; … }; … };
404
+ var: { foo?: string; … };
405
+ repeat: { index: number; item: unknown }; // only when inside a repeat
406
+ };
407
+ ```
408
+
409
+ `jsonSchemaToTypeScript` from `@checkstack/ui` is reused via a deep
410
+ import (rather than the barrel) so the bun test runner doesn't try to
411
+ load Monaco's Vite-only `?worker` modules during unit tests.
412
+
413
+ **`@checkstack/ui` — new editor primitives**
414
+
415
+ - `TemplateValueInput` — single-line `{{ }}` autocomplete input.
416
+ Extracted from `DynamicForm/KeyValueEditor`'s previously-private
417
+ `TemplateInput` so other editor surfaces can share it without
418
+ rebuilding the picker UX. `KeyValueEditor` is now a one-line
419
+ delegation; `detectTemplateContext` is also exported.
420
+ - `VariablePicker` — hierarchical popover for the explicit "fx" /
421
+ "Insert variable" workflow. Renders a filterable tree of
422
+ `VariableNode`s with type chips and `Only when …` hints sourced from
423
+ the resolver's `conditionalOnTriggers`. Defaults to a small "fx" pill
424
+ trigger; callers can pass a custom one.
425
+ - `TemplateInput` — high-level mode switcher: `text` mode delegates to
426
+ `TemplateValueInput`, all other modes (`code` / `bash` / `json` /
427
+ `yaml`) delegate to `CodeEditor` with the matching language so the
428
+ action editor can swap widgets purely from the action's
429
+ `x-editor-types` annotation without touching the consuming code.
430
+ - `TemplateInputToggle` — the small "fx" pill that flips a typed input
431
+ (number / select / date / …) into template mode and back. Auto-infers
432
+ template mode when the saved value already starts with `{{`, so
433
+ round-tripping a previously-templated automation works out of the
434
+ box. Render-prop API for the typed editor so consumers keep control
435
+ over their own input shape.
436
+ - `ActionCard` — collapsible card that hosts a single action in the
437
+ visual editor. Decoupled from `DynamicForm` so container blocks
438
+ (`ChooseBlock` / `ParallelBlock` / `RepeatBlock` in Phase 12) can use
439
+ it as a structural shell over their own children. Toggle / delete /
440
+ drag handle are conditionally rendered on their callback's presence.
441
+
442
+ Storybook stories shipped for each of the new primitives.
443
+
444
+ **`@checkstack/integration-script-backend`**
445
+
446
+ `ScriptContext` docstring and the `scriptRunConfigSchema.script` field
447
+ description now point at `generateAutomationContextTypes` so the Phase
448
+ 12 editor wiring is unambiguous — the runtime payload type stays
449
+ `Record<string, unknown>` (the runner can't know the trigger schema),
450
+ but the **editor** narrows it per-automation from the subscribed
451
+ triggers' payload schemas.
452
+
453
+ - 4832e33: fix(automation): insert runtime-parseable `templateRef` from editor autocomplete + variable picker, with array indexing
454
+
455
+ The automation editor's `{{ }}` autocomplete and the `fx` variable picker
456
+ previously inserted the canonical dotted path (e.g.
457
+ `artifact.integration-jira.issue.issueKey`), which the template engine
458
+ cannot parse when an artifact id contains dots or hyphens, and which used
459
+ the singular `artifact`/`var` namespaces the runtime template context does
460
+ not expose. They now insert the runtime-parseable `templateRef` form -
461
+ plural top-level namespace (`artifacts`/`variables`) plus bracket notation
462
+ for non-identifier segments, e.g. `artifacts["integration-jira.issue"].issueKey`.
463
+
464
+ - `@checkstack/automation-common`: `VariableEntry` gains `templateRef`
465
+ (runtime-parseable insertion form) and `referenceable`, alongside the
466
+ unchanged canonical `path`. New exported helpers `isTemplateIdentifier`,
467
+ `appendTemplateSegment`, and `appendArrayIndex` build the form. Scope
468
+ derivation now descends into `array` schemas, offering both the whole
469
+ array and a representative element subtree (`tags[0]`, `comments[0].author`,
470
+ nested `matrix[0][0]`).
471
+ - `CompletionField` / `TemplateProperty` / `VariableNode` carry a
472
+ `templateRef` alongside the canonical `path`.
473
+ - The staged completion provider's field label, filter/match, insert text,
474
+ and value-stage field lookup all operate in `templateRef` space. The
475
+ expression tokenizer now emits bracket tokens and reconstructs the full
476
+ `foo["bar"].baz` / `foo["bar"].list[0]` access chain (normalising single
477
+ quotes to the stored double-quoted form, and supporting bare numeric array
478
+ indices) so value-stage enum suggestions resolve for bracket-notation and
479
+ indexed fields.
480
+ - `VariablePicker` and the `DynamicForm` template inserters write the
481
+ `templateRef` (falling back to `path` when absent).
482
+ - Shell-env (`$CHECKSTACK_*`) name derivation deliberately keeps using the
483
+ canonical dotted `path`, so the suggested env names stay byte-identical
484
+ to the backend's path-based injection. Script-context type generation is
485
+ unchanged.
486
+ - `@checkstack/integration-script-backend`: shell-script actions now also
487
+ expose array elements as indexed `$CHECKSTACK_*_<i>` env vars (and
488
+ `$CHECKSTACK_*_<i>_<field>` for object elements), alongside the existing
489
+ whole-array newline-joined var, so the runtime injects exactly the
490
+ array-element names the editor now suggests.
491
+
492
+ - 35bc682: feat(healthcheck): expose check + system run-context to script collectors
493
+
494
+ Script health checks can now read which check and system a run is for.
495
+ Previously shell scripts got only a curated env whitelist and inline
496
+ scripts only `context.config`, so a script had no built-in way to know
497
+ its own check name or the system it was checking.
498
+
499
+ - `@checkstack/backend-api`: new `CollectorRunContext` type
500
+ (`{ check: { id, name, intervalSeconds }, system: { id, name } }`) and
501
+ an optional `runContext` param on `CollectorStrategy.execute`. Optional,
502
+ so existing collector implementations are unaffected.
503
+ - Shell-script collector: injects reserved `CHECKSTACK_CHECK_ID`,
504
+ `CHECKSTACK_CHECK_NAME`, `CHECKSTACK_CHECK_INTERVAL_SECONDS`,
505
+ `CHECKSTACK_SYSTEM_ID`, `CHECKSTACK_SYSTEM_NAME` env vars (user-supplied
506
+ `env` still wins on collision).
507
+ - Inline-script collector: exposes `context.check` and `context.system`
508
+ alongside `context.config`; the inline-script editor now types them for
509
+ autocomplete.
510
+ - Shell editors (health-check collectors and automation shell actions) now
511
+ also suggest the user's own `env` (JSON) keys as `$NAME` completions, via
512
+ the new exported `customShellEnvVars` helper. Keys that aren't valid shell
513
+ identifiers are omitted.
514
+ - Fix: the Typefox `CodeEditor` captured a stale `onChange` at editor start,
515
+ so editing one `DynamicForm` field reverted sibling fields changed since
516
+ mount (e.g. typing in a shell `script` field wiped an unsaved `env` value,
517
+ or deleted a sibling automation action added after mount). The change
518
+ handler now routes through a ref to the current `onChange`.
519
+ - Fix: focusing a JSON editor threw "LanguageStatusService.addStatus is not
520
+ supported" because the standalone service set omitted `ILanguageStatusService`.
521
+ That one service is now registered via `serviceOverrides`.
522
+ - Fix: the automation trigger card nested a `<Badge>` (a `<div>`) inside a
523
+ `<p>`, producing a `validateDOMNesting` warning. Switched the wrapper to a
524
+ `<div>`.
525
+ - Local runs (`queue-executor`) and satellite runs both populate the
526
+ context. `SatelliteAssignment` (and the `getAssignmentsForSatellite`
527
+ RPC output) gained optional `configName` / `systemName` so the metadata
528
+ reaches satellite-side execution; `HealthCheckService` resolves the
529
+ system name via the catalog client.
530
+
531
+ BREAKING CHANGE: `createHealthCheckRouter` now requires a `catalogClient`
532
+ option (used to resolve system names for satellite assignments). Update
533
+ call sites to pass the catalog RPC client.
534
+
535
+ - c39ee69: Replace the Monaco-based `CodeEditor` with `@typefox/monaco-editor-react`, backed
536
+ by the standalone VS Code language services (no SharedArrayBuffer / cross-origin
537
+ isolation required). The `CodeEditor` public API is unchanged except for the
538
+ breaking note below; existing consumers keep working.
539
+
540
+ What this improves:
541
+
542
+ - Typed `context` IntelliSense is reliable (no more `addExtraLib` timing race).
543
+ - JSON / YAML / XML editors gain template-aware structural validation: the
544
+ content is validated as the JSON/YAML/XML it renders to, so `{{ }}` templates
545
+ are tolerated in any position (including unquoted, e.g. a numeric value) while
546
+ genuine structural errors are still flagged.
547
+ - JSON uses the real VS Code JSON language service (proper highlighting +
548
+ completion).
549
+ - Template `{{ }}` completion, shell `$env` completion, and external validation
550
+ markers are preserved.
551
+
552
+ > [!IMPORTANT]
553
+ > BREAKING (beta): the `dottedKeyCompletions` prop is removed from `CodeEditor`
554
+ > (and from `DynamicForm` / `FormField`). Bracket-notation completions for
555
+ > non-identifier object keys (e.g. `context.artifacts["integration-jira.issue"]`)
556
+ > are now derived automatically from the injected `typeDefinitions`, so the prop
557
+ > is no longer needed.
558
+
559
+ The `monaco-editor` and `@monaco-editor/react` dependencies are removed.
560
+
561
+ ### Patch Changes
562
+
563
+ - Updated dependencies [e2d6f25]
564
+ - Updated dependencies [6d52276]
565
+ - @checkstack/frontend-api@0.6.0
566
+ - @checkstack/common@0.12.0
567
+
3
568
  ## 1.10.0
4
569
 
5
570
  ### Minor Changes