@worca/ui 0.2.0 → 0.3.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.
- package/app/main.bundle.js +676 -628
- package/app/main.bundle.js.map +3 -3
- package/app/styles.css +117 -0
- package/package.json +1 -1
- package/server/watcher.js +7 -18
package/app/styles.css
CHANGED
|
@@ -3937,3 +3937,120 @@ sl-details.learnings-panel::part(content) {
|
|
|
3937
3937
|
.project-worca-version { font-size: 11px; color: var(--muted); font-family: var(--sl-font-mono); margin-top: 2px; }
|
|
3938
3938
|
.project-worca-version--behind { color: var(--status-failed, #dc2626); }
|
|
3939
3939
|
|
|
3940
|
+
/* ─── Bead tooltip content ──────────────────────────────────────────── */
|
|
3941
|
+
.bead-tooltip-content {
|
|
3942
|
+
max-width: 540px;
|
|
3943
|
+
padding: 4px 2px;
|
|
3944
|
+
display: flex;
|
|
3945
|
+
flex-direction: column;
|
|
3946
|
+
gap: 2px;
|
|
3947
|
+
}
|
|
3948
|
+
|
|
3949
|
+
.bead-tooltip-header {
|
|
3950
|
+
display: flex;
|
|
3951
|
+
align-items: center;
|
|
3952
|
+
justify-content: space-between;
|
|
3953
|
+
gap: 12px;
|
|
3954
|
+
}
|
|
3955
|
+
|
|
3956
|
+
sl-tooltip.bead-tooltip::part(body) {
|
|
3957
|
+
pointer-events: auto;
|
|
3958
|
+
}
|
|
3959
|
+
|
|
3960
|
+
.bead-tooltip-badges {
|
|
3961
|
+
display: flex;
|
|
3962
|
+
align-items: center;
|
|
3963
|
+
gap: 4px;
|
|
3964
|
+
}
|
|
3965
|
+
|
|
3966
|
+
.bead-tooltip-id {
|
|
3967
|
+
font-family: var(--sl-font-mono);
|
|
3968
|
+
font-size: 11px;
|
|
3969
|
+
opacity: 0.7;
|
|
3970
|
+
font-weight: 600;
|
|
3971
|
+
text-transform: uppercase;
|
|
3972
|
+
letter-spacing: 0.03em;
|
|
3973
|
+
}
|
|
3974
|
+
|
|
3975
|
+
.bead-tooltip-separator {
|
|
3976
|
+
border: none;
|
|
3977
|
+
border-top: 1px solid rgba(255, 255, 255, 0.2);
|
|
3978
|
+
margin: 4px 0;
|
|
3979
|
+
}
|
|
3980
|
+
|
|
3981
|
+
.bead-tooltip-label {
|
|
3982
|
+
font-size: 11px;
|
|
3983
|
+
opacity: 0.7;
|
|
3984
|
+
font-weight: 600;
|
|
3985
|
+
text-transform: uppercase;
|
|
3986
|
+
letter-spacing: 0.03em;
|
|
3987
|
+
}
|
|
3988
|
+
|
|
3989
|
+
.bead-tooltip-title {
|
|
3990
|
+
font-weight: 600;
|
|
3991
|
+
font-size: 13px;
|
|
3992
|
+
margin-bottom: 4px;
|
|
3993
|
+
}
|
|
3994
|
+
|
|
3995
|
+
.bead-tooltip-excerpt {
|
|
3996
|
+
font-size: 12px;
|
|
3997
|
+
white-space: pre-wrap;
|
|
3998
|
+
margin-bottom: 2px;
|
|
3999
|
+
}
|
|
4000
|
+
|
|
4001
|
+
.bead-tooltip-footer {
|
|
4002
|
+
display: flex;
|
|
4003
|
+
justify-content: flex-end;
|
|
4004
|
+
margin-top: 6px;
|
|
4005
|
+
}
|
|
4006
|
+
|
|
4007
|
+
.bead-tooltip-copy {
|
|
4008
|
+
display: inline-flex;
|
|
4009
|
+
align-items: center;
|
|
4010
|
+
gap: 4px;
|
|
4011
|
+
background: rgba(255, 255, 255, 0.15);
|
|
4012
|
+
color: inherit;
|
|
4013
|
+
border: 1px solid rgba(255, 255, 255, 0.25);
|
|
4014
|
+
border-radius: 4px;
|
|
4015
|
+
padding: 3px 8px;
|
|
4016
|
+
font-size: 11px;
|
|
4017
|
+
cursor: pointer;
|
|
4018
|
+
transition: background 0.15s;
|
|
4019
|
+
}
|
|
4020
|
+
|
|
4021
|
+
.bead-tooltip-copy:hover {
|
|
4022
|
+
background: rgba(255, 255, 255, 0.25);
|
|
4023
|
+
}
|
|
4024
|
+
|
|
4025
|
+
/* ─── Graph node tooltip overlays ─────────────────────────────────── */
|
|
4026
|
+
.run-beads-graph {
|
|
4027
|
+
position: relative;
|
|
4028
|
+
}
|
|
4029
|
+
|
|
4030
|
+
.graph-tooltip-trigger {
|
|
4031
|
+
position: absolute;
|
|
4032
|
+
cursor: pointer;
|
|
4033
|
+
}
|
|
4034
|
+
|
|
4035
|
+
.bead-chip-tooltip {
|
|
4036
|
+
display: flex;
|
|
4037
|
+
flex-direction: column;
|
|
4038
|
+
gap: 3px;
|
|
4039
|
+
max-width: 240px;
|
|
4040
|
+
padding: 2px 0;
|
|
4041
|
+
}
|
|
4042
|
+
|
|
4043
|
+
.bead-chip-tooltip-id {
|
|
4044
|
+
font-family: var(--sl-font-mono);
|
|
4045
|
+
font-size: 12px;
|
|
4046
|
+
font-weight: 600;
|
|
4047
|
+
}
|
|
4048
|
+
|
|
4049
|
+
.bead-chip-tooltip-title {
|
|
4050
|
+
font-size: 12px;
|
|
4051
|
+
color: var(--muted);
|
|
4052
|
+
white-space: nowrap;
|
|
4053
|
+
overflow: hidden;
|
|
4054
|
+
text-overflow: ellipsis;
|
|
4055
|
+
}
|
|
4056
|
+
|
package/package.json
CHANGED
package/server/watcher.js
CHANGED
|
@@ -26,22 +26,9 @@ function isTerminal(status) {
|
|
|
26
26
|
);
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
function isPipelineRunning(worcaDir) {
|
|
30
|
-
const pidPath = join(worcaDir, 'pipeline.pid');
|
|
31
|
-
if (!existsSync(pidPath)) return false;
|
|
32
|
-
try {
|
|
33
|
-
const pid = parseInt(readFileSync(pidPath, 'utf8').trim(), 10);
|
|
34
|
-
process.kill(pid, 0); // signal 0 = check if alive
|
|
35
|
-
return true;
|
|
36
|
-
} catch {
|
|
37
|
-
return false; // stale PID or unreadable
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
29
|
export function discoverRuns(worcaDir) {
|
|
42
30
|
const runs = [];
|
|
43
31
|
const seenIds = new Set();
|
|
44
|
-
const pipelineRunning = isPipelineRunning(worcaDir);
|
|
45
32
|
|
|
46
33
|
// 1. Check active_run pointer for the current run
|
|
47
34
|
const activeRunPath = join(worcaDir, 'active_run');
|
|
@@ -51,7 +38,8 @@ export function discoverRuns(worcaDir) {
|
|
|
51
38
|
const candidate = join(worcaDir, 'runs', activeId, 'status.json');
|
|
52
39
|
if (existsSync(candidate)) {
|
|
53
40
|
const status = JSON.parse(readFileSync(candidate, 'utf8'));
|
|
54
|
-
const active =
|
|
41
|
+
const active =
|
|
42
|
+
!isTerminal(status) && status.pipeline_status === 'running';
|
|
55
43
|
const id = createRunId(status);
|
|
56
44
|
runs.push({ id, active, ...status });
|
|
57
45
|
seenIds.add(id);
|
|
@@ -88,7 +76,8 @@ export function discoverRuns(worcaDir) {
|
|
|
88
76
|
const status = JSON.parse(readFileSync(statusPath, 'utf8'));
|
|
89
77
|
const id = createRunId(status);
|
|
90
78
|
if (!seenIds.has(id)) {
|
|
91
|
-
const active =
|
|
79
|
+
const active =
|
|
80
|
+
!isTerminal(status) && status.pipeline_status === 'running';
|
|
92
81
|
runs.push({ id, active, ...status });
|
|
93
82
|
seenIds.add(id);
|
|
94
83
|
}
|
|
@@ -142,7 +131,6 @@ export function discoverRuns(worcaDir) {
|
|
|
142
131
|
export async function discoverRunsAsync(worcaDir) {
|
|
143
132
|
const runs = [];
|
|
144
133
|
const seenIds = new Set();
|
|
145
|
-
const pipelineRunning = isPipelineRunning(worcaDir); // cheap check (one stat + one kill)
|
|
146
134
|
|
|
147
135
|
// 1. Active run
|
|
148
136
|
const activeRunPath = join(worcaDir, 'active_run');
|
|
@@ -150,7 +138,7 @@ export async function discoverRunsAsync(worcaDir) {
|
|
|
150
138
|
const activeId = (await readFile(activeRunPath, 'utf8')).trim();
|
|
151
139
|
const candidate = join(worcaDir, 'runs', activeId, 'status.json');
|
|
152
140
|
const status = JSON.parse(await readFile(candidate, 'utf8'));
|
|
153
|
-
const active = !isTerminal(status) &&
|
|
141
|
+
const active = !isTerminal(status) && status.pipeline_status === 'running';
|
|
154
142
|
const id = createRunId(status);
|
|
155
143
|
runs.push({ id, active, ...status });
|
|
156
144
|
seenIds.add(id);
|
|
@@ -191,7 +179,8 @@ export async function discoverRunsAsync(worcaDir) {
|
|
|
191
179
|
);
|
|
192
180
|
const id = createRunId(status);
|
|
193
181
|
if (!seenIds.has(id)) {
|
|
194
|
-
const active =
|
|
182
|
+
const active =
|
|
183
|
+
!isTerminal(status) && status.pipeline_status === 'running';
|
|
195
184
|
runs.push({ id, active, ...status });
|
|
196
185
|
seenIds.add(id);
|
|
197
186
|
}
|