@worca/ui 0.9.0 → 0.11.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 +895 -813
  2. package/app/main.bundle.js.map +4 -4
  3. package/app/styles.css +216 -9
  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 +217 -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 {
@@ -3890,7 +3889,12 @@ sl-details.learnings-panel::part(content) {
3890
3889
  .run-card-actions {
3891
3890
  display: flex;
3892
3891
  align-items: center;
3893
- margin-left: auto;
3892
+ justify-content: flex-end;
3893
+ gap: 8px;
3894
+ padding-left: 26px;
3895
+ }
3896
+ .run-card-actions:empty {
3897
+ display: none;
3894
3898
  }
3895
3899
  .btn-quick-resume {
3896
3900
  display: inline-flex;
@@ -3992,6 +3996,7 @@ sl-details.learnings-panel::part(content) {
3992
3996
  .pipeline-succeeded { border-left-color: var(--status-completed); }
3993
3997
  .pipeline-failed { border-left-color: var(--status-failed); }
3994
3998
  .pipeline-paused { border-left-color: var(--status-paused); }
3999
+ .pipeline-cancelled { border-left-color: var(--status-cancelled); }
3995
4000
  .pipeline-unknown { border-left-color: var(--muted); }
3996
4001
 
3997
4002
  .pipeline-card-header {
@@ -4318,3 +4323,205 @@ sl-tooltip.bead-tooltip::part(body) {
4318
4323
  width: 100%;
4319
4324
  }
4320
4325
 
4326
+ /* ── Integrations (card catalog) ─────────────────────────────────────── */
4327
+
4328
+ .ig-page {
4329
+ max-width: 720px;
4330
+ }
4331
+
4332
+ .ig-subtitle {
4333
+ margin: 0 0 1.25rem;
4334
+ font-size: 0.85rem;
4335
+ color: var(--sl-color-neutral-500);
4336
+ }
4337
+
4338
+ .ig-cards {
4339
+ display: flex;
4340
+ flex-direction: column;
4341
+ gap: 0.75rem;
4342
+ }
4343
+
4344
+ .ig-card {
4345
+ border: 1px solid var(--sl-color-neutral-200);
4346
+ border-radius: var(--sl-border-radius-medium);
4347
+ padding: 1rem 1.25rem;
4348
+ background: var(--sl-color-neutral-0);
4349
+ }
4350
+
4351
+ .ig-card--connected {
4352
+ border-left: 3px solid var(--sl-color-success-500);
4353
+ }
4354
+
4355
+ .ig-card--disabled {
4356
+ border-left: 3px solid var(--sl-color-neutral-300);
4357
+ opacity: 0.7;
4358
+ }
4359
+
4360
+ .ig-card-footer {
4361
+ display: flex;
4362
+ justify-content: space-between;
4363
+ align-items: center;
4364
+ margin-top: 0.75rem;
4365
+ padding-left: 2.75rem;
4366
+ }
4367
+
4368
+ .ig-card--disconnected {
4369
+ opacity: 0.85;
4370
+ }
4371
+
4372
+ .ig-card-header {
4373
+ display: flex;
4374
+ align-items: center;
4375
+ gap: 0.75rem;
4376
+ }
4377
+
4378
+ .ig-card-icon {
4379
+ font-size: 1.5rem;
4380
+ line-height: 1;
4381
+ }
4382
+
4383
+ .ig-card-title {
4384
+ flex: 1;
4385
+ min-width: 0;
4386
+ }
4387
+
4388
+ .ig-card-name {
4389
+ display: block;
4390
+ font-weight: 600;
4391
+ font-size: 0.95rem;
4392
+ }
4393
+
4394
+ .ig-card-desc {
4395
+ display: block;
4396
+ font-size: 0.8rem;
4397
+ color: var(--sl-color-neutral-500);
4398
+ }
4399
+
4400
+ .ig-badges {
4401
+ display: flex;
4402
+ flex-direction: column;
4403
+ align-items: flex-end;
4404
+ gap: 0.25rem;
4405
+ }
4406
+
4407
+ .ig-card-stats {
4408
+ display: flex;
4409
+ gap: 1rem;
4410
+ margin-top: 0.5rem;
4411
+ padding-left: 2.75rem;
4412
+ font-size: 0.8rem;
4413
+ color: var(--sl-color-neutral-500);
4414
+ }
4415
+
4416
+ .ig-card-stats .stat-warn {
4417
+ color: var(--sl-color-warning-600);
4418
+ }
4419
+
4420
+ .ig-card-chats {
4421
+ display: flex;
4422
+ gap: 0.5rem;
4423
+ flex-wrap: wrap;
4424
+ margin-top: 0.4rem;
4425
+ padding-left: 2.75rem;
4426
+ }
4427
+
4428
+ .ig-chat-badge {
4429
+ display: inline-flex;
4430
+ align-items: center;
4431
+ gap: 0.35rem;
4432
+ font-size: 0.8rem;
4433
+ }
4434
+
4435
+ .ig-chat-id {
4436
+ font-family: var(--sl-font-mono);
4437
+ color: var(--sl-color-neutral-600);
4438
+ font-size: 0.8rem;
4439
+ }
4440
+
4441
+ .ig-card-actions {
4442
+ display: flex;
4443
+ gap: 0.5rem;
4444
+ margin-top: 0.75rem;
4445
+ padding-left: 2.75rem;
4446
+ }
4447
+
4448
+ /* Inline form */
4449
+
4450
+ .ig-form {
4451
+ margin-top: 1rem;
4452
+ padding: 1rem;
4453
+ border-top: 1px solid var(--sl-color-neutral-200);
4454
+ }
4455
+
4456
+ .ig-env-hint {
4457
+ font-size: 0.8rem;
4458
+ color: var(--sl-color-neutral-600);
4459
+ background: var(--sl-color-neutral-50);
4460
+ border: 1px solid var(--sl-color-neutral-200);
4461
+ border-radius: var(--sl-border-radius-small);
4462
+ padding: 0.5rem 0.75rem;
4463
+ margin-bottom: 0.75rem;
4464
+ font-family: var(--sl-font-mono);
4465
+ }
4466
+
4467
+ .ig-form-row {
4468
+ display: grid;
4469
+ grid-template-columns: 1fr 1fr;
4470
+ gap: 0.75rem;
4471
+ }
4472
+
4473
+ @media (max-width: 600px) {
4474
+ .ig-form-row {
4475
+ grid-template-columns: 1fr;
4476
+ }
4477
+ }
4478
+
4479
+ .ig-form-field {
4480
+ margin-bottom: 0.75rem;
4481
+ }
4482
+
4483
+ .ig-form-field label {
4484
+ display: block;
4485
+ font-size: 0.8rem;
4486
+ font-weight: 600;
4487
+ margin-bottom: 0.2rem;
4488
+ color: var(--sl-color-neutral-700);
4489
+ }
4490
+
4491
+ .ig-form-field .form-hint {
4492
+ display: block;
4493
+ font-size: 0.7rem;
4494
+ color: var(--sl-color-neutral-500);
4495
+ margin-top: 0.15rem;
4496
+ }
4497
+
4498
+ .ig-detect-row {
4499
+ display: flex;
4500
+ gap: 0.5rem;
4501
+ align-items: center;
4502
+ }
4503
+
4504
+ .ig-detect-row sl-input {
4505
+ flex: 1;
4506
+ }
4507
+
4508
+ .ig-event-grid {
4509
+ display: grid;
4510
+ grid-template-columns: 1fr 1fr;
4511
+ gap: 0.2rem 0.5rem;
4512
+ }
4513
+
4514
+ .ig-form-actions {
4515
+ display: flex;
4516
+ gap: 0.5rem;
4517
+ margin-top: 0.75rem;
4518
+ }
4519
+
4520
+ .ig-loading {
4521
+ display: flex;
4522
+ align-items: center;
4523
+ gap: 0.5rem;
4524
+ color: var(--sl-color-neutral-500);
4525
+ padding: 2rem;
4526
+ }
4527
+
@@ -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.11.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": {