Apply LotusGuild design system convergence (aesthetic_diff.md)
- §5: Section headers now ╠═══ TITLE ═══╣ (was ═══ TITLE ═══) - §8+§18: Replace inline-style showTerminalNotification() with lt.toast.* delegate wrapper; load base.js from /base.js - §12: Fix --text-muted #008822→#00bb33 (WCAG AA contrast) base.js symlinked from web_template into public/ so lt.* is available. showTerminalNotification() is kept as a thin wrapper so all existing call sites continue to work unchanged. README: Remove completed pending items (toast, text-muted, position) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
48
README.md
48
README.md
@@ -4,6 +4,22 @@ A distributed workflow orchestration platform for managing and executing complex
|
||||
|
||||
> **Security Notice:** This repository is hosted on Gitea and is version-controlled. **Never commit secrets, credentials, passwords, API keys, or any sensitive information to this repo.** All sensitive configuration belongs exclusively in `.env` files which are listed in `.gitignore` and must never be committed. This includes database passwords, worker API keys, webhook secrets, and internal IP details.
|
||||
|
||||
**Design System**: [web_template](https://code.lotusguild.org/LotusGuild/web_template) — shared CSS, JS, and layout patterns for all LotusGuild apps
|
||||
|
||||
## Styling & Layout
|
||||
|
||||
PULSE uses the **LotusGuild Terminal Design System**. For all styling, component, and layout documentation see:
|
||||
|
||||
- [`web_template/README.md`](https://code.lotusguild.org/LotusGuild/web_template/src/branch/main/README.md) — full component reference, CSS variables, JS API
|
||||
- [`web_template/base.css`](https://code.lotusguild.org/LotusGuild/web_template/src/branch/main/base.css) — unified CSS (`.lt-*` classes)
|
||||
- [`web_template/base.js`](https://code.lotusguild.org/LotusGuild/web_template/src/branch/main/base.js) — `window.lt` utilities (toast, modal, WebSocket helpers, fetch)
|
||||
- [`web_template/aesthetic_diff.md`](https://code.lotusguild.org/LotusGuild/web_template/src/branch/main/aesthetic_diff.md) — cross-app divergence analysis and convergence guide
|
||||
- [`web_template/node/middleware.js`](https://code.lotusguild.org/LotusGuild/web_template/src/branch/main/node/middleware.js) — Express auth, CSRF, CSP nonce middleware
|
||||
|
||||
**Pending convergence items (see aesthetic_diff.md):**
|
||||
- Extract inline `<style>` from `public/index.html` into `public/style.css` and extend `base.css`
|
||||
- Use `lt.autoRefresh.start(refreshData, 30000)` instead of raw `setInterval`
|
||||
|
||||
## Overview
|
||||
|
||||
PULSE is a centralized workflow execution system designed to orchestrate operations across distributed infrastructure. It provides a powerful web-based interface with a vintage CRT terminal aesthetic for defining, managing, and executing workflows that can span multiple servers, require human interaction, and perform complex automation tasks at scale.
|
||||
@@ -307,12 +323,34 @@ MAX_CONCURRENT_TASKS=5 # Max parallel tasks (default: 5)
|
||||
|
||||
PULSE uses MariaDB with the following tables:
|
||||
|
||||
- **users**: User accounts from Authelia SSO
|
||||
- **workers**: Worker node registry with metadata
|
||||
- **workflows**: Workflow definitions (JSON)
|
||||
- **executions**: Execution history with logs
|
||||
| Table | Purpose |
|
||||
|-------|---------|
|
||||
| `users` | User accounts synced from Authelia SSO |
|
||||
| `workers` | Worker node registry with connection metadata |
|
||||
| `workflows` | Workflow definitions stored as JSON |
|
||||
| `executions` | Execution history with logs, status, and timestamps |
|
||||
|
||||
See [Claude.md](Claude.md) for complete schema details.
|
||||
### `executions` Table Key Columns
|
||||
|
||||
| Column | Description |
|
||||
|--------|-------------|
|
||||
| `id` | Auto-increment primary key |
|
||||
| `worker_id` | Foreign key to workers |
|
||||
| `command` | The command that was executed |
|
||||
| `status` | `running`, `completed`, `failed` |
|
||||
| `output` | Command output / log (JSON or text) |
|
||||
| `created_at` | Execution start timestamp |
|
||||
| `completed_at` | Execution end timestamp |
|
||||
|
||||
### `workers` Table Key Columns
|
||||
|
||||
| Column | Description |
|
||||
|--------|-------------|
|
||||
| `id` | Auto-increment primary key |
|
||||
| `name` | Worker name (from `WORKER_NAME` env) |
|
||||
| `last_seen` | Last heartbeat timestamp |
|
||||
| `status` | `online`, `offline` |
|
||||
| `metadata` | JSON blob of system info |
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
|
||||
1
public/base.js
Symbolic link
1
public/base.js
Symbolic link
@@ -0,0 +1 @@
|
||||
/root/code/web_template/base.js
|
||||
@@ -20,7 +20,7 @@
|
||||
--bg-terminal-border: #003300;
|
||||
--text-primary: #00ff41;
|
||||
--text-secondary: #00cc33;
|
||||
--text-muted: #008822;
|
||||
--text-muted: #00bb33;
|
||||
|
||||
/* Border & UI */
|
||||
--border-color: #00ff41;
|
||||
@@ -271,11 +271,11 @@
|
||||
text-shadow: var(--glow-amber);
|
||||
}
|
||||
.card h3::before {
|
||||
content: '═══ ';
|
||||
content: '╠═══ ';
|
||||
color: var(--terminal-green);
|
||||
}
|
||||
.card h3::after {
|
||||
content: ' ═══';
|
||||
content: ' ═══╣';
|
||||
color: var(--terminal-green);
|
||||
}
|
||||
.status {
|
||||
@@ -803,6 +803,7 @@
|
||||
animation: slide-in 0.3s ease-out;
|
||||
}
|
||||
</style>
|
||||
<script src="/base.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
@@ -2899,45 +2900,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Show terminal notification
|
||||
// Show terminal notification — delegates to lt.toast from base.js
|
||||
function showTerminalNotification(message, type = 'info') {
|
||||
const notification = document.createElement('div');
|
||||
notification.style.cssText = `
|
||||
position: fixed;
|
||||
top: 80px;
|
||||
right: 20px;
|
||||
background: #001a00;
|
||||
border: 2px solid var(--terminal-green);
|
||||
color: var(--terminal-green);
|
||||
padding: 15px 20px;
|
||||
font-family: var(--font-mono);
|
||||
z-index: 10000;
|
||||
animation: slide-in 0.3s ease-out;
|
||||
box-shadow: 0 0 20px rgba(0, 255, 65, 0.3);
|
||||
`;
|
||||
|
||||
if (type === 'error') {
|
||||
notification.style.borderColor = '#ff4444';
|
||||
notification.style.color = '#ff4444';
|
||||
message = '✗ ' + message;
|
||||
} else if (type === 'success') {
|
||||
message = '✓ ' + message;
|
||||
} else {
|
||||
message = 'ℹ ' + message;
|
||||
}
|
||||
|
||||
notification.textContent = message;
|
||||
document.body.appendChild(notification);
|
||||
|
||||
// Play beep
|
||||
terminalBeep(type);
|
||||
|
||||
// Remove after 3 seconds
|
||||
setTimeout(() => {
|
||||
notification.style.opacity = '0';
|
||||
notification.style.transition = 'opacity 0.5s';
|
||||
setTimeout(() => notification.remove(), 500);
|
||||
}, 3000);
|
||||
if (type === 'success') return lt.toast.success(message);
|
||||
if (type === 'error') return lt.toast.error(message);
|
||||
if (type === 'warning') return lt.toast.warning(message);
|
||||
return lt.toast.info(message);
|
||||
}
|
||||
|
||||
function connectWebSocket() {
|
||||
|
||||
Reference in New Issue
Block a user