adr-kit 0.9.0 → 0.10.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/README.md +18 -5
- package/README.zh.md +14 -4
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +14 -5
- package/dist/cli.js.map +1 -1
- package/dist/commands/completion.js +2 -2
- package/dist/commands/completion.js.map +1 -1
- package/dist/commands/graph.d.ts +1 -0
- package/dist/commands/graph.d.ts.map +1 -1
- package/dist/commands/graph.js +4 -1
- package/dist/commands/graph.js.map +1 -1
- package/dist/commands/tree.d.ts +1 -1
- package/dist/commands/tree.d.ts.map +1 -1
- package/dist/commands/tree.js +4 -1
- package/dist/commands/tree.js.map +1 -1
- package/dist/core/canvas-view.d.ts +5 -0
- package/dist/core/canvas-view.d.ts.map +1 -0
- package/dist/core/canvas-view.js +121 -0
- package/dist/core/canvas-view.js.map +1 -0
- package/dist/core/deliberation-html.d.ts +4 -0
- package/dist/core/deliberation-html.d.ts.map +1 -0
- package/dist/core/deliberation-html.js +81 -0
- package/dist/core/deliberation-html.js.map +1 -0
- package/dist/core/deliberation-view.d.ts +4 -0
- package/dist/core/deliberation-view.d.ts.map +1 -0
- package/dist/core/deliberation-view.js +508 -0
- package/dist/core/deliberation-view.js.map +1 -0
- package/dist/core/deliberation.d.ts +26 -7
- package/dist/core/deliberation.d.ts.map +1 -1
- package/dist/core/deliberation.js +165 -35
- package/dist/core/deliberation.js.map +1 -1
- package/dist/core/graph-html.d.ts +8 -0
- package/dist/core/graph-html.d.ts.map +1 -0
- package/dist/core/graph-html.js +180 -0
- package/dist/core/graph-html.js.map +1 -0
- package/dist/core/graph-view.d.ts +3 -0
- package/dist/core/graph-view.d.ts.map +1 -0
- package/dist/core/graph-view.js +258 -0
- package/dist/core/graph-view.js.map +1 -0
- package/dist/core/graph.d.ts +4 -1
- package/dist/core/graph.d.ts.map +1 -1
- package/dist/core/graph.js +11 -2
- package/dist/core/graph.js.map +1 -1
- package/dist/core/repository.d.ts.map +1 -1
- package/dist/core/repository.js +6 -2
- package/dist/core/repository.js.map +1 -1
- package/dist/core/templates.d.ts +8 -3
- package/dist/core/templates.d.ts.map +1 -1
- package/dist/core/templates.js +10 -2
- package/dist/core/templates.js.map +1 -1
- package/dist/core/tool-integrations.d.ts.map +1 -1
- package/dist/core/tool-integrations.js +37 -5
- package/dist/core/tool-integrations.js.map +1 -1
- package/dist/core/validate.d.ts.map +1 -1
- package/dist/core/validate.js +31 -1
- package/dist/core/validate.js.map +1 -1
- package/dist/core/view-text.d.ts +14 -0
- package/dist/core/view-text.d.ts.map +1 -0
- package/dist/core/view-text.js +77 -0
- package/dist/core/view-text.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,508 @@
|
|
|
1
|
+
/** Inline assets for the offline tree viewer. No network or runtime dependency. */
|
|
2
|
+
export const TREE_STYLE = String.raw `
|
|
3
|
+
|
|
4
|
+
:root {
|
|
5
|
+
font-family: Inter,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;
|
|
6
|
+
color: #233c36;
|
|
7
|
+
background: #f6f8f5;
|
|
8
|
+
font-synthesis: none
|
|
9
|
+
}
|
|
10
|
+
* {
|
|
11
|
+
box-sizing: border-box
|
|
12
|
+
}
|
|
13
|
+
body {
|
|
14
|
+
margin: 0
|
|
15
|
+
}
|
|
16
|
+
button {
|
|
17
|
+
font: inherit;
|
|
18
|
+
color: inherit
|
|
19
|
+
}
|
|
20
|
+
button {
|
|
21
|
+
cursor: pointer
|
|
22
|
+
}
|
|
23
|
+
button:focus-visible,summary:focus-visible,main:focus-visible {
|
|
24
|
+
outline: 3px solid #9775ce;
|
|
25
|
+
outline-offset: 4px
|
|
26
|
+
}
|
|
27
|
+
button {
|
|
28
|
+
border: 1px solid #dce4dd;
|
|
29
|
+
background: white;
|
|
30
|
+
border-radius: 8px;
|
|
31
|
+
padding: 9px 13px;
|
|
32
|
+
font-size: 12px
|
|
33
|
+
}
|
|
34
|
+
button:hover {
|
|
35
|
+
background: #edf3ef
|
|
36
|
+
}
|
|
37
|
+
header {
|
|
38
|
+
height: 72px;
|
|
39
|
+
background: #fff;
|
|
40
|
+
display: flex;
|
|
41
|
+
align-items: center;
|
|
42
|
+
justify-content: space-between;
|
|
43
|
+
padding: 0 30px;
|
|
44
|
+
border-bottom: 1px solid #e1e7e1;
|
|
45
|
+
gap: 15px
|
|
46
|
+
}
|
|
47
|
+
.brand {
|
|
48
|
+
font-size: 17px;
|
|
49
|
+
font-weight: 750;
|
|
50
|
+
letter-spacing: -.6px;
|
|
51
|
+
display: flex;
|
|
52
|
+
align-items: center;
|
|
53
|
+
gap: 11px
|
|
54
|
+
}
|
|
55
|
+
.logo {
|
|
56
|
+
background: #284f40;
|
|
57
|
+
color: white;
|
|
58
|
+
border-radius: 8px;
|
|
59
|
+
padding: 7px 9px;
|
|
60
|
+
font-family: monospace
|
|
61
|
+
}
|
|
62
|
+
.brand small {
|
|
63
|
+
font-size: 11px;
|
|
64
|
+
color: #728079;
|
|
65
|
+
font-weight: 500;
|
|
66
|
+
letter-spacing: 1px;
|
|
67
|
+
margin-left: 16px
|
|
68
|
+
}
|
|
69
|
+
.intro {
|
|
70
|
+
min-height: 145px;
|
|
71
|
+
padding: 28px 36px;
|
|
72
|
+
display: flex;
|
|
73
|
+
justify-content: space-between;
|
|
74
|
+
align-items: center;
|
|
75
|
+
gap: 24px
|
|
76
|
+
}
|
|
77
|
+
.eyebrow {
|
|
78
|
+
color: #788b7b;
|
|
79
|
+
letter-spacing: 2px;
|
|
80
|
+
font: 11px monospace;
|
|
81
|
+
margin-bottom: 9px
|
|
82
|
+
}
|
|
83
|
+
h1 {
|
|
84
|
+
font-size: 25px;
|
|
85
|
+
letter-spacing: -.7px;
|
|
86
|
+
margin: 0;
|
|
87
|
+
font-weight: 650
|
|
88
|
+
}
|
|
89
|
+
.intro p {
|
|
90
|
+
font-size: 12px;
|
|
91
|
+
color: #718078;
|
|
92
|
+
margin: 10px 0 0
|
|
93
|
+
}
|
|
94
|
+
.stats {
|
|
95
|
+
display: flex;
|
|
96
|
+
gap: 24px;
|
|
97
|
+
text-align: center
|
|
98
|
+
}
|
|
99
|
+
.stats strong {
|
|
100
|
+
font-size: 24px;
|
|
101
|
+
font-weight: 500;
|
|
102
|
+
display: block
|
|
103
|
+
}
|
|
104
|
+
.stats span {
|
|
105
|
+
font-size: 11px;
|
|
106
|
+
color: #7c8880;
|
|
107
|
+
display: block;
|
|
108
|
+
margin-top: 4px
|
|
109
|
+
}
|
|
110
|
+
main {
|
|
111
|
+
position: relative;
|
|
112
|
+
height: calc(100dvh - 251px);
|
|
113
|
+
min-height: 420px;
|
|
114
|
+
overflow: hidden;
|
|
115
|
+
touch-action: none;
|
|
116
|
+
background-image: radial-gradient(#cdd8cc .8px,transparent .8px);
|
|
117
|
+
background-size: 20px 20px;
|
|
118
|
+
border-block: 1px solid #e0e7df;
|
|
119
|
+
cursor: grab
|
|
120
|
+
}
|
|
121
|
+
main.dragging {
|
|
122
|
+
cursor: grabbing
|
|
123
|
+
}
|
|
124
|
+
#world {
|
|
125
|
+
position: absolute;
|
|
126
|
+
transform-origin: 0 0
|
|
127
|
+
}
|
|
128
|
+
#edges {
|
|
129
|
+
position: absolute;
|
|
130
|
+
inset: 0;
|
|
131
|
+
overflow: visible;
|
|
132
|
+
pointer-events: none
|
|
133
|
+
}
|
|
134
|
+
.card {
|
|
135
|
+
width: 292px;
|
|
136
|
+
background: #fff;
|
|
137
|
+
border: 1px solid #dce4dc;
|
|
138
|
+
border-radius: 13px;
|
|
139
|
+
box-shadow: 0 3px 8px #25403506;
|
|
140
|
+
cursor: auto;
|
|
141
|
+
overflow: visible
|
|
142
|
+
}
|
|
143
|
+
.card:hover {
|
|
144
|
+
border-color: #a6bcae
|
|
145
|
+
}
|
|
146
|
+
.cardhead {
|
|
147
|
+
padding: 19px 20px 15px
|
|
148
|
+
}
|
|
149
|
+
.label {
|
|
150
|
+
display: flex;
|
|
151
|
+
align-items: center;
|
|
152
|
+
justify-content: space-between;
|
|
153
|
+
gap: 8px;
|
|
154
|
+
font-size: 10px;
|
|
155
|
+
color: #78877e;
|
|
156
|
+
letter-spacing: 1px;
|
|
157
|
+
margin-bottom: 12px
|
|
158
|
+
}
|
|
159
|
+
.state {
|
|
160
|
+
color: #387456;
|
|
161
|
+
letter-spacing: 0;
|
|
162
|
+
background: #edf6ef;
|
|
163
|
+
border-radius: 4px;
|
|
164
|
+
padding: 3px 6px
|
|
165
|
+
}
|
|
166
|
+
.card h2 {
|
|
167
|
+
font-size: 16px;
|
|
168
|
+
line-height: 1.45;
|
|
169
|
+
letter-spacing: -.25px;
|
|
170
|
+
margin: 0;
|
|
171
|
+
font-weight: 600
|
|
172
|
+
}
|
|
173
|
+
.answer {
|
|
174
|
+
margin: 0 13px 13px;
|
|
175
|
+
padding: 13px;
|
|
176
|
+
background: #f1f7f1;
|
|
177
|
+
border: 1px solid #e2ece1;
|
|
178
|
+
border-radius: 8px;
|
|
179
|
+
position: relative
|
|
180
|
+
}
|
|
181
|
+
.answer p {
|
|
182
|
+
font-size: 13px;
|
|
183
|
+
line-height: 1.5;
|
|
184
|
+
margin: 8px 0 0
|
|
185
|
+
}
|
|
186
|
+
.badge {
|
|
187
|
+
font-size: 10px;
|
|
188
|
+
color: #407455
|
|
189
|
+
}
|
|
190
|
+
.answer .reason {
|
|
191
|
+
font-size: 11px;
|
|
192
|
+
color: #748576;
|
|
193
|
+
line-height: 1.55
|
|
194
|
+
}
|
|
195
|
+
.override {
|
|
196
|
+
background: #f4effb;
|
|
197
|
+
color: #7750a5;
|
|
198
|
+
font-size: 10px;
|
|
199
|
+
padding: 4px 6px;
|
|
200
|
+
border-radius: 4px;
|
|
201
|
+
letter-spacing: 0
|
|
202
|
+
}
|
|
203
|
+
.alts {
|
|
204
|
+
border-top: 1px solid #e7ece6;
|
|
205
|
+
padding: 12px 20px;
|
|
206
|
+
color: #748078;
|
|
207
|
+
font-size: 11px
|
|
208
|
+
}
|
|
209
|
+
.alts summary {
|
|
210
|
+
cursor: pointer;
|
|
211
|
+
list-style: none;
|
|
212
|
+
display: flex;
|
|
213
|
+
justify-content: space-between
|
|
214
|
+
}
|
|
215
|
+
.alts summary:after {
|
|
216
|
+
content: '+';
|
|
217
|
+
font-size: 15px
|
|
218
|
+
}
|
|
219
|
+
.alts[open] summary:after {
|
|
220
|
+
content: '−'
|
|
221
|
+
}
|
|
222
|
+
.alt {
|
|
223
|
+
padding-top: 15px;
|
|
224
|
+
margin-top: 12px;
|
|
225
|
+
border-top: 1px solid #eef0ed;
|
|
226
|
+
line-height: 1.55;
|
|
227
|
+
font-size: 12px;
|
|
228
|
+
color: #59645d
|
|
229
|
+
}
|
|
230
|
+
.alt p {
|
|
231
|
+
margin: 5px 0;
|
|
232
|
+
font-size: 11px;
|
|
233
|
+
color: #788279
|
|
234
|
+
}
|
|
235
|
+
.root {
|
|
236
|
+
background: #294d3e;
|
|
237
|
+
border-color: #294d3e;
|
|
238
|
+
color: #fff;
|
|
239
|
+
width: 245px
|
|
240
|
+
}
|
|
241
|
+
.root .cardhead {
|
|
242
|
+
padding: 25px
|
|
243
|
+
}
|
|
244
|
+
.root .label {
|
|
245
|
+
color: #bacdbc
|
|
246
|
+
}
|
|
247
|
+
.root h2 {
|
|
248
|
+
font-size: 21px;
|
|
249
|
+
font-weight: 500;
|
|
250
|
+
line-height: 1.4
|
|
251
|
+
}
|
|
252
|
+
.branch {
|
|
253
|
+
position: absolute;
|
|
254
|
+
right: -13px;
|
|
255
|
+
bottom: 25px;
|
|
256
|
+
padding: 0;
|
|
257
|
+
width: 26px;
|
|
258
|
+
height: 26px;
|
|
259
|
+
border-radius: 50%;
|
|
260
|
+
background: white;
|
|
261
|
+
color: #5a7d64;
|
|
262
|
+
font-size: 15px;
|
|
263
|
+
box-shadow: 0 2px 5px #274b3910;
|
|
264
|
+
z-index: 2
|
|
265
|
+
}
|
|
266
|
+
.controls {
|
|
267
|
+
position: absolute;
|
|
268
|
+
bottom: 22px;
|
|
269
|
+
right: 24px;
|
|
270
|
+
display: flex;
|
|
271
|
+
align-items: center;
|
|
272
|
+
padding: 5px;
|
|
273
|
+
gap: 3px;
|
|
274
|
+
background: white;
|
|
275
|
+
border: 1px solid #dce4dc;
|
|
276
|
+
border-radius: 11px;
|
|
277
|
+
box-shadow: 0 4px 20px #294d3e0a
|
|
278
|
+
}
|
|
279
|
+
.controls button {
|
|
280
|
+
border: 0
|
|
281
|
+
}
|
|
282
|
+
.controls output {
|
|
283
|
+
font: 11px monospace;
|
|
284
|
+
width: 44px;
|
|
285
|
+
text-align: center
|
|
286
|
+
}
|
|
287
|
+
.hint {
|
|
288
|
+
position: absolute;
|
|
289
|
+
bottom: 25px;
|
|
290
|
+
left: 28px;
|
|
291
|
+
color: #7a8a7f;
|
|
292
|
+
font-size: 11px;
|
|
293
|
+
background: #f6f8f5df;
|
|
294
|
+
padding: 7px;
|
|
295
|
+
border-radius: 5px
|
|
296
|
+
}
|
|
297
|
+
footer {
|
|
298
|
+
height: 34px;
|
|
299
|
+
display: flex;
|
|
300
|
+
align-items: center;
|
|
301
|
+
justify-content: space-between;
|
|
302
|
+
padding: 0 30px;
|
|
303
|
+
font-size: 10px;
|
|
304
|
+
color: #87928a
|
|
305
|
+
}
|
|
306
|
+
.legend {
|
|
307
|
+
display: flex;
|
|
308
|
+
gap: 18px
|
|
309
|
+
}
|
|
310
|
+
.legend span {
|
|
311
|
+
display: flex;
|
|
312
|
+
align-items: center;
|
|
313
|
+
gap: 6px
|
|
314
|
+
}
|
|
315
|
+
@media(max-width:700px) {
|
|
316
|
+
header {
|
|
317
|
+
padding: 0 14px
|
|
318
|
+
}
|
|
319
|
+
.brand small,.stats {
|
|
320
|
+
display: none
|
|
321
|
+
}
|
|
322
|
+
.intro {
|
|
323
|
+
padding: 20px;
|
|
324
|
+
min-height: 135px
|
|
325
|
+
}
|
|
326
|
+
h1 {
|
|
327
|
+
font-size: 20px
|
|
328
|
+
}
|
|
329
|
+
main {
|
|
330
|
+
height: calc(100dvh - 241px)
|
|
331
|
+
}
|
|
332
|
+
footer {
|
|
333
|
+
padding: 0 12px
|
|
334
|
+
}
|
|
335
|
+
.hint {
|
|
336
|
+
display: none
|
|
337
|
+
}
|
|
338
|
+
.controls {
|
|
339
|
+
right: 12px;
|
|
340
|
+
bottom: 14px
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
.card { overflow-wrap: anywhere; }
|
|
347
|
+
.cardhead .reason { font-size: 12px; color: #67786c; line-height: 1.6; }
|
|
348
|
+
.root .reason { color: #bed0c2; }
|
|
349
|
+
.state.open { color: #805f0e; background: #fff5d6; }
|
|
350
|
+
.state.rejected { color: #96554c; background: #faeeeb; }
|
|
351
|
+
.state.unrecorded { color: #647369; background: #eff2ee; }
|
|
352
|
+
.root .state { color: #264c38; }
|
|
353
|
+
.override-key { color: #7750a5; }
|
|
354
|
+
.option { border-style: dashed; }
|
|
355
|
+
.card[hidden] { display: none; }
|
|
356
|
+
.card { position: relative; margin: 18px 24px 18px calc(24px + var(--depth) * 24px); }
|
|
357
|
+
#world { position: relative; }
|
|
358
|
+
main { height: auto; min-height: 0; overflow: auto; touch-action: auto; cursor: auto; }
|
|
359
|
+
#edges, .hint, .branch, .js-control { display: none; }
|
|
360
|
+
.interactive main { height: calc(100dvh - 251px); min-height: 360px; overflow: hidden; touch-action: none; cursor: grab; }
|
|
361
|
+
.interactive #world { position: absolute; }
|
|
362
|
+
.interactive .card { position: absolute; margin: 0; }
|
|
363
|
+
.interactive #edges, .interactive .branch, .interactive .hint, .interactive .js-control { display: block; }
|
|
364
|
+
.interactive .controls { display: flex; }
|
|
365
|
+
.interactive .dragging { cursor: grabbing; }
|
|
366
|
+
.no-script { padding: 20px; }
|
|
367
|
+
@media (max-width: 700px) {
|
|
368
|
+
.interactive main { height: calc(100dvh - 241px); }
|
|
369
|
+
.interactive .hint { display: none; }
|
|
370
|
+
.intro { align-items: start; }
|
|
371
|
+
footer { height: auto; min-height: 34px; gap: 12px; flex-wrap: wrap; }
|
|
372
|
+
}
|
|
373
|
+
`;
|
|
374
|
+
// Kept as readable JavaScript: tsc ships this string unchanged in the CLI bundle.
|
|
375
|
+
// All record text is server-escaped HTML, never interpolated into this program.
|
|
376
|
+
export const TREE_SCRIPT = String.raw `
|
|
377
|
+
(() => {
|
|
378
|
+
const canvas = window.__adrCanvas;
|
|
379
|
+
if (!canvas) return;
|
|
380
|
+
const { viewport, world } = canvas;
|
|
381
|
+
const svg = document.getElementById('edges');
|
|
382
|
+
const allButton = document.getElementById('all');
|
|
383
|
+
const cards = Array.from(document.querySelectorAll('.card'));
|
|
384
|
+
if (!cards.length) return;
|
|
385
|
+
const items = cards.map(card => ({
|
|
386
|
+
card, id: card.id, parentId: card.dataset.parent,
|
|
387
|
+
anchor: document.getElementById(card.dataset.anchor),
|
|
388
|
+
children: [], x: 0, y: 0, width: 0, height: 0, span: 0
|
|
389
|
+
}));
|
|
390
|
+
const byId = new Map(items.map(item => [item.id, item]));
|
|
391
|
+
const roots = items.filter(item => !item.parentId);
|
|
392
|
+
for (const item of items) {
|
|
393
|
+
if (item.parentId) byId.get(item.parentId).children.push(item);
|
|
394
|
+
}
|
|
395
|
+
const collapsed = new Set();
|
|
396
|
+
|
|
397
|
+
function updateVisibility(item, hidden) {
|
|
398
|
+
item.card.hidden = hidden;
|
|
399
|
+
for (const child of item.children) {
|
|
400
|
+
const disclosure = child.anchor && child.anchor.closest('details');
|
|
401
|
+
updateVisibility(child, hidden || collapsed.has(item.id) || !!(disclosure && !disclosure.open));
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
function measure(item) {
|
|
406
|
+
item.width = item.card.offsetWidth;
|
|
407
|
+
item.height = item.card.offsetHeight;
|
|
408
|
+
const children = item.children.filter(child => !child.card.hidden);
|
|
409
|
+
const childrenHeight = children.reduce((sum, child) => sum + measure(child), 0);
|
|
410
|
+
item.span = Math.max(item.height, childrenHeight + Math.max(0, children.length - 1) * 34);
|
|
411
|
+
return item.span;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
function place(item, x, y) {
|
|
415
|
+
item.x = x;
|
|
416
|
+
item.y = y + (item.span - item.height) / 2;
|
|
417
|
+
item.card.style.left = item.x + 'px';
|
|
418
|
+
item.card.style.top = item.y + 'px';
|
|
419
|
+
let nextY = y;
|
|
420
|
+
for (const child of item.children) {
|
|
421
|
+
if (child.card.hidden) continue;
|
|
422
|
+
place(child, x + item.width + 94, nextY);
|
|
423
|
+
nextY += child.span + 34;
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
function layout() {
|
|
428
|
+
roots.forEach(root => updateVisibility(root, false));
|
|
429
|
+
roots.forEach(measure);
|
|
430
|
+
let nextY = 28;
|
|
431
|
+
for (const root of roots) {
|
|
432
|
+
place(root, 28, nextY);
|
|
433
|
+
nextY += root.span + 36;
|
|
434
|
+
}
|
|
435
|
+
const visible = items.filter(item => !item.card.hidden);
|
|
436
|
+
const width = visible.reduce((max, item) => Math.max(max, item.x + item.width), 0) + 28;
|
|
437
|
+
const height = visible.reduce((max, item) => Math.max(max, item.y + item.height), 0) + 28;
|
|
438
|
+
world.style.width = width + 'px';
|
|
439
|
+
world.style.height = height + 'px';
|
|
440
|
+
svg.setAttribute('width', width);
|
|
441
|
+
svg.setAttribute('height', height);
|
|
442
|
+
svg.replaceChildren();
|
|
443
|
+
for (const item of visible) {
|
|
444
|
+
if (!item.parentId) continue;
|
|
445
|
+
const parent = byId.get(item.parentId);
|
|
446
|
+
const source = item.anchor || parent.card.querySelector('.cardhead');
|
|
447
|
+
const sourceRect = source.getBoundingClientRect();
|
|
448
|
+
const parentRect = parent.card.getBoundingClientRect();
|
|
449
|
+
const startY = parent.y + (sourceRect.top - parentRect.top + sourceRect.height / 2) / canvas.scale;
|
|
450
|
+
const startX = parent.x + parent.width;
|
|
451
|
+
const endX = item.x, endY = item.y + Math.min(65, item.height / 2);
|
|
452
|
+
const midpoint = (startX + endX) / 2;
|
|
453
|
+
const sourceState = item.anchor ? item.anchor.dataset.state : parent.card.dataset.state;
|
|
454
|
+
// The unlock edge keys off the node that raised the follow-up, not the
|
|
455
|
+
// card it is drawn from: a follow-up nested under a settled option of
|
|
456
|
+
// the root card is still unlocked by that option. Mermaid asks whether
|
|
457
|
+
// the immediate parent node is the root; this is the same question.
|
|
458
|
+
const sourceIsRoot = !item.anchor && parent.card.classList.contains('root');
|
|
459
|
+
const unlocked = !sourceIsRoot
|
|
460
|
+
&& item.card.classList.contains('question') && sourceState === 'settled';
|
|
461
|
+
const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
|
|
462
|
+
path.setAttribute('d', 'M' + startX + ',' + startY + ' C' + midpoint + ',' + startY
|
|
463
|
+
+ ' ' + midpoint + ',' + endY + ' ' + endX + ',' + endY);
|
|
464
|
+
path.setAttribute('fill', 'none');
|
|
465
|
+
path.setAttribute('stroke', unlocked ? '#7ca38a' : '#b6c7ba');
|
|
466
|
+
path.setAttribute('stroke-width', unlocked ? '2' : '1.5');
|
|
467
|
+
if (!unlocked && !parent.card.classList.contains('root')) path.setAttribute('stroke-dasharray', '4 4');
|
|
468
|
+
path.dataset.from = item.anchor ? item.anchor.id : parent.id;
|
|
469
|
+
path.dataset.to = item.id;
|
|
470
|
+
path.dataset.unlocked = String(unlocked);
|
|
471
|
+
svg.append(path);
|
|
472
|
+
}
|
|
473
|
+
const details = Array.from(document.querySelectorAll('.alts'));
|
|
474
|
+
allButton.textContent = details.length && details.every(detail => detail.open)
|
|
475
|
+
? 'Collapse all options' : 'Expand all options';
|
|
476
|
+
allButton.disabled = details.length === 0;
|
|
477
|
+
canvas.paint();
|
|
478
|
+
}
|
|
479
|
+
window.__adrCanvasLayout = layout;
|
|
480
|
+
|
|
481
|
+
for (const item of items) {
|
|
482
|
+
const button = item.card.querySelector('.branch');
|
|
483
|
+
if (!button) continue;
|
|
484
|
+
button.addEventListener('click', () => {
|
|
485
|
+
if (collapsed.has(item.id)) collapsed.delete(item.id);
|
|
486
|
+
else collapsed.add(item.id);
|
|
487
|
+
button.textContent = collapsed.has(item.id) ? '+' : '−';
|
|
488
|
+
button.setAttribute('aria-expanded', String(!collapsed.has(item.id)));
|
|
489
|
+
const before = item.card.getBoundingClientRect();
|
|
490
|
+
layout();
|
|
491
|
+
const after = item.card.getBoundingClientRect();
|
|
492
|
+
canvas.addPan(before.left - after.left, before.top - after.top);
|
|
493
|
+
});
|
|
494
|
+
}
|
|
495
|
+
for (const detail of document.querySelectorAll('.alts')) detail.addEventListener('toggle', () => canvas.schedule());
|
|
496
|
+
allButton.addEventListener('click', () => {
|
|
497
|
+
const details = Array.from(document.querySelectorAll('.alts'));
|
|
498
|
+
const open = !details.every(detail => detail.open);
|
|
499
|
+
details.forEach(detail => { detail.open = open; });
|
|
500
|
+
layout();
|
|
501
|
+
});
|
|
502
|
+
|
|
503
|
+
layout();
|
|
504
|
+
canvas.fit();
|
|
505
|
+
})();
|
|
506
|
+
|
|
507
|
+
`;
|
|
508
|
+
//# sourceMappingURL=deliberation-view.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deliberation-view.js","sourceRoot":"","sources":["../../src/core/deliberation-view.ts"],"names":[],"mappings":"AAAA,mFAAmF;AACnF,MAAM,CAAC,MAAM,UAAU,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmXnC,CAAC;AAEF,kFAAkF;AAClF,gFAAgF;AAChF,MAAM,CAAC,MAAM,WAAW,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmIpC,CAAC"}
|
|
@@ -1,21 +1,40 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The optional
|
|
2
|
+
* The optional ## Deliberation appendix: a grilling session's design tree,
|
|
3
3
|
* stored as a nested Markdown list so it stays diffable and readable, and
|
|
4
|
-
* rendered to mermaid or
|
|
4
|
+
* rendered to text, mermaid, or a single HTML document on demand. The stored
|
|
5
|
+
* outline is the source of truth; every renderer is a view.
|
|
6
|
+
*
|
|
7
|
+
* Grammar (ADR 5):
|
|
8
|
+
*
|
|
9
|
+
* - [Q: | A: ]<text>[ [status]][ (recommended)][ em-dash <reason>]
|
|
10
|
+
*
|
|
11
|
+
* Q:/A: marks a question or an option (inferred when omitted: a node with
|
|
12
|
+
* children is a question, a leaf is an option, the top level is the root).
|
|
13
|
+
* [settled], [rejected], [open] is the state. (recommended) marks the option
|
|
14
|
+
* the agent recommended. The em-dash reason explains the node.
|
|
15
|
+
*
|
|
16
|
+
* Dependency is nesting (ADR 7): a follow-up question is a child of the node
|
|
17
|
+
* whose settlement raised it, so related questions run deeper and unrelated
|
|
18
|
+
* ones stay flat. Nothing stores a round; depth is the frontier.
|
|
5
19
|
*/
|
|
6
20
|
export type DeliberationStatus = 'settled' | 'rejected' | 'open';
|
|
21
|
+
export type DeliberationType = 'question' | 'option';
|
|
7
22
|
export interface DeliberationNode {
|
|
8
23
|
text: string;
|
|
24
|
+
type?: DeliberationType;
|
|
9
25
|
status?: DeliberationStatus;
|
|
26
|
+
recommended?: boolean;
|
|
27
|
+
reason?: string;
|
|
10
28
|
children: DeliberationNode[];
|
|
11
29
|
}
|
|
30
|
+
export declare function parseDeliberation(body: string | undefined): DeliberationNode[];
|
|
12
31
|
/**
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* Non-bullet lines are commentary and ignored, so a session can interleave
|
|
16
|
-
* prose without breaking the tree.
|
|
32
|
+
* True when the body parses to at least one node: the same predicate `tree`
|
|
33
|
+
* renders by, so a marker can never promise a tree the command refuses.
|
|
17
34
|
*/
|
|
18
|
-
export declare function
|
|
35
|
+
export declare function hasDeliberationTree(body: string | undefined): boolean;
|
|
19
36
|
export declare function renderDeliberationText(nodes: DeliberationNode[]): string;
|
|
20
37
|
export declare function renderDeliberationMermaid(nodes: DeliberationNode[]): string;
|
|
38
|
+
/** An offline HTML view; the annotated outline remains the source. */
|
|
39
|
+
export declare function renderDeliberationHtml(nodes: DeliberationNode[], title: string): string;
|
|
21
40
|
//# sourceMappingURL=deliberation.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deliberation.d.ts","sourceRoot":"","sources":["../../src/core/deliberation.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"deliberation.d.ts","sourceRoot":"","sources":["../../src/core/deliberation.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG,UAAU,GAAG,MAAM,CAAC;AACjE,MAAM,MAAM,gBAAgB,GAAG,UAAU,GAAG,QAAQ,CAAC;AAErD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,gBAAgB,CAAC;IACxB,MAAM,CAAC,EAAE,kBAAkB,CAAC;IAC5B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,gBAAgB,EAAE,CAAC;CAC9B;AA4DD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,gBAAgB,EAAE,CAsB9E;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAErE;AA6BD,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,gBAAgB,EAAE,GAAG,MAAM,CAYxE;AAkBD,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,gBAAgB,EAAE,GAAG,MAAM,CA8D3E;AAED,sEAAsE;AACtE,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,gBAAgB,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAEvF"}
|