yarramate 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/catalogues/core-enrichment.yaml +225 -2
- package/dist/adapters/visual/session-server.js +16 -1
- package/dist/adapters/visual/view-identity.d.ts +1 -1
- package/dist/adapters/visual/view-identity.js +61 -3
- package/dist/adapters/visual/wire.d.ts +30 -0
- package/dist/adapters/visual/workspace-model.d.ts +23 -3
- package/dist/adapters/visual/workspace-model.js +52 -2
- package/dist/ask-command.js +29 -13
- package/dist/cli-support.d.ts +1 -1
- package/dist/cli-support.js +1 -1
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +26 -5
- package/dist/concept-drafting.d.ts +13 -2
- package/dist/concept-drafting.js +15 -3
- package/dist/design-command.js +16 -1
- package/dist/evidence.js +25 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/interrogate-command.d.ts +20 -1
- package/dist/interrogate-command.js +23 -4
- package/dist/interrogation-entry.d.ts +1 -1
- package/dist/layout-direction.d.ts +14 -0
- package/dist/layout-direction.js +5 -0
- package/dist/projection.d.ts +22 -6
- package/dist/projection.js +23 -2
- package/dist/relationship-drafting.d.ts +21 -2
- package/dist/relationship-drafting.js +33 -3
- package/dist/subject-references.js +5 -0
- package/dist/visual-app/assets/index-C3i9SxTe.js +394 -0
- package/dist/visual-app/assets/index-Rkq6smL2.css +1 -0
- package/dist/visual-app/index.html +2 -2
- package/dist/visual-app-lib/editor.js +28464 -26953
- package/dist/visual-app-lib/styles.css +1 -1
- package/dist/visual-app-lib/types/adapters/visual/view-identity.d.ts +1 -1
- package/dist/visual-app-lib/types/adapters/visual/wire.d.ts +30 -0
- package/dist/visual-app-lib/types/adapters/visual/workspace-model.d.ts +23 -3
- package/dist/visual-app-lib/types/concept-drafting.d.ts +13 -2
- package/dist/visual-app-lib/types/interrogate-command.d.ts +190 -0
- package/dist/visual-app-lib/types/layout-direction.d.ts +14 -0
- package/dist/visual-app-lib/types/projection.d.ts +22 -6
- package/dist/visual-app-lib/types/relationship-drafting.d.ts +21 -2
- package/dist/visual-app-lib/types/subject-identity.d.ts +34 -0
- package/dist/visual-app-lib/types/visual-app/App.d.ts +27 -2
- package/dist/visual-app-lib/types/visual-app/badges.d.ts +1 -0
- package/dist/visual-app-lib/types/visual-app/connection-panel.d.ts +9 -1
- package/dist/visual-app-lib/types/visual-app/context-menu-model.d.ts +15 -6
- package/dist/visual-app-lib/types/visual-app/graph-canvas.d.ts +77 -6
- package/dist/visual-app-lib/types/visual-app/kind-palette.d.ts +37 -0
- package/dist/visual-app-lib/types/visual-app/mount.d.ts +73 -2
- package/dist/visual-app-lib/types/visual-app/open-questions.d.ts +15 -0
- package/dist/visual-app-lib/types/visual-app/query-fields.d.ts +3 -2
- package/dist/visual-app-lib/types/visual-app/query-panel.d.ts +8 -1
- package/dist/visual-app-lib/types/visual-app/save-view.d.ts +11 -5
- package/dist/visual-app-lib/types/visual-app/shipped-catalogue.d.ts +10 -0
- package/dist/visual-app-lib/types/visual-app/state.d.ts +15 -4
- package/dist/visual-app-lib/types/visual-app/subject-draft-panel.d.ts +13 -1
- package/dist/visual-app-lib/types/visual-app/subject-filter.d.ts +35 -0
- package/dist/visual-app-lib/types/visual-app/subject-form.d.ts +8 -0
- package/dist/visual-app-lib/types/visual-app/view-tree-model.d.ts +42 -9
- package/dist/visual-app-lib/types/visual-app/view-tree.d.ts +11 -2
- package/dist/visual-app-lib/types/visual-app/workspace-state.d.ts +81 -11
- package/docs/CONSUMING-YARRAMATE.md +40 -0
- package/package.json +1 -1
- package/schema/yarramate-design-step.schema.json +13 -0
- package/schema/yarramate-interrogation-report.schema.json +13 -0
- package/schema/yarramate-projection.schema.json +9 -0
- package/schema/yarramate-question-catalogue.schema.json +13 -0
- package/skills/yarramate-architecture/SKILL.md +5 -0
- package/dist/visual-app/assets/index-CcmfL3oY.js +0 -394
- package/dist/visual-app/assets/index-DLutIWES.css +0 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { type DecorationMap } from "./graph-canvas.js";
|
|
1
2
|
import type { EditorHost } from "./editor-host.js";
|
|
2
|
-
import { type RightSectionId } from "./workspace-state.js";
|
|
3
|
+
import { type EditorPointer, type RightSectionId } from "./workspace-state.js";
|
|
3
4
|
/**
|
|
4
5
|
* The editor.
|
|
5
6
|
*
|
|
@@ -8,8 +9,32 @@ import { type RightSectionId } from "./workspace-state.js";
|
|
|
8
9
|
* embedder's own store with no server at all. `sections` is what the host
|
|
9
10
|
* wants shown - a product with no agent behind it leaves `chat` out, and the
|
|
10
11
|
* section and the session button go with it.
|
|
12
|
+
*
|
|
13
|
+
* `readOnly` is one flag, threaded once (#298, ADR 0117): a viewer keeps
|
|
14
|
+
* everything that reads - the canvas, the tree, the query fields, the facts,
|
|
15
|
+
* the questions - and every affordance that stages or commits is absent
|
|
16
|
+
* rather than disabled. A UI posture only: whatever this shell draws, the
|
|
17
|
+
* host still answers for its own store.
|
|
11
18
|
*/
|
|
12
|
-
export declare const App: ({ host, sections, }: {
|
|
19
|
+
export declare const App: ({ host, sections, readOnly, decorations: initialDecorations, onReady, }: {
|
|
13
20
|
readonly host: EditorHost;
|
|
14
21
|
readonly sections?: readonly RightSectionId[];
|
|
22
|
+
readonly readOnly?: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* The host's per-subject marks at mount time (#314, ADR 0119) - the
|
|
25
|
+
* initial value only, the way React means an initial value: later
|
|
26
|
+
* hand-overs travel through the pointer's `setDecorations`, each one
|
|
27
|
+
* replacing the map wholesale. Client state like selection, so it rides a
|
|
28
|
+
* prop rather than the `EditorHost` seam.
|
|
29
|
+
*/
|
|
30
|
+
readonly decorations?: DecorationMap;
|
|
31
|
+
/**
|
|
32
|
+
* How the mount layer's handle reaches this shell's reducer (#297,
|
|
33
|
+
* ADR 0118). Called once, after the first render, with the pointer the
|
|
34
|
+
* handle delegates to - which is what makes the handle's pre-ready
|
|
35
|
+
* false-return window real. Selection and dialog state are client state,
|
|
36
|
+
* so this rides a prop rather than the `EditorHost` seam: the protocol
|
|
37
|
+
* carries documents, not gestures.
|
|
38
|
+
*/
|
|
39
|
+
readonly onReady?: (pointer: EditorPointer) => void;
|
|
15
40
|
}) => import("react").JSX.Element;
|
|
@@ -4,4 +4,5 @@ export declare const LIFECYCLE_BADGE_URI: Record<LifecycleStatus, string>;
|
|
|
4
4
|
export declare const EVIDENCE_BADGE_URI: string;
|
|
5
5
|
export declare function ownerColorOf(owner: string | null): string | null;
|
|
6
6
|
export declare function ownerBadgeUri(owner: string, initials: string): string;
|
|
7
|
+
export declare function openQuestionsBadgeUri(count: number): string;
|
|
7
8
|
export declare function ownerInitialsOf(owner: string | null): string | null;
|
|
@@ -15,9 +15,17 @@ import type { ConnectionDraft } from './workspace-state.js';
|
|
|
15
15
|
* means an endpoint outside the ArchiMate vocabulary rather than a dead end,
|
|
16
16
|
* and the panel says which.
|
|
17
17
|
*/
|
|
18
|
-
export declare const ConnectionPanel: ({ draft, graph, onStage, onCancel, }: {
|
|
18
|
+
export declare const ConnectionPanel: ({ draft, graph, reservedIds, onStage, onCancel, }: {
|
|
19
19
|
readonly draft: ConnectionDraft;
|
|
20
20
|
readonly graph: CanvasGraph;
|
|
21
|
+
/**
|
|
22
|
+
* Ids the pending changeset already claims. The graph only knows what has
|
|
23
|
+
* landed, so without these a second relationship between the same pair
|
|
24
|
+
* proposed the identical id and replace-by-target staging swallowed it
|
|
25
|
+
* silently (#306). Required rather than defaulted: a caller has to say
|
|
26
|
+
* what is staged, even when the answer is nothing.
|
|
27
|
+
*/
|
|
28
|
+
readonly reservedIds: readonly string[];
|
|
21
29
|
readonly onStage: (operation: YarramateOperation) => void;
|
|
22
30
|
readonly onCancel: () => void;
|
|
23
31
|
}) => React.ReactElement;
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
*/
|
|
25
25
|
import type { CanvasGraph } from "../graph-projection.js";
|
|
26
26
|
import type { VisualKindOption } from "../adapters/visual/protocol-contract.js";
|
|
27
|
+
import type { ActiveViewMembership } from "./state.js";
|
|
27
28
|
/** The id of the "All subjects" row, which is the absence of a view. */
|
|
28
29
|
export declare const ALL_SUBJECTS_VIEW = "";
|
|
29
30
|
export type ContextMenuTarget = {
|
|
@@ -144,14 +145,22 @@ export interface ContextMenuContext {
|
|
|
144
145
|
/** Whether anything at all is narrowing the canvas right now. */
|
|
145
146
|
readonly filtered: boolean;
|
|
146
147
|
/**
|
|
147
|
-
*
|
|
148
|
+
* How the active view can be told what it holds, or `null` when no view is
|
|
149
|
+
* active and there is nothing to tell.
|
|
148
150
|
*
|
|
149
|
-
*
|
|
150
|
-
*
|
|
151
|
-
*
|
|
152
|
-
*
|
|
151
|
+
* A view that enumerates its subjects is told by its list; one that
|
|
152
|
+
* describes them with facets is told by `exclude` (#267, ADR 0122). A
|
|
153
|
+
* faceted view used to be `null` here, on the reasoning that an item which
|
|
154
|
+
* could only ever do nothing is worse than no item (#255) - true of adding a
|
|
155
|
+
* subject to a rule, and never true of taking one out of it.
|
|
153
156
|
*/
|
|
154
|
-
readonly membership:
|
|
157
|
+
readonly membership: ActiveViewMembership | null;
|
|
158
|
+
/**
|
|
159
|
+
* A viewer, not an author (#298, ADR 0117). A read-only menu keeps the items
|
|
160
|
+
* that read or navigate and drops every item whose intent stages a change -
|
|
161
|
+
* absent, never disabled.
|
|
162
|
+
*/
|
|
163
|
+
readonly readOnly?: boolean;
|
|
155
164
|
}
|
|
156
165
|
/**
|
|
157
166
|
* The menu for a target, already ordered: view groups first, model groups
|
|
@@ -1,22 +1,65 @@
|
|
|
1
1
|
import type React from 'react';
|
|
2
2
|
import cytoscape from 'cytoscape';
|
|
3
|
-
import type { Core, NodeCollection } from 'cytoscape';
|
|
4
|
-
import type { CanvasGraph, CanvasEdge } from '../graph-projection.js';
|
|
3
|
+
import type { Core, ElementDefinition, NodeCollection } from 'cytoscape';
|
|
4
|
+
import type { CanvasGraph, CanvasNode, CanvasEdge } from '../graph-projection.js';
|
|
5
5
|
import { type NestingKind } from '../nesting.js';
|
|
6
|
+
import { type LayoutDirection } from '../layout-direction.js';
|
|
6
7
|
import type { VisualLayoutPositions, VisualLayoutSavePayload } from '../adapters/visual/protocol-contract.js';
|
|
7
8
|
import { LAYER_COLORS } from '../notation/archimate.js';
|
|
8
9
|
export { LAYER_COLORS };
|
|
9
|
-
export declare function
|
|
10
|
-
export declare function
|
|
10
|
+
export declare function steppedZoom(current: number, direction: 1 | -1): number;
|
|
11
|
+
export declare function buildLayoutConfig(direction: LayoutDirection): cytoscape.LayoutOptions;
|
|
12
|
+
/**
|
|
13
|
+
* The closed mark vocabulary a host may hand the mounted viewer (#314,
|
|
14
|
+
* ADR 0119). Three marks, because three is what comparison against another
|
|
15
|
+
* model needs and a fourth waits for the demand that names it. What a mark
|
|
16
|
+
* MEANS - added relative to what, changed since when - lives entirely on the
|
|
17
|
+
* host's side of the seam: this canvas renders marks, it never diffs.
|
|
18
|
+
*/
|
|
19
|
+
export type DecorationMark = 'added' | 'removed' | 'changed';
|
|
20
|
+
/**
|
|
21
|
+
* Subject id (concepts and relationships alike) to mark. The whole map is the
|
|
22
|
+
* unit of exchange: each hand-over REPLACES the previous marks wholesale,
|
|
23
|
+
* never merges into them, and an id the current model does not name marks
|
|
24
|
+
* nothing, silently - the host may be describing subjects this model has not
|
|
25
|
+
* gained (or has already lost).
|
|
26
|
+
*/
|
|
27
|
+
export type DecorationMap = Readonly<Record<string, DecorationMark>>;
|
|
28
|
+
/**
|
|
29
|
+
* Marks every subject the host's decoration map names, the exact class
|
|
30
|
+
* mechanism faults use: previous `deco-*` classes come off every element
|
|
31
|
+
* first (replacement is wholesale, the map is the unit), then each id that
|
|
32
|
+
* names a drawn node or edge gains its mark's class. Unknown ids are
|
|
33
|
+
* silently inert. The `faulted` class is never touched here, and the
|
|
34
|
+
* stylesheet orders the fault rule after the decoration rules, so a subject
|
|
35
|
+
* both decorated and refused reads as refused.
|
|
36
|
+
*/
|
|
37
|
+
export declare function applyDecorations(cy: Core, decorations: DecorationMap): void;
|
|
38
|
+
export declare function buildStylesheet(showLifecycle: boolean, showEvidence: boolean, showOwnership: boolean, showNudges: boolean): cytoscape.StylesheetJsonBlock[];
|
|
11
39
|
export declare function resolveNestingParents(edges: readonly CanvasEdge[], nesting: readonly NestingKind[], kindOf: (id: string) => string): {
|
|
12
40
|
readonly parentOf: ReadonlyMap<string, string>;
|
|
13
41
|
readonly consumedEdgeIds: ReadonlySet<string>;
|
|
14
42
|
};
|
|
43
|
+
export declare function graphToElements(graph: CanvasGraph, nesting: readonly NestingKind[], openQuestionCounts: ReadonlyMap<string, number>): ElementDefinition[];
|
|
44
|
+
export declare function filteredSubjectCount(nodes: readonly Pick<CanvasNode, 'id' | 'name' | 'kindLabel'>[], matchedIds: readonly string[] | null, quickFilterText: string): number;
|
|
15
45
|
export declare function applyFilter(cy: Core, matchedIds: readonly string[] | null, quickFilterText: string): void;
|
|
16
|
-
export declare function relayoutVisible(cy: Core): void;
|
|
46
|
+
export declare function relayoutVisible(cy: Core, direction: LayoutDirection): void;
|
|
47
|
+
export declare function fitVisible(cy: Core): boolean;
|
|
17
48
|
export declare const DRAG_SAVE_DEBOUNCE_MS = 500;
|
|
18
49
|
export declare function buildPositionMap(nodes: NodeCollection): VisualLayoutPositions;
|
|
19
50
|
export declare function applySavedPositions(cy: Core, saved: VisualLayoutPositions | undefined): void;
|
|
51
|
+
export declare function effectiveSavedPositions(saved: VisualLayoutPositions | undefined, viewId: string, discardedViews: ReadonlySet<string>): VisualLayoutPositions | undefined;
|
|
52
|
+
export declare function savedLayoutInForce(saved: VisualLayoutPositions | undefined, graphNodeIds: readonly string[], matchedIds: readonly string[] | null): boolean;
|
|
53
|
+
export declare function modelPositionOf(rendered: {
|
|
54
|
+
readonly x: number;
|
|
55
|
+
readonly y: number;
|
|
56
|
+
}, pan: {
|
|
57
|
+
readonly x: number;
|
|
58
|
+
readonly y: number;
|
|
59
|
+
}, zoom: number): {
|
|
60
|
+
readonly x: number;
|
|
61
|
+
readonly y: number;
|
|
62
|
+
};
|
|
20
63
|
export interface DragSaveHandle {
|
|
21
64
|
/** Cancels a queued save without unbinding the drag listener. */
|
|
22
65
|
readonly cancelPending: () => void;
|
|
@@ -46,13 +89,41 @@ interface GraphCanvasProps {
|
|
|
46
89
|
readonly nesting: readonly NestingKind[];
|
|
47
90
|
/** Subjects a diagnostic named, marked so a failure is visible where it is. */
|
|
48
91
|
readonly faultedIds: ReadonlySet<string>;
|
|
92
|
+
/**
|
|
93
|
+
* The host's per-subject marks (#314, ADR 0119), rendered as `deco-*`
|
|
94
|
+
* classes the way faults are rendered. The map replaces wholesale on every
|
|
95
|
+
* change; an empty map draws nothing, an unknown id marks nothing, and a
|
|
96
|
+
* subject that is also faulted reads as faulted.
|
|
97
|
+
*/
|
|
98
|
+
readonly decorations: DecorationMap;
|
|
49
99
|
readonly showLifecycle: boolean;
|
|
50
100
|
readonly showEvidence: boolean;
|
|
51
101
|
readonly showOwnership: boolean;
|
|
102
|
+
readonly showNudges: boolean;
|
|
103
|
+
/** Open-question count per subject id, from the model's interrogation
|
|
104
|
+
* overlay; an empty map (host shipped no overlay) draws no chips. */
|
|
105
|
+
readonly openQuestionCounts: ReadonlyMap<string, number>;
|
|
52
106
|
readonly activeViewId: string;
|
|
107
|
+
/**
|
|
108
|
+
* Which way the active view runs its layers (#274, ADR 0121), from its
|
|
109
|
+
* `presentation.direction`. A view that declares none is handed
|
|
110
|
+
* `DEFAULT_DIRECTION`, so the canvas never has to decide what silence means.
|
|
111
|
+
*/
|
|
112
|
+
readonly direction: LayoutDirection;
|
|
53
113
|
/** Saved layout for the active view, or undefined when it has none yet. */
|
|
54
114
|
readonly savedPositions: VisualLayoutPositions | undefined;
|
|
55
115
|
readonly onSaveLayout: (payload: VisualLayoutSavePayload) => void;
|
|
116
|
+
/**
|
|
117
|
+
* A kind dropped from the palette (#295): the kind's label and the model
|
|
118
|
+
* position under the pointer. Optional because only a shell with a palette
|
|
119
|
+
* has anything to drop; a host without one never sees a drop at all - the
|
|
120
|
+
* `dragover` acceptance is gated on the callback too, so a stray drag is
|
|
121
|
+
* left to the browser's default refusal.
|
|
122
|
+
*/
|
|
123
|
+
readonly onKindDrop?: (kindLabel: string, position: {
|
|
124
|
+
readonly x: number;
|
|
125
|
+
readonly y: number;
|
|
126
|
+
}) => void;
|
|
56
127
|
/**
|
|
57
128
|
* A way to take a picture of what is drawn, handed up once the instance
|
|
58
129
|
* exists and withdrawn when it goes. The shell holds it so a menu item can
|
|
@@ -70,4 +141,4 @@ interface GraphCanvasProps {
|
|
|
70
141
|
* - Wires node/edge tap handlers to call onSelect(id, type)
|
|
71
142
|
* - Reflects selectedId prop as a visual highlight class on the matching element
|
|
72
143
|
*/
|
|
73
|
-
export declare function GraphCanvas({ graph, selectedId, onSelect, onContextMenu, matchedIds, quickFilterText, nesting, faultedIds, activeViewId, savedPositions, onSaveLayout, onCanvasReady, showLifecycle, showEvidence, showOwnership, }: GraphCanvasProps): React.ReactElement;
|
|
144
|
+
export declare function GraphCanvas({ graph, selectedId, onSelect, onContextMenu, matchedIds, quickFilterText, nesting, faultedIds, decorations, activeViewId, direction, savedPositions, onSaveLayout, onKindDrop, onCanvasReady, showLifecycle, showEvidence, showOwnership, showNudges, openQuestionCounts, }: GraphCanvasProps): React.ReactElement;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
import type { VisualKindOption } from '../adapters/visual/protocol-contract.js';
|
|
3
|
+
/**
|
|
4
|
+
* The kind palette (#295): the profile's concept kinds, listed to be picked up.
|
|
5
|
+
*
|
|
6
|
+
* The kinds are the same vocabulary the Add-subject dialog's Kind select
|
|
7
|
+
* compiles from - `vocabulary.conceptKinds`, sent with every model frame - so
|
|
8
|
+
* nothing here decides what a workspace may contain. A row is a thing to drag
|
|
9
|
+
* onto the canvas, and a thing to click for the same result without a pointer
|
|
10
|
+
* gesture: either way the details dialog opens with the kind already chosen,
|
|
11
|
+
* and the palette itself holds nothing afterwards (ADR 0116).
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* The drag payload's type. Custom rather than `text/plain`, so the canvas
|
|
15
|
+
* accepts exactly what the palette offers and a stray text drop onto the
|
|
16
|
+
* diagram stays inert. The payload is the kind's LABEL, not its full identity:
|
|
17
|
+
* a document names a kind the short way, and `apply` refuses the identity as
|
|
18
|
+
* an unknown kind (`YM401`) - the same rule the dialog's own select follows.
|
|
19
|
+
*/
|
|
20
|
+
export declare const KIND_MIME = "application/x-yarramate-kind";
|
|
21
|
+
export interface PaletteGroup {
|
|
22
|
+
readonly layer: string;
|
|
23
|
+
readonly kinds: readonly VisualKindOption[];
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Rows grouped by layer, in the profile's own layer order - the same bands the
|
|
27
|
+
* model tree groups subjects by, so the palette and the rail read as one
|
|
28
|
+
* organisation. Within a group the wire's order is kept: the vocabulary
|
|
29
|
+
* arrives sorted and re-sorting it here would be a second opinion.
|
|
30
|
+
*/
|
|
31
|
+
export declare const paletteGroups: (kinds: readonly VisualKindOption[]) => readonly PaletteGroup[];
|
|
32
|
+
export declare const KindPalette: ({ kinds, onPick, }: {
|
|
33
|
+
readonly kinds: readonly VisualKindOption[];
|
|
34
|
+
/** A kind chosen without the drag - a click, a keyboard - which opens the
|
|
35
|
+
* same dialog a drop does. */
|
|
36
|
+
readonly onPick: (kindLabel: string) => void;
|
|
37
|
+
}) => React.ReactElement;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type LocalHostOptions } from './local-host.js';
|
|
2
|
+
import type { DecorationMap } from './graph-canvas.js';
|
|
2
3
|
import type { EditorHost } from './editor-host.js';
|
|
3
4
|
import { type RightSectionId } from './workspace-state.js';
|
|
4
5
|
import './styles.css';
|
|
@@ -19,6 +20,8 @@ import './styles.css';
|
|
|
19
20
|
* workspace, // a resolved manifest
|
|
20
21
|
* sections: ['properties', 'changes'],
|
|
21
22
|
* })
|
|
23
|
+
* editor.select('app.checkout') // as a canvas tap would (#297)
|
|
24
|
+
* editor.openDraft({ kind: 'goal' }) // as a palette pick would
|
|
22
25
|
* // later
|
|
23
26
|
* editor.unmount()
|
|
24
27
|
* ```
|
|
@@ -26,6 +29,9 @@ import './styles.css';
|
|
|
26
29
|
* `sections` is what the host wants shown. Chat is the one a product usually
|
|
27
30
|
* leaves out: with no agent behind it there is nobody to talk to and nothing to
|
|
28
31
|
* hand control back to, so the section and the session button go together.
|
|
32
|
+
*
|
|
33
|
+
* `readOnly: true` mounts a viewer (#298): the same canvas, tree, questions
|
|
34
|
+
* and properties, with every staging and committing affordance absent.
|
|
29
35
|
*/
|
|
30
36
|
export interface MountOptions extends LocalHostOptions {
|
|
31
37
|
/**
|
|
@@ -35,10 +41,72 @@ export interface MountOptions extends LocalHostOptions {
|
|
|
35
41
|
* name the two it wants.
|
|
36
42
|
*/
|
|
37
43
|
readonly sections?: readonly RightSectionId[];
|
|
44
|
+
/**
|
|
45
|
+
* A viewer, not an author (#298, ADR 0117). Every affordance that stages or
|
|
46
|
+
* commits a change is absent - not disabled - so a frozen snapshot renders
|
|
47
|
+
* with the authoring surface's visual language and none of its pen. A UI
|
|
48
|
+
* posture only: a host whose store also refuses writes has two independent
|
|
49
|
+
* defenses, and this option is not the one that guards the data.
|
|
50
|
+
*/
|
|
51
|
+
readonly readOnly?: boolean;
|
|
52
|
+
/**
|
|
53
|
+
* The host's per-subject marks at mount time (#314, ADR 0119): subject id -
|
|
54
|
+
* concept or relationship - to `'added' | 'removed' | 'changed'`, rendered
|
|
55
|
+
* as class-based visual treatments the way faults are. This is the seam
|
|
56
|
+
* that lets a host with its own comparison model use the one viewer for
|
|
57
|
+
* decorated comparison: the SEMANTICS stay host-side - the viewer never
|
|
58
|
+
* diffs, it renders the marks it is handed. An id the model does not name
|
|
59
|
+
* is silently inert. This option is the initial map; a live comparison
|
|
60
|
+
* replaces it wholesale through the handle's `setDecorations`.
|
|
61
|
+
*/
|
|
62
|
+
readonly decorations?: DecorationMap;
|
|
38
63
|
}
|
|
64
|
+
/**
|
|
65
|
+
* The handle a mount returns (#297, ADR 0118): the disposal it always had,
|
|
66
|
+
* and three ways for the host to point at the canvas. Each method is the
|
|
67
|
+
* programmatic twin of a gesture the surface already has - never a second
|
|
68
|
+
* write path: nothing here commits, and anything the opened affordances stage
|
|
69
|
+
* still goes through the changeset like every reviewer gesture.
|
|
70
|
+
*
|
|
71
|
+
* Every method answers with whether it acted. False means nothing moved: the
|
|
72
|
+
* id named nothing in the current model, the model has not arrived yet - the
|
|
73
|
+
* editor renders before its host's first frame lands - or the mount is a
|
|
74
|
+
* viewer (`readOnly`, #298) and the gesture would have reached for the pen.
|
|
75
|
+
*/
|
|
39
76
|
export interface MountedEditor {
|
|
40
77
|
/** Releases the host and takes the editor out of the element. */
|
|
41
78
|
readonly unmount: () => void;
|
|
79
|
+
/**
|
|
80
|
+
* Selects the subject - concept or relationship - on the canvas and in the
|
|
81
|
+
* inspector, exactly as a tap on it would, which also scopes the Open
|
|
82
|
+
* questions section to it.
|
|
83
|
+
*/
|
|
84
|
+
readonly select: (subjectId: string) => boolean;
|
|
85
|
+
/**
|
|
86
|
+
* Opens the Add-subject dialog, with the kind preselected when one is
|
|
87
|
+
* given - the same seed a palette pick rides (#295). Without a kind, the
|
|
88
|
+
* plain no-default form.
|
|
89
|
+
*/
|
|
90
|
+
readonly openDraft: (options?: {
|
|
91
|
+
readonly kind?: string;
|
|
92
|
+
}) => boolean;
|
|
93
|
+
/**
|
|
94
|
+
* Arms the connection tool from the named subject, exactly as the
|
|
95
|
+
* inspector's Connect does: the next selection becomes the target and the
|
|
96
|
+
* kinds on offer are derived from the two endpoints.
|
|
97
|
+
*/
|
|
98
|
+
readonly startConnection: (fromSubjectId: string) => boolean;
|
|
99
|
+
/**
|
|
100
|
+
* Replaces the per-subject marks wholesale (#314, ADR 0119) - never a
|
|
101
|
+
* merge: the map handed here is the map drawn, and `{}` clears every mark.
|
|
102
|
+
* The one handle method that is not a gesture's twin, because no gesture
|
|
103
|
+
* decorates: it is the live half of the `decorations` mount option, for a
|
|
104
|
+
* comparison that moves under an open viewer. Decorating is reading, so it
|
|
105
|
+
* works under `readOnly`, and unknown ids are silently inert - false is
|
|
106
|
+
* only the shared not-there window: before the shell's first render, or
|
|
107
|
+
* after unmount.
|
|
108
|
+
*/
|
|
109
|
+
readonly setDecorations: (decorations: DecorationMap) => boolean;
|
|
42
110
|
}
|
|
43
111
|
export declare const mountEditor: (element: Element, options: MountOptions) => MountedEditor;
|
|
44
112
|
/**
|
|
@@ -47,10 +115,13 @@ export declare const mountEditor: (element: Element, options: MountOptions) => M
|
|
|
47
115
|
* Exported for the case `mountEditor` does not cover: a product that already
|
|
48
116
|
* speaks the visual protocol - to its own server, over its own transport - and
|
|
49
117
|
* wants the editor in front of it. The protocol is the contract (ADR 0081), so
|
|
50
|
-
* anything that answers it is a host.
|
|
118
|
+
* anything that answers it is a host. `readOnly` composes: a custom host gets
|
|
119
|
+
* the same viewer posture `mountEditor` offers, and stays free to refuse
|
|
120
|
+
* writes on its own side of the seam as well.
|
|
51
121
|
*/
|
|
52
|
-
export declare const mountEditorWith: (element: Element, host: EditorHost, sections?: readonly RightSectionId[]) => MountedEditor;
|
|
122
|
+
export declare const mountEditorWith: (element: Element, host: EditorHost, sections?: readonly RightSectionId[], readOnly?: boolean, decorations?: DecorationMap) => MountedEditor;
|
|
53
123
|
export type { EditorHost, EditorHostEvents } from './editor-host.js';
|
|
124
|
+
export type { DecorationMap, DecorationMark } from './graph-canvas.js';
|
|
54
125
|
export type { LocalHostOptions } from './local-host.js';
|
|
55
126
|
export { createLocalHost } from './local-host.js';
|
|
56
127
|
export { RIGHT_SECTIONS, type RightSectionId } from './workspace-state.js';
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { VisualInterrogationOverlay } from '../adapters/visual/wire.js';
|
|
2
|
+
/**
|
|
3
|
+
* The interview, where the drawing happens (#292).
|
|
4
|
+
*
|
|
5
|
+
* One home for both scopes: a selected element shows the questions that name
|
|
6
|
+
* it — the `design --subject` reading of the model — and no selection shows
|
|
7
|
+
* the workspace-scoped questions, which name no subject and would otherwise
|
|
8
|
+
* be the model's biggest holes rendered nowhere. Read-only by design: the
|
|
9
|
+
* answer path stays `apply` (through the editor's own forms or an agent),
|
|
10
|
+
* never a text box here that would bypass the compile gate.
|
|
11
|
+
*/
|
|
12
|
+
export declare function OpenQuestions({ overlay, selectedId, }: {
|
|
13
|
+
readonly overlay: VisualInterrogationOverlay;
|
|
14
|
+
readonly selectedId: string | null;
|
|
15
|
+
}): import("react").JSX.Element;
|
|
@@ -39,7 +39,7 @@ export declare const queryToFields: (query: ProjectionQuery | null) => QueryFiel
|
|
|
39
39
|
* single-choice field is never sent, since `minItems: 1` on the schema's
|
|
40
40
|
* array properties makes `[]` itself invalid. */
|
|
41
41
|
export declare const composeQuery: (fields: QueryFields) => ProjectionQuery;
|
|
42
|
-
export type PresentationFlag = 'showLifecycle' | 'showEvidence' | 'showOwnership';
|
|
42
|
+
export type PresentationFlag = 'showLifecycle' | 'showEvidence' | 'showOwnership' | 'showNudges';
|
|
43
43
|
/** The checkbox's onChange handler, extracted so it is directly testable in
|
|
44
44
|
* isolation from rendering: it calls `onTogglePresentation` and nothing
|
|
45
45
|
* else — never `composeQuery`/`scheduleApply`. These three flags are
|
|
@@ -61,9 +61,10 @@ export declare function QueryFacets({ fields, onChange, }: {
|
|
|
61
61
|
* view document's `presentation` and never composed into a `ProjectionQuery`,
|
|
62
62
|
* which is why they take their own handler rather than sharing `onChange`.
|
|
63
63
|
*/
|
|
64
|
-
export declare function PresentationToggles({ showLifecycle, showEvidence, showOwnership, onTogglePresentation, }: {
|
|
64
|
+
export declare function PresentationToggles({ showLifecycle, showEvidence, showOwnership, showNudges, onTogglePresentation, }: {
|
|
65
65
|
readonly showLifecycle: boolean;
|
|
66
66
|
readonly showEvidence: boolean;
|
|
67
67
|
readonly showOwnership: boolean;
|
|
68
|
+
readonly showNudges: boolean;
|
|
68
69
|
readonly onTogglePresentation: (flag: PresentationFlag, value: boolean) => void;
|
|
69
70
|
}): import("react").JSX.Element;
|
|
@@ -131,6 +131,7 @@ export interface QueryPanelProps {
|
|
|
131
131
|
readonly showLifecycle: boolean;
|
|
132
132
|
readonly showEvidence: boolean;
|
|
133
133
|
readonly showOwnership: boolean;
|
|
134
|
+
readonly showNudges: boolean;
|
|
134
135
|
readonly onTogglePresentation: (flag: PresentationFlag, value: boolean) => void;
|
|
135
136
|
readonly onToggleOpen: () => void;
|
|
136
137
|
readonly onSelectTab: (tab: BottomPanelTabId) => void;
|
|
@@ -138,5 +139,11 @@ export interface QueryPanelProps {
|
|
|
138
139
|
* write: what is on screen is what the reviewer is composing. */
|
|
139
140
|
readonly onApply: (query: ProjectionQuery) => void;
|
|
140
141
|
readonly onStage: (operation: VisualViewOperation) => void;
|
|
142
|
+
/**
|
|
143
|
+
* A viewer, not an author (#298): the fields still narrow the canvas - a
|
|
144
|
+
* live filter writes nothing - but the affordance that stages the edit as a
|
|
145
|
+
* view change is absent. The document still shows, because it is a fact.
|
|
146
|
+
*/
|
|
147
|
+
readonly readOnly?: boolean;
|
|
141
148
|
}
|
|
142
|
-
export declare function QueryPanel({ nodes, activeFilter, view, open, tab, showLifecycle, showEvidence, showOwnership, onTogglePresentation, onToggleOpen, onSelectTab, onApply, onStage, }: QueryPanelProps): import("react").JSX.Element;
|
|
149
|
+
export declare function QueryPanel({ nodes, activeFilter, view, open, tab, showLifecycle, showEvidence, showOwnership, showNudges, onTogglePresentation, onToggleOpen, onSelectTab, onApply, onStage, readOnly, }: QueryPanelProps): import("react").JSX.Element;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { LayoutDirection } from "../layout-direction.js";
|
|
1
2
|
import type { ProjectionQuery } from "../projection.js";
|
|
2
3
|
import type { VisualViewOperation, VisualViewSummary } from "../adapters/visual/protocol-contract.js";
|
|
3
4
|
export interface SaveViewDialogProps {
|
|
@@ -52,12 +53,12 @@ export interface BuildPayloadParams {
|
|
|
52
53
|
readonly showOwnership: boolean;
|
|
53
54
|
/**
|
|
54
55
|
* Whatever the view being overwritten already declared, carried through
|
|
55
|
-
* rather than restated. The canvas
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
* drop a value the reviewer never
|
|
56
|
+
* rather than restated. The canvas draws the direction now (#274, ADR 0121)
|
|
57
|
+
* and the LikeC4 export has always read it, but there is still no control
|
|
58
|
+
* that sets one: the view declares it, so a save that simply omitted it
|
|
59
|
+
* would drop a value the reviewer never asked to discard.
|
|
59
60
|
*/
|
|
60
|
-
readonly carriedDirection:
|
|
61
|
+
readonly carriedDirection: LayoutDirection | undefined;
|
|
61
62
|
}
|
|
62
63
|
/**
|
|
63
64
|
* Pure translation from the form's local state to the staged operation — no
|
|
@@ -82,5 +83,10 @@ export declare const buildPayload: ({ id, taken, path, folder, title, descriptio
|
|
|
82
83
|
* an overwrite was immediate and unundoable; a staged overwrite is a row the
|
|
83
84
|
* reviewer can read, discard and undo before it lands, which is a better
|
|
84
85
|
* answer than a dialog.
|
|
86
|
+
*
|
|
87
|
+
* Opened with a folder preset — "New folder…", "New view in this folder…" —
|
|
88
|
+
* the overwrite is disabled (#299): it carries the active view's own folder
|
|
89
|
+
* by design, so it is the one button that would silently drop the folder the
|
|
90
|
+
* reviewer just named.
|
|
85
91
|
*/
|
|
86
92
|
export declare function SaveViewDialog({ views, activeViewId, query, layout, showLifecycle, showEvidence, showOwnership, open, folder, onClose, onStage, }: SaveViewDialogProps): import("react").JSX.Element | null;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The shipped question catalogue, bundled into the browser build so the
|
|
3
|
+
* embedded editor computes the same interrogation overlay the session
|
|
4
|
+
* server does (#292). The path is a diagnostic label, not a file: nothing
|
|
5
|
+
* in the browser resolves it.
|
|
6
|
+
*/
|
|
7
|
+
export declare const SHIPPED_CATALOGUE: {
|
|
8
|
+
readonly path: 'core-enrichment.yaml';
|
|
9
|
+
readonly source: string;
|
|
10
|
+
};
|
|
@@ -301,17 +301,28 @@ export declare const visualBrowserInputFor: (intent: VisualAppIntent, state: Vis
|
|
|
301
301
|
* reporting itself as the reviewer's own.
|
|
302
302
|
*/
|
|
303
303
|
/**
|
|
304
|
-
*
|
|
304
|
+
* How the active view can be told what it holds, as the menus must read it.
|
|
305
305
|
*
|
|
306
|
-
* `null` where there is no
|
|
307
|
-
*
|
|
306
|
+
* `null` only where there is no view at all. A view that ENUMERATES its
|
|
307
|
+
* subjects is told by editing that list; a view that describes them with
|
|
308
|
+
* FACETS is told by editing `exclude`, the exception a rule cannot state
|
|
309
|
+
* (#267, ADR 0122). Both are membership; they differ in which field moves and
|
|
310
|
+
* in which direction, which is why the shape is a union rather than a list
|
|
311
|
+
* with a flag.
|
|
308
312
|
*
|
|
309
313
|
* Read through the PENDING row when one is staged, not off the saved document.
|
|
310
314
|
* A reviewer who has just added a subject and right-clicks it again must be
|
|
311
315
|
* offered "Remove from view"; a menu built from the saved list would offer
|
|
312
316
|
* "Add to this view" a second time and stage nothing.
|
|
313
317
|
*/
|
|
314
|
-
export
|
|
318
|
+
export type ActiveViewMembership = {
|
|
319
|
+
readonly kind: "enumerated";
|
|
320
|
+
readonly subjects: readonly string[];
|
|
321
|
+
} | {
|
|
322
|
+
readonly kind: "faceted";
|
|
323
|
+
readonly excluded: readonly string[];
|
|
324
|
+
};
|
|
325
|
+
export declare const activeViewMembership: (state: VisualAppState) => ActiveViewMembership | null;
|
|
315
326
|
export declare const filterToReresolve: (frame: VisualServerFrame, state: VisualAppState) => {
|
|
316
327
|
readonly query: ProjectionQuery;
|
|
317
328
|
readonly source: FilterSource;
|
|
@@ -12,11 +12,23 @@ import type { VisualKindOption } from '../adapters/visual/protocol-contract.js';
|
|
|
12
12
|
* than a transliteration of the name does. It is shown before landing, because
|
|
13
13
|
* a derived address the author never saw is one nobody agreed to.
|
|
14
14
|
*/
|
|
15
|
-
export declare const SubjectDraftPanel: ({ graph, kinds, documents, defaultDocument, onStage, onCancel, }: {
|
|
15
|
+
export declare const SubjectDraftPanel: ({ graph, kinds, documents, defaultDocument, initialKind, reservedIds, onStage, onCancel, }: {
|
|
16
16
|
readonly graph: CanvasGraph;
|
|
17
17
|
readonly kinds: readonly VisualKindOption[];
|
|
18
18
|
readonly documents: readonly string[];
|
|
19
19
|
readonly defaultDocument: string;
|
|
20
|
+
/** A kind the reviewer picked up on the way in - dragged from the palette
|
|
21
|
+
* or clicked there (#295). Their own choice arriving with the gesture, not
|
|
22
|
+
* a default this form chose for them, so the no-default rule below stands. */
|
|
23
|
+
readonly initialKind?: string;
|
|
24
|
+
/**
|
|
25
|
+
* Ids the pending changeset already claims. The graph only knows what has
|
|
26
|
+
* landed, so without these a second subject slugging to the same id
|
|
27
|
+
* proposed it again and replace-by-target staging swallowed the first
|
|
28
|
+
* silently (#315). Required rather than defaulted: a caller has to say
|
|
29
|
+
* what is staged, even when the answer is nothing.
|
|
30
|
+
*/
|
|
31
|
+
readonly reservedIds: readonly string[];
|
|
20
32
|
readonly onStage: (operation: YarramateOperation) => void;
|
|
21
33
|
readonly onCancel: () => void;
|
|
22
34
|
}) => React.ReactElement;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one substring judgement every surface that filters subjects by typed
|
|
3
|
+
* text shares.
|
|
4
|
+
*
|
|
5
|
+
* #307 extracted the predicate inside `graph-canvas.tsx` so the canvas pass
|
|
6
|
+
* and the shell's empty-state honesty could not drift; #317 lifts it here so
|
|
7
|
+
* the rail's tree filter can share it too. It cannot simply be imported from
|
|
8
|
+
* `graph-canvas.tsx`: the rail's tree model (`view-tree-model.ts`) keeps a
|
|
9
|
+
* zero-dependency discipline — no React, no cytoscape — and merely loading
|
|
10
|
+
* the canvas module registers cytoscape-elk. So the predicate lives in this
|
|
11
|
+
* small pure module and both surfaces import it from here.
|
|
12
|
+
*/
|
|
13
|
+
import type { CanvasNode } from "../graph-projection.js";
|
|
14
|
+
/**
|
|
15
|
+
* The slice of a subject the predicate reads — the render data both the
|
|
16
|
+
* canvas and the rail already hold.
|
|
17
|
+
*/
|
|
18
|
+
export type FilterableSubject = Pick<CanvasNode, "id" | "name" | "kindLabel">;
|
|
19
|
+
/**
|
|
20
|
+
* Typed filter text made comparable: trimmed and lowercased, once, so every
|
|
21
|
+
* surface trims the same way before matching.
|
|
22
|
+
*/
|
|
23
|
+
export declare const normalizeFilterText: (text: string) => string;
|
|
24
|
+
/**
|
|
25
|
+
* Whether a subject survives the typed text: case-insensitive, against its
|
|
26
|
+
* id, name, and kind label. `name` and `kindLabel` are `unknown` because the
|
|
27
|
+
* canvas reads them out of cytoscape data, which types nothing.
|
|
28
|
+
*/
|
|
29
|
+
export declare function subjectMatchesQuickFilter(trimmedLowerFilter: string, id: string, name: unknown, kindLabel: unknown): boolean;
|
|
30
|
+
/**
|
|
31
|
+
* How many of these subjects survive the typed text — the number a tree row
|
|
32
|
+
* shows while the filter narrows (#317). With no text every subject
|
|
33
|
+
* survives, so this is also the plain length.
|
|
34
|
+
*/
|
|
35
|
+
export declare const countMatchingSubjects: (subjects: readonly FilterableSubject[], filterText: string) => number;
|
|
@@ -32,6 +32,14 @@ export interface ConceptFormProps {
|
|
|
32
32
|
readonly onStageChange: (operation: YarramateOperation) => void;
|
|
33
33
|
}
|
|
34
34
|
export declare const ConceptForm: ({ node, model, operations, onStageChange }: ConceptFormProps) => import("react").JSX.Element;
|
|
35
|
+
export declare const ConceptFacts: ({ node, model, }: {
|
|
36
|
+
readonly node: CanvasNode;
|
|
37
|
+
readonly model: VisualRenderedModel;
|
|
38
|
+
}) => import("react").JSX.Element;
|
|
39
|
+
export declare const RelationshipFacts: ({ edge, model, }: {
|
|
40
|
+
readonly edge: CanvasEdge;
|
|
41
|
+
readonly model: VisualRenderedModel;
|
|
42
|
+
}) => import("react").JSX.Element;
|
|
35
43
|
export interface RelationshipFormProps {
|
|
36
44
|
readonly edge: CanvasEdge;
|
|
37
45
|
readonly model: VisualRenderedModel;
|