@worca/ui 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.
Files changed (33) hide show
  1. package/app/main.bundle.js +900 -803
  2. package/app/main.bundle.js.map +4 -4
  3. package/app/styles.css +210 -8
  4. package/app/utils/state-actions.js +55 -0
  5. package/package.json +6 -4
  6. package/server/app.js +291 -6
  7. package/server/beads-reader.js +1 -1
  8. package/server/dispatch-external.js +106 -0
  9. package/server/ensure-webhook.js +66 -0
  10. package/server/index.js +22 -0
  11. package/server/integrations/adapter.js +91 -0
  12. package/server/integrations/adapters/discord.js +109 -0
  13. package/server/integrations/adapters/slack.js +106 -0
  14. package/server/integrations/adapters/telegram.js +231 -0
  15. package/server/integrations/adapters/webhook_out.js +253 -0
  16. package/server/integrations/allowlist.js +19 -0
  17. package/server/integrations/chat_context.js +68 -0
  18. package/server/integrations/commands/control.js +120 -0
  19. package/server/integrations/commands/global.js +239 -0
  20. package/server/integrations/commands/parser.js +29 -0
  21. package/server/integrations/commands/project.js +394 -0
  22. package/server/integrations/config-loader.js +40 -0
  23. package/server/integrations/index.js +390 -0
  24. package/server/integrations/markdown.js +220 -0
  25. package/server/integrations/rate_limiter.js +131 -0
  26. package/server/integrations/renderers.js +191 -0
  27. package/server/integrations/rest_client.js +17 -0
  28. package/server/integrations/verify.js +23 -0
  29. package/server/process-manager.js +212 -14
  30. package/server/project-routes.js +210 -44
  31. package/server/settings-validator.js +250 -0
  32. package/server/ws-beads-watcher.js +22 -6
  33. package/server/ws-message-router.js +1 -1
package/app/styles.css CHANGED
@@ -22,8 +22,9 @@
22
22
  --status-paused: #f59e0b;
23
23
  --status-completed: #22c55e;
24
24
  --status-failed: #ef4444;
25
- --status-resuming: #3b82f6;
26
25
  --status-skipped: #94a3b8;
26
+ --status-interrupted: #f59e0b;
27
+ --status-cancelled: #94a3b8;
27
28
  /* legacy */
28
29
  --status-in-progress: #3b82f6;
29
30
  --status-error: #ef4444;
@@ -730,8 +731,7 @@ h1, h2, h3, h4, h5, h6 {
730
731
  }
731
732
 
732
733
  .stage-node.status-interrupted .stage-icon {
733
- border-color: var(--status-in-progress);
734
- opacity: 0.6;
734
+ border-color: var(--status-interrupted);
735
735
  }
736
736
 
737
737
  .stage-label {
@@ -1110,8 +1110,7 @@ sl-details.log-history-panel::part(content) {
1110
1110
  }
1111
1111
 
1112
1112
  .status-interrupted {
1113
- color: var(--status-in-progress);
1114
- opacity: 0.6;
1113
+ color: var(--status-interrupted);
1115
1114
  }
1116
1115
 
1117
1116
  .status-running {
@@ -1126,8 +1125,8 @@ sl-details.log-history-panel::part(content) {
1126
1125
  color: var(--status-failed);
1127
1126
  }
1128
1127
 
1129
- .status-resuming {
1130
- color: var(--status-resuming);
1128
+ .status-cancelled {
1129
+ color: var(--status-cancelled);
1131
1130
  }
1132
1131
 
1133
1132
  /* --- 18b. Control Buttons --- */
@@ -1282,11 +1281,11 @@ sl-details.log-history-panel::part(content) {
1282
1281
 
1283
1282
  /* Status-colored left border accent on run cards */
1284
1283
  .run-card.status-running { border-left: 3px solid var(--status-running); }
1285
- .run-card.status-resuming { border-left: 3px solid var(--status-resuming); }
1286
1284
  .run-card.status-paused { border-left: 3px solid var(--status-paused); }
1287
1285
  .run-card.status-completed { border-left: 3px solid var(--status-completed); }
1288
1286
  .run-card.status-failed { border-left: 3px solid var(--status-failed); }
1289
1287
  .run-card.status-pending { border-left: 3px solid var(--status-pending); }
1288
+ .run-card.status-cancelled { border-left: 3px solid var(--status-cancelled); }
1290
1289
 
1291
1290
  /* --- 21. Dashboard --- */
1292
1291
  .dashboard {
@@ -3992,6 +3991,7 @@ sl-details.learnings-panel::part(content) {
3992
3991
  .pipeline-succeeded { border-left-color: var(--status-completed); }
3993
3992
  .pipeline-failed { border-left-color: var(--status-failed); }
3994
3993
  .pipeline-paused { border-left-color: var(--status-paused); }
3994
+ .pipeline-cancelled { border-left-color: var(--status-cancelled); }
3995
3995
  .pipeline-unknown { border-left-color: var(--muted); }
3996
3996
 
3997
3997
  .pipeline-card-header {
@@ -4318,3 +4318,205 @@ sl-tooltip.bead-tooltip::part(body) {
4318
4318
  width: 100%;
4319
4319
  }
4320
4320
 
4321
+ /* ── Integrations (card catalog) ─────────────────────────────────────── */
4322
+
4323
+ .ig-page {
4324
+ max-width: 720px;
4325
+ }
4326
+
4327
+ .ig-subtitle {
4328
+ margin: 0 0 1.25rem;
4329
+ font-size: 0.85rem;
4330
+ color: var(--sl-color-neutral-500);
4331
+ }
4332
+
4333
+ .ig-cards {
4334
+ display: flex;
4335
+ flex-direction: column;
4336
+ gap: 0.75rem;
4337
+ }
4338
+
4339
+ .ig-card {
4340
+ border: 1px solid var(--sl-color-neutral-200);
4341
+ border-radius: var(--sl-border-radius-medium);
4342
+ padding: 1rem 1.25rem;
4343
+ background: var(--sl-color-neutral-0);
4344
+ }
4345
+
4346
+ .ig-card--connected {
4347
+ border-left: 3px solid var(--sl-color-success-500);
4348
+ }
4349
+
4350
+ .ig-card--disabled {
4351
+ border-left: 3px solid var(--sl-color-neutral-300);
4352
+ opacity: 0.7;
4353
+ }
4354
+
4355
+ .ig-card-footer {
4356
+ display: flex;
4357
+ justify-content: space-between;
4358
+ align-items: center;
4359
+ margin-top: 0.75rem;
4360
+ padding-left: 2.75rem;
4361
+ }
4362
+
4363
+ .ig-card--disconnected {
4364
+ opacity: 0.85;
4365
+ }
4366
+
4367
+ .ig-card-header {
4368
+ display: flex;
4369
+ align-items: center;
4370
+ gap: 0.75rem;
4371
+ }
4372
+
4373
+ .ig-card-icon {
4374
+ font-size: 1.5rem;
4375
+ line-height: 1;
4376
+ }
4377
+
4378
+ .ig-card-title {
4379
+ flex: 1;
4380
+ min-width: 0;
4381
+ }
4382
+
4383
+ .ig-card-name {
4384
+ display: block;
4385
+ font-weight: 600;
4386
+ font-size: 0.95rem;
4387
+ }
4388
+
4389
+ .ig-card-desc {
4390
+ display: block;
4391
+ font-size: 0.8rem;
4392
+ color: var(--sl-color-neutral-500);
4393
+ }
4394
+
4395
+ .ig-badges {
4396
+ display: flex;
4397
+ flex-direction: column;
4398
+ align-items: flex-end;
4399
+ gap: 0.25rem;
4400
+ }
4401
+
4402
+ .ig-card-stats {
4403
+ display: flex;
4404
+ gap: 1rem;
4405
+ margin-top: 0.5rem;
4406
+ padding-left: 2.75rem;
4407
+ font-size: 0.8rem;
4408
+ color: var(--sl-color-neutral-500);
4409
+ }
4410
+
4411
+ .ig-card-stats .stat-warn {
4412
+ color: var(--sl-color-warning-600);
4413
+ }
4414
+
4415
+ .ig-card-chats {
4416
+ display: flex;
4417
+ gap: 0.5rem;
4418
+ flex-wrap: wrap;
4419
+ margin-top: 0.4rem;
4420
+ padding-left: 2.75rem;
4421
+ }
4422
+
4423
+ .ig-chat-badge {
4424
+ display: inline-flex;
4425
+ align-items: center;
4426
+ gap: 0.35rem;
4427
+ font-size: 0.8rem;
4428
+ }
4429
+
4430
+ .ig-chat-id {
4431
+ font-family: var(--sl-font-mono);
4432
+ color: var(--sl-color-neutral-600);
4433
+ font-size: 0.8rem;
4434
+ }
4435
+
4436
+ .ig-card-actions {
4437
+ display: flex;
4438
+ gap: 0.5rem;
4439
+ margin-top: 0.75rem;
4440
+ padding-left: 2.75rem;
4441
+ }
4442
+
4443
+ /* Inline form */
4444
+
4445
+ .ig-form {
4446
+ margin-top: 1rem;
4447
+ padding: 1rem;
4448
+ border-top: 1px solid var(--sl-color-neutral-200);
4449
+ }
4450
+
4451
+ .ig-env-hint {
4452
+ font-size: 0.8rem;
4453
+ color: var(--sl-color-neutral-600);
4454
+ background: var(--sl-color-neutral-50);
4455
+ border: 1px solid var(--sl-color-neutral-200);
4456
+ border-radius: var(--sl-border-radius-small);
4457
+ padding: 0.5rem 0.75rem;
4458
+ margin-bottom: 0.75rem;
4459
+ font-family: var(--sl-font-mono);
4460
+ }
4461
+
4462
+ .ig-form-row {
4463
+ display: grid;
4464
+ grid-template-columns: 1fr 1fr;
4465
+ gap: 0.75rem;
4466
+ }
4467
+
4468
+ @media (max-width: 600px) {
4469
+ .ig-form-row {
4470
+ grid-template-columns: 1fr;
4471
+ }
4472
+ }
4473
+
4474
+ .ig-form-field {
4475
+ margin-bottom: 0.75rem;
4476
+ }
4477
+
4478
+ .ig-form-field label {
4479
+ display: block;
4480
+ font-size: 0.8rem;
4481
+ font-weight: 600;
4482
+ margin-bottom: 0.2rem;
4483
+ color: var(--sl-color-neutral-700);
4484
+ }
4485
+
4486
+ .ig-form-field .form-hint {
4487
+ display: block;
4488
+ font-size: 0.7rem;
4489
+ color: var(--sl-color-neutral-500);
4490
+ margin-top: 0.15rem;
4491
+ }
4492
+
4493
+ .ig-detect-row {
4494
+ display: flex;
4495
+ gap: 0.5rem;
4496
+ align-items: center;
4497
+ }
4498
+
4499
+ .ig-detect-row sl-input {
4500
+ flex: 1;
4501
+ }
4502
+
4503
+ .ig-event-grid {
4504
+ display: grid;
4505
+ grid-template-columns: 1fr 1fr;
4506
+ gap: 0.2rem 0.5rem;
4507
+ }
4508
+
4509
+ .ig-form-actions {
4510
+ display: flex;
4511
+ gap: 0.5rem;
4512
+ margin-top: 0.75rem;
4513
+ }
4514
+
4515
+ .ig-loading {
4516
+ display: flex;
4517
+ align-items: center;
4518
+ gap: 0.5rem;
4519
+ color: var(--sl-color-neutral-500);
4520
+ padding: 2rem;
4521
+ }
4522
+
@@ -0,0 +1,55 @@
1
+ export const STATES = [
2
+ 'pending',
3
+ 'running',
4
+ 'paused',
5
+ 'completed',
6
+ 'failed',
7
+ 'interrupted',
8
+ 'cancelled',
9
+ ];
10
+
11
+ const ACTION_MATRIX = {
12
+ stop: { running: true },
13
+ pause: { running: true },
14
+ resume: { paused: true, failed: true, interrupted: true },
15
+ cancel: {
16
+ pending: true,
17
+ running: true,
18
+ paused: true,
19
+ failed: true,
20
+ interrupted: true,
21
+ },
22
+ archive: {
23
+ pending: true,
24
+ paused: true,
25
+ completed: true,
26
+ failed: true,
27
+ interrupted: true,
28
+ cancelled: true,
29
+ },
30
+ unarchive: {
31
+ completed: true,
32
+ failed: true,
33
+ interrupted: true,
34
+ cancelled: true,
35
+ },
36
+ delete: {
37
+ pending: true,
38
+ paused: true,
39
+ completed: true,
40
+ failed: true,
41
+ interrupted: true,
42
+ cancelled: true,
43
+ },
44
+ learn: {
45
+ paused: true,
46
+ completed: true,
47
+ failed: true,
48
+ interrupted: true,
49
+ cancelled: true,
50
+ },
51
+ };
52
+
53
+ export function actionAllowed(action, status) {
54
+ return Boolean(ACTION_MATRIX[action]?.[status]);
55
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@worca/ui",
3
- "version": "0.9.0",
3
+ "version": "0.10.0",
4
4
  "description": "Pipeline monitoring UI for worca-cc",
5
5
  "license": "MIT",
6
6
  "author": "Sinisha Djukic",
@@ -23,9 +23,10 @@
23
23
  },
24
24
  "files": [
25
25
  "bin/worca-ui.js",
26
- "server/*.js",
27
- "!server/*.test.js",
28
- "!server/test/",
26
+ "server/**/*.js",
27
+ "!server/**/*.test.js",
28
+ "!server/test/**",
29
+ "!server/**/test/**",
29
30
  "app/favicon-*.svg",
30
31
  "app/index.html",
31
32
  "app/main.bundle.js",
@@ -34,6 +35,7 @@
34
35
  "app/vendor/",
35
36
  "app/protocol.js",
36
37
  "app/utils/stage-order.js",
38
+ "app/utils/state-actions.js",
37
39
  "scripts/build-frontend.js"
38
40
  ],
39
41
  "engines": {