clementine-agent 1.3.1 → 1.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.
- package/dist/cli/dashboard.js +400 -149
- package/package.json +1 -1
package/dist/cli/dashboard.js
CHANGED
|
@@ -2513,6 +2513,37 @@ export async function cmdDashboard(opts) {
|
|
|
2513
2513
|
res.status(500).json({ error: 'mcp-discovery failed', detail: String(err) });
|
|
2514
2514
|
}
|
|
2515
2515
|
});
|
|
2516
|
+
app.delete('/api/builder/workflows/:id', async (req, res) => {
|
|
2517
|
+
try {
|
|
2518
|
+
const id = decodeURIComponent(req.params.id);
|
|
2519
|
+
const [{ readWorkflow, parseBuilderId }, { emitBuilderEvent }] = await Promise.all([
|
|
2520
|
+
import('../dashboard/builder/serializer.js'),
|
|
2521
|
+
import('../dashboard/builder/events.js'),
|
|
2522
|
+
]);
|
|
2523
|
+
const parsed = parseBuilderId(id);
|
|
2524
|
+
if (!parsed) {
|
|
2525
|
+
res.status(400).json({ error: 'Bad id' });
|
|
2526
|
+
return;
|
|
2527
|
+
}
|
|
2528
|
+
if (parsed.origin === 'cron') {
|
|
2529
|
+
res.status(400).json({ error: 'Cron entries: use workflow_set_enabled false (or edit CRON.md directly).' });
|
|
2530
|
+
return;
|
|
2531
|
+
}
|
|
2532
|
+
const wf = readWorkflow(id);
|
|
2533
|
+
if (!wf) {
|
|
2534
|
+
res.status(404).json({ error: 'Not found' });
|
|
2535
|
+
return;
|
|
2536
|
+
}
|
|
2537
|
+
const { unlinkSync, existsSync } = await import('node:fs');
|
|
2538
|
+
if (wf.sourceFile && existsSync(wf.sourceFile))
|
|
2539
|
+
unlinkSync(wf.sourceFile);
|
|
2540
|
+
emitBuilderEvent({ type: 'workflow:deleted', workflowId: id });
|
|
2541
|
+
res.json({ ok: true });
|
|
2542
|
+
}
|
|
2543
|
+
catch (err) {
|
|
2544
|
+
res.status(500).json({ error: String(err) });
|
|
2545
|
+
}
|
|
2546
|
+
});
|
|
2516
2547
|
app.post('/api/builder/workflows/:id/save-from-drawflow', async (req, res) => {
|
|
2517
2548
|
try {
|
|
2518
2549
|
const id = decodeURIComponent(req.params.id);
|
|
@@ -8120,20 +8151,24 @@ if('serviceWorker' in navigator){navigator.serviceWorker.getRegistrations().then
|
|
|
8120
8151
|
</script>
|
|
8121
8152
|
<link rel="icon" href="/icon.svg" type="image/svg+xml">
|
|
8122
8153
|
<link rel="stylesheet" href="/static/drawflow.min.css">
|
|
8154
|
+
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
8155
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
8156
|
+
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap">
|
|
8123
8157
|
<title>${name} Command Center</title>
|
|
8124
8158
|
<style>
|
|
8125
8159
|
:root {
|
|
8126
|
-
|
|
8160
|
+
/* ── Slate palette (chromatic, not pure neutral) ── */
|
|
8161
|
+
--bg-primary: #f8fafc;
|
|
8127
8162
|
--bg-secondary: #ffffff;
|
|
8128
|
-
--bg-card: rgba(255,255,255,0.
|
|
8129
|
-
--bg-hover: #
|
|
8130
|
-
--bg-input: #
|
|
8131
|
-
--bg-tertiary: #
|
|
8132
|
-
--border: #
|
|
8133
|
-
--border-light: #
|
|
8134
|
-
--text-primary: #
|
|
8135
|
-
--text-secondary: #
|
|
8136
|
-
--text-muted: #
|
|
8163
|
+
--bg-card: rgba(255,255,255,0.96);
|
|
8164
|
+
--bg-hover: #f1f5f9;
|
|
8165
|
+
--bg-input: #f8fafc;
|
|
8166
|
+
--bg-tertiary: #e2e8f0;
|
|
8167
|
+
--border: #cbd5e1;
|
|
8168
|
+
--border-light: #e2e8f0;
|
|
8169
|
+
--text-primary: #0f172a;
|
|
8170
|
+
--text-secondary: #475569;
|
|
8171
|
+
--text-muted: #94a3b8;
|
|
8137
8172
|
--accent: #4d9eff;
|
|
8138
8173
|
--accent-glow: rgba(43, 125, 233, 0.10);
|
|
8139
8174
|
--purple: #7c3aed;
|
|
@@ -8142,56 +8177,122 @@ if('serviceWorker' in navigator){navigator.serviceWorker.getRegistrations().then
|
|
|
8142
8177
|
--clementine-dark: #e67a10;
|
|
8143
8178
|
--clementine-glow: rgba(255, 140, 33, 0.10);
|
|
8144
8179
|
--clementine-bg: rgba(255, 140, 33, 0.08);
|
|
8145
|
-
--green: #
|
|
8146
|
-
--green-bg: rgba(
|
|
8147
|
-
--red: #
|
|
8148
|
-
--red-bg: rgba(
|
|
8149
|
-
--yellow: #
|
|
8150
|
-
--yellow-bg: rgba(
|
|
8151
|
-
|
|
8152
|
-
--shadow-
|
|
8153
|
-
--shadow-
|
|
8154
|
-
--
|
|
8155
|
-
--
|
|
8156
|
-
|
|
8157
|
-
--
|
|
8180
|
+
--green: #16a34a;
|
|
8181
|
+
--green-bg: rgba(22, 163, 74, 0.10);
|
|
8182
|
+
--red: #ef4444;
|
|
8183
|
+
--red-bg: rgba(239, 68, 68, 0.10);
|
|
8184
|
+
--yellow: #ca8a04;
|
|
8185
|
+
--yellow-bg: rgba(202, 138, 4, 0.10);
|
|
8186
|
+
/* ── Shadows (softer + more elevated) ── */
|
|
8187
|
+
--shadow-xs: 0 1px 2px rgba(15, 23, 42, 0.04);
|
|
8188
|
+
--shadow-sm: 0 1px 3px rgba(15, 23, 42, 0.06), 0 1px 2px rgba(15, 23, 42, 0.04);
|
|
8189
|
+
--shadow-md: 0 4px 12px rgba(15, 23, 42, 0.08), 0 2px 4px rgba(15, 23, 42, 0.06);
|
|
8190
|
+
--shadow-lg: 0 12px 32px rgba(15, 23, 42, 0.12), 0 4px 8px rgba(15, 23, 42, 0.08);
|
|
8191
|
+
/* ── Layout ── */
|
|
8192
|
+
--sidebar-w: 200px;
|
|
8193
|
+
--header-h: 52px;
|
|
8194
|
+
/* ── Radius scale (tightened) ── */
|
|
8195
|
+
--radius-xs: 4px;
|
|
8196
|
+
--radius-sm: 6px;
|
|
8197
|
+
--radius-md: 8px;
|
|
8198
|
+
--radius-lg: 12px;
|
|
8199
|
+
--radius-xl: 16px;
|
|
8200
|
+
--radius: 8px; /* alias for legacy callers */
|
|
8201
|
+
/* ── Type scale ── */
|
|
8202
|
+
--text-xs: 11px;
|
|
8203
|
+
--text-sm: 12px;
|
|
8204
|
+
--text-base: 13px;
|
|
8205
|
+
--text-md: 14px;
|
|
8206
|
+
--text-lg: 16px;
|
|
8207
|
+
--text-xl: 20px;
|
|
8208
|
+
--text-2xl: 24px;
|
|
8209
|
+
/* ── Motion ── */
|
|
8210
|
+
--motion-fast: 100ms cubic-bezier(0.4, 0, 0.2, 1);
|
|
8211
|
+
--motion: 150ms cubic-bezier(0.4, 0, 0.2, 1);
|
|
8212
|
+
--motion-slow: 300ms cubic-bezier(0.4, 0, 0.2, 1);
|
|
8213
|
+
/* ── Focus ring ── */
|
|
8214
|
+
--ring: 0 0 0 2px var(--clementine), 0 0 0 4px rgba(255, 140, 33, 0.18);
|
|
8158
8215
|
}
|
|
8159
8216
|
[data-theme="dark"] {
|
|
8160
|
-
--bg-primary: #
|
|
8161
|
-
--bg-secondary: #
|
|
8162
|
-
--bg-card: rgba(
|
|
8163
|
-
--bg-hover: #
|
|
8164
|
-
--bg-input: #
|
|
8165
|
-
--bg-tertiary: #
|
|
8166
|
-
--border: #
|
|
8167
|
-
--border-light: #
|
|
8168
|
-
--text-primary: #
|
|
8169
|
-
--text-secondary: #
|
|
8170
|
-
--text-muted: #
|
|
8171
|
-
--accent: #
|
|
8172
|
-
--accent-glow: rgba(
|
|
8173
|
-
--purple: #
|
|
8217
|
+
--bg-primary: #0b0f17;
|
|
8218
|
+
--bg-secondary: #131923;
|
|
8219
|
+
--bg-card: rgba(19, 25, 35, 0.96);
|
|
8220
|
+
--bg-hover: #1a212d;
|
|
8221
|
+
--bg-input: #1a212d;
|
|
8222
|
+
--bg-tertiary: #1f2733;
|
|
8223
|
+
--border: #2d3748;
|
|
8224
|
+
--border-light: #1f2733;
|
|
8225
|
+
--text-primary: #e2e8f0;
|
|
8226
|
+
--text-secondary: #94a3b8;
|
|
8227
|
+
--text-muted: #64748b;
|
|
8228
|
+
--accent: #60a5fa;
|
|
8229
|
+
--accent-glow: rgba(96, 165, 250, 0.12);
|
|
8230
|
+
--purple: #a78bfa;
|
|
8174
8231
|
--clementine: #ffa54f;
|
|
8175
8232
|
--clementine-dark: #ff8c21;
|
|
8176
|
-
--clementine-glow: rgba(255, 165, 79, 0.
|
|
8233
|
+
--clementine-glow: rgba(255, 165, 79, 0.14);
|
|
8177
8234
|
--clementine-bg: rgba(255, 165, 79, 0.08);
|
|
8178
|
-
--green: #
|
|
8179
|
-
--green-bg: rgba(
|
|
8180
|
-
--red: #
|
|
8181
|
-
--red-bg: rgba(248,
|
|
8182
|
-
--yellow: #
|
|
8183
|
-
--yellow-bg: rgba(
|
|
8184
|
-
--
|
|
8185
|
-
--shadow-sm: 0
|
|
8186
|
-
--shadow-md: 0
|
|
8235
|
+
--green: #22c55e;
|
|
8236
|
+
--green-bg: rgba(34, 197, 94, 0.14);
|
|
8237
|
+
--red: #f87171;
|
|
8238
|
+
--red-bg: rgba(248, 113, 113, 0.14);
|
|
8239
|
+
--yellow: #eab308;
|
|
8240
|
+
--yellow-bg: rgba(234, 179, 8, 0.14);
|
|
8241
|
+
--shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.4);
|
|
8242
|
+
--shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.5), 0 1px 2px rgba(0, 0, 0, 0.3);
|
|
8243
|
+
--shadow-md: 0 4px 12px rgba(0, 0, 0, 0.5), 0 2px 4px rgba(0, 0, 0, 0.3);
|
|
8244
|
+
--shadow-lg: 0 12px 32px rgba(0, 0, 0, 0.6), 0 4px 8px rgba(0, 0, 0, 0.4);
|
|
8245
|
+
--ring: 0 0 0 2px var(--clementine), 0 0 0 4px rgba(255, 165, 79, 0.22);
|
|
8246
|
+
}
|
|
8247
|
+
/* OS-preference dark mode unless user has explicitly chosen a theme */
|
|
8248
|
+
@media (prefers-color-scheme: dark) {
|
|
8249
|
+
:root:not([data-theme]) {
|
|
8250
|
+
--bg-primary: #0b0f17;
|
|
8251
|
+
--bg-secondary: #131923;
|
|
8252
|
+
--bg-card: rgba(19, 25, 35, 0.96);
|
|
8253
|
+
--bg-hover: #1a212d;
|
|
8254
|
+
--bg-input: #1a212d;
|
|
8255
|
+
--bg-tertiary: #1f2733;
|
|
8256
|
+
--border: #2d3748;
|
|
8257
|
+
--border-light: #1f2733;
|
|
8258
|
+
--text-primary: #e2e8f0;
|
|
8259
|
+
--text-secondary: #94a3b8;
|
|
8260
|
+
--text-muted: #64748b;
|
|
8261
|
+
--accent: #60a5fa;
|
|
8262
|
+
--accent-glow: rgba(96, 165, 250, 0.12);
|
|
8263
|
+
--purple: #a78bfa;
|
|
8264
|
+
--clementine: #ffa54f;
|
|
8265
|
+
--clementine-glow: rgba(255, 165, 79, 0.14);
|
|
8266
|
+
--clementine-bg: rgba(255, 165, 79, 0.08);
|
|
8267
|
+
--green: #22c55e;
|
|
8268
|
+
--green-bg: rgba(34, 197, 94, 0.14);
|
|
8269
|
+
--red: #f87171;
|
|
8270
|
+
--red-bg: rgba(248, 113, 113, 0.14);
|
|
8271
|
+
--yellow: #eab308;
|
|
8272
|
+
--yellow-bg: rgba(234, 179, 8, 0.14);
|
|
8273
|
+
--shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.4);
|
|
8274
|
+
--shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.5), 0 1px 2px rgba(0, 0, 0, 0.3);
|
|
8275
|
+
--shadow-md: 0 4px 12px rgba(0, 0, 0, 0.5), 0 2px 4px rgba(0, 0, 0, 0.3);
|
|
8276
|
+
--shadow-lg: 0 12px 32px rgba(0, 0, 0, 0.6), 0 4px 8px rgba(0, 0, 0, 0.4);
|
|
8277
|
+
}
|
|
8187
8278
|
}
|
|
8188
8279
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
8280
|
+
*:focus-visible {
|
|
8281
|
+
outline: none;
|
|
8282
|
+
box-shadow: var(--ring);
|
|
8283
|
+
border-radius: var(--radius-xs);
|
|
8284
|
+
}
|
|
8189
8285
|
body {
|
|
8190
|
-
font-family: -apple-system, BlinkMacSystemFont, '
|
|
8286
|
+
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
|
|
8287
|
+
font-feature-settings: 'cv02', 'cv11', 'ss01', 'ss03';
|
|
8288
|
+
-webkit-font-smoothing: antialiased;
|
|
8289
|
+
-moz-osx-font-smoothing: grayscale;
|
|
8191
8290
|
background: var(--bg-primary);
|
|
8192
8291
|
color: var(--text-primary);
|
|
8193
8292
|
min-height: 100vh;
|
|
8194
8293
|
overflow: hidden;
|
|
8294
|
+
font-size: var(--text-base);
|
|
8295
|
+
line-height: 1.5;
|
|
8195
8296
|
}
|
|
8196
8297
|
|
|
8197
8298
|
/* ── Layout ─────────────────────────────── */
|
|
@@ -8326,41 +8427,58 @@ if('serviceWorker' in navigator){navigator.serviceWorker.getRegistrations().then
|
|
|
8326
8427
|
display: flex;
|
|
8327
8428
|
align-items: center;
|
|
8328
8429
|
gap: 10px;
|
|
8329
|
-
padding:
|
|
8430
|
+
padding: 7px 10px;
|
|
8330
8431
|
border-radius: var(--radius-sm);
|
|
8331
|
-
font-size:
|
|
8432
|
+
font-size: var(--text-base);
|
|
8433
|
+
font-weight: 500;
|
|
8332
8434
|
color: var(--text-secondary);
|
|
8333
8435
|
cursor: pointer;
|
|
8334
|
-
transition:
|
|
8436
|
+
transition: background var(--motion), color var(--motion);
|
|
8335
8437
|
user-select: none;
|
|
8438
|
+
position: relative;
|
|
8336
8439
|
}
|
|
8337
8440
|
.nav-item:hover {
|
|
8338
8441
|
background: var(--bg-hover);
|
|
8339
8442
|
color: var(--text-primary);
|
|
8340
8443
|
}
|
|
8341
8444
|
.nav-item.active {
|
|
8342
|
-
background:
|
|
8445
|
+
background: linear-gradient(90deg, rgba(255,140,33,0.14) 0%, rgba(255,140,33,0.06) 100%);
|
|
8343
8446
|
color: var(--clementine);
|
|
8447
|
+
font-weight: 600;
|
|
8448
|
+
}
|
|
8449
|
+
.nav-item.active::before {
|
|
8450
|
+
content: '';
|
|
8451
|
+
position: absolute;
|
|
8452
|
+
left: 0;
|
|
8453
|
+
top: 6px;
|
|
8454
|
+
bottom: 6px;
|
|
8455
|
+
width: 3px;
|
|
8456
|
+
background: var(--clementine);
|
|
8457
|
+
border-radius: 0 2px 2px 0;
|
|
8344
8458
|
}
|
|
8345
8459
|
.nav-icon {
|
|
8460
|
+
display: inline-flex;
|
|
8461
|
+
align-items: center;
|
|
8462
|
+
justify-content: center;
|
|
8346
8463
|
width: 18px;
|
|
8347
|
-
|
|
8348
|
-
font-size: 14px;
|
|
8464
|
+
height: 18px;
|
|
8349
8465
|
flex-shrink: 0;
|
|
8466
|
+
color: currentColor;
|
|
8350
8467
|
}
|
|
8468
|
+
.nav-icon .icn { width: 16px; height: 16px; }
|
|
8351
8469
|
.nav-badge {
|
|
8352
8470
|
margin-left: auto;
|
|
8353
8471
|
background: var(--bg-hover);
|
|
8354
8472
|
color: var(--text-muted);
|
|
8355
|
-
font-size:
|
|
8473
|
+
font-size: var(--text-xs);
|
|
8356
8474
|
font-weight: 600;
|
|
8357
|
-
padding:
|
|
8475
|
+
padding: 1px 7px;
|
|
8358
8476
|
border-radius: 10px;
|
|
8359
8477
|
min-width: 18px;
|
|
8360
8478
|
text-align: center;
|
|
8361
8479
|
}
|
|
8362
8480
|
.nav-item.active .nav-badge {
|
|
8363
|
-
background:
|
|
8481
|
+
background: rgba(255,140,33,0.18);
|
|
8364
8482
|
color: var(--clementine);
|
|
8365
8483
|
}
|
|
8366
8484
|
|
|
@@ -8379,44 +8497,47 @@ if('serviceWorker' in navigator){navigator.serviceWorker.getRegistrations().then
|
|
|
8379
8497
|
letter-spacing: -0.02em;
|
|
8380
8498
|
}
|
|
8381
8499
|
|
|
8382
|
-
/* ── Standard page header (.page-head) —
|
|
8500
|
+
/* ── Standard page header (.page-head) — refined for v1.4 ── */
|
|
8383
8501
|
.page-head {
|
|
8384
8502
|
display: flex;
|
|
8385
|
-
align-items:
|
|
8503
|
+
align-items: center;
|
|
8386
8504
|
gap: 14px;
|
|
8387
|
-
padding:
|
|
8505
|
+
padding: 20px 24px 16px;
|
|
8388
8506
|
border-bottom: 1px solid var(--border);
|
|
8389
|
-
margin-bottom:
|
|
8507
|
+
margin-bottom: 20px;
|
|
8390
8508
|
flex-wrap: wrap;
|
|
8509
|
+
position: relative;
|
|
8510
|
+
background: linear-gradient(180deg, rgba(255,140,33,0.025) 0%, transparent 70%);
|
|
8391
8511
|
}
|
|
8392
8512
|
.page-head .icon {
|
|
8393
|
-
width:
|
|
8394
|
-
height:
|
|
8395
|
-
border-radius:
|
|
8396
|
-
background:
|
|
8513
|
+
width: 32px;
|
|
8514
|
+
height: 32px;
|
|
8515
|
+
border-radius: var(--radius-sm);
|
|
8516
|
+
background: var(--clementine-bg);
|
|
8397
8517
|
color: var(--clementine);
|
|
8398
8518
|
display: flex;
|
|
8399
8519
|
align-items: center;
|
|
8400
8520
|
justify-content: center;
|
|
8401
|
-
font-size: 20px;
|
|
8402
8521
|
flex-shrink: 0;
|
|
8403
8522
|
}
|
|
8523
|
+
.page-head .icon .icn { width: 18px; height: 18px; }
|
|
8404
8524
|
.page-head .title-block {
|
|
8405
8525
|
flex: 1;
|
|
8406
8526
|
min-width: 220px;
|
|
8407
8527
|
}
|
|
8408
8528
|
.page-head .title-block h1 {
|
|
8409
|
-
font-size:
|
|
8529
|
+
font-size: var(--text-xl);
|
|
8410
8530
|
font-weight: 600;
|
|
8411
8531
|
margin: 0 0 2px;
|
|
8412
|
-
letter-spacing: -0.
|
|
8532
|
+
letter-spacing: -0.02em;
|
|
8413
8533
|
color: var(--text-primary);
|
|
8534
|
+
line-height: 1.2;
|
|
8414
8535
|
}
|
|
8415
8536
|
.page-head .title-block .desc {
|
|
8416
|
-
font-size:
|
|
8537
|
+
font-size: var(--text-base);
|
|
8417
8538
|
color: var(--text-muted);
|
|
8418
8539
|
margin: 0;
|
|
8419
|
-
line-height: 1.
|
|
8540
|
+
line-height: 1.45;
|
|
8420
8541
|
}
|
|
8421
8542
|
.page-head .actions {
|
|
8422
8543
|
display: flex;
|
|
@@ -8425,7 +8546,7 @@ if('serviceWorker' in navigator){navigator.serviceWorker.getRegistrations().then
|
|
|
8425
8546
|
flex-wrap: wrap;
|
|
8426
8547
|
}
|
|
8427
8548
|
.page-section {
|
|
8428
|
-
padding: 0
|
|
8549
|
+
padding: 0 24px 24px;
|
|
8429
8550
|
}
|
|
8430
8551
|
/* ── First-time empty state with CTA (use when there's truly no data yet) ── */
|
|
8431
8552
|
.empty-cta {
|
|
@@ -8514,6 +8635,24 @@ if('serviceWorker' in navigator){navigator.serviceWorker.getRegistrations().then
|
|
|
8514
8635
|
/* Cmd+K palette */
|
|
8515
8636
|
.cmdk-row:hover { background: var(--bg-hover) !important; }
|
|
8516
8637
|
|
|
8638
|
+
/* ── Lucide stroke icons (vendored) ── */
|
|
8639
|
+
.icn {
|
|
8640
|
+
display: inline-block;
|
|
8641
|
+
vertical-align: middle;
|
|
8642
|
+
width: 16px;
|
|
8643
|
+
height: 16px;
|
|
8644
|
+
stroke: currentColor;
|
|
8645
|
+
stroke-width: 2;
|
|
8646
|
+
stroke-linecap: round;
|
|
8647
|
+
stroke-linejoin: round;
|
|
8648
|
+
fill: none;
|
|
8649
|
+
flex-shrink: 0;
|
|
8650
|
+
}
|
|
8651
|
+
.icn-sm { width: 14px; height: 14px; }
|
|
8652
|
+
.icn-md { width: 18px; height: 18px; }
|
|
8653
|
+
.icn-lg { width: 22px; height: 22px; stroke-width: 1.75; }
|
|
8654
|
+
.icn-xl { width: 28px; height: 28px; stroke-width: 1.5; }
|
|
8655
|
+
|
|
8517
8656
|
/* ── Home layout — chat-first daily driver ─── */
|
|
8518
8657
|
.home-layout {
|
|
8519
8658
|
display: grid;
|
|
@@ -8863,38 +9002,58 @@ if('serviceWorker' in navigator){navigator.serviceWorker.getRegistrations().then
|
|
|
8863
9002
|
background: currentColor;
|
|
8864
9003
|
}
|
|
8865
9004
|
|
|
8866
|
-
/* ── Buttons
|
|
9005
|
+
/* ── Buttons (v1.4 refresh) ─────────────────── */
|
|
8867
9006
|
button, .btn {
|
|
8868
|
-
background: var(--bg-
|
|
9007
|
+
background: var(--bg-secondary);
|
|
8869
9008
|
color: var(--text-primary);
|
|
8870
|
-
border: 1px solid var(--border
|
|
9009
|
+
border: 1px solid var(--border);
|
|
8871
9010
|
border-radius: var(--radius-sm);
|
|
8872
|
-
padding:
|
|
8873
|
-
font-size:
|
|
9011
|
+
padding: 7px 14px;
|
|
9012
|
+
font-size: var(--text-base);
|
|
8874
9013
|
font-weight: 500;
|
|
8875
9014
|
cursor: pointer;
|
|
8876
|
-
transition:
|
|
9015
|
+
transition: background var(--motion), border-color var(--motion), color var(--motion), transform var(--motion-fast), box-shadow var(--motion);
|
|
8877
9016
|
font-family: inherit;
|
|
9017
|
+
line-height: 1.2;
|
|
9018
|
+
display: inline-flex;
|
|
9019
|
+
align-items: center;
|
|
9020
|
+
justify-content: center;
|
|
9021
|
+
gap: 6px;
|
|
9022
|
+
white-space: nowrap;
|
|
8878
9023
|
}
|
|
8879
9024
|
button:hover, .btn:hover {
|
|
8880
|
-
background: var(--
|
|
9025
|
+
background: var(--bg-hover);
|
|
9026
|
+
border-color: var(--border-light);
|
|
8881
9027
|
}
|
|
8882
|
-
.btn
|
|
9028
|
+
button:active, .btn:active { transform: translateY(1px); }
|
|
9029
|
+
.btn-sm { padding: 4px 10px; font-size: var(--text-sm); border-radius: var(--radius-xs); }
|
|
9030
|
+
.btn-lg { padding: 9px 18px; font-size: var(--text-md); }
|
|
8883
9031
|
.btn-primary {
|
|
8884
|
-
background: var(--
|
|
8885
|
-
border-color: var(--
|
|
9032
|
+
background: var(--clementine);
|
|
9033
|
+
border-color: var(--clementine);
|
|
8886
9034
|
color: #fff;
|
|
9035
|
+
box-shadow: var(--shadow-xs);
|
|
8887
9036
|
}
|
|
8888
9037
|
.btn-primary:hover {
|
|
8889
|
-
background:
|
|
8890
|
-
border-color:
|
|
9038
|
+
background: var(--clementine-dark);
|
|
9039
|
+
border-color: var(--clementine-dark);
|
|
9040
|
+
box-shadow: var(--shadow-sm);
|
|
9041
|
+
}
|
|
9042
|
+
.btn-accent {
|
|
9043
|
+
background: var(--accent);
|
|
9044
|
+
border-color: var(--accent);
|
|
9045
|
+
color: #fff;
|
|
9046
|
+
box-shadow: var(--shadow-xs);
|
|
8891
9047
|
}
|
|
9048
|
+
.btn-accent:hover { filter: brightness(1.05); }
|
|
8892
9049
|
.btn-success {
|
|
9050
|
+
background: var(--bg-secondary);
|
|
8893
9051
|
border-color: var(--green);
|
|
8894
9052
|
color: var(--green);
|
|
8895
9053
|
}
|
|
8896
9054
|
.btn-success:hover { background: var(--green-bg); }
|
|
8897
9055
|
.btn-danger {
|
|
9056
|
+
background: var(--bg-secondary);
|
|
8898
9057
|
border-color: var(--red);
|
|
8899
9058
|
color: var(--red);
|
|
8900
9059
|
}
|
|
@@ -8908,10 +9067,19 @@ if('serviceWorker' in navigator){navigator.serviceWorker.getRegistrations().then
|
|
|
8908
9067
|
background: var(--bg-hover);
|
|
8909
9068
|
color: var(--text-primary);
|
|
8910
9069
|
}
|
|
9070
|
+
.btn-icon {
|
|
9071
|
+
padding: 6px;
|
|
9072
|
+
width: 32px;
|
|
9073
|
+
height: 32px;
|
|
9074
|
+
border-radius: var(--radius-sm);
|
|
9075
|
+
}
|
|
9076
|
+
.btn-icon.btn-sm { width: 26px; height: 26px; padding: 4px; }
|
|
8911
9077
|
.btn-group {
|
|
8912
9078
|
display: flex;
|
|
8913
|
-
gap:
|
|
9079
|
+
gap: 6px;
|
|
8914
9080
|
}
|
|
9081
|
+
.btn .icn { width: 14px; height: 14px; }
|
|
9082
|
+
.btn-lg .icn { width: 16px; height: 16px; }
|
|
8915
9083
|
|
|
8916
9084
|
/* ── Tables ─────────────────────────────── */
|
|
8917
9085
|
table {
|
|
@@ -10100,16 +10268,7 @@ if('serviceWorker' in navigator){navigator.serviceWorker.getRegistrations().then
|
|
|
10100
10268
|
padding-top: 16px;
|
|
10101
10269
|
border-top: 1px solid var(--border);
|
|
10102
10270
|
}
|
|
10103
|
-
|
|
10104
|
-
background: var(--accent);
|
|
10105
|
-
color: white;
|
|
10106
|
-
border: none;
|
|
10107
|
-
padding: 8px 20px;
|
|
10108
|
-
border-radius: var(--radius);
|
|
10109
|
-
font-weight: 600;
|
|
10110
|
-
cursor: pointer;
|
|
10111
|
-
}
|
|
10112
|
-
.btn-primary:hover { opacity: 0.9; }
|
|
10271
|
+
/* Disabled-state hooks for primary buttons (rest is unified above). */
|
|
10113
10272
|
.btn-primary:disabled { opacity: 0.4; cursor: not-allowed; }
|
|
10114
10273
|
|
|
10115
10274
|
/* ── Desk Stats Strip ─────────────────── */
|
|
@@ -11000,33 +11159,40 @@ if('serviceWorker' in navigator){navigator.serviceWorker.getRegistrations().then
|
|
|
11000
11159
|
.toggle-switch input:checked + .toggle-slider { background: var(--green); }
|
|
11001
11160
|
.toggle-switch input:checked + .toggle-slider::before { transform: translateX(16px); }
|
|
11002
11161
|
|
|
11003
|
-
/* ── Tab Bar
|
|
11162
|
+
/* ── Tab Bar (v1.4 refresh) ─────────────────── */
|
|
11004
11163
|
.tab-bar {
|
|
11005
11164
|
display: flex;
|
|
11006
11165
|
border-bottom: 1px solid var(--border);
|
|
11007
11166
|
margin-bottom: 20px;
|
|
11008
|
-
gap:
|
|
11167
|
+
gap: 4px;
|
|
11009
11168
|
overflow-x: auto;
|
|
11169
|
+
padding: 0 4px;
|
|
11010
11170
|
}
|
|
11011
11171
|
.tab-bar button {
|
|
11012
11172
|
background: none;
|
|
11013
11173
|
border: none;
|
|
11014
|
-
padding: 10px
|
|
11015
|
-
font-size:
|
|
11174
|
+
padding: 10px 14px;
|
|
11175
|
+
font-size: var(--text-base);
|
|
11016
11176
|
font-weight: 500;
|
|
11017
11177
|
color: var(--text-muted);
|
|
11018
11178
|
cursor: pointer;
|
|
11019
11179
|
border-bottom: 2px solid transparent;
|
|
11020
11180
|
font-family: inherit;
|
|
11021
|
-
transition: color
|
|
11181
|
+
transition: color var(--motion), border-color var(--motion), background var(--motion);
|
|
11022
11182
|
white-space: nowrap;
|
|
11023
11183
|
position: relative;
|
|
11184
|
+
border-radius: var(--radius-xs) var(--radius-xs) 0 0;
|
|
11185
|
+
display: inline-flex;
|
|
11186
|
+
align-items: center;
|
|
11187
|
+
gap: 7px;
|
|
11024
11188
|
}
|
|
11025
|
-
.tab-bar button:hover { color: var(--text-primary); }
|
|
11189
|
+
.tab-bar button:hover { color: var(--text-primary); background: var(--bg-hover); }
|
|
11026
11190
|
.tab-bar button.active {
|
|
11027
|
-
color: var(--
|
|
11028
|
-
border-bottom-color: var(--
|
|
11191
|
+
color: var(--clementine);
|
|
11192
|
+
border-bottom-color: var(--clementine);
|
|
11193
|
+
background: transparent;
|
|
11029
11194
|
}
|
|
11195
|
+
.tab-bar button .icn { width: 14px; height: 14px; }
|
|
11030
11196
|
.tab-bar .tab-badge {
|
|
11031
11197
|
display: inline-flex;
|
|
11032
11198
|
align-items: center;
|
|
@@ -11136,39 +11302,60 @@ if('serviceWorker' in navigator){navigator.serviceWorker.getRegistrations().then
|
|
|
11136
11302
|
<!-- Sidebar — 5 destinations only. Sub-pages live as tabs within each. -->
|
|
11137
11303
|
<nav class="sidebar">
|
|
11138
11304
|
<div class="nav-section">
|
|
11139
|
-
<div class="nav-item active" data-page="home" title="Chat, today, activity">
|
|
11140
|
-
<span class="nav-icon"
|
|
11305
|
+
<div class="nav-item active" data-page="home" data-icon="home" title="Chat, today, activity">
|
|
11306
|
+
<span class="nav-icon"></span> Home
|
|
11141
11307
|
</div>
|
|
11142
|
-
<div class="nav-item" data-page="build" title="Workflows, crons, skills">
|
|
11143
|
-
<span class="nav-icon"
|
|
11144
|
-
<span class="nav-badge" id="nav-cron-count">0</span>
|
|
11308
|
+
<div class="nav-item" data-page="build" data-icon="workflow" title="Workflows, crons, skills">
|
|
11309
|
+
<span class="nav-icon"></span> Build
|
|
11310
|
+
<span class="nav-badge" id="nav-cron-count" style="display:none">0</span>
|
|
11145
11311
|
</div>
|
|
11146
|
-
<div class="nav-item" data-page="team" title="Agents, activity, goals">
|
|
11147
|
-
<span class="nav-icon"
|
|
11312
|
+
<div class="nav-item" data-page="team" data-icon="users" title="Agents, activity, goals">
|
|
11313
|
+
<span class="nav-icon"></span> Team
|
|
11148
11314
|
</div>
|
|
11149
|
-
<div class="nav-item" data-page="brain" title="Memory, knowledge, ingestion, health">
|
|
11150
|
-
<span class="nav-icon"
|
|
11315
|
+
<div class="nav-item" data-page="brain" data-icon="brain" title="Memory, knowledge, ingestion, health">
|
|
11316
|
+
<span class="nav-icon"></span> Brain
|
|
11151
11317
|
</div>
|
|
11152
|
-
<div class="nav-item" data-page="settings" title="Channels, integrations, system">
|
|
11153
|
-
<span class="nav-icon"
|
|
11318
|
+
<div class="nav-item" data-page="settings" data-icon="settings" title="Channels, integrations, system">
|
|
11319
|
+
<span class="nav-icon"></span> Settings
|
|
11154
11320
|
</div>
|
|
11155
11321
|
</div>
|
|
11156
11322
|
<!-- Per-agent quick-jump (loaded from team-nav helper). -->
|
|
11157
|
-
<div class="nav-section" style="margin-top:
|
|
11323
|
+
<div class="nav-section" style="margin-top:14px">
|
|
11158
11324
|
<div class="nav-section-title">Agents</div>
|
|
11159
11325
|
<div id="team-nav"></div>
|
|
11160
|
-
<div class="team-hire-btn" onclick="showAgentCreateModal()">
|
|
11161
|
-
<span
|
|
11326
|
+
<div class="team-hire-btn" onclick="showAgentCreateModal()" data-icon="plus">
|
|
11327
|
+
<span class="hire-plus"></span> Hire
|
|
11162
11328
|
</div>
|
|
11163
11329
|
</div>
|
|
11164
11330
|
<div style="flex:1"></div>
|
|
11165
11331
|
<div class="nav-section">
|
|
11166
|
-
<div class="nav-item" onclick="openCommandK()" style="font-size:12px;color:var(--text-muted);justify-content:space-between" title="Quick search (Cmd+K)">
|
|
11167
|
-
<span><span class="nav-icon"
|
|
11168
|
-
<kbd style="font-size:10px;padding:
|
|
11332
|
+
<div class="nav-item" onclick="openCommandK()" data-icon="search" style="font-size:12px;color:var(--text-muted);justify-content:space-between" title="Quick search (Cmd+K)">
|
|
11333
|
+
<span style="display:inline-flex;align-items:center;gap:8px"><span class="nav-icon"></span> Search</span>
|
|
11334
|
+
<kbd style="font-size:10px;padding:2px 6px;border:1px solid var(--border);border-radius:var(--radius-xs);background:var(--bg-input);color:var(--text-secondary)">⌘K</kbd>
|
|
11169
11335
|
</div>
|
|
11170
11336
|
</div>
|
|
11171
11337
|
</nav>
|
|
11338
|
+
<script>
|
|
11339
|
+
// Inject Lucide icons into elements that declared data-icon, after page render.
|
|
11340
|
+
(function hydrateIcons() {
|
|
11341
|
+
function run() {
|
|
11342
|
+
document.querySelectorAll('[data-icon]').forEach(function(el) {
|
|
11343
|
+
if (el.dataset._iconHydrated) return;
|
|
11344
|
+
el.dataset._iconHydrated = '1';
|
|
11345
|
+
var name = el.getAttribute('data-icon');
|
|
11346
|
+
if (!window.LUCIDE || !window.lucide) return;
|
|
11347
|
+
var slot = el.querySelector('.nav-icon, .hire-plus, .icon-slot');
|
|
11348
|
+
if (slot) slot.innerHTML = window.lucide(name, 'icn-md');
|
|
11349
|
+
});
|
|
11350
|
+
}
|
|
11351
|
+
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', run);
|
|
11352
|
+
else run();
|
|
11353
|
+
// Re-run on dynamic insertion (e.g. agent nav). Polled cheaply.
|
|
11354
|
+
setInterval(run, 1000);
|
|
11355
|
+
// Expose so dynamic markup can call after building DOM.
|
|
11356
|
+
window.hydrateLucideIcons = run;
|
|
11357
|
+
})();
|
|
11358
|
+
</script>
|
|
11172
11359
|
<div class="sidebar-overlay" id="sidebar-overlay" onclick="toggleSidebar()"></div>
|
|
11173
11360
|
|
|
11174
11361
|
<!-- Content -->
|
|
@@ -11317,10 +11504,10 @@ if('serviceWorker' in navigator){navigator.serviceWorker.getRegistrations().then
|
|
|
11317
11504
|
<!-- ═══ Builder Page — Conversational Artifact Creation ═══ -->
|
|
11318
11505
|
<div class="page" id="page-build">
|
|
11319
11506
|
<div class="tab-bar" id="build-tabs" style="margin:0;padding:0 18px;background:var(--bg-secondary);border-bottom:1px solid var(--border)">
|
|
11320
|
-
<button class="active" data-build-tab="workflows" onclick="switchBuildTab('workflows')"
|
|
11321
|
-
<button data-build-tab="crons" onclick="switchBuildTab('crons')"
|
|
11322
|
-
<button data-build-tab="skills" onclick="switchBuildTab('skills')"
|
|
11323
|
-
<button data-build-tab="templates" onclick="switchBuildTab('templates')"
|
|
11507
|
+
<button class="active" data-build-tab="workflows" data-icon="workflow" onclick="switchBuildTab('workflows')"><span class="icon-slot"></span> Workflows</button>
|
|
11508
|
+
<button data-build-tab="crons" data-icon="clock" onclick="switchBuildTab('crons')"><span class="icon-slot"></span> Crons <span class="tab-badge" id="build-tab-cron-count" style="display:none">0</span></button>
|
|
11509
|
+
<button data-build-tab="skills" data-icon="shield" onclick="switchBuildTab('skills')"><span class="icon-slot"></span> Skills <span class="tab-badge" id="build-tab-skill-count" style="display:none">0</span></button>
|
|
11510
|
+
<button data-build-tab="templates" data-icon="fileText" onclick="switchBuildTab('templates')"><span class="icon-slot"></span> Templates</button>
|
|
11324
11511
|
</div>
|
|
11325
11512
|
<!-- Builder header strip — persists across tabs (except Templates) -->
|
|
11326
11513
|
<div id="build-header-strip" style="display:flex;align-items:center;gap:12px;padding:10px 18px;border-bottom:1px solid var(--border)">
|
|
@@ -11337,10 +11524,10 @@ if('serviceWorker' in navigator){navigator.serviceWorker.getRegistrations().then
|
|
|
11337
11524
|
<button class="btn-sm" id="builder-test-btn" onclick="testBuilderSkill()" style="background:var(--bg-tertiary);border:1px solid var(--border);color:var(--text-secondary);padding:4px 12px;border-radius:6px;cursor:pointer;font-size:12px;display:none">Test</button>
|
|
11338
11525
|
<button class="btn-sm btn-primary" id="builder-save-btn" onclick="saveBuilderArtifact()" style="padding:4px 16px;font-size:12px;display:none">Save</button>
|
|
11339
11526
|
</div>
|
|
11340
|
-
<!-- Build tab content area -->
|
|
11527
|
+
<!-- Build tab content area: canvas DOMINATES, chat is a sidebar -->
|
|
11341
11528
|
<div id="build-tab-workflows" data-build-tabpane="workflows" style="display:flex;flex:1;min-height:0;overflow:hidden">
|
|
11342
|
-
<!-- Left: Chat -->
|
|
11343
|
-
<div style="flex:
|
|
11529
|
+
<!-- Left: Chat sidebar (compact) -->
|
|
11530
|
+
<div id="builder-chat-sidebar" style="width:360px;flex-shrink:0;display:flex;flex-direction:column;border-right:1px solid var(--border);background:var(--bg-secondary)">
|
|
11344
11531
|
<div id="builder-messages" style="flex:1;overflow-y:auto;padding:16px">
|
|
11345
11532
|
<div class="empty-state" id="builder-empty-state" style="margin-top:40px">
|
|
11346
11533
|
<p style="color:var(--text-muted);margin-bottom:12px">Describe what you want to build.</p>
|
|
@@ -11371,8 +11558,8 @@ if('serviceWorker' in navigator){navigator.serviceWorker.getRegistrations().then
|
|
|
11371
11558
|
<button class="btn-primary" onclick="sendBuilderChat()" style="padding:10px 18px;border-radius:8px">Send</button>
|
|
11372
11559
|
</div>
|
|
11373
11560
|
</div>
|
|
11374
|
-
<!-- Right:
|
|
11375
|
-
<div id="builder-right-pane" style="width:
|
|
11561
|
+
<!-- Right: Canvas (dominant) + Existing Skills drawer -->
|
|
11562
|
+
<div id="builder-right-pane" style="flex:1;min-width:0;display:flex;flex-direction:column;background:var(--bg-primary)">
|
|
11376
11563
|
<div style="padding:12px 16px;border-bottom:1px solid var(--border);font-weight:600;font-size:13px;color:var(--text-secondary);display:flex;align-items:center;gap:10px;flex-wrap:wrap">
|
|
11377
11564
|
<span id="builder-right-pane-title">Live Preview</span>
|
|
11378
11565
|
<span id="builder-preview-status" style="font-size:11px;color:var(--text-muted)"></span>
|
|
@@ -11414,7 +11601,8 @@ if('serviceWorker' in navigator){navigator.serviceWorker.getRegistrations().then
|
|
|
11414
11601
|
<div id="builder-canvas-footer" style="padding:6px 14px;border-top:1px solid var(--border);font-size:11px;color:var(--text-muted);display:flex;gap:14px;align-items:center">
|
|
11415
11602
|
<span id="builder-canvas-status"></span>
|
|
11416
11603
|
<span style="flex:1"></span>
|
|
11417
|
-
<
|
|
11604
|
+
<button id="builder-delete-btn" onclick="deleteCurrentBuilderWorkflow()" title="Delete this workflow" style="display:none;background:none;border:1px solid transparent;color:var(--red);font-size:11px;cursor:pointer;padding:2px 8px;border-radius:var(--radius-xs)">Delete</button>
|
|
11605
|
+
<span id="builder-canvas-id" style="font-family:'JetBrains Mono',monospace;opacity:0.6"></span>
|
|
11418
11606
|
</div>
|
|
11419
11607
|
</div>
|
|
11420
11608
|
<!-- Existing skills drawer (visible in skill mode) -->
|
|
@@ -11533,7 +11721,7 @@ if('serviceWorker' in navigator){navigator.serviceWorker.getRegistrations().then
|
|
|
11533
11721
|
<!-- ═══ Brain Page (unified: Search + Graph + Stats + Sources + Seed + Runs) ═══ -->
|
|
11534
11722
|
<div class="page" id="page-brain">
|
|
11535
11723
|
<div class="page-head">
|
|
11536
|
-
<div class="icon"
|
|
11724
|
+
<div class="icon icon-slot" data-icon="brain"></div>
|
|
11537
11725
|
<div class="title-block">
|
|
11538
11726
|
<h1>Brain</h1>
|
|
11539
11727
|
<p class="desc">Query what you know, feed new knowledge in, and watch the system learn.</p>
|
|
@@ -11544,12 +11732,12 @@ if('serviceWorker' in navigator){navigator.serviceWorker.getRegistrations().then
|
|
|
11544
11732
|
</div>
|
|
11545
11733
|
</div>
|
|
11546
11734
|
<div class="tab-bar" id="intelligence-tabs" style="margin:0 0 0 18px">
|
|
11547
|
-
<button class="active" onclick="switchTab('intelligence','search')">Memory</button>
|
|
11548
|
-
<button onclick="switchTab('intelligence','graph')">Knowledge</button>
|
|
11549
|
-
<button onclick="switchTab('intelligence','sources')">Ingestion</button>
|
|
11550
|
-
<button onclick="switchTab('intelligence','health')">Health <span class="tab-badge" id="brain-health-badge" style="display:none;background:#ef4444;color:#fff">0</span></button>
|
|
11551
|
-
<button onclick="switchTab('intelligence','user-model')">User Model</button>
|
|
11552
|
-
<button onclick="switchTab('intelligence','learning')">Learning <span class="tab-badge" id="brain-learning-badge" style="display:none;background:#f59e0b;color:#000">0</span></button>
|
|
11735
|
+
<button class="active" data-icon="database" onclick="switchTab('intelligence','search')"><span class="icon-slot"></span> Memory</button>
|
|
11736
|
+
<button data-icon="sparkles" onclick="switchTab('intelligence','graph')"><span class="icon-slot"></span> Knowledge</button>
|
|
11737
|
+
<button data-icon="folder" onclick="switchTab('intelligence','sources')"><span class="icon-slot"></span> Ingestion</button>
|
|
11738
|
+
<button data-icon="zap" onclick="switchTab('intelligence','health')"><span class="icon-slot"></span> Health <span class="tab-badge" id="brain-health-badge" style="display:none;background:#ef4444;color:#fff">0</span></button>
|
|
11739
|
+
<button data-icon="users" onclick="switchTab('intelligence','user-model')"><span class="icon-slot"></span> User Model</button>
|
|
11740
|
+
<button data-icon="brain" onclick="switchTab('intelligence','learning')"><span class="icon-slot"></span> Learning <span class="tab-badge" id="brain-learning-badge" style="display:none;background:#f59e0b;color:#000">0</span></button>
|
|
11553
11741
|
<button onclick="switchTab('intelligence','memory')">Stats</button>
|
|
11554
11742
|
<button onclick="switchTab('intelligence','seed')">Seed</button>
|
|
11555
11743
|
<button onclick="switchTab('intelligence','runs')">Runs</button>
|
|
@@ -12791,7 +12979,7 @@ if('serviceWorker' in navigator){navigator.serviceWorker.getRegistrations().then
|
|
|
12791
12979
|
<!-- ═══ Team Page — The Office ═══ -->
|
|
12792
12980
|
<div class="page" id="page-team">
|
|
12793
12981
|
<div class="page-head">
|
|
12794
|
-
<div class="icon"
|
|
12982
|
+
<div class="icon icon-slot" data-icon="users"></div>
|
|
12795
12983
|
<div class="title-block">
|
|
12796
12984
|
<h1>The Office</h1>
|
|
12797
12985
|
<p class="desc">Your team of agents — what they're doing, what they're contributing to.</p>
|
|
@@ -12804,10 +12992,10 @@ if('serviceWorker' in navigator){navigator.serviceWorker.getRegistrations().then
|
|
|
12804
12992
|
</div>
|
|
12805
12993
|
</div>
|
|
12806
12994
|
<div class="tab-bar" id="team-tabs" style="margin:0 0 0 18px">
|
|
12807
|
-
<button class="active" onclick="switchTab('team','roster')">Roster</button>
|
|
12808
|
-
<button onclick="switchTab('team','activity')">Activity</button>
|
|
12809
|
-
<button onclick="switchTab('team','goals')">Goals</button>
|
|
12810
|
-
<button onclick="switchTab('team','comms')">Comms</button>
|
|
12995
|
+
<button class="active" data-icon="users" onclick="switchTab('team','roster')"><span class="icon-slot"></span> Roster</button>
|
|
12996
|
+
<button data-icon="list" onclick="switchTab('team','activity')"><span class="icon-slot"></span> Activity</button>
|
|
12997
|
+
<button data-icon="target" onclick="switchTab('team','goals')"><span class="icon-slot"></span> Goals</button>
|
|
12998
|
+
<button data-icon="messageSquare" onclick="switchTab('team','comms')"><span class="icon-slot"></span> Comms</button>
|
|
12811
12999
|
</div>
|
|
12812
13000
|
<div id="team-tab-content">
|
|
12813
13001
|
<div class="tab-pane active" id="tab-team-roster">
|
|
@@ -13870,6 +14058,46 @@ var prevAgentSlugs = null;
|
|
|
13870
14058
|
// Sub-pages live as tabs within each destination.
|
|
13871
14059
|
// Old routes redirect once for back-compat.
|
|
13872
14060
|
|
|
14061
|
+
// ── Lucide stroke icons (MIT, lucide.dev). Inline so there's no font/asset fetch. ──
|
|
14062
|
+
var LUCIDE = {
|
|
14063
|
+
home: '<path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/>',
|
|
14064
|
+
wrench: '<path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z"/>',
|
|
14065
|
+
users: '<path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M22 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/>',
|
|
14066
|
+
brain: '<path d="M9.5 2A2.5 2.5 0 0 1 12 4.5v15a2.5 2.5 0 0 1-4.96.44 2.5 2.5 0 0 1-2.96-3.08 3 3 0 0 1-.34-5.58 2.5 2.5 0 0 1 1.32-4.24 2.5 2.5 0 0 1 1.98-3A2.5 2.5 0 0 1 9.5 2"/><path d="M14.5 2A2.5 2.5 0 0 0 12 4.5v15a2.5 2.5 0 0 0 4.96.44 2.5 2.5 0 0 0 2.96-3.08 3 3 0 0 0 .34-5.58 2.5 2.5 0 0 0-1.32-4.24 2.5 2.5 0 0 0-1.98-3A2.5 2.5 0 0 0 14.5 2"/>',
|
|
14067
|
+
settings: '<path d="M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2"/><circle cx="12" cy="12" r="3"/>',
|
|
14068
|
+
search: '<circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/>',
|
|
14069
|
+
plus: '<path d="M5 12h14"/><path d="M12 5v14"/>',
|
|
14070
|
+
x: '<path d="M18 6 6 18"/><path d="m6 6 12 12"/>',
|
|
14071
|
+
check: '<path d="M20 6 9 17l-5-5"/>',
|
|
14072
|
+
play: '<polygon points="6 3 20 12 6 21 6 3"/>',
|
|
14073
|
+
eye: '<path d="M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7Z"/><circle cx="12" cy="12" r="3"/>',
|
|
14074
|
+
trash: '<path d="M3 6h18"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6"/><path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/>',
|
|
14075
|
+
pencil: '<path d="M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z"/>',
|
|
14076
|
+
link: '<path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/>',
|
|
14077
|
+
clock: '<circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/>',
|
|
14078
|
+
shield: '<path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z"/>',
|
|
14079
|
+
fileText: '<path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z"/><polyline points="14 2 14 8 20 8"/><line x1="16" x2="8" y1="13" y2="13"/><line x1="16" x2="8" y1="17" y2="17"/><line x1="10" x2="8" y1="9" y2="9"/>',
|
|
14080
|
+
workflow: '<rect x="3" y="3" width="6" height="6" rx="1"/><rect x="15" y="3" width="6" height="6" rx="1"/><rect x="9" y="15" width="6" height="6" rx="1"/><path d="M6 9v3a2 2 0 0 0 2 2h2"/><path d="M18 9v3a2 2 0 0 1-2 2h-2"/>',
|
|
14081
|
+
bell: '<path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9"/><path d="M10.3 21a1.94 1.94 0 0 0 3.4 0"/>',
|
|
14082
|
+
calendar: '<rect width="18" height="18" x="3" y="4" rx="2"/><path d="M16 2v4"/><path d="M8 2v4"/><path d="M3 10h18"/>',
|
|
14083
|
+
list: '<line x1="8" x2="21" y1="6" y2="6"/><line x1="8" x2="21" y1="12" y2="12"/><line x1="8" x2="21" y1="18" y2="18"/><line x1="3" x2="3.01" y1="6" y2="6"/><line x1="3" x2="3.01" y1="12" y2="12"/><line x1="3" x2="3.01" y1="18" y2="18"/>',
|
|
14084
|
+
messageSquare:'<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/>',
|
|
14085
|
+
target: '<circle cx="12" cy="12" r="10"/><circle cx="12" cy="12" r="6"/><circle cx="12" cy="12" r="2"/>',
|
|
14086
|
+
folder: '<path d="M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.93a2 2 0 0 1-1.66-.9l-.82-1.2A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z"/>',
|
|
14087
|
+
refresh: '<path d="M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8"/><path d="M21 3v5h-5"/><path d="M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16"/><path d="M3 21v-5h5"/>',
|
|
14088
|
+
zap: '<path d="M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z"/>',
|
|
14089
|
+
sparkles: '<path d="M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z"/>',
|
|
14090
|
+
command: '<path d="M15 6v12a3 3 0 1 0 3-3H6a3 3 0 1 0 3 3V6a3 3 0 1 0-3 3h12a3 3 0 1 0-3-3"/>',
|
|
14091
|
+
send: '<path d="m22 2-7 20-4-9-9-4Z"/><path d="M22 2 11 13"/>',
|
|
14092
|
+
arrowRight: '<path d="M5 12h14"/><path d="m12 5 7 7-7 7"/>',
|
|
14093
|
+
tool: '<path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z"/>',
|
|
14094
|
+
database: '<ellipse cx="12" cy="5" rx="9" ry="3"/><path d="M3 5v14a9 3 0 0 0 18 0V5"/><path d="M3 12a9 3 0 0 0 18 0"/>',
|
|
14095
|
+
};
|
|
14096
|
+
function lucide(name, cls) {
|
|
14097
|
+
var path = LUCIDE[name] || '';
|
|
14098
|
+
return '<svg class="icn ' + (cls || '') + '" viewBox="0 0 24 24" aria-hidden="true">' + path + '</svg>';
|
|
14099
|
+
}
|
|
14100
|
+
|
|
13873
14101
|
var DESTINATIONS = ['home', 'build', 'team', 'brain', 'settings'];
|
|
13874
14102
|
|
|
13875
14103
|
var ROUTE_REDIRECTS = {
|
|
@@ -18313,6 +18541,8 @@ async function openBuilderWorkflow(id) {
|
|
|
18313
18541
|
|
|
18314
18542
|
var idEl = document.getElementById('builder-canvas-id');
|
|
18315
18543
|
if (idEl) idEl.textContent = id;
|
|
18544
|
+
var delBtn = document.getElementById('builder-delete-btn');
|
|
18545
|
+
if (delBtn) delBtn.style.display = id.startsWith('workflow:') ? '' : 'none';
|
|
18316
18546
|
|
|
18317
18547
|
var banner = document.getElementById('builder-canvas-banner');
|
|
18318
18548
|
if (banner) {
|
|
@@ -18347,13 +18577,16 @@ function _renderBuilderCanvas(drawflowData) {
|
|
|
18347
18577
|
editor.reroute = true;
|
|
18348
18578
|
editor.editor_mode = 'edit';
|
|
18349
18579
|
editor.start();
|
|
18580
|
+
// Assign global BEFORE decoration runs — decoration reads node data via
|
|
18581
|
+
// editor.export() to recover stepIds (Drawflow doesn't preserve our
|
|
18582
|
+
// df-* attrs without a template).
|
|
18583
|
+
_builderCanvasEditor = editor;
|
|
18350
18584
|
try {
|
|
18351
18585
|
editor.import(drawflowData || { drawflow: { Home: { data: {} } } });
|
|
18352
18586
|
_decorateBuilderNodes(host, _builderCanvasLastWorkflow);
|
|
18353
18587
|
} catch (err) {
|
|
18354
18588
|
host.innerHTML = '<div style="padding:24px;color:var(--red)">Failed to render canvas: ' + esc(String(err)) + '</div>';
|
|
18355
18589
|
}
|
|
18356
|
-
_builderCanvasEditor = editor;
|
|
18357
18590
|
_bindBuilderCanvasEvents(editor);
|
|
18358
18591
|
}
|
|
18359
18592
|
|
|
@@ -18396,16 +18629,13 @@ async function _flushBuilderSave() {
|
|
|
18396
18629
|
setTimeout(function() { _builderRecentSaveTokens.delete(saveToken); }, 5000);
|
|
18397
18630
|
try {
|
|
18398
18631
|
var data = _builderCanvasEditor.export();
|
|
18399
|
-
|
|
18632
|
+
// force:true — autosave persists partial states (incomplete MCP/channel
|
|
18633
|
+
// configs, dangling deps). Validation surfaces in the banner; never blocks.
|
|
18634
|
+
var r = await apiJson('POST', '/api/builder/workflows/' + encodeURIComponent(_builderCanvasOpenId) + '/save-from-drawflow', { drawflow: data, saveToken: saveToken, force: true });
|
|
18400
18635
|
if (r.error) {
|
|
18401
|
-
|
|
18402
|
-
_setBuilderSaveStatus('error', r.validation.issues.length + ' validation error' + (r.validation.issues.length === 1 ? '' : 's'));
|
|
18403
|
-
} else {
|
|
18404
|
-
_setBuilderSaveStatus('error', r.error);
|
|
18405
|
-
}
|
|
18636
|
+
_setBuilderSaveStatus('error', r.error);
|
|
18406
18637
|
} else {
|
|
18407
18638
|
_setBuilderSaveStatus('saved');
|
|
18408
|
-
// Refresh banner from validation if warnings
|
|
18409
18639
|
_updateBuilderBannerFromValidation(r.validation);
|
|
18410
18640
|
}
|
|
18411
18641
|
} catch (err) {
|
|
@@ -18516,6 +18746,27 @@ async function validateBuilderCanvas() {
|
|
|
18516
18746
|
} catch (err) { toast('Validate failed: ' + err, 'error'); }
|
|
18517
18747
|
}
|
|
18518
18748
|
|
|
18749
|
+
async function deleteCurrentBuilderWorkflow() {
|
|
18750
|
+
if (!_builderCanvasOpenId) return;
|
|
18751
|
+
if (!_builderCanvasOpenId.startsWith('workflow:')) {
|
|
18752
|
+
toast('Cron entries can\\x27t be deleted from here — disable instead.', 'info');
|
|
18753
|
+
return;
|
|
18754
|
+
}
|
|
18755
|
+
var name = _builderCanvasOpenId.replace(/^workflow:/, '');
|
|
18756
|
+
if (!confirm('Delete workflow "' + name + '"? This is permanent.')) return;
|
|
18757
|
+
try {
|
|
18758
|
+
var r = await fetch('/api/builder/workflows/' + encodeURIComponent(_builderCanvasOpenId), {
|
|
18759
|
+
method: 'DELETE',
|
|
18760
|
+
headers: { 'authorization': 'Bearer ' + _dashToken },
|
|
18761
|
+
});
|
|
18762
|
+
if (!r.ok) { var d = await r.json().catch(function() { return {}; }); toast('Delete failed: ' + (d.error || r.status), 'error'); return; }
|
|
18763
|
+
toast('Deleted ' + name, 'success');
|
|
18764
|
+
closeBuilderCanvas();
|
|
18765
|
+
var t = document.querySelector('#build-tabs button.active')?.getAttribute('data-build-tab');
|
|
18766
|
+
refreshBuilderCanvasPicker(t === 'crons' ? 'cron' : 'workflow');
|
|
18767
|
+
} catch (err) { toast('Delete error: ' + err, 'error'); }
|
|
18768
|
+
}
|
|
18769
|
+
|
|
18519
18770
|
async function dryRunBuilderCanvas() {
|
|
18520
18771
|
if (!_builderCanvasOpenId) { toast('Open a workflow first', 'info'); return; }
|
|
18521
18772
|
try {
|