opencastle 0.33.3 → 0.33.5

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 (30) hide show
  1. package/dist/cli/convoy/pipeline.d.ts +2 -0
  2. package/dist/cli/convoy/pipeline.d.ts.map +1 -1
  3. package/dist/cli/convoy/pipeline.js +12 -3
  4. package/dist/cli/convoy/pipeline.js.map +1 -1
  5. package/dist/cli/convoy/pipeline.test.js +30 -0
  6. package/dist/cli/convoy/pipeline.test.js.map +1 -1
  7. package/dist/cli/run.d.ts.map +1 -1
  8. package/dist/cli/run.js +87 -3
  9. package/dist/cli/run.js.map +1 -1
  10. package/package.json +1 -1
  11. package/src/cli/convoy/pipeline.test.ts +30 -0
  12. package/src/cli/convoy/pipeline.ts +15 -3
  13. package/src/cli/run.ts +87 -3
  14. package/src/dashboard/dist/data/convoys/demo-api-v2.json +3 -3
  15. package/src/dashboard/dist/data/convoys/demo-auth-revamp.json +4 -4
  16. package/src/dashboard/dist/data/convoys/demo-dashboard-ui.json +24 -24
  17. package/src/dashboard/dist/data/convoys/demo-data-pipeline.json +3 -3
  18. package/src/dashboard/dist/data/convoys/demo-deploy-ci.json +1 -1
  19. package/src/dashboard/dist/data/convoys/demo-docs-update.json +3 -3
  20. package/src/dashboard/dist/data/convoys/demo-perf-opt.json +4 -4
  21. package/src/dashboard/dist/index.html +13 -10
  22. package/src/dashboard/node_modules/.vite/deps/_metadata.json +6 -6
  23. package/src/dashboard/public/data/convoys/demo-api-v2.json +3 -3
  24. package/src/dashboard/public/data/convoys/demo-auth-revamp.json +4 -4
  25. package/src/dashboard/public/data/convoys/demo-dashboard-ui.json +24 -24
  26. package/src/dashboard/public/data/convoys/demo-data-pipeline.json +3 -3
  27. package/src/dashboard/public/data/convoys/demo-deploy-ci.json +1 -1
  28. package/src/dashboard/public/data/convoys/demo-docs-update.json +3 -3
  29. package/src/dashboard/public/data/convoys/demo-perf-opt.json +4 -4
  30. package/src/dashboard/src/pages/index.astro +13 -10
@@ -42,28 +42,28 @@
42
42
  "name": "libs/auth/src/jwt-middleware.ts",
43
43
  "type": "file",
44
44
  "task_id": "auth-t2",
45
- "created_at": "2026-04-06T07:21:04.702Z"
45
+ "created_at": "2026-04-06T09:01:29.677Z"
46
46
  },
47
47
  {
48
48
  "id": "artifact-demo-auth-revamp-libs-auth-src-rls-policies-sql",
49
49
  "name": "libs/auth/src/rls-policies.sql",
50
50
  "type": "file",
51
51
  "task_id": "auth-t3",
52
- "created_at": "2026-04-06T07:21:04.702Z"
52
+ "created_at": "2026-04-06T09:01:29.677Z"
53
53
  },
54
54
  {
55
55
  "id": "artifact-demo-auth-revamp-reports-auth-review-summary-md",
56
56
  "name": "reports/auth-review-summary.md",
57
57
  "type": "summary",
58
58
  "task_id": "auth-t5",
59
- "created_at": "2026-04-06T07:21:04.702Z"
59
+ "created_at": "2026-04-06T09:01:29.677Z"
60
60
  },
61
61
  {
62
62
  "id": "artifact-demo-auth-revamp-tests-auth-integration-test-ts",
63
63
  "name": "tests/auth/integration.test.ts",
64
64
  "type": "file",
65
65
  "task_id": "auth-t4",
66
- "created_at": "2026-04-06T07:21:04.702Z"
66
+ "created_at": "2026-04-06T09:01:29.677Z"
67
67
  }
68
68
  ],
69
69
  "has_more_events": false,
@@ -46,47 +46,47 @@
46
46
  ],
47
47
  "artifact_count": 6,
48
48
  "artifacts": [
49
- {
50
- "id": "artifact-demo-dashboard-ui-reports-visual-regression-json",
51
- "name": "reports/visual-regression.json",
52
- "type": "json",
53
- "task_id": "ui-t6",
54
- "created_at": "2026-04-06T07:21:04.702Z"
55
- },
56
- {
57
- "id": "artifact-demo-dashboard-ui-src-components-DonutChart-tsx",
58
- "name": "src/components/DonutChart.tsx",
59
- "type": "file",
60
- "task_id": "ui-t3",
61
- "created_at": "2026-04-06T07:21:04.702Z"
62
- },
63
49
  {
64
50
  "id": "artifact-demo-dashboard-ui-src-components-KpiCard-tsx",
65
51
  "name": "src/components/KpiCard.tsx",
66
52
  "type": "file",
67
53
  "task_id": "ui-t2",
68
- "created_at": "2026-04-06T07:21:04.702Z"
54
+ "created_at": "2026-04-06T09:01:29.677Z"
69
55
  },
70
56
  {
71
57
  "id": "artifact-demo-dashboard-ui-src-components-design-tokens-ts",
72
58
  "name": "src/components/design-tokens.ts",
73
59
  "type": "file",
74
60
  "task_id": "ui-t1",
75
- "created_at": "2026-04-06T07:21:04.702Z"
76
- },
77
- {
78
- "id": "artifact-demo-dashboard-ui-src-styles-animations-css",
79
- "name": "src/styles/animations.css",
80
- "type": "file",
81
- "task_id": "ui-t4",
82
- "created_at": "2026-04-06T07:21:04.702Z"
61
+ "created_at": "2026-04-06T09:01:29.677Z"
83
62
  },
84
63
  {
85
64
  "id": "artifact-demo-dashboard-ui-reports-panel-review-dashboard-md",
86
65
  "name": "reports/panel-review-dashboard.md",
87
66
  "type": "summary",
88
67
  "task_id": "ui-t7",
89
- "created_at": "2026-04-06T07:21:04.703Z"
68
+ "created_at": "2026-04-06T09:01:29.678Z"
69
+ },
70
+ {
71
+ "id": "artifact-demo-dashboard-ui-reports-visual-regression-json",
72
+ "name": "reports/visual-regression.json",
73
+ "type": "json",
74
+ "task_id": "ui-t6",
75
+ "created_at": "2026-04-06T09:01:29.678Z"
76
+ },
77
+ {
78
+ "id": "artifact-demo-dashboard-ui-src-components-DonutChart-tsx",
79
+ "name": "src/components/DonutChart.tsx",
80
+ "type": "file",
81
+ "task_id": "ui-t3",
82
+ "created_at": "2026-04-06T09:01:29.678Z"
83
+ },
84
+ {
85
+ "id": "artifact-demo-dashboard-ui-src-styles-animations-css",
86
+ "name": "src/styles/animations.css",
87
+ "type": "file",
88
+ "task_id": "ui-t4",
89
+ "created_at": "2026-04-06T09:01:29.678Z"
90
90
  }
91
91
  ],
92
92
  "has_more_events": false,
@@ -42,21 +42,21 @@
42
42
  "name": "src/etl/pipeline.ts",
43
43
  "type": "file",
44
44
  "task_id": "etl-t2",
45
- "created_at": "2026-04-06T07:21:04.703Z"
45
+ "created_at": "2026-04-06T09:01:29.678Z"
46
46
  },
47
47
  {
48
48
  "id": "artifact-demo-data-pipeline-src-etl-schema-ts",
49
49
  "name": "src/etl/schema.ts",
50
50
  "type": "file",
51
51
  "task_id": "etl-t1",
52
- "created_at": "2026-04-06T07:21:04.703Z"
52
+ "created_at": "2026-04-06T09:01:29.678Z"
53
53
  },
54
54
  {
55
55
  "id": "artifact-demo-data-pipeline-tests-etl-pipeline-test-ts",
56
56
  "name": "tests/etl/pipeline.test.ts",
57
57
  "type": "file",
58
58
  "task_id": "etl-t3",
59
- "created_at": "2026-04-06T07:21:04.703Z"
59
+ "created_at": "2026-04-06T09:01:29.679Z"
60
60
  }
61
61
  ],
62
62
  "has_more_events": false,
@@ -51,7 +51,7 @@
51
51
  "name": ".github/workflows/ci.yml",
52
52
  "type": "file",
53
53
  "task_id": "ci-t1",
54
- "created_at": "2026-04-06T07:21:04.704Z"
54
+ "created_at": "2026-04-06T09:01:29.679Z"
55
55
  }
56
56
  ],
57
57
  "has_more_events": false,
@@ -42,21 +42,21 @@
42
42
  "name": "docs/ARCHITECTURE.md",
43
43
  "type": "file",
44
44
  "task_id": "docs-t1",
45
- "created_at": "2026-04-06T07:21:04.704Z"
45
+ "created_at": "2026-04-06T09:01:29.679Z"
46
46
  },
47
47
  {
48
48
  "id": "artifact-demo-docs-update-docs-README-md",
49
49
  "name": "docs/README.md",
50
50
  "type": "file",
51
51
  "task_id": "docs-t1",
52
- "created_at": "2026-04-06T07:21:04.704Z"
52
+ "created_at": "2026-04-06T09:01:29.679Z"
53
53
  },
54
54
  {
55
55
  "id": "artifact-demo-docs-update-docs-api-reference-json",
56
56
  "name": "docs/api-reference.json",
57
57
  "type": "json",
58
58
  "task_id": "docs-t2",
59
- "created_at": "2026-04-06T07:21:04.704Z"
59
+ "created_at": "2026-04-06T09:01:29.679Z"
60
60
  }
61
61
  ],
62
62
  "has_more_events": false,
@@ -42,28 +42,28 @@
42
42
  "name": "reports/bundle-analysis.json",
43
43
  "type": "json",
44
44
  "task_id": "perf-t1",
45
- "created_at": "2026-04-06T07:21:04.703Z"
45
+ "created_at": "2026-04-06T09:01:29.678Z"
46
46
  },
47
47
  {
48
48
  "id": "artifact-demo-perf-opt-reports-web-vitals-improvement-md",
49
49
  "name": "reports/web-vitals-improvement.md",
50
50
  "type": "summary",
51
51
  "task_id": "perf-t4",
52
- "created_at": "2026-04-06T07:21:04.703Z"
52
+ "created_at": "2026-04-06T09:01:29.678Z"
53
53
  },
54
54
  {
55
55
  "id": "artifact-demo-perf-opt-src-charts-index-ts",
56
56
  "name": "src/charts/index.ts",
57
57
  "type": "file",
58
58
  "task_id": "perf-t2",
59
- "created_at": "2026-04-06T07:21:04.703Z"
59
+ "created_at": "2026-04-06T09:01:29.678Z"
60
60
  },
61
61
  {
62
62
  "id": "artifact-demo-perf-opt-src-utils-image-loader-ts",
63
63
  "name": "src/utils/image-loader.ts",
64
64
  "type": "file",
65
65
  "task_id": "perf-t3",
66
- "created_at": "2026-04-06T07:21:04.703Z"
66
+ "created_at": "2026-04-06T09:01:29.678Z"
67
67
  }
68
68
  ],
69
69
  "has_more_events": false,
@@ -124,8 +124,8 @@ Export
124
124
  const convoy = data.convoy;
125
125
  const isRunningOrPending = convoy.status === 'running' || convoy.status === 'pending';
126
126
 
127
- // If we haven't navigated to any convoy yet, navigate now
128
- if (!_activePollingConvoyId) {
127
+ // If we haven't navigated to any convoy yet, navigate to a running/pending one
128
+ if (!_activePollingConvoyId && isRunningOrPending) {
129
129
  _activePollingConvoyId = convoy.id;
130
130
  _lastPolledConvoyStatus = null;
131
131
  // Refresh ETL data so convoy detail JSON exists
@@ -1811,18 +1811,21 @@ Export
1811
1811
 
1812
1812
  if (convoyParam === 'active') {
1813
1813
  const running = convoys.find((c) => c.status === 'running');
1814
- const latest = convoys.slice().sort((a, b) => b.created_at.localeCompare(a.created_at))[0];
1815
- const target = running || latest;
1816
- if (target) {
1817
- _activePollingConvoyId = target.id;
1814
+ const pending = convoys.find((c) => c.status === 'pending');
1815
+ const active = running || pending;
1816
+ if (active) {
1817
+ // A convoy is actively running or pending — show it directly
1818
+ _activePollingConvoyId = active.id;
1818
1819
  _lastPolledConvoyStatus = null;
1819
- showConvoyDetailView(target.id, target.name || target.id);
1820
- startActiveConvoyPolling();
1820
+ // Ensure ETL data exists for this convoy before rendering
1821
+ fetch(base + 'data/refresh').catch(() => {});
1822
+ showConvoyDetailView(active.id, active.name || active.id);
1821
1823
  } else {
1822
- // No convoy exists yet — show waiting state and poll
1824
+ // No active convoy yet — show waiting banner until one starts
1823
1825
  showWaitingBanner();
1824
- startActiveConvoyPolling();
1825
1826
  }
1827
+ // Always poll in active mode — detects new convoys automatically
1828
+ startActiveConvoyPolling();
1826
1829
  } else if (convoyParam) {
1827
1830
  showConvoyDetailView(convoyParam, convoyParam);
1828
1831
  }
@@ -1,25 +1,25 @@
1
1
  {
2
- "hash": "d74027c1",
2
+ "hash": "f9d8b2ea",
3
3
  "configHash": "30f8ea04",
4
- "lockfileHash": "28031305",
5
- "browserHash": "bbd1c901",
4
+ "lockfileHash": "551cc41b",
5
+ "browserHash": "0d3f31ae",
6
6
  "optimized": {
7
7
  "astro > cssesc": {
8
8
  "src": "../../../../../node_modules/cssesc/cssesc.js",
9
9
  "file": "astro___cssesc.js",
10
- "fileHash": "a24223d9",
10
+ "fileHash": "a83566fd",
11
11
  "needsInterop": true
12
12
  },
13
13
  "astro > aria-query": {
14
14
  "src": "../../../../../node_modules/aria-query/lib/index.js",
15
15
  "file": "astro___aria-query.js",
16
- "fileHash": "ebcad73a",
16
+ "fileHash": "3ecfd4b9",
17
17
  "needsInterop": true
18
18
  },
19
19
  "astro > axobject-query": {
20
20
  "src": "../../../../../node_modules/axobject-query/lib/index.js",
21
21
  "file": "astro___axobject-query.js",
22
- "fileHash": "d06654a7",
22
+ "fileHash": "8b00bf90",
23
23
  "needsInterop": true
24
24
  }
25
25
  },
@@ -51,21 +51,21 @@
51
51
  "name": "docs/api-v2-contract.json",
52
52
  "type": "json",
53
53
  "task_id": "api-t1",
54
- "created_at": "2026-04-06T07:21:04.703Z"
54
+ "created_at": "2026-04-06T09:01:29.678Z"
55
55
  },
56
56
  {
57
57
  "id": "artifact-demo-api-v2-reports-security-gate-failure-md",
58
58
  "name": "reports/security-gate-failure.md",
59
59
  "type": "summary",
60
60
  "task_id": "api-t3",
61
- "created_at": "2026-04-06T07:21:04.703Z"
61
+ "created_at": "2026-04-06T09:01:29.678Z"
62
62
  },
63
63
  {
64
64
  "id": "artifact-demo-api-v2-src-api-rate-limiter-ts",
65
65
  "name": "src/api/rate-limiter.ts",
66
66
  "type": "file",
67
67
  "task_id": "api-t2",
68
- "created_at": "2026-04-06T07:21:04.703Z"
68
+ "created_at": "2026-04-06T09:01:29.678Z"
69
69
  }
70
70
  ],
71
71
  "has_more_events": false,
@@ -42,28 +42,28 @@
42
42
  "name": "libs/auth/src/jwt-middleware.ts",
43
43
  "type": "file",
44
44
  "task_id": "auth-t2",
45
- "created_at": "2026-04-06T07:21:04.702Z"
45
+ "created_at": "2026-04-06T09:01:29.677Z"
46
46
  },
47
47
  {
48
48
  "id": "artifact-demo-auth-revamp-libs-auth-src-rls-policies-sql",
49
49
  "name": "libs/auth/src/rls-policies.sql",
50
50
  "type": "file",
51
51
  "task_id": "auth-t3",
52
- "created_at": "2026-04-06T07:21:04.702Z"
52
+ "created_at": "2026-04-06T09:01:29.677Z"
53
53
  },
54
54
  {
55
55
  "id": "artifact-demo-auth-revamp-reports-auth-review-summary-md",
56
56
  "name": "reports/auth-review-summary.md",
57
57
  "type": "summary",
58
58
  "task_id": "auth-t5",
59
- "created_at": "2026-04-06T07:21:04.702Z"
59
+ "created_at": "2026-04-06T09:01:29.677Z"
60
60
  },
61
61
  {
62
62
  "id": "artifact-demo-auth-revamp-tests-auth-integration-test-ts",
63
63
  "name": "tests/auth/integration.test.ts",
64
64
  "type": "file",
65
65
  "task_id": "auth-t4",
66
- "created_at": "2026-04-06T07:21:04.702Z"
66
+ "created_at": "2026-04-06T09:01:29.677Z"
67
67
  }
68
68
  ],
69
69
  "has_more_events": false,
@@ -46,47 +46,47 @@
46
46
  ],
47
47
  "artifact_count": 6,
48
48
  "artifacts": [
49
- {
50
- "id": "artifact-demo-dashboard-ui-reports-visual-regression-json",
51
- "name": "reports/visual-regression.json",
52
- "type": "json",
53
- "task_id": "ui-t6",
54
- "created_at": "2026-04-06T07:21:04.702Z"
55
- },
56
- {
57
- "id": "artifact-demo-dashboard-ui-src-components-DonutChart-tsx",
58
- "name": "src/components/DonutChart.tsx",
59
- "type": "file",
60
- "task_id": "ui-t3",
61
- "created_at": "2026-04-06T07:21:04.702Z"
62
- },
63
49
  {
64
50
  "id": "artifact-demo-dashboard-ui-src-components-KpiCard-tsx",
65
51
  "name": "src/components/KpiCard.tsx",
66
52
  "type": "file",
67
53
  "task_id": "ui-t2",
68
- "created_at": "2026-04-06T07:21:04.702Z"
54
+ "created_at": "2026-04-06T09:01:29.677Z"
69
55
  },
70
56
  {
71
57
  "id": "artifact-demo-dashboard-ui-src-components-design-tokens-ts",
72
58
  "name": "src/components/design-tokens.ts",
73
59
  "type": "file",
74
60
  "task_id": "ui-t1",
75
- "created_at": "2026-04-06T07:21:04.702Z"
76
- },
77
- {
78
- "id": "artifact-demo-dashboard-ui-src-styles-animations-css",
79
- "name": "src/styles/animations.css",
80
- "type": "file",
81
- "task_id": "ui-t4",
82
- "created_at": "2026-04-06T07:21:04.702Z"
61
+ "created_at": "2026-04-06T09:01:29.677Z"
83
62
  },
84
63
  {
85
64
  "id": "artifact-demo-dashboard-ui-reports-panel-review-dashboard-md",
86
65
  "name": "reports/panel-review-dashboard.md",
87
66
  "type": "summary",
88
67
  "task_id": "ui-t7",
89
- "created_at": "2026-04-06T07:21:04.703Z"
68
+ "created_at": "2026-04-06T09:01:29.678Z"
69
+ },
70
+ {
71
+ "id": "artifact-demo-dashboard-ui-reports-visual-regression-json",
72
+ "name": "reports/visual-regression.json",
73
+ "type": "json",
74
+ "task_id": "ui-t6",
75
+ "created_at": "2026-04-06T09:01:29.678Z"
76
+ },
77
+ {
78
+ "id": "artifact-demo-dashboard-ui-src-components-DonutChart-tsx",
79
+ "name": "src/components/DonutChart.tsx",
80
+ "type": "file",
81
+ "task_id": "ui-t3",
82
+ "created_at": "2026-04-06T09:01:29.678Z"
83
+ },
84
+ {
85
+ "id": "artifact-demo-dashboard-ui-src-styles-animations-css",
86
+ "name": "src/styles/animations.css",
87
+ "type": "file",
88
+ "task_id": "ui-t4",
89
+ "created_at": "2026-04-06T09:01:29.678Z"
90
90
  }
91
91
  ],
92
92
  "has_more_events": false,
@@ -42,21 +42,21 @@
42
42
  "name": "src/etl/pipeline.ts",
43
43
  "type": "file",
44
44
  "task_id": "etl-t2",
45
- "created_at": "2026-04-06T07:21:04.703Z"
45
+ "created_at": "2026-04-06T09:01:29.678Z"
46
46
  },
47
47
  {
48
48
  "id": "artifact-demo-data-pipeline-src-etl-schema-ts",
49
49
  "name": "src/etl/schema.ts",
50
50
  "type": "file",
51
51
  "task_id": "etl-t1",
52
- "created_at": "2026-04-06T07:21:04.703Z"
52
+ "created_at": "2026-04-06T09:01:29.678Z"
53
53
  },
54
54
  {
55
55
  "id": "artifact-demo-data-pipeline-tests-etl-pipeline-test-ts",
56
56
  "name": "tests/etl/pipeline.test.ts",
57
57
  "type": "file",
58
58
  "task_id": "etl-t3",
59
- "created_at": "2026-04-06T07:21:04.703Z"
59
+ "created_at": "2026-04-06T09:01:29.679Z"
60
60
  }
61
61
  ],
62
62
  "has_more_events": false,
@@ -51,7 +51,7 @@
51
51
  "name": ".github/workflows/ci.yml",
52
52
  "type": "file",
53
53
  "task_id": "ci-t1",
54
- "created_at": "2026-04-06T07:21:04.704Z"
54
+ "created_at": "2026-04-06T09:01:29.679Z"
55
55
  }
56
56
  ],
57
57
  "has_more_events": false,
@@ -42,21 +42,21 @@
42
42
  "name": "docs/ARCHITECTURE.md",
43
43
  "type": "file",
44
44
  "task_id": "docs-t1",
45
- "created_at": "2026-04-06T07:21:04.704Z"
45
+ "created_at": "2026-04-06T09:01:29.679Z"
46
46
  },
47
47
  {
48
48
  "id": "artifact-demo-docs-update-docs-README-md",
49
49
  "name": "docs/README.md",
50
50
  "type": "file",
51
51
  "task_id": "docs-t1",
52
- "created_at": "2026-04-06T07:21:04.704Z"
52
+ "created_at": "2026-04-06T09:01:29.679Z"
53
53
  },
54
54
  {
55
55
  "id": "artifact-demo-docs-update-docs-api-reference-json",
56
56
  "name": "docs/api-reference.json",
57
57
  "type": "json",
58
58
  "task_id": "docs-t2",
59
- "created_at": "2026-04-06T07:21:04.704Z"
59
+ "created_at": "2026-04-06T09:01:29.679Z"
60
60
  }
61
61
  ],
62
62
  "has_more_events": false,
@@ -42,28 +42,28 @@
42
42
  "name": "reports/bundle-analysis.json",
43
43
  "type": "json",
44
44
  "task_id": "perf-t1",
45
- "created_at": "2026-04-06T07:21:04.703Z"
45
+ "created_at": "2026-04-06T09:01:29.678Z"
46
46
  },
47
47
  {
48
48
  "id": "artifact-demo-perf-opt-reports-web-vitals-improvement-md",
49
49
  "name": "reports/web-vitals-improvement.md",
50
50
  "type": "summary",
51
51
  "task_id": "perf-t4",
52
- "created_at": "2026-04-06T07:21:04.703Z"
52
+ "created_at": "2026-04-06T09:01:29.678Z"
53
53
  },
54
54
  {
55
55
  "id": "artifact-demo-perf-opt-src-charts-index-ts",
56
56
  "name": "src/charts/index.ts",
57
57
  "type": "file",
58
58
  "task_id": "perf-t2",
59
- "created_at": "2026-04-06T07:21:04.703Z"
59
+ "created_at": "2026-04-06T09:01:29.678Z"
60
60
  },
61
61
  {
62
62
  "id": "artifact-demo-perf-opt-src-utils-image-loader-ts",
63
63
  "name": "src/utils/image-loader.ts",
64
64
  "type": "file",
65
65
  "task_id": "perf-t3",
66
- "created_at": "2026-04-06T07:21:04.703Z"
66
+ "created_at": "2026-04-06T09:01:29.678Z"
67
67
  }
68
68
  ],
69
69
  "has_more_events": false,
@@ -474,8 +474,8 @@ try {
474
474
  const convoy = data.convoy;
475
475
  const isRunningOrPending = convoy.status === 'running' || convoy.status === 'pending';
476
476
 
477
- // If we haven't navigated to any convoy yet, navigate now
478
- if (!_activePollingConvoyId) {
477
+ // If we haven't navigated to any convoy yet, navigate to a running/pending one
478
+ if (!_activePollingConvoyId && isRunningOrPending) {
479
479
  _activePollingConvoyId = convoy.id;
480
480
  _lastPolledConvoyStatus = null;
481
481
  // Refresh ETL data so convoy detail JSON exists
@@ -2161,18 +2161,21 @@ try {
2161
2161
 
2162
2162
  if (convoyParam === 'active') {
2163
2163
  const running = convoys.find((c) => c.status === 'running');
2164
- const latest = convoys.slice().sort((a, b) => b.created_at.localeCompare(a.created_at))[0];
2165
- const target = running || latest;
2166
- if (target) {
2167
- _activePollingConvoyId = target.id;
2164
+ const pending = convoys.find((c) => c.status === 'pending');
2165
+ const active = running || pending;
2166
+ if (active) {
2167
+ // A convoy is actively running or pending — show it directly
2168
+ _activePollingConvoyId = active.id;
2168
2169
  _lastPolledConvoyStatus = null;
2169
- showConvoyDetailView(target.id, target.name || target.id);
2170
- startActiveConvoyPolling();
2170
+ // Ensure ETL data exists for this convoy before rendering
2171
+ fetch(base + 'data/refresh').catch(() => {});
2172
+ showConvoyDetailView(active.id, active.name || active.id);
2171
2173
  } else {
2172
- // No convoy exists yet — show waiting state and poll
2174
+ // No active convoy yet — show waiting banner until one starts
2173
2175
  showWaitingBanner();
2174
- startActiveConvoyPolling();
2175
2176
  }
2177
+ // Always poll in active mode — detects new convoys automatically
2178
+ startActiveConvoyPolling();
2176
2179
  } else if (convoyParam) {
2177
2180
  showConvoyDetailView(convoyParam, convoyParam);
2178
2181
  }