jev-devtools 0.5.1 → 0.5.2
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 +49 -27
- package/lib/flow/index.d.ts +32 -4
- package/lib/flow/index.js +133 -55
- package/lib/server/flows.js +14 -3
- package/lib/server/recorder.js +9 -3
- package/lib/src/FlowOverview.js +50 -59
- package/lib/src/JevDevtools.js +31 -5
- package/lib/src/TraceDiagram.js +1 -1
- package/lib/src/flow-protocol.d.ts +4 -0
- package/lib/src/inspector-styles.js +1 -1
- package/lib/src/inspector.css +154 -17
- package/lib/src/useDiagramViewport.js +1 -1
- package/package.json +1 -1
- package/skills/setup-jev-devtools/SKILL.md +9 -9
- package/skills/setup-jev-devtools/references/flows.md +188 -111
package/lib/src/inspector.css
CHANGED
|
@@ -64,6 +64,21 @@
|
|
|
64
64
|
padding: 8px;
|
|
65
65
|
width: 100%;
|
|
66
66
|
}
|
|
67
|
+
.jev-devtools select {
|
|
68
|
+
appearance: none;
|
|
69
|
+
padding-right: 34px;
|
|
70
|
+
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16' fill='none'%3E%3Cpath d='m4 6 4 4 4-4' stroke='%23bcadbf' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
|
|
71
|
+
background-repeat: no-repeat;
|
|
72
|
+
background-position: right 10px center;
|
|
73
|
+
background-size: 16px 16px;
|
|
74
|
+
}
|
|
75
|
+
@media (forced-colors: active) {
|
|
76
|
+
.jev-devtools select {
|
|
77
|
+
/* Let the system draw a visible arrow in high-contrast themes. */
|
|
78
|
+
appearance: auto;
|
|
79
|
+
background-image: none;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
67
82
|
.jev-devtools button:hover:not(:disabled) {
|
|
68
83
|
border-color: #e551ba;
|
|
69
84
|
}
|
|
@@ -149,13 +164,17 @@
|
|
|
149
164
|
min-width: 0;
|
|
150
165
|
}
|
|
151
166
|
.jev-devtools .list-filters select {
|
|
152
|
-
width:
|
|
167
|
+
width: 100px;
|
|
168
|
+
flex-shrink: 0;
|
|
153
169
|
font-size: 11px;
|
|
154
170
|
}
|
|
155
171
|
.jev-devtools .request-items {
|
|
156
172
|
overflow: auto;
|
|
157
173
|
flex: 1;
|
|
158
174
|
}
|
|
175
|
+
.jev-devtools .request-navigation {
|
|
176
|
+
display: none;
|
|
177
|
+
}
|
|
159
178
|
.jev-devtools .request-row {
|
|
160
179
|
display: flex;
|
|
161
180
|
align-items: center;
|
|
@@ -495,6 +514,63 @@
|
|
|
495
514
|
min-width: 240px;
|
|
496
515
|
padding: 8px 12px;
|
|
497
516
|
}
|
|
517
|
+
/* Requests use separate list/detail screens so history cannot collapse into
|
|
518
|
+
the fixed-height strip used by flow runs. CSS keeps desktop split panes. */
|
|
519
|
+
.jev-devtools .jev-inspector[data-mobile-view="list"] > .request-list {
|
|
520
|
+
flex: 1;
|
|
521
|
+
}
|
|
522
|
+
.jev-devtools .jev-inspector[data-mobile-view="list"] > .request-detail,
|
|
523
|
+
.jev-devtools .jev-inspector[data-mobile-view="detail"] .list-filters,
|
|
524
|
+
.jev-devtools .jev-inspector[data-mobile-view="detail"] .request-items {
|
|
525
|
+
display: none;
|
|
526
|
+
}
|
|
527
|
+
.jev-devtools .jev-inspector[data-mobile-view="detail"] > .request-list {
|
|
528
|
+
flex: none;
|
|
529
|
+
}
|
|
530
|
+
.jev-devtools .jev-inspector[data-mobile-view="detail"] .request-navigation {
|
|
531
|
+
display: flex;
|
|
532
|
+
align-items: center;
|
|
533
|
+
justify-content: space-between;
|
|
534
|
+
min-height: 44px;
|
|
535
|
+
margin: 6px 12px;
|
|
536
|
+
text-align: left;
|
|
537
|
+
}
|
|
538
|
+
.jev-devtools .jev-inspector[data-mobile-view] .request-items {
|
|
539
|
+
flex-direction: column;
|
|
540
|
+
}
|
|
541
|
+
.jev-devtools .jev-inspector[data-mobile-view] .request-row {
|
|
542
|
+
flex: none;
|
|
543
|
+
min-width: 0;
|
|
544
|
+
min-height: 60px;
|
|
545
|
+
padding: 12px;
|
|
546
|
+
}
|
|
547
|
+
.jev-devtools
|
|
548
|
+
.jev-inspector[data-mobile-view]
|
|
549
|
+
.request-row
|
|
550
|
+
> span:nth-child(2) {
|
|
551
|
+
min-width: 0;
|
|
552
|
+
overflow-wrap: anywhere;
|
|
553
|
+
}
|
|
554
|
+
.jev-devtools .jev-inspector[data-mobile-view] > .request-detail {
|
|
555
|
+
overflow: auto;
|
|
556
|
+
}
|
|
557
|
+
.jev-devtools
|
|
558
|
+
.jev-inspector[data-mobile-view]
|
|
559
|
+
> .request-detail
|
|
560
|
+
> :is(.detail-header, .detail-meta, .detail-tabs) {
|
|
561
|
+
flex: none;
|
|
562
|
+
}
|
|
563
|
+
.jev-devtools
|
|
564
|
+
.jev-inspector[data-mobile-view]
|
|
565
|
+
> .request-detail
|
|
566
|
+
> .detail-body-flow {
|
|
567
|
+
/* Let metadata scroll above the diagram instead of clipping its toolbar. */
|
|
568
|
+
flex: 1 0 auto;
|
|
569
|
+
min-height: min-content;
|
|
570
|
+
}
|
|
571
|
+
.jev-devtools .flow-details-bar > span {
|
|
572
|
+
display: none;
|
|
573
|
+
}
|
|
498
574
|
.jev-devtools .detail-header {
|
|
499
575
|
padding: 12px;
|
|
500
576
|
}
|
|
@@ -503,6 +579,10 @@
|
|
|
503
579
|
padding-left: 12px;
|
|
504
580
|
padding-right: 12px;
|
|
505
581
|
}
|
|
582
|
+
.jev-devtools .detail-tabs {
|
|
583
|
+
overflow-x: auto;
|
|
584
|
+
flex-shrink: 0;
|
|
585
|
+
}
|
|
506
586
|
.jev-devtools .detail-body {
|
|
507
587
|
padding: 12px;
|
|
508
588
|
}
|
|
@@ -668,14 +748,16 @@
|
|
|
668
748
|
padding: 12px 16px;
|
|
669
749
|
flex-wrap: wrap;
|
|
670
750
|
}
|
|
671
|
-
.jev-devtools .lab-flow-toolbar label
|
|
751
|
+
.jev-devtools .lab-flow-toolbar label,
|
|
752
|
+
.jev-devtools .flow-step-select {
|
|
672
753
|
display: flex;
|
|
673
754
|
gap: 10px;
|
|
674
755
|
align-items: center;
|
|
675
756
|
font-size: 11px;
|
|
676
757
|
min-width: 0;
|
|
677
758
|
}
|
|
678
|
-
.jev-devtools .lab-flow-toolbar select
|
|
759
|
+
.jev-devtools .lab-flow-toolbar select,
|
|
760
|
+
.jev-devtools .flow-step-select select {
|
|
679
761
|
width: auto;
|
|
680
762
|
max-width: 240px;
|
|
681
763
|
font-size: 11px;
|
|
@@ -685,10 +767,12 @@
|
|
|
685
767
|
gap: 8px;
|
|
686
768
|
align-items: center;
|
|
687
769
|
}
|
|
688
|
-
.jev-devtools .lab-flow-toolbar button
|
|
770
|
+
.jev-devtools .lab-flow-toolbar button,
|
|
771
|
+
.jev-devtools .flow-canvas-controls button {
|
|
689
772
|
font-size: 11px;
|
|
690
773
|
}
|
|
691
|
-
.jev-devtools .lab-flow-toolbar output
|
|
774
|
+
.jev-devtools .lab-flow-toolbar output,
|
|
775
|
+
.jev-devtools .flow-canvas-controls output {
|
|
692
776
|
font-size: 11px;
|
|
693
777
|
min-width: 35px;
|
|
694
778
|
text-align: center;
|
|
@@ -722,10 +806,9 @@
|
|
|
722
806
|
flex-shrink: 0;
|
|
723
807
|
padding: 8px 16px;
|
|
724
808
|
margin: 0;
|
|
725
|
-
}
|
|
726
|
-
.jev-devtools .lab-gesture-hint {
|
|
727
|
-
display: block;
|
|
728
809
|
color: #c6a7bd;
|
|
810
|
+
font-size: 11px;
|
|
811
|
+
line-height: 1.6;
|
|
729
812
|
}
|
|
730
813
|
.jev-devtools .lab-flow-canvas {
|
|
731
814
|
position: absolute;
|
|
@@ -1144,14 +1227,20 @@
|
|
|
1144
1227
|
min-width: 0;
|
|
1145
1228
|
overflow: hidden;
|
|
1146
1229
|
}
|
|
1147
|
-
:where(.jev-devtools)
|
|
1148
|
-
|
|
1230
|
+
:where(.jev-devtools)
|
|
1231
|
+
.flow-overview-stack:not(.flow-inline-overview)
|
|
1232
|
+
> .whole-flow {
|
|
1233
|
+
/* Short drawers must scroll metadata instead of clipping the canvas controls. */
|
|
1234
|
+
overflow: auto;
|
|
1235
|
+
}
|
|
1236
|
+
:where(.jev-devtools) .whole-flow > .detail-header {
|
|
1237
|
+
flex-wrap: wrap;
|
|
1149
1238
|
flex-shrink: 0;
|
|
1150
1239
|
}
|
|
1151
1240
|
:where(.jev-devtools) .flow-workspace {
|
|
1152
1241
|
display: flex;
|
|
1153
1242
|
flex-direction: column;
|
|
1154
|
-
flex: 1;
|
|
1243
|
+
flex: 1 0 auto;
|
|
1155
1244
|
min-height: 0;
|
|
1156
1245
|
overflow: hidden;
|
|
1157
1246
|
}
|
|
@@ -1207,8 +1296,11 @@
|
|
|
1207
1296
|
outline-offset: -1px;
|
|
1208
1297
|
}
|
|
1209
1298
|
:where(.jev-devtools) .flow-overview-viewport {
|
|
1299
|
+
background-color: #08060a;
|
|
1210
1300
|
position: relative;
|
|
1211
|
-
|
|
1301
|
+
/* The panel's grid row reserves its actual height, including wrapped buttons. */
|
|
1302
|
+
display: grid;
|
|
1303
|
+
min-height: min-content;
|
|
1212
1304
|
flex: 1 1 0;
|
|
1213
1305
|
overflow: hidden;
|
|
1214
1306
|
touch-action: none;
|
|
@@ -1220,11 +1312,31 @@
|
|
|
1220
1312
|
);
|
|
1221
1313
|
background-size: 20px 20px;
|
|
1222
1314
|
}
|
|
1315
|
+
.jev-devtools .flow-canvas-controls {
|
|
1316
|
+
align-self: start;
|
|
1317
|
+
justify-self: end;
|
|
1318
|
+
margin: 12px;
|
|
1319
|
+
z-index: 1;
|
|
1320
|
+
display: flex;
|
|
1321
|
+
flex-wrap: wrap;
|
|
1322
|
+
align-items: center;
|
|
1323
|
+
gap: 8px;
|
|
1324
|
+
max-width: calc(100% - 24px);
|
|
1325
|
+
padding: 8px;
|
|
1326
|
+
border: 1px solid #3b303d;
|
|
1327
|
+
border-radius: 10px;
|
|
1328
|
+
background: #17121b;
|
|
1329
|
+
box-shadow: 0 4px 16px #0006;
|
|
1330
|
+
cursor: default;
|
|
1331
|
+
}
|
|
1223
1332
|
:where(.jev-devtools) .flow-overview-viewport[data-panning] {
|
|
1224
1333
|
cursor: grabbing;
|
|
1225
1334
|
}
|
|
1226
1335
|
:where(.jev-devtools) .flow-overview-canvas {
|
|
1227
1336
|
position: absolute;
|
|
1337
|
+
/* Keep camera coordinates at the viewport origin when the overlay uses grid. */
|
|
1338
|
+
top: 0;
|
|
1339
|
+
left: 0;
|
|
1228
1340
|
transform-origin: 0 0;
|
|
1229
1341
|
}
|
|
1230
1342
|
:where(.jev-devtools) .flow-connections {
|
|
@@ -1658,14 +1770,22 @@
|
|
|
1658
1770
|
margin-bottom: 5px;
|
|
1659
1771
|
}
|
|
1660
1772
|
:where(.jev-devtools) .flow-condition-rule code {
|
|
1661
|
-
display: block;
|
|
1662
1773
|
white-space: pre-wrap;
|
|
1663
|
-
overflow-wrap: anywhere;
|
|
1664
1774
|
font:
|
|
1665
1775
|
12px/1.6 ui-monospace,
|
|
1666
1776
|
monospace;
|
|
1667
1777
|
color: #f2d7eb;
|
|
1668
1778
|
}
|
|
1779
|
+
/* Bound card previews so long captured literals cannot push warnings off-canvas.
|
|
1780
|
+
The complete captured rule remains available in selected-step details. */
|
|
1781
|
+
:where(.jev-devtools) .flow-condition-rule code,
|
|
1782
|
+
:where(.jev-devtools) .flow-map-progress > code {
|
|
1783
|
+
display: -webkit-box;
|
|
1784
|
+
-webkit-box-orient: vertical;
|
|
1785
|
+
-webkit-line-clamp: 4;
|
|
1786
|
+
overflow: hidden;
|
|
1787
|
+
overflow-wrap: anywhere;
|
|
1788
|
+
}
|
|
1669
1789
|
|
|
1670
1790
|
:where(.jev-devtools) .flow-condition-incoming {
|
|
1671
1791
|
display: block;
|
|
@@ -1870,15 +1990,32 @@
|
|
|
1870
1990
|
right: -76px;
|
|
1871
1991
|
}
|
|
1872
1992
|
.jev-devtools .flow-run-summary {
|
|
1993
|
+
max-width: 100%;
|
|
1994
|
+
margin-left: auto;
|
|
1873
1995
|
text-align: right;
|
|
1874
1996
|
}
|
|
1997
|
+
.jev-devtools .flow-run-controls {
|
|
1998
|
+
display: flex;
|
|
1999
|
+
flex-wrap: wrap;
|
|
2000
|
+
align-items: center;
|
|
2001
|
+
justify-content: flex-end;
|
|
2002
|
+
gap: 10px;
|
|
2003
|
+
margin-top: 6px;
|
|
2004
|
+
}
|
|
2005
|
+
.jev-devtools .flow-run-controls .flow-step-select {
|
|
2006
|
+
max-width: 100%;
|
|
2007
|
+
}
|
|
2008
|
+
.jev-devtools .flow-step-select select {
|
|
2009
|
+
min-width: 0;
|
|
2010
|
+
}
|
|
1875
2011
|
.jev-devtools .flow-fixture-button {
|
|
1876
|
-
|
|
1877
|
-
margin: 6px 0 0 auto;
|
|
2012
|
+
flex-shrink: 0;
|
|
1878
2013
|
/* Keep the header still when the shorter confirmation replaces the label. */
|
|
1879
2014
|
min-width: 96px;
|
|
1880
2015
|
font-size: 11px;
|
|
1881
|
-
transition:
|
|
2016
|
+
transition:
|
|
2017
|
+
background-color 160ms ease,
|
|
2018
|
+
border-color 160ms ease;
|
|
1882
2019
|
}
|
|
1883
2020
|
.jev-devtools .flow-fixture-button[data-copied] {
|
|
1884
2021
|
border-color: #e551ba;
|
|
@@ -96,7 +96,7 @@ export function useDiagramViewport(width, height, scene, origin = { x: 0, y: 0 }
|
|
|
96
96
|
const down = (event) => {
|
|
97
97
|
if (event.button !== 0 ||
|
|
98
98
|
pointers.size >= 2 ||
|
|
99
|
-
event.target.closest("button, input, select, textarea, a, summary, [data-diagram-scroll]"))
|
|
99
|
+
event.target.closest("button, input, select, textarea, a, summary, [data-diagram-scroll], [data-diagram-controls]"))
|
|
100
100
|
return;
|
|
101
101
|
event.preventDefault();
|
|
102
102
|
el.focus({ preventScroll: true });
|
package/package.json
CHANGED
|
@@ -19,15 +19,15 @@ Inspect the app's package manager/lockfile, React and Node versions, root compon
|
|
|
19
19
|
|
|
20
20
|
Install `jev-devtools` using the app's existing package manager (npm: `npm install jev-devtools @typesafe-ai/sdk`; pnpm: `pnpm add jev-devtools @typesafe-ai/sdk`; Yarn: `yarn add jev-devtools @typesafe-ai/sdk`; Bun: `bun add jev-devtools @typesafe-ai/sdk`). `@typesafe-ai/sdk` is a peer dependency: keep the app's existing SDK version when it satisfies the peer range. Install in the workspace(s) that actually import it. It is a regular dependency when application modules import it, even though capture/display are development-only. Do not replace the app's framework or upgrade unrelated dependencies to force compatibility.
|
|
21
21
|
|
|
22
|
-
### Consumer compatibility (0.5.
|
|
22
|
+
### Consumer compatibility (0.5.2)
|
|
23
23
|
|
|
24
|
-
| Requirement
|
|
25
|
-
|
|
|
26
|
-
| Node.js
|
|
27
|
-
| React / React DOM | Matching 18.x or 19.x versions; both remain required peers even for server-only installations.
|
|
28
|
-
| TypeSafe SDK
|
|
29
|
-
| TypeScript
|
|
30
|
-
| Modules
|
|
24
|
+
| Requirement | Contract |
|
|
25
|
+
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
|
|
26
|
+
| Node.js | 22.12+ for the adapter and flow execution; Edge runtimes are unsupported. |
|
|
27
|
+
| React / React DOM | Matching 18.x or 19.x versions; both remain required peers even for server-only installations. |
|
|
28
|
+
| TypeSafe SDK | `>=0.7.0 <0.8.0`; verified with 0.7.0. |
|
|
29
|
+
| TypeScript | 5.4+ for the public declarations; verified with 5.4.5. The flow API uses built-in `NoInfer`, which 5.3.3 cannot resolve. |
|
|
30
|
+
| Modules | ESM imports with export-aware `Bundler` or `NodeNext` resolution and a matching module setting. There is no CommonJS `require` entry. |
|
|
31
31
|
|
|
32
32
|
Use React types matching the app's React major, Node types compatible with its runtime/compiler, and DOM types for Web `Request`/`Response` APIs. The packed declarations passed strict checks without `skipLibCheck` using TypeScript 5.4.5, SDK 0.7.0, React 19.3.1, `@types/react` 19.3.0, and `@types/node` 22.10.2. Frameworks and newer type packages can require a newer compiler; preserve compatible app dependencies rather than downgrading to this verification baseline.
|
|
33
33
|
|
|
@@ -35,7 +35,7 @@ Import application APIs from `jev-devtools` (React and browser-safe capture help
|
|
|
35
35
|
|
|
36
36
|
## Optional connected flow API
|
|
37
37
|
|
|
38
|
-
When asked to build or inspect connected calls, read [references/flows.md](references/flows.md) after the framework recipe. For 0.5.
|
|
38
|
+
When asked to build or inspect connected calls, read [references/flows.md](references/flows.md) after the framework recipe. For 0.5.2 it covers requests, server function tasks, runtime request factories, parallel checks, terminal branches, returning conditionals, bounded collections, stateful loops, captured-answer replay, and fixture comparison. It includes sample verification, scope/execution rules, and privacy limits. For an older installation, use its bundled recipe and declarations rather than assuming these operations exist. Preserve existing application policies; do not convert unrelated calls just to install the drawer. Flow execution is server-only and continues even with the inspector disabled.
|
|
39
39
|
|
|
40
40
|
## Integration invariants
|
|
41
41
|
|