yarramate 1.3.0 → 1.4.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 +13 -1
- package/dist/adapters/visual/workspace-model.d.ts +14 -2
- package/dist/adapters/visual/workspace-model.js +19 -9
- package/dist/ask-command.js +8 -1
- package/dist/compiler.d.ts +13 -1
- package/dist/compiler.js +646 -0
- package/dist/design-command.js +14 -3
- package/dist/graph-projection.d.ts +10 -0
- package/dist/graph-projection.js +1 -0
- package/dist/interrogate-command.d.ts +17 -0
- package/dist/interrogate-command.js +72 -40
- package/dist/relationship-drafting.js +16 -1
- package/dist/visual-app/assets/{index-C3i9SxTe.js → index-yCHtmQUH.js} +1 -1
- package/dist/visual-app/index.html +1 -1
- package/dist/visual-app-lib/editor.js +22875 -22261
- package/dist/visual-app-lib/types/adapters/visual/workspace-model.d.ts +14 -2
- package/dist/visual-app-lib/types/compiler.d.ts +13 -1
- package/dist/visual-app-lib/types/graph-projection.d.ts +10 -0
- package/dist/visual-app-lib/types/interrogate-command.d.ts +17 -0
- package/dist/visual-app-lib/types/visual-app/local-host.d.ts +42 -0
- package/dist/visual-app-lib/types/workspace.d.ts +2 -0
- package/dist/workspace.d.ts +2 -0
- package/dist/workspace.js +1 -0
- package/docs/CONSUMING-YARRAMATE.md +41 -0
- package/package.json +2 -1
- package/schema/yarramate-design-step.schema.json +13 -0
- package/schema/yarramate-document.schema.json +14 -0
- package/schema/yarramate-interrogation-report.schema.json +18 -0
- package/schema/yarramate-pattern.schema.json +133 -0
- package/schema/yarramate-question-catalogue.schema.json +21 -0
- package/schema/yarramate-visual-graph.schema.json +9 -0
- package/schema/yarramate-workspace.schema.json +4 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
format: yarramate/question-catalogue/v1
|
|
2
2
|
id: core-enrichment
|
|
3
|
-
version: "1.
|
|
3
|
+
version: "1.3"
|
|
4
4
|
profile: yarramate/core@0.1
|
|
5
5
|
presentation:
|
|
6
6
|
title: Core enrichment interview
|
|
@@ -25,27 +25,39 @@ waves:
|
|
|
25
25
|
Load-bearing hops: the behavior a component is assigned to or the
|
|
26
26
|
interface it composes, the serving/triggering/flow mechanism,
|
|
27
27
|
payload, trust, reliability, and capacity. Hygiene waits.
|
|
28
|
+
opensWhen:
|
|
29
|
+
- condition: has-any-subject
|
|
28
30
|
- id: business
|
|
29
31
|
name: Business
|
|
30
32
|
description: Who acts, what is served, and what information matters.
|
|
33
|
+
opensWhen:
|
|
34
|
+
- condition: has-any-subject
|
|
31
35
|
- id: application
|
|
32
36
|
name: Application
|
|
33
37
|
description: >-
|
|
34
38
|
How declared services are realized, performed, and fed with
|
|
35
39
|
information.
|
|
40
|
+
opensWhen:
|
|
41
|
+
- condition: has-any-subject
|
|
36
42
|
- id: technology
|
|
37
43
|
name: Technology
|
|
38
44
|
description: >-
|
|
39
45
|
Where the declared applications actually run and what materializes
|
|
40
46
|
them.
|
|
47
|
+
opensWhen:
|
|
48
|
+
- condition: has-any-subject
|
|
41
49
|
- id: implementation
|
|
42
50
|
name: Implementation
|
|
43
51
|
description: >-
|
|
44
52
|
How the planned architecture becomes real: work, deliverables, and
|
|
45
53
|
the plateaus between here and there.
|
|
54
|
+
opensWhen:
|
|
55
|
+
- condition: has-any-subject
|
|
46
56
|
- id: hygiene
|
|
47
57
|
name: Model hygiene
|
|
48
58
|
description: Cross-cutting completeness that keeps every wave honest.
|
|
59
|
+
opensWhen:
|
|
60
|
+
- condition: has-any-subject
|
|
49
61
|
|
|
50
62
|
questions:
|
|
51
63
|
# ---- motivation ----------------------------------------------------------
|
|
@@ -49,13 +49,25 @@ export declare const conceptCountOf: (graph: SemanticGraph, query: ProjectionQue
|
|
|
49
49
|
* Subject ids come from the same compiled graph as `CanvasNode.id`, so the
|
|
50
50
|
* join in the browser is a plain lookup.
|
|
51
51
|
*/
|
|
52
|
+
export interface DismissedQuestion {
|
|
53
|
+
readonly questionId: string;
|
|
54
|
+
/** Absent dismisses the question wherever it appears. */
|
|
55
|
+
readonly subject?: string;
|
|
56
|
+
}
|
|
52
57
|
export declare const interrogationOverlayOf: (compiled: {
|
|
53
58
|
readonly graph: SemanticGraph;
|
|
54
59
|
readonly profileContext: ResolvedProfileContext;
|
|
55
60
|
}, catalogue: {
|
|
56
61
|
readonly path: string;
|
|
57
62
|
readonly source: string;
|
|
58
|
-
}
|
|
63
|
+
},
|
|
64
|
+
/**
|
|
65
|
+
* What the host has already dealt with (#328). Evaluation is unchanged and
|
|
66
|
+
* the model is untouched: this decides only what the pane draws, because a
|
|
67
|
+
* question set aside in the host's own product should not be asked again by
|
|
68
|
+
* a pane embedded in it.
|
|
69
|
+
*/
|
|
70
|
+
dismissed?: readonly DismissedQuestion[]) => VisualInterrogationOverlay | undefined;
|
|
59
71
|
/**
|
|
60
72
|
* Rebuilds the shared editor workspace from one successful compile.
|
|
61
73
|
*
|
|
@@ -71,7 +83,7 @@ export declare const renderedWorkspaceOf: (compiled: {
|
|
|
71
83
|
}, views: readonly VisualViewSummary[], metadata: Omit<VisualRenderedModel, "graph" | "vocabulary" | "interrogation">, catalogue?: {
|
|
72
84
|
readonly path: string;
|
|
73
85
|
readonly source: string;
|
|
74
|
-
}) => {
|
|
86
|
+
}, dismissed?: readonly DismissedQuestion[]) => {
|
|
75
87
|
readonly model: VisualRenderedModel;
|
|
76
88
|
readonly views: readonly VisualViewSummary[];
|
|
77
89
|
};
|
|
@@ -46,25 +46,32 @@ export const kindOptionsOf = (lineages) => [...lineages.keys()].map((id) => ({
|
|
|
46
46
|
* them would read as five, and the reviewer counting boxes would find three.
|
|
47
47
|
*/
|
|
48
48
|
export const conceptCountOf = (graph, query, profileContext) => evaluateProjection(graph, adHoc(query), profileContext).subjects.filter(({ type }) => type === "concept").length;
|
|
49
|
+
export const interrogationOverlayOf = (compiled, catalogue,
|
|
49
50
|
/**
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
* Subject ids come from the same compiled graph as `CanvasNode.id`, so the
|
|
55
|
-
* join in the browser is a plain lookup.
|
|
51
|
+
* What the host has already dealt with (#328). Evaluation is unchanged and
|
|
52
|
+
* the model is untouched: this decides only what the pane draws, because a
|
|
53
|
+
* question set aside in the host's own product should not be asked again by
|
|
54
|
+
* a pane embedded in it.
|
|
56
55
|
*/
|
|
57
|
-
|
|
56
|
+
dismissed = []) => {
|
|
58
57
|
const loaded = loadQuestionCatalogue(catalogue);
|
|
59
58
|
if (!loaded.ok)
|
|
60
59
|
return undefined;
|
|
61
60
|
const report = evaluateCatalogue(loaded.catalogue, compiled.graph, compiled.profileContext);
|
|
61
|
+
const dismissedEverywhere = new Set(dismissed
|
|
62
|
+
.filter(({ subject }) => subject === undefined)
|
|
63
|
+
.map(({ questionId }) => questionId));
|
|
64
|
+
const dismissedForSubject = new Set(dismissed
|
|
65
|
+
.filter(({ subject }) => subject !== undefined)
|
|
66
|
+
.map(({ questionId, subject }) => `${questionId}\u0000${subject}`));
|
|
62
67
|
const workspace = [];
|
|
63
68
|
const subjects = {};
|
|
64
69
|
for (const wave of report.waves) {
|
|
65
70
|
for (const question of wave.questions) {
|
|
66
71
|
if (!question.open)
|
|
67
72
|
continue;
|
|
73
|
+
if (dismissedEverywhere.has(question.id))
|
|
74
|
+
continue;
|
|
68
75
|
const base = {
|
|
69
76
|
questionId: question.id,
|
|
70
77
|
authority: question.authority,
|
|
@@ -75,6 +82,9 @@ export const interrogationOverlayOf = (compiled, catalogue) => {
|
|
|
75
82
|
continue;
|
|
76
83
|
}
|
|
77
84
|
for (const subject of question.subjects) {
|
|
85
|
+
if (dismissedForSubject.has(`${question.id}\u0000${subject.id}`)) {
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
78
88
|
(subjects[subject.id] ??= []).push({
|
|
79
89
|
...base,
|
|
80
90
|
question: subject.question,
|
|
@@ -98,14 +108,14 @@ export const interrogationOverlayOf = (compiled, catalogue) => {
|
|
|
98
108
|
* is the question catalogue's bytes — this module cannot read files, so
|
|
99
109
|
* whoever can hands them over; omitting it ships a model with no overlay.
|
|
100
110
|
*/
|
|
101
|
-
export const renderedWorkspaceOf = (compiled, views, metadata, catalogue) => {
|
|
111
|
+
export const renderedWorkspaceOf = (compiled, views, metadata, catalogue, dismissed) => {
|
|
102
112
|
const refreshedViews = views.map((view) => ({
|
|
103
113
|
...view,
|
|
104
114
|
subjectCount: conceptCountOf(compiled.graph, view.query, compiled.profileContext),
|
|
105
115
|
}));
|
|
106
116
|
const interrogation = catalogue === undefined
|
|
107
117
|
? undefined
|
|
108
|
-
: interrogationOverlayOf(compiled, catalogue);
|
|
118
|
+
: interrogationOverlayOf(compiled, catalogue, dismissed);
|
|
109
119
|
return {
|
|
110
120
|
model: {
|
|
111
121
|
...metadata,
|
package/dist/ask-command.js
CHANGED
|
@@ -500,8 +500,15 @@ export function runAskCommand(options, cwd) {
|
|
|
500
500
|
if (reconciliation !== undefined) {
|
|
501
501
|
lines.push(reconciliationLine(reconciliation));
|
|
502
502
|
}
|
|
503
|
+
// Zero open has two causes and only one is complete (#334): a
|
|
504
|
+
// catalogue whose waves are all gated shut has asked nothing, and
|
|
505
|
+
// reporting that as a finished interview is the same empty-set
|
|
506
|
+
// flattery the wave rail carried.
|
|
507
|
+
const askedAnything = report.waves.some((wave) => wave.questions.length > 0);
|
|
503
508
|
lines.push(report.summary.open === 0
|
|
504
|
-
?
|
|
509
|
+
? askedAnything
|
|
510
|
+
? `Design interview complete (catalogue ${report.catalogue}): no open questions.`
|
|
511
|
+
: `Design interview not started (catalogue ${report.catalogue}): no wave has opened yet.`
|
|
505
512
|
: `Design interview: ${plural(report.summary.open, 'open question')} (catalogue ${report.catalogue}) — continue: yarramate design ${workspacePath}`, '', 'Backlog — planned, dependency order:', ...plannedLines(planned), '', `Current: ${plural(current.length, 'subject')} · Retired: ${retired.length} ` +
|
|
506
513
|
`(roster: yarramate ask ${workspacePath} --subjects)`);
|
|
507
514
|
return emit(result, `${lines.join('\n')}\n`);
|
package/dist/compiler.d.ts
CHANGED
|
@@ -74,6 +74,18 @@ export interface ResolvedProfileContext {
|
|
|
74
74
|
/** Kind identity -> the core kind it resolves to through lineage. */
|
|
75
75
|
readonly conceptKindCoreAncestors: ReadonlyMap<string, CoreConceptKindId>;
|
|
76
76
|
readonly relationshipKindCoreAncestors: ReadonlyMap<string, RelationshipKind>;
|
|
77
|
+
/**
|
|
78
|
+
* The core relationship kinds a pattern PORTS for a concept kind (#268
|
|
79
|
+
* phase 3, ADR 0124), keyed by kind identity. Only kinds that have a
|
|
80
|
+
* pattern with ports appear.
|
|
81
|
+
*
|
|
82
|
+
* A macro edge needs both ends to port its kind, so a consumer offering a
|
|
83
|
+
* palette between two instances intersects the two sets. Two raw groupings
|
|
84
|
+
* permit ten of the eleven kinds, which is no narrowing at all; the ports
|
|
85
|
+
* are what restore the guidance the relationship table gives everywhere
|
|
86
|
+
* else.
|
|
87
|
+
*/
|
|
88
|
+
readonly patternPortKinds: ReadonlyMap<string, readonly RelationshipKind[]>;
|
|
77
89
|
/**
|
|
78
90
|
* The core relationship kinds the ArchiMate table permits between two
|
|
79
91
|
* concept kind identities, resolved through lineage; undefined when either
|
|
@@ -104,7 +116,7 @@ export type ContextualCompilationResult = {
|
|
|
104
116
|
*/
|
|
105
117
|
export interface ParsedWorkspaceSource {
|
|
106
118
|
readonly source: string;
|
|
107
|
-
readonly kind: 'profile' | 'document';
|
|
119
|
+
readonly kind: 'profile' | 'document' | 'pattern';
|
|
108
120
|
readonly value: unknown;
|
|
109
121
|
readonly schemaDiagnostics: readonly Diagnostic[];
|
|
110
122
|
/**
|