@signalsafe/tree-spec-editor 0.4.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +168 -0
- package/README.md +14 -4
- package/RELEASING.md +102 -0
- package/SECURITY.md +22 -0
- package/dist/modals/AuditLogModal.d.ts.map +1 -1
- package/dist/modals/AuditLogModal.js +3 -3
- package/dist/modals/DraftHistoryModal.d.ts.map +1 -1
- package/dist/modals/DraftHistoryModal.js +4 -3
- package/dist/modals/EditorHistoryModalFrame.d.ts +12 -0
- package/dist/modals/EditorHistoryModalFrame.d.ts.map +1 -0
- package/dist/modals/EditorHistoryModalFrame.js +7 -0
- package/dist/panels/inspector/ChoiceEditorCard.d.ts +3 -22
- package/dist/panels/inspector/ChoiceEditorCard.d.ts.map +1 -1
- package/dist/panels/inspector/ChoiceEditorCard.js +8 -5
- package/dist/panels/inspector/ChoiceEditorList.d.ts +2 -22
- package/dist/panels/inspector/ChoiceEditorList.d.ts.map +1 -1
- package/dist/panels/inspector/types.d.ts +21 -0
- package/dist/panels/inspector/types.d.ts.map +1 -1
- package/docs/README.md +5 -0
- package/docs/UI_KIT_AGNOSTIC_REFACTOR.md +1 -1
- package/docs/UI_KIT_AGNOSTIC_USAGE.md +1 -1
- package/docs/current-release-candidate.md +11 -0
- package/package.json +11 -7
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
No unreleased changes recorded.
|
|
11
|
+
|
|
12
|
+
## [0.4.1] - 2026-10-21
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
|
|
16
|
+
- Disable label/target mutations in published or read-only choice inspectors, retain the inspected draft/history presentation and audit fixes, and align the coordinated editor dependency floors.
|
|
17
|
+
- Refresh current README, release preparation and package compatibility documentation.
|
|
18
|
+
|
|
19
|
+
## [0.4.1+step5.readonly.20261018.1] - 2026-10-18 (local candidate)
|
|
20
|
+
|
|
21
|
+
- Disable choice Label and Next mutation controls under the existing published/read-only flag; preserve enabled disclosure inspection and default editable controls.
|
|
22
|
+
- Hosts can remove blanket disabled fieldsets around editor panels while retaining their own prompt slot permission binding. No props, dependency minors or theme changes.
|
|
23
|
+
|
|
24
|
+
## [0.4.0] - 2026-10-09
|
|
25
|
+
|
|
26
|
+
### Added
|
|
27
|
+
|
|
28
|
+
- `InspectorPanel` `collapsibleChoices` renders each choice as a collapsible card with a label toggle (`graph-editor-choice-toggle`); one card is open at a time and all start collapsed.
|
|
29
|
+
|
|
30
|
+
### Changed
|
|
31
|
+
|
|
32
|
+
- Depend on `@signalsafe/tree-spec` `^0.4.1`, `@signalsafe/tree-spec-editor-core` `^0.2.2` and `@signalsafe/tree-spec-editor-react` `^0.3.2` so consumers resolve a single copy of each.
|
|
33
|
+
|
|
34
|
+
## [0.3.7] - 2026-09-08
|
|
35
|
+
|
|
36
|
+
### Changed
|
|
37
|
+
|
|
38
|
+
- Adopt `@signalsafe/tree-spec-editor-core` **^0.2.1** and
|
|
39
|
+
`@signalsafe/tree-spec-editor-react` **^0.3.1** so consumers receive the
|
|
40
|
+
corrected cycle-with-an-exit terminal-path behavior and revision-aware save
|
|
41
|
+
contract.
|
|
42
|
+
|
|
43
|
+
## [0.3.6] - 2026-08-28
|
|
44
|
+
|
|
45
|
+
### Changed
|
|
46
|
+
|
|
47
|
+
- Require `@signalsafe/tree-spec` **^0.3.4**, `@signalsafe/tree-spec-editor-core` **^0.1.6**, and `@signalsafe/tree-spec-editor-react` **^0.2.5**.
|
|
48
|
+
|
|
49
|
+
## [0.3.5] - 2026-08-28
|
|
50
|
+
|
|
51
|
+
### Added
|
|
52
|
+
|
|
53
|
+
- Optional node and transition counts in `GraphEditorInfoPanel`'s property table.
|
|
54
|
+
- `renderPromptField`, an inspector extension point that lets host applications replace the default prompt textarea while preserving the selected-node update contract.
|
|
55
|
+
|
|
56
|
+
### Notes
|
|
57
|
+
|
|
58
|
+
- Existing hosts retain the default prompt textarea when `renderPromptField` is omitted.
|
|
59
|
+
|
|
60
|
+
## [0.3.4] - 2026-07-01
|
|
61
|
+
|
|
62
|
+
### Added
|
|
63
|
+
|
|
64
|
+
- Semantic class hooks for the choices inspector row layout: `graph-editor-list__item--choice-inspector`, `graph-editor-choice-inspector-header`, and `graph-editor-choice-inspector-actions`.
|
|
65
|
+
- Exported the new hooks from the package barrel.
|
|
66
|
+
- Tests asserting choice inspector semantic classes render on `ChoiceEditorCard`.
|
|
67
|
+
|
|
68
|
+
### Notes
|
|
69
|
+
|
|
70
|
+
- Additive release only — default layout is unchanged when host CSS does not target the new hooks.
|
|
71
|
+
- Pairs with `@signalsafe/tree-spec-editor-theme-bootstrap@0.3.2` choice-inspector styling slice.
|
|
72
|
+
- Republished under `v0.3.4` after `v0.3.3` was already tagged.
|
|
73
|
+
|
|
74
|
+
## [0.3.3] - 2026-07-01
|
|
75
|
+
|
|
76
|
+
### Added
|
|
77
|
+
|
|
78
|
+
- Semantic class hooks for the choices inspector row layout: `graph-editor-list__item--choice-inspector`, `graph-editor-choice-inspector-header`, and `graph-editor-choice-inspector-actions`.
|
|
79
|
+
- Exported the new hooks from the package barrel.
|
|
80
|
+
- Tests asserting choice inspector semantic classes render on `ChoiceEditorCard`.
|
|
81
|
+
|
|
82
|
+
### Notes
|
|
83
|
+
|
|
84
|
+
- Additive release only — default layout is unchanged when host CSS does not target the new hooks.
|
|
85
|
+
- Pairs with `@signalsafe/tree-spec-editor-theme-bootstrap@0.3.1` choice-inspector styling slice.
|
|
86
|
+
- Superseded on npm by `0.3.4` (tag collision).
|
|
87
|
+
|
|
88
|
+
## [0.3.2] - 2026-06-30
|
|
89
|
+
|
|
90
|
+
### Added
|
|
91
|
+
|
|
92
|
+
- Semantic icon and empty-state class hooks (`graph-editor-action-icon--*`, `graph-editor-empty-state`, `graph-editor-list__item--with-delete`) for host styling without DOM enhancers.
|
|
93
|
+
- Tests and barrel exports for the new hooks.
|
|
94
|
+
|
|
95
|
+
### Notes
|
|
96
|
+
|
|
97
|
+
- Additive release only — existing editor screens render unchanged when hooks are not styled.
|
|
98
|
+
|
|
99
|
+
## [0.3.1] - 2026-06-28
|
|
100
|
+
|
|
101
|
+
### Fixed
|
|
102
|
+
|
|
103
|
+
- Updated the editor shell release line to explicitly consume the patched `@signalsafe/tree-spec-editor-react@^0.2.1` package, which removes the React Flow CSS side-effect import from built JavaScript.
|
|
104
|
+
|
|
105
|
+
### Notes
|
|
106
|
+
|
|
107
|
+
- No public editor shell API changes.
|
|
108
|
+
- No Bootstrap or UI framework dependencies were added.
|
|
109
|
+
- Host applications remain responsible for editor styling, including importing `reactflow/dist/style.css` from the host app entrypoint when default React Flow styling is desired.
|
|
110
|
+
|
|
111
|
+
## [0.3.0] - 2026-06-28
|
|
112
|
+
|
|
113
|
+
### Changed
|
|
114
|
+
|
|
115
|
+
- Removed Bootstrap-specific runtime styling assumptions from the tree-spec editor shell.
|
|
116
|
+
- Updated the editor shell to use UI-kit-agnostic `graph-editor-*` class hooks.
|
|
117
|
+
- Updated internal SignalSafe dependency ranges for the current package release line:
|
|
118
|
+
- `@signalsafe/tree-spec@^0.3.3`
|
|
119
|
+
- `@signalsafe/tree-spec-editor-core@^0.1.4`
|
|
120
|
+
- `@signalsafe/tree-spec-editor-react@^0.2.0`
|
|
121
|
+
- Raised the supported Node.js baseline to Node 22.12+.
|
|
122
|
+
|
|
123
|
+
### Fixed
|
|
124
|
+
|
|
125
|
+
- Addressed SonarCloud maintainability findings by marking editor shell component props as read-only across panels, modals, inspector fields, toolbar helpers, and UI primitives.
|
|
126
|
+
- Addressed SonarCloud consistency findings by using `export…from` for shared toolbar constant re-exports.
|
|
127
|
+
|
|
128
|
+
### Notes
|
|
129
|
+
|
|
130
|
+
- This release does not include `react-bootstrap` or `bootstrap`.
|
|
131
|
+
- Host applications are responsible for providing styling for the emitted `graph-editor-*` hooks.
|
|
132
|
+
|
|
133
|
+
## [0.2.3] - 2026-06-26
|
|
134
|
+
|
|
135
|
+
### Fixed
|
|
136
|
+
|
|
137
|
+
- Clear monorepo `paths` from standalone `tsconfig.build.json` so local `yarn build` works outside the monorepo.
|
|
138
|
+
|
|
139
|
+
### Changed
|
|
140
|
+
|
|
141
|
+
- Standardize development on Yarn 1.22.22 (`packageManager`, README dev commands).
|
|
142
|
+
- Bump internal `@signalsafe/*` dependencies to current release ranges.
|
|
143
|
+
|
|
144
|
+
## [0.2.2] - 2026-06-26
|
|
145
|
+
|
|
146
|
+
### Added
|
|
147
|
+
|
|
148
|
+
- `SECURITY.md`, Dependabot, `CHANGELOG.md`, updated [RELEASING.md](./RELEASING.md).
|
|
149
|
+
- Expanded React package test coverage.
|
|
150
|
+
- Package artifact smoke test (`yarn smoke:package`).
|
|
151
|
+
|
|
152
|
+
### Changed
|
|
153
|
+
|
|
154
|
+
- Package metadata and README (Batches 3–4).
|
|
155
|
+
|
|
156
|
+
### CI
|
|
157
|
+
|
|
158
|
+
- Checks and tests on every PR; Sonar **`scan`** is label-gated on PRs and runs on tag push and manual dispatch (Batch 1).
|
|
159
|
+
- Publish only from manual **`main`** dispatch or **`v*`** tags (not PR labels); publish requires **`checks`**, **`tests`**, and **`scan`**.
|
|
160
|
+
|
|
161
|
+
[Unreleased]: https://github.com/SignalSafeSoftware/tree-spec-editor/compare/v0.4.0...HEAD
|
|
162
|
+
[0.3.7]: https://github.com/SignalSafeSoftware/tree-spec-editor/compare/v0.3.6...v0.3.7
|
|
163
|
+
[0.3.6]: https://github.com/SignalSafeSoftware/tree-spec-editor/compare/v0.3.5...v0.3.6
|
|
164
|
+
[0.3.5]: https://github.com/SignalSafeSoftware/tree-spec-editor/compare/v0.3.4...v0.3.5
|
|
165
|
+
[0.3.1]: https://github.com/SignalSafeSoftware/tree-spec-editor/compare/v0.3.0...v0.3.1
|
|
166
|
+
[0.3.0]: https://github.com/SignalSafeSoftware/tree-spec-editor/compare/v0.2.3...v0.3.0
|
|
167
|
+
[0.2.3]: https://github.com/SignalSafeSoftware/tree-spec-editor/releases/tag/v0.2.3
|
|
168
|
+
[0.2.2]: https://github.com/SignalSafeSoftware/tree-spec-editor/releases/tag/v0.2.2
|
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# `@signalsafe/tree-spec-editor`
|
|
2
2
|
|
|
3
|
+
Current source and planned customer-subdomain impact: [current-state summary](docs/current-release-candidate.md).
|
|
4
|
+
|
|
3
5
|
React **UI-kit agnostic shell** for authoring TreeSpec graphs: canvas (from `@signalsafe/tree-spec-editor-react`), sidebar panels, modals, and toolbar helpers. Hosts style panels with Bootstrap, Material UI, or custom CSS via `graph-editor-*` class hooks.
|
|
4
6
|
|
|
5
7
|
| | |
|
|
@@ -116,9 +118,9 @@ Published consumers import only the package root. Layer stack:
|
|
|
116
118
|
|
|
117
119
|
| Layer | Package | Owns |
|
|
118
120
|
|-------|---------|------|
|
|
119
|
-
| Wire | [`@signalsafe/tree-spec`](
|
|
120
|
-
| Core | [`@signalsafe/tree-spec-editor-core`](
|
|
121
|
-
| React | [`@signalsafe/tree-spec-editor-react`](
|
|
121
|
+
| Wire | [`@signalsafe/tree-spec`](https://github.com/SignalSafeSoftware/tree-spec#readme) | TreeSpec wire types, constants, compile/lint. Pure TS. |
|
|
122
|
+
| Core | [`@signalsafe/tree-spec-editor-core`](https://github.com/SignalSafeSoftware/tree-spec-editor-core#readme) | Editor model, tree operations, layout/autosave/keyboard helpers, constants. Pure TS. |
|
|
123
|
+
| React | [`@signalsafe/tree-spec-editor-react`](https://github.com/SignalSafeSoftware/tree-spec-editor-react#readme) | React Flow canvas (`TreeSpecGraphEditor`). React-specific, UI-library-agnostic. |
|
|
122
124
|
| Shell | **`@signalsafe/tree-spec-editor`** (this package) | UI-kit agnostic panels, modals, toolbar (`graph-editor-*` hooks). Re-exports canvas from `-react` and helpers from `-core`. |
|
|
123
125
|
|
|
124
126
|
| Directory | Contents |
|
|
@@ -732,7 +734,7 @@ import NodeAppearanceFields from '../ui/components/NodeAppearanceFields';
|
|
|
732
734
|
/>
|
|
733
735
|
```
|
|
734
736
|
|
|
735
|
-
Wire format details: [`@signalsafe/tree-spec` README](
|
|
737
|
+
Wire format details: [`@signalsafe/tree-spec` README](https://github.com/SignalSafeSoftware/tree-spec#readme) — **Graph editor metadata**.
|
|
736
738
|
|
|
737
739
|
### `SelectedEdgePanel`
|
|
738
740
|
|
|
@@ -1253,3 +1255,11 @@ function addPromptNode(tree: EditorTree): EditorTree {
|
|
|
1253
1255
|
Standalone source and releases: [SignalSafeSoftware/tree-spec-editor](https://github.com/SignalSafeSoftware/tree-spec-editor).
|
|
1254
1256
|
|
|
1255
1257
|
Published as [`@signalsafe/tree-spec-editor`](https://www.npmjs.com/package/@signalsafe/tree-spec-editor) on npm.
|
|
1258
|
+
|
|
1259
|
+
Choice inspector Label and Next controls honor the existing read-only state, including published versions. Choice disclosures remain available for inspection. No host blanket disabled fieldset is required.
|
|
1260
|
+
|
|
1261
|
+
## Release and compatibility
|
|
1262
|
+
|
|
1263
|
+
Release `0.4.1` preserves the installed Step 5 editor capabilities and the verified audit fixes. The coordinated dependency floor is TreeSpec `^0.4.4`, editor-core `^0.2.3`, and editor-react `^0.3.3` where declared. React integrations retain React 18 / React Flow 11. See [release preparation](./RELEASING.md) for verification and publication order. The coordinated release was approved on 2026-10-21; registry availability is recorded in release verification receipts.
|
|
1264
|
+
|
|
1265
|
+
See the [current release documentation](docs/current-release-candidate.md) for release-specific compatibility and verification boundaries.
|
package/RELEASING.md
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# Releasing @signalsafe/tree-spec-editor
|
|
2
|
+
|
|
3
|
+
## Release 0.4.1
|
|
4
|
+
|
|
5
|
+
The coordinated release was approved on 2026-10-21. Publish only the reviewed source revision and verified archive after the required checks; this document does not assert registry availability.
|
|
6
|
+
|
|
7
|
+
The supported editor chain is TreeSpec `^0.4.4` → editor-core `^0.2.3` → editor-react `^0.3.3` → editor `0.4.1`, with the CSS-only theme `0.3.7`. Publish and verify each upstream registry archive before releasing its dependent. React packages retain React/React DOM 18 and React Flow 11; the theme has no runtime JavaScript dependencies.
|
|
8
|
+
|
|
9
|
+
## Verification
|
|
10
|
+
|
|
11
|
+
Use the committed lockfile and Node 22.12+; CI checks Node 22 and 24. Before release, run the package scripts declared in `package.json`, inspect `npm pack --dry-run`, and test downstream packages using the exact packed candidate. Record local candidate proof separately from a smoke test that installs published dependencies. A registry smoke test remains pending until its required upstream version is available.
|
|
12
|
+
|
|
13
|
+
After successful hosted checks at the approved revision, the existing `.github/workflows/ci.yml` publishes on an approved `v*` tag. Manual dispatch runs verification without publishing. Preserve the workflow's checks, tests, scan, smoke, and publish conditions as applicable; inspect their actual results before a release. Verify registry metadata and downloaded archive contents after publication, then update host declarations and locks together and run host integration checks.
|
|
14
|
+
|
|
15
|
+
## Historical release notes
|
|
16
|
+
|
|
17
|
+
The following records describe earlier release preparation; their version pins and sequencing are historical.
|
|
18
|
+
|
|
19
|
+
## Releasing `@signalsafe/tree-spec-editor`
|
|
20
|
+
|
|
21
|
+
Standalone repository: [SignalSafeSoftware/tree-spec-editor](https://github.com/SignalSafeSoftware/tree-spec-editor).
|
|
22
|
+
|
|
23
|
+
**Depends on:** `@signalsafe/tree-spec`, `@signalsafe/tree-spec-editor-core`, `@signalsafe/tree-spec-editor-react`. **Peer deps:** `react`, `react-dom`, `reactflow`.
|
|
24
|
+
|
|
25
|
+
## UI-kit release publish order
|
|
26
|
+
|
|
27
|
+
When shipping the UI-kit agnostic line, publish dependencies **before** this package:
|
|
28
|
+
|
|
29
|
+
1. `@signalsafe/tree-spec-editor-core@0.1.3` (unchanged unless core changed)
|
|
30
|
+
2. `@signalsafe/tree-spec-editor-react@0.2.0` — canvas `graph-editor-*` hooks
|
|
31
|
+
3. **`@signalsafe/tree-spec-editor@0.3.0`** (this package) — requires `^0.2.0` of `-react` on the registry
|
|
32
|
+
|
|
33
|
+
Until `@signalsafe/tree-spec-editor-react@0.2.0` is published, `yarn install` and `yarn smoke:package` in this repo may fail resolving `^0.2.0`. After publishing `-react`, run `yarn install` here to refresh `yarn.lock`, then smoke and publish this package.
|
|
34
|
+
|
|
35
|
+
## Requirements
|
|
36
|
+
|
|
37
|
+
- Node.js **>=22.12.0** for local development, CI, and publish smoke (see `package.json` `engines`). Node 20 is no longer supported (GitHub Actions Node 20 deprecation).
|
|
38
|
+
|
|
39
|
+
## CI publish policy
|
|
40
|
+
|
|
41
|
+
- **Checks and tests** run on every pull request.
|
|
42
|
+
- **`scan` (Sonar)** on pull requests is **optional** — it runs only when the PR has the **`scan`** label. On **`push`** (including **`v*`** tag pushes) and **`workflow_dispatch`**, **`scan`** runs automatically.
|
|
43
|
+
- **Publish does not run** from PR labels.
|
|
44
|
+
- **Publish runs** when:
|
|
45
|
+
- **Manual:** GitHub Actions → **CI** → **Run workflow** on branch **`main`**, or
|
|
46
|
+
- **Tag:** push a semver tag matching `v*` (for example `vX.Y.Z`).
|
|
47
|
+
- **Publish requires** successful **`checks`**, **`tests`**, and **`scan`** jobs in the same workflow run (see [`.github/workflows/ci.yml`](https://github.com/SignalSafeSoftware/tree-spec-editor/blob/main/.github/workflows/ci.yml)).
|
|
48
|
+
- Pushing a **`v*`** tag starts a workflow run where **`checks`**, **`tests`**, and **`scan`** run before **Publish** can proceed.
|
|
49
|
+
- **GitHub Releases do not trigger publish** in the current workflow.
|
|
50
|
+
- **No npm Environment approval or provenance** in CI today.
|
|
51
|
+
|
|
52
|
+
## CI tooling and npm auth
|
|
53
|
+
|
|
54
|
+
- Local development and CI use **Yarn** for `install`, `test`, `build`, and `smoke:package`.
|
|
55
|
+
- CI **publish** uses **`npm publish`** (non-interactive; compatible with 2FA-enabled npm accounts when auth is configured correctly).
|
|
56
|
+
- Set the GitHub Actions secret **`NPM_TOKEN`** to a publish-capable npm token unless **npm trusted publishing/OIDC** is configured for the repository.
|
|
57
|
+
- If the npm account or package requires **2FA for publish**, the token must support non-interactive publishing — for example a granular access token with read/write package access and **2FA bypass enabled for write actions**, or npm trusted publishing/OIDC.
|
|
58
|
+
- CI writes auth to `~/.npmrc` only; no `.npmrc` is committed to the repository.
|
|
59
|
+
- CI does not run `npm version` or bump versions during publish; the committed `package.json` version is published as-is.
|
|
60
|
+
|
|
61
|
+
## Before you release
|
|
62
|
+
|
|
63
|
+
1. Bump `version` in `package.json` (and `@signalsafe/*` dependency versions if needed).
|
|
64
|
+
2. Update [CHANGELOG.md](./CHANGELOG.md) (`[Unreleased]` → new version section when tagging).
|
|
65
|
+
3. Run locally:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
yarn install --frozen-lockfile
|
|
69
|
+
yarn typecheck
|
|
70
|
+
yarn test
|
|
71
|
+
yarn build
|
|
72
|
+
npm publish --dry-run
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
4. Run artifact smoke test: `yarn smoke:package` (pack, temp consumer install, export/type checks — enforced in CI before publish).
|
|
76
|
+
|
|
77
|
+
## Publish
|
|
78
|
+
|
|
79
|
+
1. Commit the version and changelog updates on **`main`**:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
git add package.json CHANGELOG.md
|
|
83
|
+
git commit -m "Release vX.Y.Z"
|
|
84
|
+
git push origin main
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
2. Tag and push (recommended — triggers **Publish** when required jobs succeed):
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
git tag vX.Y.Z
|
|
91
|
+
git push origin vX.Y.Z
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
**Option B — Manual dispatch:** merge release commits to **`main`**, then GitHub → **Actions** → **CI** → **Run workflow** (branch **`main`**). Ensure `package.json` `version` matches the release you intend to ship.
|
|
95
|
+
|
|
96
|
+
## After publish
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
npm view @signalsafe/tree-spec-editor version
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
CI runs `yarn smoke:package`, logs the package version, then publishes with `npm publish` using `NPM_TOKEN` auth.
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
## Supported versions
|
|
4
|
+
|
|
5
|
+
Node.js 22.12 or newer (see `package.json` `engines`). Only the latest published release line receives security fixes.
|
|
6
|
+
|
|
7
|
+
## Reporting a vulnerability
|
|
8
|
+
|
|
9
|
+
Please report suspected security vulnerabilities **privately**. Do **not** open a public GitHub issue for security reports.
|
|
10
|
+
|
|
11
|
+
Email: security@signalsafe.software
|
|
12
|
+
|
|
13
|
+
Include a description, reproduction steps, affected versions, and impact if known. We aim to acknowledge reports within five business days.
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
## Security boundaries
|
|
17
|
+
|
|
18
|
+
This package provides the **full TreeSpec editor UI shell** (panels, modals, toolbars). It does not own routing, backend APIs, or authentication.
|
|
19
|
+
|
|
20
|
+
- It manipulates and displays TreeSpec authoring data supplied by the host application.
|
|
21
|
+
- The host application must enforce who may view or edit scenarios, validate publish payloads server-side, and secure stored drafts and audit logs.
|
|
22
|
+
- Form fields and rendered labels may contain operator-authored text; the host decides what content is trusted and how it is sanitized.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuditLogModal.d.ts","sourceRoot":"","sources":["../../src/modals/AuditLogModal.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,CAAC;
|
|
1
|
+
{"version":3,"file":"AuditLogModal.d.ts","sourceRoot":"","sources":["../../src/modals/AuditLogModal.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,CAAC;AAehF,MAAM,WAAW,kBAAkB;IAC/B,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,OAAO,CAAC;IACtB,WAAW,EAAE,sBAAsB,EAAE,CAAC;IACtC,OAAO,EAAE,MAAM,IAAI,CAAC;IAEpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AASD,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,EAClC,IAAI,EACJ,YAAY,EACZ,WAAW,EACX,OAAO,EACP,KAAqB,EACrB,QAA2B,EAC3B,WAAkC,EAClC,cAAyC,EACzC,UAAgC,EAChC,UAAgC,GACnC,EAAE,QAAQ,CAAC,kBAAkB,CAAC,sCA8C9B"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { EDITOR_BADGE, EDITOR_EMPTY_STATE, EDITOR_FLEX_BETWEEN,
|
|
3
|
-
import
|
|
2
|
+
import { EDITOR_BADGE, EDITOR_EMPTY_STATE, EDITOR_FLEX_BETWEEN, EDITOR_MONO, EDITOR_MUTED, EDITOR_SCROLL, EDITOR_SPACING_MB_0, EDITOR_SPACING_MT_1, joinClasses, } from '../ui/editorClasses.js';
|
|
3
|
+
import EditorHistoryModalFrame from './EditorHistoryModalFrame.js';
|
|
4
4
|
const DEFAULT_TITLE = 'Audit log';
|
|
5
5
|
const DEFAULT_SUBTITLE = 'Authoring actions for this tree_spec version.';
|
|
6
6
|
const DEFAULT_LOADING_TEXT = 'Loading…';
|
|
@@ -20,5 +20,5 @@ export default function AuditLogModal({ show, loadingAudit, auditEvents, onClose
|
|
|
20
20
|
else {
|
|
21
21
|
auditContent = (_jsx("ul", { className: joinClasses('graph-editor-list--plain', EDITOR_SCROLL, EDITOR_SPACING_MB_0), children: auditEvents.map((e) => (_jsxs("li", { className: "graph-editor-list__plain-item", children: [_jsxs("div", { className: EDITOR_FLEX_BETWEEN, children: [_jsx("span", { className: joinClasses(EDITOR_BADGE, 'graph-editor-badge--neutral'), children: e.action }), _jsx("span", { className: joinClasses(EDITOR_MUTED, 'graph-editor-text--sm'), children: new Date(e.created_on).toLocaleString() })] }), e.actor == null ? null : (_jsxs("span", { className: joinClasses(EDITOR_MUTED, 'graph-editor-text--sm'), children: [actorLabel, " ", e.actor] })), e.detail && Object.keys(e.detail).length > 0 ? (_jsx("pre", { className: joinClasses(EDITOR_MONO, EDITOR_MUTED, 'graph-editor-text--sm', EDITOR_SPACING_MB_0, EDITOR_SPACING_MT_1), children: JSON.stringify(e.detail) })) : null] }, e.id))) }));
|
|
22
22
|
}
|
|
23
|
-
return (_jsx(
|
|
23
|
+
return (_jsx(EditorHistoryModalFrame, { title: title, subtitle: subtitle, closeLabel: closeLabel, onClose: onClose, children: auditContent }));
|
|
24
24
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DraftHistoryModal.d.ts","sourceRoot":"","sources":["../../src/modals/DraftHistoryModal.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;
|
|
1
|
+
{"version":3,"file":"DraftHistoryModal.d.ts","sourceRoot":"","sources":["../../src/modals/DraftHistoryModal.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAc1F,MAAM,WAAW,sBAAsB;IACnC,IAAI,EAAE,OAAO,CAAC;IACd,gBAAgB,EAAE,OAAO,CAAC;IAC1B,SAAS,EAAE,oBAAoB,EAAE,CAAC;IAClC,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,IAAI,EAAE,UAAU,GAAG,IAAI,CAAC;IACxB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,iBAAiB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAEhD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAcD,MAAM,CAAC,OAAO,UAAU,iBAAiB,CAAC,EACtC,IAAI,EACJ,gBAAgB,EAChB,SAAS,EACT,mBAAmB,EACnB,gBAAgB,EAChB,IAAI,EACJ,OAAO,EACP,gBAAgB,EAChB,iBAAiB,EACjB,KAAqB,EACrB,QAA2B,EAC3B,WAAkC,EAClC,mBAA0C,EAC1C,qBAA8C,EAC9C,YAAoC,EACpC,cAAwC,EACxC,WAAkC,EAClC,cAAyC,EACzC,UAAgC,GACnC,EAAE,QAAQ,CAAC,sBAAsB,CAAC,sCAsDlC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { EDITOR_EMPTY_STATE, EDITOR_FLEX_BETWEEN,
|
|
3
|
-
import { EditorButton
|
|
2
|
+
import { EDITOR_EMPTY_STATE, EDITOR_FLEX_BETWEEN, EDITOR_MUTED, EDITOR_SCROLL, EDITOR_SPACING_MB_0, EDITOR_SPACING_MB_3, joinClasses, } from '../ui/editorClasses.js';
|
|
3
|
+
import { EditorButton } from '../ui/primitives.js';
|
|
4
|
+
import EditorHistoryModalFrame from './EditorHistoryModalFrame.js';
|
|
4
5
|
const DEFAULT_TITLE = 'Draft history';
|
|
5
6
|
const DEFAULT_SUBTITLE = 'Restore an earlier snapshot into the current draft. Creating a snapshot saves the current graph state.';
|
|
6
7
|
const DEFAULT_LIST_CAPTION = 'Snapshots (newest first)';
|
|
@@ -24,5 +25,5 @@ export default function DraftHistoryModal({ show, loadingSnapshots, snapshots, r
|
|
|
24
25
|
else {
|
|
25
26
|
snapshotsContent = (_jsx("ul", { className: joinClasses('graph-editor-list--plain', EDITOR_SCROLL, EDITOR_SPACING_MB_0), children: snapshots.map((s) => (_jsxs("li", { className: joinClasses(EDITOR_FLEX_BETWEEN, 'graph-editor-list__plain-item'), children: [_jsxs("div", { children: [_jsx("span", { className: EDITOR_MUTED, children: new Date(s.created_on).toLocaleString() }), s.label ? _jsx("span", { className: "graph-editor-inline-gap", children: s.label }) : null, s.spec_hash ? (_jsxs("span", { className: joinClasses(EDITOR_MUTED, 'graph-editor-text--sm'), children: [s.spec_hash.slice(0, 8), "\u2026"] })) : null] }), _jsx(EditorButton, { tone: "warning", onClick: () => onRestoreSnapshot(s.id), disabled: restoringSnapshotId !== null, children: restoringSnapshotId === s.id ? restoringLabel : restoreLabel })] }, s.id))) }));
|
|
26
27
|
}
|
|
27
|
-
return (
|
|
28
|
+
return (_jsxs(EditorHistoryModalFrame, { title: title, subtitle: subtitle, closeLabel: closeLabel, onClose: onClose, children: [_jsxs("div", { className: joinClasses(EDITOR_FLEX_BETWEEN, EDITOR_SPACING_MB_3), children: [_jsx("span", { className: joinClasses(EDITOR_MUTED, 'graph-editor-text--sm'), children: listCaption }), _jsx(EditorButton, { tone: "primary", onClick: onCreateSnapshot, disabled: !tree || creatingSnapshot, children: creatingSnapshot ? creatingSnapshotLabel : createSnapshotLabel })] }), snapshotsContent] }));
|
|
28
29
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
interface EditorHistoryModalFrameProps {
|
|
3
|
+
title: string;
|
|
4
|
+
subtitle: string;
|
|
5
|
+
closeLabel: string;
|
|
6
|
+
onClose: () => void;
|
|
7
|
+
children: ReactNode;
|
|
8
|
+
}
|
|
9
|
+
/** Shared history dialog chrome; each caller owns its data and body actions. */
|
|
10
|
+
export default function EditorHistoryModalFrame({ title, subtitle, closeLabel, onClose, children, }: Readonly<EditorHistoryModalFrameProps>): import("react").JSX.Element;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=EditorHistoryModalFrame.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EditorHistoryModalFrame.d.ts","sourceRoot":"","sources":["../../src/modals/EditorHistoryModalFrame.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAevC,UAAU,4BAA4B;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,EAAE,SAAS,CAAC;CACvB;AAED,gFAAgF;AAChF,MAAM,CAAC,OAAO,UAAU,uBAAuB,CAAC,EAC5C,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,QAAQ,GACjD,EAAE,QAAQ,CAAC,4BAA4B,CAAC,+BAsBxC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { EDITOR_MODAL, EDITOR_MODAL_BODY, EDITOR_MODAL_CONTENT, EDITOR_MODAL_DIALOG, EDITOR_MODAL_FOOTER, EDITOR_MODAL_HEADER, EDITOR_MODAL_TITLE, EDITOR_MUTED, joinClasses, } from '../ui/editorClasses.js';
|
|
3
|
+
import { EditorButton, EditorCloseButton } from '../ui/primitives.js';
|
|
4
|
+
/** Shared history dialog chrome; each caller owns its data and body actions. */
|
|
5
|
+
export default function EditorHistoryModalFrame({ title, subtitle, closeLabel, onClose, children, }) {
|
|
6
|
+
return (_jsx("dialog", { className: joinClasses(EDITOR_MODAL, 'graph-editor-modal--open'), open: true, children: _jsx("div", { className: joinClasses(EDITOR_MODAL_DIALOG, 'graph-editor-modal__dialog--lg'), children: _jsxs("div", { className: EDITOR_MODAL_CONTENT, children: [_jsxs("div", { className: EDITOR_MODAL_HEADER, children: [_jsx("h2", { className: EDITOR_MODAL_TITLE, children: title }), _jsx(EditorCloseButton, { onClick: onClose })] }), _jsxs("div", { className: EDITOR_MODAL_BODY, children: [_jsx("p", { className: joinClasses(EDITOR_MUTED, 'graph-editor-text--sm'), children: subtitle }), children] }), _jsx("div", { className: EDITOR_MODAL_FOOTER, children: _jsx(EditorButton, { tone: "neutral", onClick: onClose, children: closeLabel }) })] }) }) }));
|
|
7
|
+
}
|
|
@@ -1,29 +1,10 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
export default function ChoiceEditorCard({ choice, tree, selectedNode, focusChoiceId, isPublished, canMoveUp, canMoveDown, usedChoiceTypeIds, onUpdateSelectedNode, onDeleteChoice, onMoveChoice, onSetChoiceTarget, onSetChoiceOutcome, onSetChoiceType, choiceTypes, outcomeOptions, hideOutcomeField, renderExtraChoiceFields, onFocusChoice, collapsible, expanded, onToggleExpanded, }: Readonly<{
|
|
1
|
+
import { type EditorChoice } from '@signalsafe/tree-spec-editor-core';
|
|
2
|
+
import type { ChoiceEditorSharedProps } from './types.js';
|
|
3
|
+
export default function ChoiceEditorCard({ choice, tree, selectedNode, focusChoiceId, isPublished, canMoveUp, canMoveDown, usedChoiceTypeIds, onUpdateSelectedNode, onDeleteChoice, onMoveChoice, onSetChoiceTarget, onSetChoiceOutcome, onSetChoiceType, choiceTypes, outcomeOptions, hideOutcomeField, renderExtraChoiceFields, onFocusChoice, collapsible, expanded, onToggleExpanded, }: Readonly<ChoiceEditorSharedProps & {
|
|
5
4
|
choice: EditorChoice;
|
|
6
|
-
tree: EditorTree;
|
|
7
|
-
selectedNode: EditorNode;
|
|
8
|
-
focusChoiceId: string | null;
|
|
9
|
-
isPublished: boolean;
|
|
10
5
|
canMoveUp: boolean;
|
|
11
6
|
canMoveDown: boolean;
|
|
12
7
|
usedChoiceTypeIds: Set<string>;
|
|
13
|
-
onUpdateSelectedNode: (patch: Partial<EditorNode>) => void;
|
|
14
|
-
onDeleteChoice: (choiceId: string) => void;
|
|
15
|
-
onMoveChoice?: (choiceId: string, direction: 'up' | 'down') => void;
|
|
16
|
-
onSetChoiceTarget: (choiceId: string, targetNodeId: string) => void;
|
|
17
|
-
onSetChoiceOutcome: (choiceId: string, outcome: string) => void;
|
|
18
|
-
onSetChoiceType?: (choiceId: string, typeId: string, defaultLabel?: string) => void;
|
|
19
|
-
choiceTypes?: ReadonlyArray<ChoiceTypeOption>;
|
|
20
|
-
outcomeOptions: ReadonlyArray<{
|
|
21
|
-
value: string;
|
|
22
|
-
label: string;
|
|
23
|
-
}>;
|
|
24
|
-
hideOutcomeField: boolean;
|
|
25
|
-
renderExtraChoiceFields?: (ctx: InspectorChoiceRenderContext) => ReactNode;
|
|
26
|
-
onFocusChoice?: (choiceId: string) => void;
|
|
27
8
|
collapsible?: boolean;
|
|
28
9
|
expanded?: boolean;
|
|
29
10
|
onToggleExpanded?: () => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChoiceEditorCard.d.ts","sourceRoot":"","sources":["../../../src/panels/inspector/ChoiceEditorCard.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ChoiceEditorCard.d.ts","sourceRoot":"","sources":["../../../src/panels/inspector/ChoiceEditorCard.tsx"],"names":[],"mappings":"AAEA,OAAO,EAGH,KAAK,YAAY,EACpB,MAAM,mCAAmC,CAAC;AA4B3C,OAAO,KAAK,EAAE,uBAAuB,EAAoB,MAAM,YAAY,CAAC;AAY5E,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,EACrC,MAAM,EACN,IAAI,EACJ,YAAY,EACZ,aAAa,EACb,WAAW,EACX,SAAS,EACT,WAAW,EACX,iBAAiB,EACjB,oBAAoB,EACpB,cAAc,EACd,YAAY,EACZ,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EACf,WAAW,EACX,cAAc,EACd,gBAAgB,EAChB,uBAAuB,EACvB,aAAa,EACb,WAAmB,EACnB,QAAe,EACf,gBAAgB,GACnB,EAAE,QAAQ,CAAC,uBAAuB,GAAG;IAClC,MAAM,EAAE,YAAY,CAAC;IACrB,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,OAAO,CAAC;IACrB,iBAAiB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC/B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;CACjC,CAAC,+BA8LD"}
|
|
@@ -4,15 +4,18 @@ import { LIST_SELECTION_CLASS, LIST_SELECTION_TEXT_CLASS } from '../../lib/selec
|
|
|
4
4
|
import { EDITOR_CHOICE_INSPECTOR_ACTIONS, EDITOR_CHOICE_TOGGLE, EDITOR_CHOICE_INSPECTOR_HEADER, EDITOR_FLEX_BETWEEN, EDITOR_FLEX_FILL, EDITOR_FLEX_GROW_1, EDITOR_FLEX_ROW, EDITOR_LIST_ITEM, EDITOR_LIST_ITEM_CHOICE_INSPECTOR, EDITOR_MIN_W_0, EDITOR_SPACING_MB_0, EDITOR_SPACING_MB_1, EDITOR_SPACING_MB_2, EDITOR_SPACING_MT_0, EDITOR_SPACING_MT_2, joinClasses, } from '../../ui/editorClasses.js';
|
|
5
5
|
import { EditorField, EditorInput, EditorLabel, EditorSelect, } from '../../ui/primitives.js';
|
|
6
6
|
import { choiceActionIconProps } from './choiceActionIconProps.js';
|
|
7
|
+
function choiceTypeSelection(choice, choiceTypes, hasTypeSetter) {
|
|
8
|
+
const knownTypeIds = new Set((choiceTypes ?? []).map((type) => type.id));
|
|
9
|
+
const showTypeSelect = Boolean(choiceTypes?.length && hasTypeSetter);
|
|
10
|
+
return { showTypeSelect, isCustomType: showTypeSelect && !knownTypeIds.has(choice.id) };
|
|
11
|
+
}
|
|
7
12
|
export default function ChoiceEditorCard({ choice, tree, selectedNode, focusChoiceId, isPublished, canMoveUp, canMoveDown, usedChoiceTypeIds, onUpdateSelectedNode, onDeleteChoice, onMoveChoice, onSetChoiceTarget, onSetChoiceOutcome, onSetChoiceType, choiceTypes, outcomeOptions, hideOutcomeField, renderExtraChoiceFields, onFocusChoice, collapsible = false, expanded = true, onToggleExpanded, }) {
|
|
8
13
|
const transition = getTransition(tree, selectedNode.id, choice.id);
|
|
9
14
|
const targetNodeId = transition?.toNodeId ?? '';
|
|
10
15
|
const outcomeValue = transition?.outcome ?? outcomeOptions[0]?.value ?? '';
|
|
11
16
|
const isFocused = focusChoiceId === choice.id;
|
|
12
17
|
const showOutcome = !hideOutcomeField && targetNodeId === END_NODE_ID;
|
|
13
|
-
const
|
|
14
|
-
const showTypeSelect = Boolean(choiceTypes?.length && onSetChoiceType);
|
|
15
|
-
const isCustomType = showTypeSelect && !knownTypeIds.has(choice.id);
|
|
18
|
+
const { showTypeSelect, isCustomType } = choiceTypeSelection(choice, choiceTypes, Boolean(onSetChoiceType));
|
|
16
19
|
const bodyId = `choice-editor-body-${selectedNode.id}-${choice.id}`;
|
|
17
20
|
const body = (_jsxs(_Fragment, { children: [_jsxs("div", { className: joinClasses(EDITOR_CHOICE_INSPECTOR_HEADER, EDITOR_FLEX_BETWEEN, EDITOR_SPACING_MB_2), children: [_jsxs("div", { className: joinClasses(EDITOR_FLEX_ROW, EDITOR_FLEX_GROW_1, EDITOR_MIN_W_0, 'graph-editor-flex--gap'), children: [showTypeSelect ? (_jsxs(EditorField, { className: joinClasses(EDITOR_SPACING_MB_0, EDITOR_FLEX_FILL, EDITOR_MIN_W_0), children: [_jsx(EditorLabel, { className: EDITOR_SPACING_MB_1, children: "Type" }), _jsxs(EditorSelect, { value: isCustomType ? '__custom__' : choice.id, disabled: isPublished, "aria-label": `Choice type for ${choice.id}`, onChange: (event) => {
|
|
18
21
|
const nextTypeId = event.target.value;
|
|
@@ -20,12 +23,12 @@ export default function ChoiceEditorCard({ choice, tree, selectedNode, focusChoi
|
|
|
20
23
|
const type = choiceTypes.find((item) => item.id === nextTypeId);
|
|
21
24
|
onSetChoiceType(choice.id, nextTypeId, type?.label);
|
|
22
25
|
}
|
|
23
|
-
}, children: [choiceTypes.map((type) => (_jsx("option", { value: type.id, disabled: type.id !== choice.id && usedChoiceTypeIds.has(type.id), title: type.label, children: type.id }, type.id))), isCustomType ? (_jsxs("option", { value: "__custom__", children: [choice.id, " (custom)"] })) : null] })] })) : (_jsxs(EditorField, { className: joinClasses(EDITOR_SPACING_MB_0, EDITOR_FLEX_FILL, EDITOR_MIN_W_0), children: [_jsx(EditorLabel, { className: EDITOR_SPACING_MB_1, children: "Type" }), _jsx(EditorInput, { readOnly: true, className: "graph-editor-input--plain graph-editor-text--uppercase graph-editor-text--semibold", value: choice.id })] })), hideOutcomeField ? null : (_jsxs(EditorField, { className: joinClasses(EDITOR_SPACING_MB_0, EDITOR_FLEX_FILL, EDITOR_MIN_W_0), children: [_jsx(EditorLabel, { className: EDITOR_SPACING_MB_1, children: "Outcome" }), showOutcome ? (_jsx(EditorSelect, { value: outcomeValue, disabled: isPublished, "aria-label": `Outcome for ${choice.id}`, onChange: (e) => onSetChoiceOutcome(choice.id, e.target.value), children: outcomeOptions.map((opt) => (_jsx("option", { value: opt.value, children: opt.label }, opt.value))) })) : (_jsx(EditorSelect, { disabled: true, "aria-label": `Outcome for ${choice.id}`, value: "", children: _jsx("option", { value: "", children: "When Next is END" }) }))] }))] }), _jsxs("div", { className: EDITOR_CHOICE_INSPECTOR_ACTIONS, children: [onMoveChoice ? (_jsxs(_Fragment, { children: [_jsx("span", { ...choiceActionIconProps(() => onMoveChoice(choice.id, 'up'), 'Move choice up', undefined, isPublished || !canMoveUp, '↑', 'move-up') }), _jsx("span", { ...choiceActionIconProps(() => onMoveChoice(choice.id, 'down'), 'Move choice down', undefined, isPublished || !canMoveDown, '↓', 'move-down') })] })) : null, _jsx("span", { ...choiceActionIconProps(() => onDeleteChoice(choice.id), 'Delete choice', 'graph-editor-action-icon--danger', isPublished, '×', 'delete') })] })] }), _jsx(EditorLabel, { className: EDITOR_SPACING_MT_0, children: "Label" }), _jsx(EditorInput, { value: choice.label, onChange: (event) => {
|
|
26
|
+
}, children: [choiceTypes.map((type) => (_jsx("option", { value: type.id, disabled: type.id !== choice.id && usedChoiceTypeIds.has(type.id), title: type.label, children: type.id }, type.id))), isCustomType ? (_jsxs("option", { value: "__custom__", children: [choice.id, " (custom)"] })) : null] })] })) : (_jsxs(EditorField, { className: joinClasses(EDITOR_SPACING_MB_0, EDITOR_FLEX_FILL, EDITOR_MIN_W_0), children: [_jsx(EditorLabel, { className: EDITOR_SPACING_MB_1, children: "Type" }), _jsx(EditorInput, { readOnly: true, className: "graph-editor-input--plain graph-editor-text--uppercase graph-editor-text--semibold", value: choice.id })] })), hideOutcomeField ? null : (_jsxs(EditorField, { className: joinClasses(EDITOR_SPACING_MB_0, EDITOR_FLEX_FILL, EDITOR_MIN_W_0), children: [_jsx(EditorLabel, { className: EDITOR_SPACING_MB_1, children: "Outcome" }), showOutcome ? (_jsx(EditorSelect, { value: outcomeValue, disabled: isPublished, "aria-label": `Outcome for ${choice.id}`, onChange: (e) => onSetChoiceOutcome(choice.id, e.target.value), children: outcomeOptions.map((opt) => (_jsx("option", { value: opt.value, children: opt.label }, opt.value))) })) : (_jsx(EditorSelect, { disabled: true, "aria-label": `Outcome for ${choice.id}`, value: "", children: _jsx("option", { value: "", children: "When Next is END" }) }))] }))] }), _jsxs("div", { className: EDITOR_CHOICE_INSPECTOR_ACTIONS, children: [onMoveChoice ? (_jsxs(_Fragment, { children: [_jsx("span", { ...choiceActionIconProps(() => onMoveChoice(choice.id, 'up'), 'Move choice up', undefined, isPublished || !canMoveUp, '↑', 'move-up') }), _jsx("span", { ...choiceActionIconProps(() => onMoveChoice(choice.id, 'down'), 'Move choice down', undefined, isPublished || !canMoveDown, '↓', 'move-down') })] })) : null, _jsx("span", { ...choiceActionIconProps(() => onDeleteChoice(choice.id), 'Delete choice', 'graph-editor-action-icon--danger', isPublished, '×', 'delete') })] })] }), _jsx(EditorLabel, { className: EDITOR_SPACING_MT_0, children: "Label" }), _jsx(EditorInput, { disabled: isPublished, value: choice.label, onChange: (event) => {
|
|
24
27
|
const updatedChoices = (selectedNode.choices ?? []).map((existingChoice) => existingChoice.id === choice.id
|
|
25
28
|
? { ...existingChoice, label: event.target.value }
|
|
26
29
|
: existingChoice);
|
|
27
30
|
onUpdateSelectedNode({ choices: updatedChoices });
|
|
28
|
-
} }), _jsx(EditorLabel, { className: EDITOR_SPACING_MT_2, children: "Next" }), _jsxs(EditorSelect, { value: targetNodeId, onChange: (e) => onSetChoiceTarget(choice.id, e.target.value), children: [_jsx("option", { value: "", children: "(not connected)" }), Object.values(tree.nodes).map((n) => (_jsxs("option", { value: n.id, children: [n.id, " \u00B7 ", n.prompt?.slice(0, 40) || n.type] }, n.id))), _jsx("option", { value: END_NODE_ID, children: "END" })] }), renderExtraChoiceFields
|
|
31
|
+
} }), _jsx(EditorLabel, { className: EDITOR_SPACING_MT_2, children: "Next" }), _jsxs(EditorSelect, { disabled: isPublished, value: targetNodeId, onChange: (e) => onSetChoiceTarget(choice.id, e.target.value), children: [_jsx("option", { value: "", children: "(not connected)" }), Object.values(tree.nodes).map((n) => (_jsxs("option", { value: n.id, children: [n.id, " \u00B7 ", n.prompt?.slice(0, 40) || n.type] }, n.id))), _jsx("option", { value: END_NODE_ID, children: "END" })] }), renderExtraChoiceFields
|
|
29
32
|
? renderExtraChoiceFields({
|
|
30
33
|
tree,
|
|
31
34
|
node: selectedNode,
|
|
@@ -1,26 +1,6 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
import type { ChoiceTypeOption, InspectorChoiceRenderContext } from './types.js';
|
|
4
|
-
export default function ChoiceEditorList({ tree, selectedNode, focusChoiceId, isPublished, onAddChoice, onUpdateSelectedNode, onDeleteChoice, onMoveChoice, onSetChoiceTarget, onSetChoiceOutcome, onSetChoiceType, choiceTypes, outcomeOptions, hideOutcomeField, renderExtraChoiceFields, onFocusChoice, collapsibleChoices, }: Readonly<{
|
|
5
|
-
tree: EditorTree;
|
|
6
|
-
selectedNode: EditorNode;
|
|
7
|
-
focusChoiceId: string | null;
|
|
8
|
-
isPublished: boolean;
|
|
1
|
+
import type { ChoiceEditorSharedProps } from './types.js';
|
|
2
|
+
export default function ChoiceEditorList({ tree, selectedNode, focusChoiceId, isPublished, onAddChoice, onUpdateSelectedNode, onDeleteChoice, onMoveChoice, onSetChoiceTarget, onSetChoiceOutcome, onSetChoiceType, choiceTypes, outcomeOptions, hideOutcomeField, renderExtraChoiceFields, onFocusChoice, collapsibleChoices, }: Readonly<ChoiceEditorSharedProps & {
|
|
9
3
|
onAddChoice: () => void;
|
|
10
|
-
onUpdateSelectedNode: (patch: Partial<EditorNode>) => void;
|
|
11
|
-
onDeleteChoice: (choiceId: string) => void;
|
|
12
|
-
onMoveChoice?: (choiceId: string, direction: 'up' | 'down') => void;
|
|
13
|
-
onSetChoiceTarget: (choiceId: string, targetNodeId: string) => void;
|
|
14
|
-
onSetChoiceOutcome: (choiceId: string, outcome: string) => void;
|
|
15
|
-
onSetChoiceType?: (choiceId: string, typeId: string, defaultLabel?: string) => void;
|
|
16
|
-
choiceTypes?: ReadonlyArray<ChoiceTypeOption>;
|
|
17
|
-
outcomeOptions: ReadonlyArray<{
|
|
18
|
-
value: string;
|
|
19
|
-
label: string;
|
|
20
|
-
}>;
|
|
21
|
-
hideOutcomeField: boolean;
|
|
22
|
-
renderExtraChoiceFields?: (ctx: InspectorChoiceRenderContext) => ReactNode;
|
|
23
|
-
onFocusChoice?: (choiceId: string) => void;
|
|
24
4
|
collapsibleChoices?: boolean;
|
|
25
5
|
}>): import("react").JSX.Element;
|
|
26
6
|
//# sourceMappingURL=ChoiceEditorList.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ChoiceEditorList.d.ts","sourceRoot":"","sources":["../../../src/panels/inspector/ChoiceEditorList.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ChoiceEditorList.d.ts","sourceRoot":"","sources":["../../../src/panels/inspector/ChoiceEditorList.tsx"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAE1D,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,EACrC,IAAI,EACJ,YAAY,EACZ,aAAa,EACb,WAAW,EACX,WAAW,EACX,oBAAoB,EACpB,cAAc,EACd,YAAY,EACZ,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EACf,WAAW,EACX,cAAc,EACd,gBAAgB,EAChB,uBAAuB,EACvB,aAAa,EACb,kBAA0B,GAC7B,EAAE,QAAQ,CAAC,uBAAuB,GAAG;IAClC,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAChC,CAAC,+BAgFD"}
|
|
@@ -5,6 +5,27 @@ export type ChoiceTypeOption = {
|
|
|
5
5
|
id: string;
|
|
6
6
|
label: string;
|
|
7
7
|
};
|
|
8
|
+
/** Internal context and actions shared by the choice list and each choice card. */
|
|
9
|
+
export interface ChoiceEditorSharedProps {
|
|
10
|
+
tree: EditorTree;
|
|
11
|
+
selectedNode: EditorNode;
|
|
12
|
+
focusChoiceId: string | null;
|
|
13
|
+
isPublished: boolean;
|
|
14
|
+
onUpdateSelectedNode: (patch: Partial<EditorNode>) => void;
|
|
15
|
+
onDeleteChoice: (choiceId: string) => void;
|
|
16
|
+
onMoveChoice?: (choiceId: string, direction: 'up' | 'down') => void;
|
|
17
|
+
onSetChoiceTarget: (choiceId: string, targetNodeId: string) => void;
|
|
18
|
+
onSetChoiceOutcome: (choiceId: string, outcome: string) => void;
|
|
19
|
+
onSetChoiceType?: (choiceId: string, typeId: string, defaultLabel?: string) => void;
|
|
20
|
+
choiceTypes?: ReadonlyArray<ChoiceTypeOption>;
|
|
21
|
+
outcomeOptions: ReadonlyArray<{
|
|
22
|
+
value: string;
|
|
23
|
+
label: string;
|
|
24
|
+
}>;
|
|
25
|
+
hideOutcomeField: boolean;
|
|
26
|
+
renderExtraChoiceFields?: (ctx: InspectorChoiceRenderContext) => ReactNode;
|
|
27
|
+
onFocusChoice?: (choiceId: string) => void;
|
|
28
|
+
}
|
|
8
29
|
/**
|
|
9
30
|
* Canonical outcome values from the `@signalsafe/tree-spec` wire contract.
|
|
10
31
|
* Hosts can override via the `outcomeOptions` prop.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/panels/inspector/types.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/panels/inspector/types.ts"],"names":[],"mappings":"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"}
|
package/docs/README.md
ADDED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# UI-kit agnostic editor refactor — design scan (Prompt 8)
|
|
2
2
|
|
|
3
|
-
**Status:** Implemented on `cleanup` (Prompts 9–10, 9A). `@signalsafe/tree-spec-editor@0.3.0` and `@signalsafe/tree-spec-editor-react@0.2.0` are UI-kit agnostic. See [UI_KIT_AGNOSTIC_USAGE.md](./UI_KIT_AGNOSTIC_USAGE.md) and [`tree-spec-editor-react` canvas doc](
|
|
3
|
+
**Status:** Implemented on `cleanup` (Prompts 9–10, 9A). `@signalsafe/tree-spec-editor@0.3.0` and `@signalsafe/tree-spec-editor-react@0.2.0` are UI-kit agnostic. See [UI_KIT_AGNOSTIC_USAGE.md](./UI_KIT_AGNOSTIC_USAGE.md) and [`tree-spec-editor-react` canvas doc](https://github.com/SignalSafeSoftware/tree-spec-editor-react/blob/main/docs/UI_KIT_AGNOSTIC_CANVAS.md).
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -22,7 +22,7 @@ Peer dependencies: `react`, `react-dom`, `reactflow` only.
|
|
|
22
22
|
|-------|---------|------------|
|
|
23
23
|
| Wire | `@signalsafe/tree-spec` | None |
|
|
24
24
|
| Model | `@signalsafe/tree-spec-editor-core` | None |
|
|
25
|
-
| Canvas | `@signalsafe/tree-spec-editor-react` | None (React Flow only; canvas emits `graph-editor-*` hooks — see [`UI_KIT_AGNOSTIC_CANVAS.md`](
|
|
25
|
+
| Canvas | `@signalsafe/tree-spec-editor-react` | None (React Flow only; canvas emits `graph-editor-*` hooks — see [`UI_KIT_AGNOSTIC_CANVAS.md`](https://github.com/SignalSafeSoftware/tree-spec-editor-react/blob/main/docs/UI_KIT_AGNOSTIC_CANVAS.md)) |
|
|
26
26
|
| Shell | `@signalsafe/tree-spec-editor` | **Host-owned** — semantic hooks only |
|
|
27
27
|
|
|
28
28
|
---
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Current release: @signalsafe/tree-spec-editor 0.4.1
|
|
2
|
+
|
|
3
|
+
Status: coordinated release approved on 2026-10-21; registry availability is established by release verification receipts. Existing canonical source and host installations remain unchanged. The candidate combines the installed Step 5 capabilities with the verified package audit fixes; earlier dated state summaries and verification records remain historical evidence.
|
|
4
|
+
|
|
5
|
+
The package README describes supported entry points and behavior; `../RELEASING.md` describes the publication gate and order. Use the committed declaration in `../package.json` as the dependency authority. Candidate source, built files, packed archive, and isolated installed consumer must agree. Check actual gate receipts rather than inferring completion from this document.
|
|
6
|
+
|
|
7
|
+
TreeSpec `0.4.4` precedes editor-core `0.2.3`, editor-react `0.3.3`, editor `0.4.1` and theme `0.3.7`. Before publication, local archive proof verifies this chain without pretending unpublished versions can pass a frozen registry install. Registry lock refresh and published-dependency smoke verification remain staged until the upstream versions exist. React 18 / React Flow 11 support is retained.
|
|
8
|
+
|
|
9
|
+
## Review record
|
|
10
|
+
|
|
11
|
+
The canonical repository is preserved. Candidate changes are reviewed as a source delta over the verified remote baseline; frozen registry lock regeneration and final hosted checks remain separately recorded gates. Local passing tests do not establish production cutover or provider readiness.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@signalsafe/tree-spec-editor",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "UI-kit agnostic TreeSpec graph editor shell (React Flow canvas, panels, modals, toolbar).",
|
|
6
6
|
"license": "MIT",
|
|
@@ -35,7 +35,10 @@
|
|
|
35
35
|
"dist",
|
|
36
36
|
"docs",
|
|
37
37
|
"README.md",
|
|
38
|
-
"LICENSE"
|
|
38
|
+
"LICENSE",
|
|
39
|
+
"CHANGELOG.md",
|
|
40
|
+
"RELEASING.md",
|
|
41
|
+
"SECURITY.md"
|
|
39
42
|
],
|
|
40
43
|
"engines": {
|
|
41
44
|
"node": ">=22.12.0"
|
|
@@ -65,9 +68,9 @@
|
|
|
65
68
|
"test:monorepo": "cd ../../frontend && yarn vitest run --config vitest.tree-spec-editor.config.ts"
|
|
66
69
|
},
|
|
67
70
|
"dependencies": {
|
|
68
|
-
"@signalsafe/tree-spec": "^0.4.
|
|
69
|
-
"@signalsafe/tree-spec-editor-core": "^0.2.
|
|
70
|
-
"@signalsafe/tree-spec-editor-react": "^0.3.
|
|
71
|
+
"@signalsafe/tree-spec": "^0.4.4",
|
|
72
|
+
"@signalsafe/tree-spec-editor-core": "^0.2.3",
|
|
73
|
+
"@signalsafe/tree-spec-editor-react": "^0.3.3"
|
|
71
74
|
},
|
|
72
75
|
"peerDependencies": {
|
|
73
76
|
"react": "^18.0.0",
|
|
@@ -83,7 +86,8 @@
|
|
|
83
86
|
"react-test-renderer": "^18.3.1",
|
|
84
87
|
"reactflow": "^11.11.4",
|
|
85
88
|
"typescript": "^7.0.2",
|
|
86
|
-
"@vitest/coverage-v8": "^
|
|
87
|
-
"vitest": "^
|
|
89
|
+
"@vitest/coverage-v8": "^5.0.5",
|
|
90
|
+
"vitest": "^5.0.5",
|
|
91
|
+
"vite": "^8.3.4"
|
|
88
92
|
}
|
|
89
93
|
}
|