@nanobpm/nano-workforce 0.125.0 → 0.127.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.
@@ -9,30 +9,12 @@
9
9
  "variant": "bar",
10
10
  "title": "Nano Workforce",
11
11
  "items": [
12
- {
13
- "label": "Overview",
14
- "page": "overview"
15
- },
16
- {
17
- "label": "Lineage",
18
- "page": "lineage"
19
- },
20
- {
21
- "label": "Convergence",
22
- "page": "home"
23
- },
24
- {
25
- "label": "Epics",
26
- "page": "epic"
27
- },
28
- {
29
- "label": "Feature",
30
- "page": "feature"
31
- },
32
- {
33
- "label": "Delivery Graphs",
34
- "page": "delivery-graphs"
35
- },
12
+ { "label": "Overview", "page": "overview" },
13
+ { "label": "Lineage", "page": "lineage" },
14
+ { "label": "Convergence", "page": "home" },
15
+ { "label": "Epics", "page": "epic" },
16
+ { "label": "Feature", "page": "feature" },
17
+ { "label": "Delivery Graphs", "page": "delivery-graphs" },
36
18
  {
37
19
  "label": "Tasks",
38
20
  "page": "tasks",
@@ -45,18 +27,9 @@
45
27
  "hideWhenZero": true
46
28
  }
47
29
  },
48
- {
49
- "label": "Cockpit",
50
- "page": "cockpit"
51
- },
52
- {
53
- "label": "Board",
54
- "page": "board"
55
- },
56
- {
57
- "label": "Velocity",
58
- "page": "velocity"
59
- }
30
+ { "label": "Cockpit", "page": "cockpit" },
31
+ { "label": "Board", "page": "board" },
32
+ { "label": "Velocity", "page": "velocity" }
60
33
  ],
61
34
  "sticky": true
62
35
  }
@@ -64,42 +37,30 @@
64
37
  {
65
38
  "type": "text",
66
39
  "id": "title",
67
- "props": {
68
- "text": "Tasks",
69
- "variant": "heading"
70
- }
40
+ "props": { "text": "Tasks", "variant": "heading" }
71
41
  },
72
42
  {
73
43
  "type": "text",
74
44
  "id": "subtitle",
75
45
  "props": {
76
- "text": "Open native user-task escalations awaiting a human decision — across feature runs, epics, and PR review loops. Each row parks a process on your decision; submit one and the process resumes on the same canonical path Urban's task inbox uses. Rows disappear once completed (here, via the inbox, or out-of-band).",
46
+ "text": "Every open native user-task escalation awaiting a human decision — feature runs, epics, PR review/merge loops, conformance reviews, and delivery-graph human/escalation gates in one list. The \"Type\" column tells them apart; open a row to complete it via the process's own deployed form, on the same canonical path Urban's task inbox uses. This list is exactly the set the nav badge counts, so a badge always maps to a visible, completable row. Rows disappear once completed (here, via the inbox, or out-of-band).",
77
47
  "variant": "sub"
78
48
  }
79
49
  },
80
50
  {
81
51
  "type": "dataGrid",
82
- "id": "feature-escalations",
52
+ "id": "user-tasks",
83
53
  "props": {
84
- "title": "Feature escalations",
54
+ "title": "Open tasks",
85
55
  "data": {
86
56
  "kind": "datasource",
87
57
  "source": "app",
88
58
  "table": "user_tasks",
89
- "filter": [
90
- {
91
- "field": "element_id",
92
- "in": [
93
- "feature-escalation"
94
- ]
95
- }
96
- ],
97
- "orderBy": {
98
- "field": "updated_at",
99
- "dir": "desc"
100
- }
59
+ "filter": [],
60
+ "orderBy": { "field": "updated_at", "dir": "desc" }
101
61
  },
102
62
  "columns": [
63
+ { "field": "kind_label", "header": "Type" },
103
64
  {
104
65
  "field": "subject_title",
105
66
  "template": "{{subject_title}}",
@@ -108,518 +69,27 @@
108
69
  "truncate": true,
109
70
  "linkField": "subject_url"
110
71
  },
111
- {
112
- "field": "subject_url",
113
- "header": "Issue"
114
- },
72
+ { "field": "subject_url", "header": "Link" },
115
73
  {
116
74
  "field": "process_key",
117
75
  "header": "Process",
118
- "link": {
119
- "kind": "processExplorer",
120
- "keyField": "process_key"
121
- }
76
+ "link": { "kind": "processExplorer", "keyField": "process_key" }
122
77
  },
123
- {
124
- "field": "updated_at",
125
- "header": "Updated",
126
- "format": "datetime"
127
- }
78
+ { "field": "updated_at", "header": "Updated", "format": "datetime" }
128
79
  ],
129
80
  "rowKey": "user_task_key",
130
81
  "detail": {
131
82
  "linkField": "subject_url",
132
83
  "fields": [
133
- {
134
- "field": "question",
135
- "label": "Escalation question"
136
- }
84
+ { "field": "question", "label": "Decision context" }
137
85
  ],
138
- "form": {
139
- "showWhenField": "user_task_key",
140
- "title": "Answer escalation",
141
- "promptField": "question",
142
- "submitLabel": "Submit decision",
143
- "fields": [
144
- {
145
- "inputKey": "resolution",
146
- "type": "select",
147
- "inputLabel": "Resolution",
148
- "options": [
149
- { "value": "answer", "label": "Answer — re-dispatch the task with this guidance" },
150
- { "value": "abandon", "label": "Abandon — give up on this task" }
151
- ]
152
- },
153
- {
154
- "inputKey": "answer",
155
- "type": "textarea",
156
- "inputLabel": "Answer / guidance for the implementation agent",
157
- "conditional": {
158
- "hide": "=resolution != \"answer\""
159
- }
160
- }
161
- ],
162
- "action": {
163
- "path": "/app/api/actions/complete-user-task",
164
- "successLabel": "Decision submitted — the process will continue",
165
- "body": {
166
- "userTaskKey": "{{row.user_task_key}}",
167
- "variables": "{{form}}"
168
- }
169
- }
170
- }
171
- },
172
- "refreshMs": 5000
173
- }
174
- },
175
- {
176
- "type": "dataGrid",
177
- "id": "plan-reviews",
178
- "props": {
179
- "title": "Plan-review decisions",
180
- "data": {
181
- "kind": "datasource",
182
- "source": "app",
183
- "table": "user_tasks",
184
- "filter": [
185
- {
186
- "field": "element_id",
187
- "in": [
188
- "plan-review-decision"
189
- ]
190
- }
191
- ],
192
- "orderBy": {
193
- "field": "updated_at",
194
- "dir": "desc"
195
- }
196
- },
197
- "columns": [
198
- {
199
- "field": "subject_title",
200
- "template": "{{subject_title}}",
201
- "header": "Item",
202
- "subtitleField": "subject_key",
203
- "truncate": true,
204
- "linkField": "subject_url"
205
- },
206
- {
207
- "field": "question",
208
- "header": "Findings"
209
- },
210
- {
211
- "field": "subject_url",
212
- "header": "Issue"
213
- },
214
- {
215
- "field": "process_key",
216
- "header": "Process",
217
- "link": {
218
- "kind": "processExplorer",
219
- "keyField": "process_key"
220
- }
221
- },
222
- {
223
- "field": "updated_at",
224
- "header": "Updated",
225
- "format": "datetime"
226
- }
227
- ],
228
- "rowKey": "user_task_key",
229
- "detail": {
230
- "linkField": "subject_url",
231
- "fields": [
232
- {
233
- "field": "question",
234
- "label": "Review findings"
235
- }
236
- ],
237
- "form": {
238
- "showWhenField": "user_task_key",
239
- "title": "Review the plan",
240
- "promptField": "question",
241
- "submitLabel": "Submit decision",
242
- "fields": [
243
- {
244
- "inputKey": "directive",
245
- "type": "select",
246
- "inputLabel": "Directive",
247
- "options": [
248
- { "value": "proceed", "label": "Proceed — dispatch the current plan as-is" },
249
- { "value": "revise", "label": "Revise — send the plan back to the planner" }
250
- ]
251
- },
252
- {
253
- "inputKey": "notes",
254
- "type": "textarea",
255
- "inputLabel": "Revision guidance for the planner",
256
- "conditional": {
257
- "hide": "=directive != \"revise\""
258
- }
259
- }
260
- ],
261
- "action": {
262
- "path": "/app/api/actions/complete-user-task",
263
- "successLabel": "Decision recorded",
264
- "body": {
265
- "userTaskKey": "{{row.user_task_key}}",
266
- "variables": "{{form}}"
267
- }
268
- }
269
- }
270
- },
271
- "refreshMs": 5000
272
- }
273
- },
274
- {
275
- "type": "dataGrid",
276
- "id": "trial-merges",
277
- "props": {
278
- "title": "Trial-merge decisions",
279
- "data": {
280
- "kind": "datasource",
281
- "source": "app",
282
- "table": "user_tasks",
283
- "filter": [
284
- {
285
- "field": "element_id",
286
- "in": [
287
- "trial-merge-decision"
288
- ]
289
- }
290
- ],
291
- "orderBy": {
292
- "field": "updated_at",
293
- "dir": "desc"
294
- }
295
- },
296
- "columns": [
297
- {
298
- "field": "subject_title",
299
- "template": "{{subject_title}}",
300
- "header": "Item",
301
- "subtitleField": "subject_key",
302
- "truncate": true,
303
- "linkField": "subject_url"
304
- },
305
- {
306
- "field": "question",
307
- "header": "Trial merge"
308
- },
309
- {
310
- "field": "subject_url",
311
- "header": "Issue"
312
- },
313
- {
314
- "field": "process_key",
315
- "header": "Process",
316
- "link": {
317
- "kind": "processExplorer",
318
- "keyField": "process_key"
319
- }
320
- },
321
- {
322
- "field": "updated_at",
323
- "header": "Updated",
324
- "format": "datetime"
325
- }
326
- ],
327
- "rowKey": "user_task_key",
328
- "detail": {
329
- "linkField": "subject_url",
330
- "fields": [
331
- {
332
- "field": "question",
333
- "label": "Trial merge"
334
- }
335
- ],
336
- "form": {
337
- "showWhenField": "user_task_key",
338
- "title": "Trial-merge decision",
339
- "promptField": "question",
340
- "submitLabel": "Submit decision",
341
- "fields": [
342
- {
343
- "inputKey": "action",
344
- "type": "select",
345
- "inputLabel": "Action",
346
- "options": [
347
- { "value": "proceed", "label": "Proceed — accept the red trial merge and continue" },
348
- { "value": "rebase", "label": "Rebase — re-run the trial merge" },
349
- { "value": "abandon", "label": "Abandon — stop and finalize the plan" }
350
- ]
351
- },
352
- {
353
- "inputKey": "notes",
354
- "type": "textarea",
355
- "inputLabel": "Notes"
356
- }
357
- ],
358
- "action": {
359
- "path": "/app/api/actions/complete-user-task",
360
- "successLabel": "Decision recorded",
361
- "body": {
362
- "userTaskKey": "{{row.user_task_key}}",
363
- "variables": "{{form}}"
364
- }
365
- }
366
- }
367
- },
368
- "refreshMs": 5000
369
- }
370
- },
371
- {
372
- "type": "dataGrid",
373
- "id": "pr-reviews",
374
- "props": {
375
- "title": "PR escalations",
376
- "data": {
377
- "kind": "datasource",
378
- "source": "app",
379
- "table": "user_tasks",
380
- "filter": [
381
- {
382
- "field": "element_id",
383
- "in": [
384
- "wait-answer",
385
- "wait-merge-answer"
386
- ]
387
- }
388
- ],
389
- "orderBy": {
390
- "field": "updated_at",
391
- "dir": "desc"
392
- }
393
- },
394
- "columns": [
395
- {
396
- "field": "subject_title",
397
- "template": "{{subject_title}}",
398
- "header": "Item",
399
- "subtitleField": "subject_key",
400
- "truncate": true,
401
- "linkField": "subject_url"
402
- },
403
- {
404
- "field": "kind_label",
405
- "header": "Stage"
406
- },
407
- {
408
- "field": "subject_url",
409
- "header": "PR link"
410
- },
411
- {
412
- "field": "process_key",
413
- "header": "Process",
414
- "link": {
415
- "kind": "processExplorer",
416
- "keyField": "process_key"
417
- }
418
- },
419
- {
420
- "field": "updated_at",
421
- "header": "Updated",
422
- "format": "datetime"
423
- }
424
- ],
425
- "rowKey": "user_task_key",
426
- "detail": {
427
- "linkField": "subject_url",
428
- "fields": [
429
- {
430
- "field": "question",
431
- "label": "Escalation question"
432
- }
433
- ],
434
- "form": {
435
- "showWhenField": "user_task_key",
436
- "title": "Answer escalation",
437
- "promptField": "question",
438
- "inputKey": "answer",
439
- "inputLabel": "Your answer",
440
- "submitLabel": "Answer & resume",
441
- "action": {
442
- "path": "/app/api/actions/complete-user-task",
443
- "successLabel": "Answered — the loop will resume",
444
- "body": {
445
- "userTaskKey": "{{row.user_task_key}}",
446
- "variables": {
447
- "answer": "{{form.answer}}"
448
- }
449
- }
450
- }
451
- }
452
- },
453
- "refreshMs": 5000
454
- }
455
- },
456
- {
457
- "type": "dataGrid",
458
- "id": "blocked-runs",
459
- "props": {
460
- "title": "Blocked feature runs",
461
- "data": {
462
- "kind": "datasource",
463
- "source": "app",
464
- "table": "user_tasks",
465
- "filter": [
466
- {
467
- "field": "element_id",
468
- "in": [
469
- "feature-blocked"
470
- ]
471
- }
472
- ],
473
- "orderBy": {
474
- "field": "updated_at",
475
- "dir": "desc"
476
- }
477
- },
478
- "columns": [
479
- {
480
- "field": "subject_title",
481
- "template": "{{subject_title}}",
482
- "header": "Item",
483
- "subtitleField": "subject_key",
484
- "truncate": true,
485
- "linkField": "subject_url"
486
- },
487
- {
488
- "field": "question",
489
- "header": "Disposition"
490
- },
491
- {
492
- "field": "subject_url",
493
- "header": "Issue"
494
- },
495
- {
496
- "field": "process_key",
497
- "header": "Process",
498
- "link": {
499
- "kind": "processExplorer",
500
- "keyField": "process_key"
501
- }
502
- },
503
- {
504
- "field": "updated_at",
505
- "header": "Updated",
506
- "format": "datetime"
507
- }
508
- ],
509
- "rowKey": "user_task_key",
510
- "detail": {
511
- "linkField": "subject_url",
512
- "fields": [
513
- {
514
- "field": "question",
515
- "label": "Disposition"
516
- }
517
- ],
518
- "form": {
519
- "showWhenField": "user_task_key",
520
- "title": "Acknowledge blocked run",
521
- "promptField": "question",
522
- "inputKey": "note",
523
- "inputLabel": "Disposition note (what you did / why)",
524
- "submitLabel": "Acknowledge & close",
525
- "action": {
526
- "path": "/app/api/actions/complete-user-task",
527
- "successLabel": "Acknowledged — the run will close",
528
- "body": {
529
- "userTaskKey": "{{row.user_task_key}}",
530
- "variables": {
531
- "note": "{{form.note}}"
532
- }
533
- }
534
- }
535
- }
536
- },
537
- "refreshMs": 5000
538
- }
539
- },
540
- {
541
- "type": "dataGrid",
542
- "id": "conformance-reviews",
543
- "props": {
544
- "title": "Conformance reviews",
545
- "data": {
546
- "kind": "datasource",
547
- "source": "app",
548
- "table": "user_tasks",
549
- "filter": [
550
- {
551
- "field": "element_id",
552
- "in": [
553
- "conformance-escalation"
554
- ]
555
- }
556
- ],
557
- "orderBy": {
558
- "field": "updated_at",
559
- "dir": "desc"
560
- }
561
- },
562
- "columns": [
563
- {
564
- "field": "subject_title",
565
- "template": "{{subject_title}}",
566
- "header": "Epic",
567
- "subtitleField": "subject_key",
568
- "truncate": true,
569
- "linkField": "subject_url"
570
- },
571
- {
572
- "field": "question",
573
- "header": "Findings"
574
- },
575
- {
576
- "field": "subject_url",
577
- "header": "Issue"
578
- },
579
- {
580
- "field": "process_key",
581
- "header": "Process",
582
- "link": {
583
- "kind": "processExplorer",
584
- "keyField": "process_key"
585
- }
586
- },
587
- {
588
- "field": "updated_at",
589
- "header": "Updated",
590
- "format": "datetime"
591
- }
592
- ],
593
- "rowKey": "user_task_key",
594
- "detail": {
595
- "linkField": "subject_url",
596
- "fields": [
597
- {
598
- "field": "question",
599
- "label": "Findings"
600
- }
601
- ],
602
- "form": {
603
- "showWhenField": "user_task_key",
604
- "title": "Acknowledge conformance review",
605
- "promptField": "question",
606
- "inputKey": "note",
607
- "inputLabel": "Disposition note (what you decided / follow-up)",
608
- "submitLabel": "Acknowledge & close",
609
- "action": {
610
- "path": "/app/api/actions/complete-user-task",
611
- "successLabel": "Acknowledged — the review will close",
612
- "body": {
613
- "userTaskKey": "{{row.user_task_key}}",
614
- "variables": {
615
- "note": "{{form.note}}"
616
- }
617
- }
618
- }
86
+ "engineForm": {
87
+ "formKeyField": "form_key",
88
+ "userTaskKeyField": "user_task_key"
619
89
  }
620
90
  },
621
91
  "refreshMs": 5000
622
92
  }
623
93
  }
624
94
  ]
625
- }
95
+ }
@@ -41,6 +41,17 @@ test("#441: mount.js wires the preview+stage door", () => {
41
41
  assert(previewUrl.endsWith("actions/delivery-graph/preview"), `previewUrl default "${previewUrl}" must hit the previewDeliveryGraph door`);
42
42
  });
43
43
 
44
+ test("DI preview: mount.js wires the proposal-bpmn door (base-relative) and hands the XML to the host explorer", () => {
45
+ const url = defaultUrl("proposalBpmnUrl");
46
+ assert(url.endsWith("actions/delivery-graph/proposal-bpmn"), `proposalBpmnUrl default "${url}" must hit the previewProposalBpmn door`);
47
+ assert(!url.startsWith("/"), `default proposalBpmnUrl "${url}" must be base-relative (App-View #279 resolution class)`);
48
+ // The staged banner exposes a Preview-DI affordance, and clicking it hands the compiled XML to the
49
+ // host console over the nano-navigate bridge with the definitionPreview target (never a dispatch).
50
+ assert(/data-preview-di=/.test(MOUNT_JS), "mount.js must render a Preview-DI affordance carrying the proposal digest");
51
+ assert(/target:\s*"definitionPreview"/.test(MOUNT_JS), "mount.js must post nano-navigate to the definitionPreview target");
52
+ assert(/params:\s*\{\s*xml:/.test(MOUNT_JS), "mount.js must carry the compiled BPMN xml in the bridge message");
53
+ });
54
+
44
55
  // The #279 App-View resolution class: a default endpoint must be BASE-RELATIVE (no leading slash) so
45
56
  // it resolves under the console app-view base, not the console origin root (which 404s the door).
46
57
  test("#441/#279: default previewUrl is base-relative (no leading slash)", () => {