@netnodeag/kraftwerk 0.3.0 → 0.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.
Files changed (57) hide show
  1. package/README.md +7 -5
  2. package/dist/cli/ui.js +36 -32
  3. package/dist/inspector/context.d.ts +5 -0
  4. package/dist/inspector/context.js +19 -0
  5. package/dist/inspector/runner.d.ts +13 -0
  6. package/dist/inspector/runner.js +66 -0
  7. package/dist/inspector/runs.d.ts +57 -0
  8. package/dist/inspector/runs.js +240 -0
  9. package/dist/inspector/server.d.ts +8 -0
  10. package/dist/inspector/server.js +186 -0
  11. package/dist/inspector/workflows.d.ts +45 -0
  12. package/dist/inspector/workflows.js +186 -0
  13. package/inspector/dist/assets/ibm-plex-mono-latin-400-normal-CvHOgSBP.woff +0 -0
  14. package/inspector/dist/assets/ibm-plex-mono-latin-400-normal-DMJ8VG8y.woff2 +0 -0
  15. package/inspector/dist/assets/ibm-plex-mono-latin-500-normal-CB9ihrfo.woff +0 -0
  16. package/inspector/dist/assets/ibm-plex-mono-latin-500-normal-DSY6xOcd.woff2 +0 -0
  17. package/inspector/dist/assets/ibm-plex-mono-latin-600-normal-BgSNZQsw.woff2 +0 -0
  18. package/inspector/dist/assets/ibm-plex-mono-latin-600-normal-DWFSQ4vo.woff +0 -0
  19. package/inspector/dist/assets/ibm-plex-mono-latin-700-normal-7sUh57Bg.woff2 +0 -0
  20. package/inspector/dist/assets/ibm-plex-mono-latin-700-normal-CNHXzs6v.woff +0 -0
  21. package/inspector/dist/assets/ibm-plex-sans-latin-400-normal-CDDApCn2.woff2 +0 -0
  22. package/inspector/dist/assets/ibm-plex-sans-latin-400-normal-CYLoc0-x.woff +0 -0
  23. package/inspector/dist/assets/ibm-plex-sans-latin-500-normal-6ng42L7E.woff2 +0 -0
  24. package/inspector/dist/assets/ibm-plex-sans-latin-500-normal-BgVn5rGT.woff +0 -0
  25. package/inspector/dist/assets/ibm-plex-sans-latin-600-normal-Cu4Hd6ag.woff +0 -0
  26. package/inspector/dist/assets/ibm-plex-sans-latin-600-normal-CuJfVYMP.woff2 +0 -0
  27. package/inspector/dist/assets/ibm-plex-sans-latin-700-normal-Bth3BMcD.woff +0 -0
  28. package/inspector/dist/assets/ibm-plex-sans-latin-700-normal-Bxkt5Cjx.woff2 +0 -0
  29. package/inspector/dist/assets/index-BCSWkslF.css +1 -0
  30. package/inspector/dist/assets/index-D6WuziFQ.js +9 -0
  31. package/inspector/dist/index.html +24 -0
  32. package/package.json +4 -10
  33. package/inspector/README.md +0 -67
  34. package/inspector/app/api/runs/[id]/file/route.ts +0 -56
  35. package/inspector/app/api/runs/[id]/route.ts +0 -15
  36. package/inspector/app/api/runs/[id]/stop/route.ts +0 -15
  37. package/inspector/app/api/runs/route.ts +0 -9
  38. package/inspector/app/api/workflows/[slug]/route.ts +0 -11
  39. package/inspector/app/api/workflows/[slug]/run/route.ts +0 -37
  40. package/inspector/app/api/workflows/route.ts +0 -8
  41. package/inspector/app/globals.css +0 -460
  42. package/inspector/app/layout.tsx +0 -54
  43. package/inspector/app/page.tsx +0 -16
  44. package/inspector/app/runs/[id]/page.tsx +0 -6
  45. package/inspector/app/runs/[id]/run-detail.tsx +0 -343
  46. package/inspector/app/shared.tsx +0 -81
  47. package/inspector/app/theme-toggle.tsx +0 -19
  48. package/inspector/app/workflows/[slug]/page.tsx +0 -6
  49. package/inspector/app/workflows/[slug]/workflow-view.tsx +0 -271
  50. package/inspector/app/workflows/page.tsx +0 -43
  51. package/inspector/lib/runner.ts +0 -78
  52. package/inspector/lib/runs.ts +0 -313
  53. package/inspector/lib/workflows.ts +0 -240
  54. package/inspector/next.config.ts +0 -5
  55. package/inspector/package-lock.json +0 -982
  56. package/inspector/package.json +0 -24
  57. package/inspector/tsconfig.json +0 -21
@@ -1,460 +0,0 @@
1
- /* kraftwerk inspector — control-room industrial. Warm graphite, hairlines,
2
- indicator lamps. Dark is the native mode; light is the day shift. */
3
-
4
- :root {
5
- --bg: #141512;
6
- --bg-deep: #0e0f0d;
7
- --panel: #1b1d19;
8
- --panel-2: #22241f;
9
- --line: #2e312a;
10
- --line-soft: #262822;
11
- --ink: #ecebe3;
12
- --ink-2: #b3b1a4;
13
- --muted: #7c7a6e;
14
- --accent: #f5a623;
15
- --accent-dim: rgba(245, 166, 35, 0.14);
16
- --ok: #56c15a;
17
- --ok-dim: rgba(86, 193, 90, 0.14);
18
- --fail: #e5484d;
19
- --fail-dim: rgba(229, 72, 77, 0.14);
20
- --run: #f5a623;
21
- --pending: #4c4e46;
22
- --shadow: 0 1px 0 rgba(255, 255, 255, 0.03) inset, 0 8px 24px rgba(0, 0, 0, 0.35);
23
- color-scheme: dark;
24
- }
25
-
26
- :root[data-theme="light"] {
27
- --bg: #f1f0ea;
28
- --bg-deep: #e8e7df;
29
- --panel: #fbfaf6;
30
- --panel-2: #f3f2ec;
31
- --line: #d9d7cc;
32
- --line-soft: #e3e1d6;
33
- --ink: #1d1e19;
34
- --ink-2: #55564c;
35
- --muted: #8a887b;
36
- --accent: #c77c11;
37
- --accent-dim: rgba(199, 124, 17, 0.12);
38
- --ok: #2e8f38;
39
- --ok-dim: rgba(46, 143, 56, 0.12);
40
- --fail: #c73538;
41
- --fail-dim: rgba(199, 53, 56, 0.1);
42
- --run: #c77c11;
43
- --pending: #c9c7bb;
44
- --shadow: 0 1px 2px rgba(29, 30, 25, 0.06);
45
- color-scheme: light;
46
- }
47
-
48
- * { box-sizing: border-box; margin: 0; padding: 0; }
49
-
50
- html { height: 100%; }
51
-
52
- body {
53
- min-height: 100%;
54
- background:
55
- radial-gradient(1200px 400px at 50% -200px, rgba(245, 166, 35, 0.05), transparent 70%),
56
- var(--bg);
57
- color: var(--ink);
58
- font-family: var(--font-sans), sans-serif;
59
- font-size: 14px;
60
- line-height: 1.5;
61
- -webkit-font-smoothing: antialiased;
62
- }
63
-
64
- a { color: inherit; text-decoration: none; }
65
- button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
66
- code, pre, .mono { font-family: var(--font-mono), monospace; }
67
-
68
- /* ---------- chrome ---------- */
69
-
70
- .topbar {
71
- position: sticky; top: 0; z-index: 10;
72
- display: flex; align-items: center; gap: 14px;
73
- padding: 10px 20px;
74
- background: color-mix(in srgb, var(--bg) 86%, transparent);
75
- backdrop-filter: blur(10px);
76
- border-bottom: 1px solid var(--line);
77
- }
78
- .wordmark { display: flex; align-items: center; gap: 10px; }
79
- .wordmark .lamp-block {
80
- width: 22px; height: 22px; border-radius: 5px;
81
- background: linear-gradient(135deg, var(--accent), #d2820b);
82
- display: grid; place-items: center;
83
- box-shadow: 0 0 14px rgba(245, 166, 35, 0.35);
84
- }
85
- .wordmark .lamp-block span { width: 7px; height: 7px; border-radius: 2px; background: #141512; }
86
- .wordmark b {
87
- font-family: var(--font-mono), monospace;
88
- font-size: 13.5px; font-weight: 700; letter-spacing: 0.14em; text-transform: uppercase;
89
- }
90
- .wordmark small {
91
- font-size: 11px; letter-spacing: 0.22em; text-transform: uppercase; color: var(--muted);
92
- }
93
- .topbar .spacer { flex: 1; }
94
- .topbar nav { display: flex; gap: 4px; margin-left: 10px; }
95
- .topbar nav a {
96
- font-size: 11px; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase;
97
- color: var(--muted); padding: 4px 10px; border-radius: 6px;
98
- }
99
- .topbar nav a:hover { color: var(--ink); background: var(--panel-2); }
100
- .topbar .outdir {
101
- font-family: var(--font-mono), monospace;
102
- font-size: 11px; color: var(--muted);
103
- max-width: 44vw; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
104
- }
105
- .theme-btn {
106
- border: 1px solid var(--line); border-radius: 6px; padding: 4px 10px;
107
- font-size: 11.5px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-2);
108
- }
109
- .theme-btn:hover { border-color: var(--accent); color: var(--ink); }
110
-
111
- .shell { max-width: 1240px; margin: 0 auto; padding: 26px 20px 80px; }
112
-
113
- /* ---------- micro type ---------- */
114
-
115
- .microlabel {
116
- font-size: 10.5px; font-weight: 600; letter-spacing: 0.18em; text-transform: uppercase;
117
- color: var(--muted);
118
- }
119
- .num { font-variant-numeric: tabular-nums; }
120
-
121
- /* ---------- lamps ---------- */
122
-
123
- .lamp { width: 9px; height: 9px; border-radius: 50%; flex: none; position: relative; }
124
- .lamp.ok { background: var(--ok); box-shadow: 0 0 6px color-mix(in srgb, var(--ok) 60%, transparent); }
125
- .lamp.failed, .lamp.blocked { background: var(--fail); box-shadow: 0 0 6px color-mix(in srgb, var(--fail) 60%, transparent); }
126
- .lamp.aborted { background: var(--pending); }
127
- .lamp.pending { background: transparent; border: 1.5px solid var(--pending); }
128
- .lamp.running { background: var(--run); animation: lamp-pulse 1.4s ease-in-out infinite; }
129
- @keyframes lamp-pulse {
130
- 0%, 100% { box-shadow: 0 0 4px color-mix(in srgb, var(--run) 55%, transparent); opacity: 1; }
131
- 50% { box-shadow: 0 0 14px var(--run); opacity: 0.75; }
132
- }
133
-
134
- .status-word { font-size: 11px; font-weight: 650; letter-spacing: 0.14em; text-transform: uppercase; }
135
- .status-word.ok { color: var(--ok); }
136
- .status-word.failed, .status-word.blocked { color: var(--fail); }
137
- .status-word.running { color: var(--run); }
138
- .status-word.aborted, .status-word.pending { color: var(--muted); }
139
-
140
- /* ---------- run index ---------- */
141
-
142
- .page-head { display: flex; align-items: baseline; gap: 14px; margin: 6px 2px 18px; }
143
- .page-head h1 { font-size: 19px; font-weight: 650; letter-spacing: -0.01em; }
144
- .page-head .count { color: var(--muted); font-size: 13px; }
145
-
146
- .run-list { display: grid; gap: 10px; }
147
- .run-card {
148
- display: grid;
149
- grid-template-columns: 12px 200px 1fr auto;
150
- gap: 8px 16px; align-items: center;
151
- background: var(--panel);
152
- border: 1px solid var(--line);
153
- border-radius: 8px;
154
- padding: 13px 18px;
155
- box-shadow: var(--shadow);
156
- transition: border-color 120ms ease, transform 120ms ease;
157
- }
158
- .run-card:hover { border-color: color-mix(in srgb, var(--accent) 55%, var(--line)); transform: translateY(-1px); }
159
- .run-card .rid { font-family: var(--font-mono), monospace; font-size: 12.5px; color: var(--ink-2); }
160
- .run-card .wf { font-weight: 650; font-size: 14px; }
161
- .run-card .req {
162
- color: var(--muted); font-size: 12.5px;
163
- overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 52ch;
164
- }
165
- .run-card .meta {
166
- display: flex; gap: 18px; align-items: center;
167
- font-family: var(--font-mono), monospace; font-size: 12px; color: var(--ink-2);
168
- }
169
- .progress-track {
170
- width: 90px; height: 4px; border-radius: 2px; background: var(--line-soft); overflow: hidden;
171
- }
172
- .progress-track i { display: block; height: 100%; background: var(--accent); border-radius: 2px; }
173
- .run-card.is-ok .progress-track i { background: var(--ok); }
174
- .run-card.is-failed .progress-track i { background: var(--fail); }
175
-
176
- .empty {
177
- border: 1px dashed var(--line); border-radius: 8px; padding: 40px;
178
- text-align: center; color: var(--muted);
179
- }
180
-
181
- /* ---------- run detail ---------- */
182
-
183
- .crumbs { display: flex; align-items: center; gap: 8px; font-size: 12.5px; color: var(--muted); margin-bottom: 14px; }
184
- .crumbs a:hover { color: var(--accent); }
185
- .crumbs .sep { color: var(--line); }
186
-
187
- .detail-head {
188
- display: flex; flex-wrap: wrap; align-items: center; gap: 10px 16px; margin-bottom: 6px;
189
- }
190
- .detail-head h1 { font-size: 18px; font-weight: 650; }
191
- .detail-head .rid { font-family: var(--font-mono), monospace; font-size: 12px; color: var(--muted); }
192
- .detail-req { color: var(--ink-2); font-size: 13px; margin-bottom: 18px; max-width: 90ch; }
193
-
194
- .statgrid { display: flex; flex-wrap: wrap; gap: 26px; margin-bottom: 22px; }
195
- .stat .microlabel { margin-bottom: 1px; }
196
- .stat .v { font-family: var(--font-mono), monospace; font-size: 15px; font-weight: 600; }
197
-
198
- .columns { display: grid; grid-template-columns: minmax(430px, 5fr) minmax(360px, 4fr); gap: 18px; align-items: start; }
199
- @media (max-width: 1020px) { .columns { grid-template-columns: 1fr; } }
200
-
201
- .panel {
202
- background: var(--panel); border: 1px solid var(--line); border-radius: 8px;
203
- box-shadow: var(--shadow); overflow: hidden;
204
- }
205
- .panel-head {
206
- display: flex; align-items: center; gap: 10px;
207
- padding: 10px 16px; border-bottom: 1px solid var(--line-soft);
208
- background: var(--panel-2);
209
- }
210
- .panel-head .microlabel { color: var(--ink-2); }
211
- .panel-head .spacer { flex: 1; }
212
-
213
- /* phase timeline */
214
-
215
- .phases { padding: 6px 0; }
216
- .phase-row { position: relative; padding: 10px 16px 10px 40px; }
217
- .phase-row + .phase-row { border-top: 1px solid var(--line-soft); }
218
- .phase-row .lamp { position: absolute; left: 17px; top: 16px; }
219
- .phase-row::before {
220
- content: ""; position: absolute; left: 21px; top: 0; bottom: 0; width: 1px;
221
- background: var(--line-soft);
222
- }
223
- .phase-row:first-child::before { top: 16px; }
224
- .phase-row:last-child::before { bottom: auto; height: 16px; }
225
- .phase-row .lamp { z-index: 1; }
226
-
227
- .phase-top { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
228
- .phase-name { font-weight: 650; font-size: 13.5px; }
229
- .chip {
230
- font-family: var(--font-mono), monospace; font-size: 10.5px;
231
- border: 1px solid var(--line); border-radius: 4px; padding: 1px 7px; color: var(--ink-2);
232
- }
233
- .chip.agent { border-color: color-mix(in srgb, var(--accent) 40%, var(--line)); color: var(--accent); }
234
- .phase-top .right { margin-left: auto; display: flex; gap: 14px; font-family: var(--font-mono), monospace; font-size: 11.5px; color: var(--muted); }
235
- .phase-sub { margin-top: 3px; font-size: 12.5px; color: var(--ink-2); max-width: 72ch; }
236
- .phase-activity {
237
- margin-top: 3px; font-family: var(--font-mono), monospace; font-size: 11.5px; color: var(--run);
238
- }
239
- .phase-activity::before { content: "▸ "; }
240
- .gate-line { margin-top: 5px; display: flex; flex-wrap: wrap; gap: 6px; }
241
- .gate {
242
- display: inline-flex; align-items: center; gap: 5px;
243
- font-family: var(--font-mono), monospace; font-size: 10.5px;
244
- border-radius: 4px; padding: 1.5px 7px;
245
- background: var(--ok-dim); color: var(--ok);
246
- }
247
- .gate.failed { background: var(--fail-dim); color: var(--fail); }
248
- .gate-fail-msg { margin-top: 4px; font-size: 12px; color: var(--fail); }
249
-
250
- /* files */
251
-
252
- .file-list { max-height: 300px; overflow: auto; }
253
- .file-row {
254
- display: flex; align-items: center; gap: 10px;
255
- width: 100%; text-align: left;
256
- padding: 7px 16px; font-family: var(--font-mono), monospace; font-size: 12.5px;
257
- border-bottom: 1px solid var(--line-soft);
258
- color: var(--ink-2);
259
- }
260
- .file-row:last-child { border-bottom: 0; }
261
- .file-row:hover { background: var(--panel-2); color: var(--ink); }
262
- .file-row.active { background: var(--accent-dim); color: var(--ink); }
263
- .file-row .fname { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
264
- .file-row .fsize { color: var(--muted); font-size: 11px; }
265
-
266
- .viewer { border-top: 1px solid var(--line); }
267
- .viewer-body pre {
268
- padding: 14px 16px; overflow: auto; max-height: 560px;
269
- font-size: 11.8px; line-height: 1.55; white-space: pre-wrap; word-break: break-word;
270
- color: var(--ink-2);
271
- }
272
- .viewer-body iframe {
273
- width: 100%; height: 620px; border: 0; background: #fff; display: block;
274
- }
275
- .viewer-body img { max-width: 100%; display: block; padding: 14px 16px; }
276
- .viewer-note { padding: 6px 16px; font-size: 11px; color: var(--muted); border-bottom: 1px solid var(--line-soft); }
277
- .open-raw {
278
- font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase;
279
- color: var(--muted); border: 1px solid var(--line); border-radius: 5px; padding: 2px 8px;
280
- }
281
- .open-raw:hover { color: var(--accent); border-color: var(--accent); }
282
-
283
- .live-note { display: inline-flex; align-items: center; gap: 7px; font-size: 11px; color: var(--muted); }
284
-
285
- /* ---------- workflows ---------- */
286
-
287
- .wf-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 12px; }
288
- .wf-card {
289
- display: flex; flex-direction: column; gap: 6px;
290
- background: var(--panel); border: 1px solid var(--line); border-radius: 8px;
291
- padding: 16px 18px; box-shadow: var(--shadow);
292
- transition: border-color 120ms ease, transform 120ms ease;
293
- }
294
- .wf-card:hover { border-color: color-mix(in srgb, var(--accent) 55%, var(--line)); transform: translateY(-1px); }
295
- .wf-card-head { display: flex; align-items: baseline; gap: 10px; }
296
- .wf-name { font-weight: 650; font-size: 15px; font-family: var(--font-mono), monospace; }
297
- .wf-desc { color: var(--ink-2); font-size: 12.5px; flex: 1; }
298
- .wf-meta { display: flex; gap: 8px; font-family: var(--font-mono), monospace; font-size: 11.5px; color: var(--muted); }
299
- .wf-workspace { font-size: 11.5px; color: var(--ink-2); white-space: pre-wrap; }
300
-
301
- /* agent identity hues */
302
- .aid-0 { --aid: var(--accent); }
303
- .aid-1 { --aid: #4fb8a8; }
304
- .aid-2 { --aid: #a78bfa; }
305
- .aid-3 { --aid: #e5793b; }
306
-
307
- .agent-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 0; }
308
- .agent-card { padding: 14px 18px; border-right: 1px solid var(--line-soft); border-bottom: 1px solid var(--line-soft); }
309
- .agent-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
310
- .agent-head b { font-size: 13.5px; }
311
- .agent-head .spacer { flex: 1; }
312
- .agent-id { font-size: 11px; color: var(--muted); }
313
- .agent-dot { width: 10px; height: 10px; border-radius: 3px; background: var(--aid); box-shadow: 0 0 8px color-mix(in srgb, var(--aid) 45%, transparent); }
314
- .agent-tools { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 8px; }
315
- .tool-chip {
316
- font-family: var(--font-mono), monospace; font-size: 10.5px;
317
- border: 1px solid var(--line); border-radius: 4px; padding: 1px 6px; color: var(--ink-2);
318
- }
319
- .agent-persona { margin-top: 8px; font-size: 12px; color: var(--muted); line-height: 1.55; white-space: pre-wrap; }
320
-
321
- .pipeline { padding: 8px 0; }
322
- .step-node { position: relative; display: flex; gap: 14px; padding: 12px 18px; }
323
- .step-node + .step-node { border-top: 1px solid var(--line-soft); }
324
- .step-node::before {
325
- content: ""; position: absolute; left: 30px; top: 0; bottom: 0; width: 1px; background: var(--line-soft);
326
- }
327
- .step-node:first-child::before { top: 18px; }
328
- .step-node:last-child::before { bottom: auto; height: 18px; }
329
- .step-index {
330
- position: relative; z-index: 1; flex: none;
331
- width: 25px; height: 25px; border-radius: 6px; margin-top: 1px;
332
- display: grid; place-items: center;
333
- font-family: var(--font-mono), monospace; font-size: 11.5px; font-weight: 700;
334
- background: color-mix(in srgb, var(--aid) 16%, var(--panel));
335
- border: 1px solid color-mix(in srgb, var(--aid) 55%, var(--line));
336
- color: var(--aid);
337
- }
338
- .step-index.is-script { --aid: var(--ink-2); }
339
- .step-body { flex: 1; min-width: 0; }
340
- .agent-chip { border-color: color-mix(in srgb, var(--aid) 50%, var(--line)); color: var(--aid); }
341
- .step-source { margin-top: 6px; }
342
- .step-source summary {
343
- cursor: pointer; font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase;
344
- color: var(--muted); user-select: none;
345
- }
346
- .step-source summary:hover { color: var(--accent); }
347
- .step-source pre {
348
- margin-top: 6px; padding: 10px 12px; border: 1px solid var(--line-soft); border-radius: 6px;
349
- background: var(--bg-deep); font-size: 11.5px; line-height: 1.55;
350
- white-space: pre-wrap; word-break: break-word; color: var(--ink-2);
351
- max-height: 360px; overflow: auto;
352
- }
353
- .gate.neutral { background: var(--panel-2); color: var(--ink-2); border: 1px solid var(--line-soft); }
354
-
355
- ::-webkit-scrollbar { width: 10px; height: 10px; }
356
- ::-webkit-scrollbar-thumb { background: var(--line); border-radius: 5px; border: 2px solid transparent; background-clip: content-box; }
357
- ::-webkit-scrollbar-track { background: transparent; }
358
-
359
- /* ---- run trigger + sandbox controls ---- */
360
- .run-form { display: flex; gap: 10px; }
361
- .run-form input[type="text"] {
362
- flex: 1; font: 13px/1.4 var(--font-mono), monospace; color: var(--ink);
363
- background: var(--panel-2); border: 1px solid var(--line);
364
- border-radius: 7px; padding: 9px 12px; outline: none;
365
- }
366
- .run-form input[type="text"]:focus { border-color: var(--accent); }
367
- .run-btn {
368
- font: 600 12.5px/1 var(--font-sans), sans-serif; white-space: nowrap;
369
- color: #141512; background: var(--accent);
370
- border-radius: 7px; padding: 10px 16px;
371
- }
372
- .run-btn:hover { filter: brightness(1.08); }
373
- .run-btn:disabled { opacity: 0.45; cursor: not-allowed; filter: none; }
374
- .run-opts { display: flex; flex-wrap: wrap; gap: 6px 22px; margin-top: 10px; }
375
- .run-opts label {
376
- display: inline-flex; align-items: center; gap: 7px;
377
- font-size: 12.5px; color: var(--ink-2); cursor: pointer;
378
- }
379
- .run-opts input[type="checkbox"] { accent-color: var(--accent); }
380
- .run-opts .opt-hint { color: var(--muted); }
381
- .sandbox-chip { border: 1px solid var(--line); color: var(--ink-2); }
382
- .stop-btn {
383
- font: 600 12px/1 var(--font-sans), sans-serif;
384
- color: var(--fail); background: var(--fail-dim);
385
- border: 1px solid color-mix(in srgb, var(--fail) 40%, transparent);
386
- border-radius: 7px; padding: 7px 13px;
387
- }
388
- .stop-btn:hover { border-color: var(--fail); }
389
- .stop-btn:disabled { opacity: 0.5; cursor: default; }
390
-
391
- /* ---- runs screen: sidebar + tabbed detail, full width ---- */
392
- .shell:has(.runs-screen) { max-width: none; padding: 0; }
393
- .runs-screen { display: grid; grid-template-columns: 300px minmax(0, 1fr); align-items: start; }
394
-
395
- .runs-side {
396
- position: sticky; top: 45px; height: calc(100vh - 45px);
397
- display: flex; flex-direction: column;
398
- border-right: 1px solid var(--line); background: var(--panel);
399
- }
400
- .side-head {
401
- display: flex; align-items: center; gap: 10px;
402
- padding: 10px 14px; border-bottom: 1px solid var(--line-soft);
403
- background: var(--panel-2);
404
- }
405
- .side-head .spacer { flex: 1; }
406
- .side-list { flex: 1; overflow-y: auto; }
407
- .side-row {
408
- display: flex; align-items: flex-start; gap: 9px;
409
- padding: 9px 12px 9px 14px; border-bottom: 1px solid var(--line-soft);
410
- border-left: 2px solid transparent;
411
- }
412
- .side-row .lamp { margin-top: 4px; }
413
- .side-row:hover { background: var(--panel-2); }
414
- .side-row.active { background: var(--accent-dim); border-left-color: var(--accent); }
415
- .side-row-body { flex: 1; min-width: 0; }
416
- .side-row-top { display: flex; align-items: baseline; gap: 8px; }
417
- .side-wf { font-weight: 650; font-size: 12.5px; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
418
- .side-when { font-family: var(--font-mono), monospace; font-size: 10.5px; color: var(--muted); }
419
- .side-row-sub { display: flex; align-items: baseline; gap: 8px; margin-top: 1px; }
420
- .side-req {
421
- flex: 1; font-size: 11.5px; color: var(--muted);
422
- overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
423
- }
424
- .side-row.active .side-req { color: var(--ink-2); }
425
- .side-meta { font-family: var(--font-mono), monospace; font-size: 10.5px; color: var(--muted); }
426
-
427
- .runs-main { padding: 16px 20px 40px; min-width: 0; }
428
- .runs-main .detail-head .spacer { flex: 1; }
429
-
430
- .tabs { display: flex; gap: 2px; background: var(--panel-2); border: 1px solid var(--line); border-radius: 7px; padding: 2px; }
431
- .tabs button {
432
- font-size: 11px; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase;
433
- color: var(--muted); padding: 5px 13px; border-radius: 5px;
434
- }
435
- .tabs button:hover { color: var(--ink); }
436
- .tabs button.active { background: var(--panel); color: var(--ink); box-shadow: var(--shadow); }
437
-
438
- .run-tab { max-width: 1080px; }
439
-
440
- .art-layout {
441
- display: grid; grid-template-columns: 280px minmax(0, 1fr); gap: 14px;
442
- height: calc(100vh - 168px); min-height: 420px;
443
- }
444
- .art-files { display: flex; flex-direction: column; min-height: 0; }
445
- .art-files .file-list { flex: 1; max-height: none; }
446
- .art-viewer { display: flex; flex-direction: column; min-height: 0; }
447
- .art-viewer .viewer { flex: 1; display: flex; flex-direction: column; min-height: 0; border-top: 0; }
448
- .art-viewer .viewer-body { flex: 1; min-height: 0; }
449
- .art-viewer .viewer-body iframe { height: 100%; }
450
- .art-viewer .viewer-body pre { max-height: none; height: 100%; box-sizing: border-box; }
451
- .art-viewer .viewer-body img { max-height: 100%; object-fit: contain; }
452
- .art-viewer .empty { flex: 1; display: grid; place-items: center; }
453
-
454
- @media (max-width: 940px) {
455
- .runs-screen { grid-template-columns: 1fr; }
456
- .runs-side { display: none; }
457
- .art-layout { grid-template-columns: 1fr; height: auto; }
458
- .art-files .file-list { max-height: 240px; }
459
- .art-viewer .viewer-body iframe { height: 560px; }
460
- }
@@ -1,54 +0,0 @@
1
- import type { Metadata } from "next";
2
- import { IBM_Plex_Sans, IBM_Plex_Mono } from "next/font/google";
3
- import "./globals.css";
4
- import { ThemeToggle } from "./theme-toggle";
5
-
6
- const sans = IBM_Plex_Sans({
7
- subsets: ["latin"],
8
- weight: ["400", "500", "600", "700"],
9
- variable: "--font-sans",
10
- });
11
- const mono = IBM_Plex_Mono({
12
- subsets: ["latin"],
13
- weight: ["400", "500", "600", "700"],
14
- variable: "--font-mono",
15
- });
16
-
17
- export const metadata: Metadata = {
18
- title: "kraftwerk inspector",
19
- description: "Inspect kraftwerk workflow runs: live executions, phase traces, artifacts",
20
- };
21
-
22
- const themeInit = `(function(){try{var t=localStorage.getItem("kw-theme");if(t){document.documentElement.dataset.theme=t}else if(matchMedia("(prefers-color-scheme: light)").matches){document.documentElement.dataset.theme="light"}}catch(e){}})()`;
23
-
24
- export default function RootLayout({ children }: { children: React.ReactNode }) {
25
- return (
26
- <html lang="en" suppressHydrationWarning>
27
- <body className={`${sans.variable} ${mono.variable}`}>
28
- <script dangerouslySetInnerHTML={{ __html: themeInit }} />
29
- <header className="topbar">
30
- <a href="/" className="wordmark">
31
- <span className="lamp-block">
32
- <span />
33
- </span>
34
- <b>kraftwerk</b>
35
- <small>inspector</small>
36
- </a>
37
- <nav>
38
- <a href="/">runs</a>
39
- <a href="/workflows">workflows</a>
40
- </nav>
41
- <span className="spacer" />
42
- <OutDir />
43
- <ThemeToggle />
44
- </header>
45
- <main className="shell">{children}</main>
46
- </body>
47
- </html>
48
- );
49
- }
50
-
51
- async function OutDir() {
52
- const { OUTPUT_DIR } = await import("@/lib/runs");
53
- return <span className="outdir" title={OUTPUT_DIR}>{OUTPUT_DIR}</span>;
54
- }
@@ -1,16 +0,0 @@
1
- import { redirect } from "next/navigation";
2
- import { listRuns, OUTPUT_DIR } from "@/lib/runs";
3
-
4
- export const dynamic = "force-dynamic";
5
-
6
- /** The runs screen lives at /runs/<id>; land on the latest run. */
7
- export default async function Home() {
8
- const runs = await listRuns();
9
- if (runs.length > 0) redirect(`/runs/${runs[0].id}`);
10
- return (
11
- <div className="empty">
12
- No runs found in <code>{OUTPUT_DIR}</code>. Start one with{" "}
13
- <code>kraftwerk run &lt;workflow&gt; &lt;request&gt;</code> or from a workflow page.
14
- </div>
15
- );
16
- }
@@ -1,6 +0,0 @@
1
- import { RunsScreen } from "./run-detail";
2
-
3
- export default async function RunPage({ params }: { params: Promise<{ id: string }> }) {
4
- const { id } = await params;
5
- return <RunsScreen id={id} />;
6
- }