@signalsafe/tree-spec-editor 0.3.7 → 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 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`](../tree-spec/README.md) | TreeSpec wire types, constants, compile/lint. Pure TS. |
120
- | Core | [`@signalsafe/tree-spec-editor-core`](../tree-spec-editor-core/README.md) | Editor model, tree operations, layout/autosave/keyboard helpers, constants. Pure TS. |
121
- | React | [`@signalsafe/tree-spec-editor-react`](../tree-spec-editor-react/README.md) | React Flow canvas (`TreeSpecGraphEditor`). React-specific, UI-library-agnostic. |
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 |
@@ -689,6 +691,7 @@ function RightRail({
689
691
  - `onMoveChoice`: when set, shows up/down icon actions to reorder choices within the node.
690
692
  - `onFocusChoice`: invoked when the user focuses any control inside a choice card; use to sync canvas/node-list highlighting.
691
693
  - `renderExtraNodeFields({ tree, node, isPublished, onUpdateNode })`: render extra UI below the Prompt textarea, scoped to the currently-selected node. Use for project-specific node metadata (render hints, scoring, classification, etc.).
694
+ - `collapsibleChoices`: render each choice as a collapsible card with a label toggle; one card is open at a time and all start collapsed (pair with `@signalsafe/tree-spec-editor-theme-bootstrap` >= 0.3.4 for toggle styling).
692
695
  - `renderExtraChoiceFields({ tree, node, choice, transition, isPublished, onUpdateNode })`: render extra UI below each choice card (after Next/Outcome). Use for project-specific per-choice metadata.
693
696
  - `onDeleteSelectedNode`: when set, shows a delete-node icon in the Required card header; wire to `useTreeSpecEditor().actions.deleteSelectedNode` (or equivalent). Disabled automatically when `isPublished` is true.
694
697
  - `title`: Required card header text (default `"Required"`).
@@ -731,7 +734,7 @@ import NodeAppearanceFields from '../ui/components/NodeAppearanceFields';
731
734
  />
732
735
  ```
733
736
 
734
- Wire format details: [`@signalsafe/tree-spec` README](../tree-spec/README.md) — **Graph editor metadata**.
737
+ Wire format details: [`@signalsafe/tree-spec` README](https://github.com/SignalSafeSoftware/tree-spec#readme) — **Graph editor metadata**.
735
738
 
736
739
  ### `SelectedEdgePanel`
737
740
 
@@ -1252,3 +1255,11 @@ function addPromptNode(tree: EditorTree): EditorTree {
1252
1255
  Standalone source and releases: [SignalSafeSoftware/tree-spec-editor](https://github.com/SignalSafeSoftware/tree-spec-editor).
1253
1256
 
1254
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;AAsBhF,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,sCA8D9B"}
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, EDITOR_MODAL, EDITOR_MODAL_BODY, EDITOR_MODAL_CONTENT, EDITOR_MODAL_DIALOG, EDITOR_MODAL_FOOTER, EDITOR_MODAL_HEADER, EDITOR_MODAL_TITLE, EDITOR_MONO, EDITOR_MUTED, EDITOR_SCROLL, EDITOR_SPACING_MB_0, EDITOR_SPACING_MT_1, joinClasses, } from '../ui/editorClasses.js';
3
- import { EditorButton, EditorCloseButton } from '../ui/primitives.js';
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("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 }), auditContent] }), _jsx("div", { className: EDITOR_MODAL_FOOTER, children: _jsx(EditorButton, { tone: "neutral", onClick: onClose, children: closeLabel }) })] }) }) }));
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;AAoB1F,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,sCAsElC"}
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, EDITOR_MODAL, EDITOR_MODAL_BODY, EDITOR_MODAL_CONTENT, EDITOR_MODAL_DIALOG, EDITOR_MODAL_FOOTER, EDITOR_MODAL_HEADER, EDITOR_MODAL_TITLE, EDITOR_MUTED, EDITOR_SCROLL, EDITOR_SPACING_MB_0, EDITOR_SPACING_MB_3, joinClasses, } from '../ui/editorClasses.js';
3
- import { EditorButton, EditorCloseButton } from '../ui/primitives.js';
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 (_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 }), _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] }), _jsx("div", { className: EDITOR_MODAL_FOOTER, children: _jsx(EditorButton, { tone: "neutral", onClick: onClose, children: closeLabel }) })] }) }) }));
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,4 +1,4 @@
1
1
  import { type InspectorPanelProps } from './inspector/types.js';
2
2
  export { DEFAULT_OUTCOME_OPTIONS, type ChoiceTypeOption, type InspectorChoiceRenderContext, type InspectorNodeRenderContext, type InspectorPanelProps, } from './inspector/types.js';
3
- export default function InspectorPanel({ tree, selectedNode, focusChoiceId, isPublished, onUpdateSelectedNode, onAddChoice, onDeleteChoice, onMoveChoice, onSetChoiceTarget, onSetChoiceOutcome, outcomeOptions, hideOutcomeField, renderPromptField, renderExtraNodeFields, renderExtraChoiceFields, choiceTypes, onSetChoiceType, title, emptyStateText, typeHelperText, onDeleteSelectedNode, onFocusChoice, }: Readonly<InspectorPanelProps>): import("react").JSX.Element;
3
+ export default function InspectorPanel({ tree, selectedNode, focusChoiceId, isPublished, onUpdateSelectedNode, onAddChoice, onDeleteChoice, onMoveChoice, onSetChoiceTarget, onSetChoiceOutcome, outcomeOptions, hideOutcomeField, renderPromptField, renderExtraNodeFields, renderExtraChoiceFields, choiceTypes, onSetChoiceType, title, emptyStateText, typeHelperText, onDeleteSelectedNode, onFocusChoice, collapsibleChoices, }: Readonly<InspectorPanelProps>): import("react").JSX.Element;
4
4
  //# sourceMappingURL=InspectorPanel.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"InspectorPanel.d.ts","sourceRoot":"","sources":["../../src/panels/InspectorPanel.tsx"],"names":[],"mappings":"AAmBA,OAAO,EAGH,KAAK,mBAAmB,EAC3B,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACH,uBAAuB,EACvB,KAAK,gBAAgB,EACrB,KAAK,4BAA4B,EACjC,KAAK,0BAA0B,EAC/B,KAAK,mBAAmB,GAC3B,MAAM,sBAAsB,CAAC;AAE9B,MAAM,CAAC,OAAO,UAAU,cAAc,CAAC,EACnC,IAAI,EACJ,YAAY,EACZ,aAAoB,EACpB,WAAmB,EACnB,oBAAoB,EACpB,WAAW,EACX,cAAc,EACd,YAAY,EACZ,iBAAiB,EACjB,kBAAkB,EAClB,cAAwC,EACxC,gBAAwB,EACxB,iBAAiB,EACjB,qBAAqB,EACrB,uBAAuB,EACvB,WAAW,EACX,eAAe,EACf,KAAkB,EAClB,cAA4C,EAC5C,cAAyC,EACzC,oBAAoB,EACpB,aAAa,GAChB,EAAE,QAAQ,CAAC,mBAAmB,CAAC,+BAwC/B"}
1
+ {"version":3,"file":"InspectorPanel.d.ts","sourceRoot":"","sources":["../../src/panels/InspectorPanel.tsx"],"names":[],"mappings":"AAmBA,OAAO,EAGH,KAAK,mBAAmB,EAC3B,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACH,uBAAuB,EACvB,KAAK,gBAAgB,EACrB,KAAK,4BAA4B,EACjC,KAAK,0BAA0B,EAC/B,KAAK,mBAAmB,GAC3B,MAAM,sBAAsB,CAAC;AAE9B,MAAM,CAAC,OAAO,UAAU,cAAc,CAAC,EACnC,IAAI,EACJ,YAAY,EACZ,aAAoB,EACpB,WAAmB,EACnB,oBAAoB,EACpB,WAAW,EACX,cAAc,EACd,YAAY,EACZ,iBAAiB,EACjB,kBAAkB,EAClB,cAAwC,EACxC,gBAAwB,EACxB,iBAAiB,EACjB,qBAAqB,EACrB,uBAAuB,EACvB,WAAW,EACX,eAAe,EACf,KAAkB,EAClB,cAA4C,EAC5C,cAAyC,EACzC,oBAAoB,EACpB,aAAa,EACb,kBAAkB,GACrB,EAAE,QAAQ,CAAC,mBAAmB,CAAC,+BAyC/B"}
@@ -20,6 +20,6 @@ import RequiredNodeCard from './inspector/RequiredNodeCard.js';
20
20
  import { EDITOR_EMPTY_STATE, EDITOR_MUTED, joinClasses } from '../ui/editorClasses.js';
21
21
  import { DEFAULT_OUTCOME_OPTIONS, DEFAULT_TYPE_HELPER_TEXT, } from './inspector/types.js';
22
22
  export { DEFAULT_OUTCOME_OPTIONS, } from './inspector/types.js';
23
- export default function InspectorPanel({ tree, selectedNode, focusChoiceId = null, isPublished = false, onUpdateSelectedNode, onAddChoice, onDeleteChoice, onMoveChoice, onSetChoiceTarget, onSetChoiceOutcome, outcomeOptions = DEFAULT_OUTCOME_OPTIONS, hideOutcomeField = false, renderPromptField, renderExtraNodeFields, renderExtraChoiceFields, choiceTypes, onSetChoiceType, title = 'Required', emptyStateText = 'Select a node to edit it.', typeHelperText = DEFAULT_TYPE_HELPER_TEXT, onDeleteSelectedNode, onFocusChoice, }) {
24
- return (_jsx("div", { children: selectedNode ? (_jsxs(_Fragment, { children: [_jsx(RequiredNodeCard, { tree: tree, selectedNode: selectedNode, isPublished: isPublished, title: title, typeHelperText: typeHelperText, onUpdateSelectedNode: onUpdateSelectedNode, onDeleteSelectedNode: onDeleteSelectedNode, renderPromptField: renderPromptField, renderExtraNodeFields: renderExtraNodeFields }), _jsx(ChoiceEditorList, { tree: tree, selectedNode: selectedNode, focusChoiceId: focusChoiceId, isPublished: isPublished, onAddChoice: onAddChoice, onUpdateSelectedNode: onUpdateSelectedNode, onDeleteChoice: onDeleteChoice, onMoveChoice: onMoveChoice, onSetChoiceTarget: onSetChoiceTarget, onSetChoiceOutcome: onSetChoiceOutcome, outcomeOptions: outcomeOptions, hideOutcomeField: hideOutcomeField, renderExtraChoiceFields: renderExtraChoiceFields, choiceTypes: choiceTypes, onSetChoiceType: onSetChoiceType, onFocusChoice: onFocusChoice })] })) : (_jsx("div", { className: joinClasses(EDITOR_MUTED, EDITOR_EMPTY_STATE), children: _jsx("em", { children: emptyStateText }) })) }));
23
+ export default function InspectorPanel({ tree, selectedNode, focusChoiceId = null, isPublished = false, onUpdateSelectedNode, onAddChoice, onDeleteChoice, onMoveChoice, onSetChoiceTarget, onSetChoiceOutcome, outcomeOptions = DEFAULT_OUTCOME_OPTIONS, hideOutcomeField = false, renderPromptField, renderExtraNodeFields, renderExtraChoiceFields, choiceTypes, onSetChoiceType, title = 'Required', emptyStateText = 'Select a node to edit it.', typeHelperText = DEFAULT_TYPE_HELPER_TEXT, onDeleteSelectedNode, onFocusChoice, collapsibleChoices, }) {
24
+ return (_jsx("div", { children: selectedNode ? (_jsxs(_Fragment, { children: [_jsx(RequiredNodeCard, { tree: tree, selectedNode: selectedNode, isPublished: isPublished, title: title, typeHelperText: typeHelperText, onUpdateSelectedNode: onUpdateSelectedNode, onDeleteSelectedNode: onDeleteSelectedNode, renderPromptField: renderPromptField, renderExtraNodeFields: renderExtraNodeFields }), _jsx(ChoiceEditorList, { tree: tree, selectedNode: selectedNode, focusChoiceId: focusChoiceId, isPublished: isPublished, onAddChoice: onAddChoice, onUpdateSelectedNode: onUpdateSelectedNode, onDeleteChoice: onDeleteChoice, onMoveChoice: onMoveChoice, onSetChoiceTarget: onSetChoiceTarget, onSetChoiceOutcome: onSetChoiceOutcome, outcomeOptions: outcomeOptions, hideOutcomeField: hideOutcomeField, renderExtraChoiceFields: renderExtraChoiceFields, choiceTypes: choiceTypes, onSetChoiceType: onSetChoiceType, onFocusChoice: onFocusChoice, collapsibleChoices: collapsibleChoices })] })) : (_jsx("div", { className: joinClasses(EDITOR_MUTED, EDITOR_EMPTY_STATE), children: _jsx("em", { children: emptyStateText }) })) }));
25
25
  }
@@ -1,28 +1,12 @@
1
- import type { ReactNode } from 'react';
2
- import { type EditorChoice, type EditorNode, type EditorTree } from '@signalsafe/tree-spec-editor-core';
3
- import type { ChoiceTypeOption, InspectorChoiceRenderContext } from './types.js';
4
- export default function ChoiceEditorCard({ choice, tree, selectedNode, focusChoiceId, isPublished, canMoveUp, canMoveDown, usedChoiceTypeIds, onUpdateSelectedNode, onDeleteChoice, onMoveChoice, onSetChoiceTarget, onSetChoiceOutcome, onSetChoiceType, choiceTypes, outcomeOptions, hideOutcomeField, renderExtraChoiceFields, onFocusChoice, }: 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;
8
+ collapsible?: boolean;
9
+ expanded?: boolean;
10
+ onToggleExpanded?: () => void;
27
11
  }>): import("react").JSX.Element;
28
12
  //# sourceMappingURL=ChoiceEditorCard.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ChoiceEditorCard.d.ts","sourceRoot":"","sources":["../../../src/panels/inspector/ChoiceEditorCard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAe,SAAS,EAAE,MAAM,OAAO,CAAC;AAEpD,OAAO,EAGH,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,KAAK,UAAU,EAClB,MAAM,mCAAmC,CAAC;AA2B3C,OAAO,KAAK,EAAE,gBAAgB,EAAE,4BAA4B,EAAE,MAAM,YAAY,CAAC;AAEjF,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,GAChB,EAAE,QAAQ,CAAC;IACR,MAAM,EAAE,YAAY,CAAC;IACrB,IAAI,EAAE,UAAU,CAAC;IACjB,YAAY,EAAE,UAAU,CAAC;IACzB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,WAAW,EAAE,OAAO,CAAC;IACrB,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,OAAO,CAAC;IACrB,iBAAiB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC/B,oBAAoB,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC;IAC3D,cAAc,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,YAAY,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,GAAG,MAAM,KAAK,IAAI,CAAC;IACpE,iBAAiB,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IACpE,kBAAkB,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAChE,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACpF,WAAW,CAAC,EAAE,aAAa,CAAC,gBAAgB,CAAC,CAAC;IAC9C,cAAc,EAAE,aAAa,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAChE,gBAAgB,EAAE,OAAO,CAAC;IAC1B,uBAAuB,CAAC,EAAE,CAAC,GAAG,EAAE,4BAA4B,KAAK,SAAS,CAAC;IAC3E,aAAa,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9C,CAAC,+BAoKD"}
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"}
@@ -1,30 +1,34 @@
1
1
  import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { END_NODE_ID, getTransition, } from '@signalsafe/tree-spec-editor-core';
3
3
  import { LIST_SELECTION_CLASS, LIST_SELECTION_TEXT_CLASS } from '../../lib/selectionStyles.js';
4
- import { EDITOR_CHOICE_INSPECTOR_ACTIONS, 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';
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
- export default function ChoiceEditorCard({ choice, tree, selectedNode, focusChoiceId, isPublished, canMoveUp, canMoveDown, usedChoiceTypeIds, onUpdateSelectedNode, onDeleteChoice, onMoveChoice, onSetChoiceTarget, onSetChoiceOutcome, onSetChoiceType, choiceTypes, outcomeOptions, hideOutcomeField, renderExtraChoiceFields, onFocusChoice, }) {
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
+ }
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 knownTypeIds = new Set((choiceTypes ?? []).map((type) => type.id));
14
- const showTypeSelect = Boolean(choiceTypes?.length && onSetChoiceType);
15
- const isCustomType = showTypeSelect && !knownTypeIds.has(choice.id);
16
- return (_jsxs("div", { id: `choice-editor-${selectedNode.id}-${choice.id}`, className: joinClasses(EDITOR_LIST_ITEM, EDITOR_LIST_ITEM_CHOICE_INSPECTOR, isFocused && LIST_SELECTION_CLASS, isFocused && LIST_SELECTION_TEXT_CLASS), onFocusCapture: () => onFocusChoice?.(choice.id), 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
+ const { showTypeSelect, isCustomType } = choiceTypeSelection(choice, choiceTypes, Boolean(onSetChoiceType));
19
+ const bodyId = `choice-editor-body-${selectedNode.id}-${choice.id}`;
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) => {
17
21
  const nextTypeId = event.target.value;
18
22
  if (nextTypeId && nextTypeId !== '__custom__') {
19
23
  const type = choiceTypes.find((item) => item.id === nextTypeId);
20
24
  onSetChoiceType(choice.id, nextTypeId, type?.label);
21
25
  }
22
- }, 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) => {
23
27
  const updatedChoices = (selectedNode.choices ?? []).map((existingChoice) => existingChoice.id === choice.id
24
28
  ? { ...existingChoice, label: event.target.value }
25
29
  : existingChoice);
26
30
  onUpdateSelectedNode({ choices: updatedChoices });
27
- } }), _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
28
32
  ? renderExtraChoiceFields({
29
33
  tree,
30
34
  node: selectedNode,
@@ -34,4 +38,5 @@ export default function ChoiceEditorCard({ choice, tree, selectedNode, focusChoi
34
38
  onUpdateNode: onUpdateSelectedNode,
35
39
  })
36
40
  : null] }));
41
+ return (_jsx("div", { id: `choice-editor-${selectedNode.id}-${choice.id}`, className: joinClasses(EDITOR_LIST_ITEM, EDITOR_LIST_ITEM_CHOICE_INSPECTOR, isFocused && LIST_SELECTION_CLASS, isFocused && LIST_SELECTION_TEXT_CLASS), onFocusCapture: () => onFocusChoice?.(choice.id), children: collapsible ? (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", className: EDITOR_CHOICE_TOGGLE, "aria-expanded": expanded, "aria-controls": bodyId, onClick: onToggleExpanded, children: choice.label || choice.id }), _jsx("div", { id: bodyId, hidden: !expanded, children: body })] })) : (body) }));
37
42
  }
@@ -1,25 +1,6 @@
1
- import type { ReactNode } from 'react';
2
- import type { EditorNode, EditorTree } from '@signalsafe/tree-spec-editor-core';
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, }: 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;
4
+ collapsibleChoices?: boolean;
24
5
  }>): import("react").JSX.Element;
25
6
  //# sourceMappingURL=ChoiceEditorList.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ChoiceEditorList.d.ts","sourceRoot":"","sources":["../../../src/panels/inspector/ChoiceEditorList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAC;AAwBhF,OAAO,KAAK,EAAE,gBAAgB,EAAE,4BAA4B,EAAE,MAAM,YAAY,CAAC;AAEjF,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,GAChB,EAAE,QAAQ,CAAC;IACR,IAAI,EAAE,UAAU,CAAC;IACjB,YAAY,EAAE,UAAU,CAAC;IACzB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,oBAAoB,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC;IAC3D,cAAc,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,YAAY,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,GAAG,MAAM,KAAK,IAAI,CAAC;IACpE,iBAAiB,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IACpE,kBAAkB,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAChE,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACpF,WAAW,CAAC,EAAE,aAAa,CAAC,gBAAgB,CAAC,CAAC;IAC9C,cAAc,EAAE,aAAa,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAChE,gBAAgB,EAAE,OAAO,CAAC;IAC1B,uBAAuB,CAAC,EAAE,CAAC,GAAG,EAAE,4BAA4B,KAAK,SAAS,CAAC;IAC3E,aAAa,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9C,CAAC,+BAsED"}
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"}
@@ -1,12 +1,16 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useState } from 'react';
2
+ import { useEffect, useState } from 'react';
3
3
  import PanelHeaderCollapseCarets from '../../lib/PanelHeaderCollapseCarets.js';
4
4
  import { EDITOR_CARD, EDITOR_CARD_BODY, EDITOR_CARD_HEADER, EDITOR_FLEX_BETWEEN, EDITOR_FLEX_ROW, EDITOR_FLEX_SHRINK_0, EDITOR_HIDDEN, EDITOR_BTN_PANEL_ADD_CHOICE, EDITOR_EMPTY_STATE, EDITOR_LIST, EDITOR_MIN_W_0, EDITOR_MUTED, EDITOR_SCROLL, EDITOR_SPACING_MT_3, EDITOR_SPACING_PX_3, EDITOR_SPACING_PY_3, joinClasses, } from '../../ui/editorClasses.js';
5
5
  import { EditorIconButton } from '../../ui/primitives.js';
6
6
  import ChoiceEditorCard from './ChoiceEditorCard.js';
7
- export default function ChoiceEditorList({ tree, selectedNode, focusChoiceId, isPublished, onAddChoice, onUpdateSelectedNode, onDeleteChoice, onMoveChoice, onSetChoiceTarget, onSetChoiceOutcome, onSetChoiceType, choiceTypes, outcomeOptions, hideOutcomeField, renderExtraChoiceFields, onFocusChoice, }) {
7
+ export default function ChoiceEditorList({ tree, selectedNode, focusChoiceId, isPublished, onAddChoice, onUpdateSelectedNode, onDeleteChoice, onMoveChoice, onSetChoiceTarget, onSetChoiceOutcome, onSetChoiceType, choiceTypes, outcomeOptions, hideOutcomeField, renderExtraChoiceFields, onFocusChoice, collapsibleChoices = false, }) {
8
8
  const choices = selectedNode.choices ?? [];
9
9
  const [choicesExpanded, setChoicesExpanded] = useState(true);
10
10
  const usedChoiceTypeIds = new Set(choices.map((choice) => choice.id));
11
- return (_jsxs("div", { className: joinClasses(EDITOR_CARD, EDITOR_SPACING_MT_3), children: [_jsxs("div", { className: joinClasses(EDITOR_CARD_HEADER, EDITOR_FLEX_BETWEEN), children: [_jsxs("div", { className: joinClasses(EDITOR_FLEX_ROW, EDITOR_MIN_W_0), children: [_jsx("span", { className: "graph-editor-text--semibold", children: "Choices" }), _jsx(PanelHeaderCollapseCarets, { expanded: choicesExpanded, onToggle: () => setChoicesExpanded((v) => !v) })] }), _jsx("div", { className: joinClasses(EDITOR_FLEX_ROW, EDITOR_FLEX_SHRINK_0), children: _jsx(EditorIconButton, { className: joinClasses(EDITOR_FLEX_SHRINK_0, EDITOR_BTN_PANEL_ADD_CHOICE, isPublished ? 'graph-editor-btn--disabled' : 'graph-editor-btn--primary'), "aria-label": "Add choice", title: "Add choice", disabled: isPublished, onClick: onAddChoice, children: "+" }) })] }), _jsx("div", { className: joinClasses(EDITOR_CARD_BODY, 'graph-editor-card__body--flush', !choicesExpanded && EDITOR_HIDDEN), "aria-hidden": !choicesExpanded, children: choices.length === 0 ? (_jsx("div", { className: joinClasses(EDITOR_MUTED, EDITOR_EMPTY_STATE, 'graph-editor-text--sm', EDITOR_SPACING_PY_3, EDITOR_SPACING_PX_3), children: _jsx("em", { children: "No choices" }) })) : (_jsx("div", { className: joinClasses(EDITOR_LIST, EDITOR_SCROLL, 'overflow-auto-max-h-320'), children: choices.map((choice, index) => (_jsx(ChoiceEditorCard, { choice: choice, tree: tree, selectedNode: selectedNode, focusChoiceId: focusChoiceId, isPublished: isPublished, canMoveUp: index > 0, canMoveDown: index < choices.length - 1, usedChoiceTypeIds: usedChoiceTypeIds, onUpdateSelectedNode: onUpdateSelectedNode, onDeleteChoice: onDeleteChoice, onMoveChoice: onMoveChoice, onSetChoiceTarget: onSetChoiceTarget, onSetChoiceOutcome: onSetChoiceOutcome, onSetChoiceType: onSetChoiceType, choiceTypes: choiceTypes, outcomeOptions: outcomeOptions, hideOutcomeField: hideOutcomeField, renderExtraChoiceFields: renderExtraChoiceFields, onFocusChoice: onFocusChoice }, choice.id))) })) })] }));
11
+ const [expandedChoiceId, setExpandedChoiceId] = useState(null);
12
+ useEffect(() => {
13
+ setExpandedChoiceId(null);
14
+ }, [selectedNode.id]);
15
+ return (_jsxs("div", { className: joinClasses(EDITOR_CARD, EDITOR_SPACING_MT_3), children: [_jsxs("div", { className: joinClasses(EDITOR_CARD_HEADER, EDITOR_FLEX_BETWEEN), children: [_jsxs("div", { className: joinClasses(EDITOR_FLEX_ROW, EDITOR_MIN_W_0), children: [_jsx("span", { className: "graph-editor-text--semibold", children: "Choices" }), _jsx(PanelHeaderCollapseCarets, { expanded: choicesExpanded, onToggle: () => setChoicesExpanded((v) => !v) })] }), _jsx("div", { className: joinClasses(EDITOR_FLEX_ROW, EDITOR_FLEX_SHRINK_0), children: _jsx(EditorIconButton, { className: joinClasses(EDITOR_FLEX_SHRINK_0, EDITOR_BTN_PANEL_ADD_CHOICE, isPublished ? 'graph-editor-btn--disabled' : 'graph-editor-btn--primary'), "aria-label": "Add choice", title: "Add choice", disabled: isPublished, onClick: onAddChoice, children: "+" }) })] }), _jsx("div", { className: joinClasses(EDITOR_CARD_BODY, 'graph-editor-card__body--flush', !choicesExpanded && EDITOR_HIDDEN), "aria-hidden": !choicesExpanded, children: choices.length === 0 ? (_jsx("div", { className: joinClasses(EDITOR_MUTED, EDITOR_EMPTY_STATE, 'graph-editor-text--sm', EDITOR_SPACING_PY_3, EDITOR_SPACING_PX_3), children: _jsx("em", { children: "No choices" }) })) : (_jsx("div", { className: joinClasses(EDITOR_LIST, EDITOR_SCROLL, 'overflow-auto-max-h-320'), children: choices.map((choice, index) => (_jsx(ChoiceEditorCard, { choice: choice, tree: tree, selectedNode: selectedNode, focusChoiceId: focusChoiceId, isPublished: isPublished, canMoveUp: index > 0, canMoveDown: index < choices.length - 1, usedChoiceTypeIds: usedChoiceTypeIds, onUpdateSelectedNode: onUpdateSelectedNode, onDeleteChoice: onDeleteChoice, onMoveChoice: onMoveChoice, onSetChoiceTarget: onSetChoiceTarget, onSetChoiceOutcome: onSetChoiceOutcome, onSetChoiceType: onSetChoiceType, choiceTypes: choiceTypes, outcomeOptions: outcomeOptions, hideOutcomeField: hideOutcomeField, renderExtraChoiceFields: renderExtraChoiceFields, onFocusChoice: onFocusChoice, collapsible: collapsibleChoices, expanded: expandedChoiceId === choice.id, onToggleExpanded: () => setExpandedChoiceId((current) => (current === choice.id ? null : choice.id)) }, choice.id))) })) })] }));
12
16
  }
@@ -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.
@@ -61,6 +82,11 @@ export interface InspectorPanelProps {
61
82
  renderExtraNodeFields?: (ctx: InspectorNodeRenderContext) => ReactNode;
62
83
  /** Render extra UI below each choice card (after Next/Outcome). */
63
84
  renderExtraChoiceFields?: (ctx: InspectorChoiceRenderContext) => ReactNode;
85
+ /**
86
+ * Render each choice as a collapsible card with a label toggle; at most one is open
87
+ * at a time and all start collapsed when the selected node changes. Defaults to always expanded.
88
+ */
89
+ collapsibleChoices?: boolean;
64
90
  /** Host-defined choice types (stable ids) for the Type selector on each choice. */
65
91
  choiceTypes?: ReadonlyArray<ChoiceTypeOption>;
66
92
  onSetChoiceType?: (choiceId: string, typeId: string, defaultLabel?: string) => void;
@@ -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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"}
@@ -26,6 +26,7 @@ export declare const EDITOR_LIST_ITEM_WITH_DELETE = "graph-editor-list__item--wi
26
26
  export declare const EDITOR_LIST_ITEM_CHOICE_INSPECTOR = "graph-editor-list__item--choice-inspector";
27
27
  export declare const EDITOR_CHOICE_INSPECTOR_HEADER = "graph-editor-choice-inspector-header";
28
28
  export declare const EDITOR_CHOICE_INSPECTOR_ACTIONS = "graph-editor-choice-inspector-actions";
29
+ export declare const EDITOR_CHOICE_TOGGLE = "graph-editor-choice-toggle";
29
30
  export declare const EDITOR_BADGE = "graph-editor-badge";
30
31
  export declare const EDITOR_MODAL = "graph-editor-modal";
31
32
  export declare const EDITOR_MODAL_DIALOG = "graph-editor-modal__dialog";
@@ -1 +1 @@
1
- {"version":3,"file":"editorClasses.d.ts","sourceRoot":"","sources":["../../src/ui/editorClasses.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"editorClasses.d.ts","sourceRoot":"","sources":["../../src/ui/editorClasses.ts"],"names":[],"mappings":"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"}
@@ -26,6 +26,7 @@ export const EDITOR_LIST_ITEM_WITH_DELETE = 'graph-editor-list__item--with-delet
26
26
  export const EDITOR_LIST_ITEM_CHOICE_INSPECTOR = 'graph-editor-list__item--choice-inspector';
27
27
  export const EDITOR_CHOICE_INSPECTOR_HEADER = 'graph-editor-choice-inspector-header';
28
28
  export const EDITOR_CHOICE_INSPECTOR_ACTIONS = 'graph-editor-choice-inspector-actions';
29
+ export const EDITOR_CHOICE_TOGGLE = 'graph-editor-choice-toggle';
29
30
  export const EDITOR_BADGE = 'graph-editor-badge';
30
31
  export const EDITOR_MODAL = 'graph-editor-modal';
31
32
  export const EDITOR_MODAL_DIALOG = 'graph-editor-modal__dialog';
package/docs/README.md ADDED
@@ -0,0 +1,5 @@
1
+ # Documentation
2
+
3
+ - [Current release reference](current-release-candidate.md)
4
+ - [Package README](../README.md)
5
+ - [Release preparation](../RELEASING.md)
@@ -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](../../tree-spec-editor-react/docs/UI_KIT_AGNOSTIC_CANVAS.md).
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`](../../tree-spec-editor-react/docs/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.3.7",
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.3.4",
69
- "@signalsafe/tree-spec-editor-core": "^0.2.1",
70
- "@signalsafe/tree-spec-editor-react": "^0.3.1"
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": "^3.2.4",
87
- "vitest": "^3.2.4"
89
+ "@vitest/coverage-v8": "^5.0.5",
90
+ "vitest": "^5.0.5",
91
+ "vite": "^8.3.4"
88
92
  }
89
93
  }