aura-code 0.3.7 → 0.6.3
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/README.md +56 -4
- package/dist/agent/compactor.d.ts +26 -0
- package/dist/agent/compactor.js +156 -0
- package/dist/agent/compactor.js.map +1 -0
- package/dist/agent/context.d.ts +4 -0
- package/dist/agent/context.js +38 -0
- package/dist/agent/context.js.map +1 -1
- package/dist/agent/design.d.ts +17 -0
- package/dist/agent/design.js +175 -0
- package/dist/agent/design.js.map +1 -0
- package/dist/agent/loop.js +24 -1
- package/dist/agent/loop.js.map +1 -1
- package/dist/agent/system-prompt.d.ts +1 -1
- package/dist/agent/system-prompt.js +14 -3
- package/dist/agent/system-prompt.js.map +1 -1
- package/dist/cli/display.js +46 -5
- package/dist/cli/display.js.map +1 -1
- package/dist/cli/index.js +323 -46
- package/dist/cli/index.js.map +1 -1
- package/dist/config/defaults.js +8 -1
- package/dist/config/defaults.js.map +1 -1
- package/dist/config/project-config.d.ts +6 -0
- package/dist/config/project-config.js +2 -0
- package/dist/config/project-config.js.map +1 -1
- package/dist/dream/dream.d.ts +71 -0
- package/dist/dream/dream.js +217 -0
- package/dist/dream/dream.js.map +1 -0
- package/dist/dream/okf.d.ts +10 -0
- package/dist/dream/okf.js +280 -0
- package/dist/dream/okf.js.map +1 -0
- package/dist/dream/parser.d.ts +60 -0
- package/dist/dream/parser.js +176 -0
- package/dist/dream/parser.js.map +1 -0
- package/dist/dream/reconcile.d.ts +69 -0
- package/dist/dream/reconcile.js +303 -0
- package/dist/dream/reconcile.js.map +1 -0
- package/dist/kanban/index.d.ts +5 -0
- package/dist/kanban/index.js +11 -0
- package/dist/kanban/index.js.map +1 -0
- package/dist/kanban/pipeline.d.ts +16 -0
- package/dist/kanban/pipeline.js +910 -0
- package/dist/kanban/pipeline.js.map +1 -0
- package/dist/kanban/server.d.ts +5 -0
- package/dist/kanban/server.js +820 -0
- package/dist/kanban/server.js.map +1 -0
- package/dist/kanban/types.d.ts +75 -0
- package/dist/kanban/types.js +6 -0
- package/dist/kanban/types.js.map +1 -0
- package/dist/learnlight/driven.d.ts +2 -0
- package/dist/learnlight/driven.js +109 -0
- package/dist/learnlight/driven.js.map +1 -0
- package/dist/learnlight/index.d.ts +4 -0
- package/dist/learnlight/index.js +32 -0
- package/dist/learnlight/index.js.map +1 -0
- package/dist/learnlight/lesson-prep.d.ts +36 -0
- package/dist/learnlight/lesson-prep.js +224 -0
- package/dist/learnlight/lesson-prep.js.map +1 -0
- package/dist/learnlight/report.d.ts +2 -0
- package/dist/learnlight/report.js +37 -0
- package/dist/learnlight/report.js.map +1 -0
- package/dist/learnlight/types.d.ts +72 -0
- package/dist/learnlight/types.js +6 -0
- package/dist/learnlight/types.js.map +1 -0
- package/dist/machina/index.d.ts +16 -0
- package/dist/machina/index.js +61 -0
- package/dist/machina/index.js.map +1 -0
- package/dist/machina/render-html.d.ts +2 -0
- package/dist/machina/render-html.js +189 -0
- package/dist/machina/render-html.js.map +1 -0
- package/dist/machina/render-terminal.d.ts +2 -0
- package/dist/machina/render-terminal.js +92 -0
- package/dist/machina/render-terminal.js.map +1 -0
- package/dist/machina/spec.d.ts +61 -0
- package/dist/machina/spec.js +124 -0
- package/dist/machina/spec.js.map +1 -0
- package/dist/machina/verify.d.ts +27 -0
- package/dist/machina/verify.js +85 -0
- package/dist/machina/verify.js.map +1 -0
- package/dist/perception/graph-store.d.ts +11 -0
- package/dist/perception/graph-store.js +33 -0
- package/dist/perception/graph-store.js.map +1 -1
- package/dist/perception/index.d.ts +1 -1
- package/dist/perception/index.js +2 -1
- package/dist/perception/index.js.map +1 -1
- package/dist/providers/anthropic.js +1 -1
- package/dist/providers/anthropic.js.map +1 -1
- package/dist/providers/factory.d.ts +49 -0
- package/dist/providers/factory.js +99 -0
- package/dist/providers/factory.js.map +1 -1
- package/dist/providers/google.js +1 -1
- package/dist/providers/google.js.map +1 -1
- package/dist/providers/openai-compatible.js +81 -50
- package/dist/providers/openai-compatible.js.map +1 -1
- package/dist/rem/graph.d.ts +72 -0
- package/dist/rem/graph.js +139 -0
- package/dist/rem/graph.js.map +1 -0
- package/dist/rem/index.d.ts +16 -0
- package/dist/rem/index.js +60 -0
- package/dist/rem/index.js.map +1 -0
- package/dist/rem/render-html.d.ts +2 -0
- package/dist/rem/render-html.js +189 -0
- package/dist/rem/render-html.js.map +1 -0
- package/dist/rem/render-terminal.d.ts +4 -0
- package/dist/rem/render-terminal.js +94 -0
- package/dist/rem/render-terminal.js.map +1 -0
- package/dist/research/council.d.ts +27 -0
- package/dist/research/council.js +263 -0
- package/dist/research/council.js.map +1 -0
- package/dist/research/research.d.ts +24 -0
- package/dist/research/research.js +116 -0
- package/dist/research/research.js.map +1 -0
- package/dist/ruby/alternator.d.ts +36 -1
- package/dist/ruby/alternator.js +40 -31
- package/dist/ruby/alternator.js.map +1 -1
- package/dist/ruby/stats.js +10 -11
- package/dist/ruby/stats.js.map +1 -1
- package/dist/ruby/types.js +1 -1
- package/dist/ruby/types.js.map +1 -1
- package/dist/safety/permissions.d.ts +8 -0
- package/dist/safety/permissions.js +12 -0
- package/dist/safety/permissions.js.map +1 -1
- package/dist/setup/provider-registry.js +14 -0
- package/dist/setup/provider-registry.js.map +1 -1
- package/dist/setup/provider-test.js +24 -2
- package/dist/setup/provider-test.js.map +1 -1
- package/dist/setup/telegram-wizard.d.ts +57 -0
- package/dist/setup/telegram-wizard.js +343 -0
- package/dist/setup/telegram-wizard.js.map +1 -0
- package/dist/tools/audio-transcribe.d.ts +20 -0
- package/dist/tools/audio-transcribe.js +39 -28
- package/dist/tools/audio-transcribe.js.map +1 -1
- package/dist/tools/browser.js +8 -10
- package/dist/tools/browser.js.map +1 -1
- package/dist/tools/gmail-tool.d.ts +15 -0
- package/dist/tools/gmail-tool.js +361 -0
- package/dist/tools/gmail-tool.js.map +1 -0
- package/dist/tools/read-file.js +13 -0
- package/dist/tools/read-file.js.map +1 -1
- package/dist/tools/telegram-bot.js +103 -20
- package/dist/tools/telegram-bot.js.map +1 -1
- package/dist/tools/telegram-voice.d.ts +22 -0
- package/dist/tools/telegram-voice.js +203 -0
- package/dist/tools/telegram-voice.js.map +1 -0
- package/dist/tools/telegram.d.ts +6 -1
- package/dist/tools/telegram.js +115 -5
- package/dist/tools/telegram.js.map +1 -1
- package/dist/tools/video-render.d.ts +11 -0
- package/dist/tools/video-render.js +189 -0
- package/dist/tools/video-render.js.map +1 -0
- package/dist/tools/web-search.d.ts +20 -0
- package/dist/tools/web-search.js +134 -38
- package/dist/tools/web-search.js.map +1 -1
- package/dist/util/errors.js +6 -0
- package/dist/util/errors.js.map +1 -1
- package/dist/viz/index.js +816 -30
- package/dist/viz/index.js.map +1 -1
- package/dist/viz/reader.d.ts +33 -0
- package/dist/viz/reader.js +343 -0
- package/dist/viz/reader.js.map +1 -0
- package/package.json +3 -1
|
@@ -0,0 +1,820 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
3
|
+
// Kanban Pipeline Server
|
|
4
|
+
// Serves the interactive board + runs the Read→Plan→Execute→Verify→Report
|
|
5
|
+
// pipeline via API + WebSocket progress events.
|
|
6
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
7
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
8
|
+
if (k2 === undefined) k2 = k;
|
|
9
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
10
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
11
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
12
|
+
}
|
|
13
|
+
Object.defineProperty(o, k2, desc);
|
|
14
|
+
}) : (function(o, m, k, k2) {
|
|
15
|
+
if (k2 === undefined) k2 = k;
|
|
16
|
+
o[k2] = m[k];
|
|
17
|
+
}));
|
|
18
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
19
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
20
|
+
}) : function(o, v) {
|
|
21
|
+
o["default"] = v;
|
|
22
|
+
});
|
|
23
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
24
|
+
var ownKeys = function(o) {
|
|
25
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
26
|
+
var ar = [];
|
|
27
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
28
|
+
return ar;
|
|
29
|
+
};
|
|
30
|
+
return ownKeys(o);
|
|
31
|
+
};
|
|
32
|
+
return function (mod) {
|
|
33
|
+
if (mod && mod.__esModule) return mod;
|
|
34
|
+
var result = {};
|
|
35
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
36
|
+
__setModuleDefault(result, mod);
|
|
37
|
+
return result;
|
|
38
|
+
};
|
|
39
|
+
})();
|
|
40
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
41
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
42
|
+
};
|
|
43
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
44
|
+
exports.startKanbanServer = startKanbanServer;
|
|
45
|
+
const http = __importStar(require("http"));
|
|
46
|
+
const express_1 = __importDefault(require("express"));
|
|
47
|
+
const ws_1 = require("ws");
|
|
48
|
+
const pipeline_js_1 = require("./pipeline.js");
|
|
49
|
+
async function startKanbanServer(opts) {
|
|
50
|
+
const app = (0, express_1.default)();
|
|
51
|
+
const server = http.createServer(app);
|
|
52
|
+
const wss = new ws_1.WebSocketServer({ server });
|
|
53
|
+
app.use(express_1.default.json());
|
|
54
|
+
let lastReport = null;
|
|
55
|
+
let isRunning = false;
|
|
56
|
+
const progressClients = new Set();
|
|
57
|
+
// ── Serve the Kanban board ───────────────────────────────────────────────
|
|
58
|
+
app.get('/', (_req, res) => {
|
|
59
|
+
res.setHeader('Content-Type', 'text/html');
|
|
60
|
+
res.send(buildKanbanUI());
|
|
61
|
+
});
|
|
62
|
+
// ── API: Get all tasks ──────────────────────────────────────────────────
|
|
63
|
+
app.get('/api/tasks', (_req, res) => {
|
|
64
|
+
res.json((0, pipeline_js_1.getBoardTasks)());
|
|
65
|
+
});
|
|
66
|
+
// ── API: Execute the full pipeline ──────────────────────────────────────
|
|
67
|
+
app.post('/api/execute', async (_req, res) => {
|
|
68
|
+
if (isRunning) {
|
|
69
|
+
res.status(409).json({ error: 'Pipeline already running' });
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
isRunning = true;
|
|
73
|
+
const start = Date.now();
|
|
74
|
+
try {
|
|
75
|
+
const report = await (0, pipeline_js_1.runPipeline)({
|
|
76
|
+
projectRoot: opts.cwd,
|
|
77
|
+
onProgress: (event) => {
|
|
78
|
+
for (const ws of progressClients) {
|
|
79
|
+
if (ws.readyState === ws_1.WebSocket.OPEN) {
|
|
80
|
+
ws.send(JSON.stringify(event));
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
lastReport = report;
|
|
86
|
+
res.json(report);
|
|
87
|
+
}
|
|
88
|
+
catch (e) {
|
|
89
|
+
res.status(500).json({ error: String(e) });
|
|
90
|
+
}
|
|
91
|
+
finally {
|
|
92
|
+
isRunning = false;
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
// ── API: Get last report ────────────────────────────────────────────────
|
|
96
|
+
app.get('/api/report', (_req, res) => {
|
|
97
|
+
if (!lastReport) {
|
|
98
|
+
res.status(404).json({ error: 'No report yet. POST /api/execute first.' });
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
res.json(lastReport);
|
|
102
|
+
});
|
|
103
|
+
// ── API: Report as Markdown ─────────────────────────────────────────────
|
|
104
|
+
app.get('/api/report.md', (_req, res) => {
|
|
105
|
+
if (!lastReport) {
|
|
106
|
+
res.status(404).send('No report yet. Run the pipeline first.');
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
res.setHeader('Content-Type', 'text/markdown');
|
|
110
|
+
res.send(renderReportMarkdown(lastReport));
|
|
111
|
+
});
|
|
112
|
+
// ── WebSocket: real-time progress ───────────────────────────────────────
|
|
113
|
+
wss.on('connection', (ws) => {
|
|
114
|
+
progressClients.add(ws);
|
|
115
|
+
ws.on('close', () => progressClients.delete(ws));
|
|
116
|
+
ws.send(JSON.stringify({ type: 'connected', running: isRunning }));
|
|
117
|
+
});
|
|
118
|
+
// ── Start listening ─────────────────────────────────────────────────────
|
|
119
|
+
server.listen(opts.port, () => {
|
|
120
|
+
console.log('');
|
|
121
|
+
console.log(' ◆ Aura Kanban Pipeline Server');
|
|
122
|
+
console.log(` ├─ Board: http://localhost:${opts.port}`);
|
|
123
|
+
console.log(` ├─ API: http://localhost:${opts.port}/api/tasks`);
|
|
124
|
+
console.log(` ├─ Execute: POST http://localhost:${opts.port}/api/execute`);
|
|
125
|
+
console.log(` ├─ Report: http://localhost:${opts.port}/api/report`);
|
|
126
|
+
console.log(` ├─ Report: http://localhost:${opts.port}/api/report.md`);
|
|
127
|
+
console.log(` └─ WebSocket ws://localhost:${opts.port}`);
|
|
128
|
+
console.log('');
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
132
|
+
// Build the Kanban board HTML (enhanced version of the original)
|
|
133
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
134
|
+
function buildKanbanUI() {
|
|
135
|
+
const tasks = (0, pipeline_js_1.getBoardTasks)();
|
|
136
|
+
// Organize tasks into a grid: row × phase
|
|
137
|
+
const grid = new Map();
|
|
138
|
+
for (const t of tasks) {
|
|
139
|
+
const key = `${t.row}|${t.phase}`;
|
|
140
|
+
const arr = grid.get(key) ?? [];
|
|
141
|
+
arr.push(t);
|
|
142
|
+
grid.set(key, arr);
|
|
143
|
+
}
|
|
144
|
+
const ROWS = [
|
|
145
|
+
{ id: 'orchestrate', label: 'Orchestrate', sub: 'Multi-Agent' },
|
|
146
|
+
{ id: 'architect', label: 'Architect', sub: 'Design Phase' },
|
|
147
|
+
{ id: 'verify', label: 'Verify', sub: 'Self-Correction' },
|
|
148
|
+
{ id: 'ruby-alternator', label: 'RubyAlternator', sub: 'Improvement' },
|
|
149
|
+
];
|
|
150
|
+
const PHASES = [
|
|
151
|
+
{ id: 'read', label: 'Read', sub: 'Context' },
|
|
152
|
+
{ id: 'plan', label: 'Plan', sub: 'Strategy' },
|
|
153
|
+
{ id: 'execute', label: 'Execute', sub: 'Ignite' },
|
|
154
|
+
{ id: 'verify', label: 'Verify', sub: 'Test' },
|
|
155
|
+
{ id: 'report', label: 'Report', sub: 'Done' },
|
|
156
|
+
];
|
|
157
|
+
function renderCard(t, phaseId, rowLabel) {
|
|
158
|
+
const isOrigin = t.phase === phaseId;
|
|
159
|
+
const border = isOrigin ? 'border-left: 3px solid #a63f2b;' : '';
|
|
160
|
+
const priority = t.highPriority ? ' high-priority' : '';
|
|
161
|
+
return `
|
|
162
|
+
<div class="kanban-card${priority}" style="${border}" data-id="${t.id}" data-phase="${phaseId}" data-row="${esc(rowLabel)}">
|
|
163
|
+
<div>
|
|
164
|
+
<span class="priority-badge">${esc(t.badge)}</span>
|
|
165
|
+
<h4 class="card-title">${esc(t.title)}</h4>
|
|
166
|
+
<p class="card-desc">${esc(t.description)}</p>
|
|
167
|
+
</div>
|
|
168
|
+
<div class="card-footer">
|
|
169
|
+
<span class="provider-tag">${esc(t.tag)}</span>
|
|
170
|
+
<div class="avatar">${t.title.substring(0, 2).toUpperCase()}</div>
|
|
171
|
+
</div>
|
|
172
|
+
</div>`;
|
|
173
|
+
}
|
|
174
|
+
// Build column HTML
|
|
175
|
+
const columnsHtml = PHASES.map(phase => {
|
|
176
|
+
const header = `<div class="column-header">${phase.label} <span>${phase.sub}</span></div>`;
|
|
177
|
+
const cells = ROWS.map(row => {
|
|
178
|
+
const key = `${row.id}|${phase.id}`;
|
|
179
|
+
const tasksInCell = grid.get(key) ?? [];
|
|
180
|
+
if (tasksInCell.length === 0) {
|
|
181
|
+
return `<div class="empty-slot" data-row="${esc(row.label)}">Empty</div>`;
|
|
182
|
+
}
|
|
183
|
+
return tasksInCell.map(t => renderCard(t, phase.id, row.label)).join('\n');
|
|
184
|
+
}).join('\n');
|
|
185
|
+
return `<div class="kanban-column" data-col="${phase.id}">${header}\n${cells}</div>`;
|
|
186
|
+
}).join('\n');
|
|
187
|
+
// Row headers
|
|
188
|
+
const rowHeaders = ROWS.map(r => `<div class="row-header-card"><h3>${r.label}</h3><span>${r.sub}</span></div>`).join('\n');
|
|
189
|
+
return `<!DOCTYPE html>
|
|
190
|
+
<html lang="en" data-theme="light">
|
|
191
|
+
<head>
|
|
192
|
+
<meta charset="UTF-8">
|
|
193
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
194
|
+
<title>Aura — Kanban Pipeline</title>
|
|
195
|
+
<style>
|
|
196
|
+
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Playfair+Display:ital,wght@0,400;0,600;1,400&display=swap');
|
|
197
|
+
|
|
198
|
+
:root {
|
|
199
|
+
--bg-base: #ebd5c9; --bg-board: #d6bdae; --bg-column: #e8d0c3;
|
|
200
|
+
--bg-card: #fcf9f7; --text-main: #3d2b25; --text-muted: #7a5f54;
|
|
201
|
+
--accent-red: #a34c38; --accent-glow: rgba(163, 76, 56, 0.4);
|
|
202
|
+
--gold: #b38b59; --border-light: rgba(179, 139, 89, 0.25);
|
|
203
|
+
--border-strong: rgba(179, 139, 89, 0.6);
|
|
204
|
+
--shadow-soft: 0 8px 24px rgba(61, 43, 37, 0.08);
|
|
205
|
+
--shadow-hover: 0 12px 32px rgba(61, 43, 37, 0.15);
|
|
206
|
+
--pattern-opacity: 0.06; --btn-text: #ffffff;
|
|
207
|
+
--accent-green: #5a9e6e; --accent-gold: #d4903a;
|
|
208
|
+
}
|
|
209
|
+
[data-theme="dark"] {
|
|
210
|
+
--bg-base: #1c1311; --bg-board: #2b1d1a; --bg-column: #382622;
|
|
211
|
+
--bg-card: #45302b; --text-main: #f5ebe6; --text-muted: #bda399;
|
|
212
|
+
--accent-red: #d9684f; --accent-glow: rgba(217, 104, 79, 0.6);
|
|
213
|
+
--gold: #d6af7a; --border-light: rgba(214, 175, 122, 0.15);
|
|
214
|
+
--border-strong: rgba(214, 175, 122, 0.4);
|
|
215
|
+
--shadow-soft: 0 8px 24px rgba(0, 0, 0, 0.4);
|
|
216
|
+
--shadow-hover: 0 12px 32px rgba(0, 0, 0, 0.6);
|
|
217
|
+
--pattern-opacity: 0.03; --btn-text: #1c1311;
|
|
218
|
+
}
|
|
219
|
+
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
220
|
+
body {
|
|
221
|
+
padding: 30px 20px; background-color: var(--bg-base);
|
|
222
|
+
background-image:
|
|
223
|
+
radial-gradient(circle at 15% 50%, rgba(179, 139, 89, var(--pattern-opacity)), transparent 25%),
|
|
224
|
+
radial-gradient(circle at 85% 30%, rgba(163, 76, 56, var(--pattern-opacity)), transparent 25%);
|
|
225
|
+
font-family: 'Inter', sans-serif; color: var(--text-main);
|
|
226
|
+
display: flex; flex-direction: column; align-items: center;
|
|
227
|
+
min-height: 100vh; transition: background-color 0.4s ease, color 0.4s ease;
|
|
228
|
+
}
|
|
229
|
+
.theme-toggle-wrapper { position: absolute; top: 30px; right: 40px; }
|
|
230
|
+
.theme-toggle {
|
|
231
|
+
background: var(--bg-card); border: 1px solid var(--border-strong);
|
|
232
|
+
color: var(--text-main); padding: 10px 18px; border-radius: 30px;
|
|
233
|
+
cursor: pointer; font-family: 'Inter', sans-serif; font-weight: 600;
|
|
234
|
+
font-size: 0.85rem; display: flex; align-items: center; gap: 8px;
|
|
235
|
+
box-shadow: var(--shadow-soft); transition: all 0.3s ease;
|
|
236
|
+
}
|
|
237
|
+
.theme-toggle:hover { transform: translateY(-2px); border-color: var(--gold); box-shadow: var(--shadow-hover); }
|
|
238
|
+
header { text-align: center; margin-bottom: 40px; width: 100%; }
|
|
239
|
+
.project-subtitle {
|
|
240
|
+
font-size: 0.85rem; text-transform: uppercase; letter-spacing: 5px;
|
|
241
|
+
color: var(--gold); margin: 0 0 10px 0; font-weight: 600;
|
|
242
|
+
}
|
|
243
|
+
h1 {
|
|
244
|
+
font-family: 'Playfair Display', serif; font-size: 4.5rem; font-weight: 400;
|
|
245
|
+
letter-spacing: 12px; color: var(--text-main); margin: 0; text-indent: 12px;
|
|
246
|
+
text-shadow: 0 4px 20px rgba(0,0,0,0.05);
|
|
247
|
+
}
|
|
248
|
+
.project-motto {
|
|
249
|
+
font-family: 'Playfair Display', serif; font-style: italic;
|
|
250
|
+
font-size: 1.1rem; color: var(--text-muted); margin-top: 10px;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/* ── Control bar ──────────────────────────────── */
|
|
254
|
+
.controls { display: flex; justify-content: center; gap: 12px; margin-bottom: 20px; z-index: 10; }
|
|
255
|
+
.btn {
|
|
256
|
+
padding: 12px 28px; border-radius: 30px; border: none; font-weight: 700;
|
|
257
|
+
cursor: pointer; font-size: 0.95rem; letter-spacing: 0.5px; transition: all 0.2s;
|
|
258
|
+
}
|
|
259
|
+
.btn-run { background: var(--accent-red); color: #fff; box-shadow: 0 4px 15px var(--accent-glow); }
|
|
260
|
+
.btn-run:hover { transform: translateY(-2px); box-shadow: 0 6px 20px var(--accent-glow); }
|
|
261
|
+
.btn-run:disabled { background: #999; cursor: not-allowed; transform: none; box-shadow: none; }
|
|
262
|
+
.btn-report { background: var(--gold); color: var(--btn-text); }
|
|
263
|
+
.btn-report:hover { transform: translateY(-2px); box-shadow: 0 4px 15px rgba(179, 139, 89, 0.4); }
|
|
264
|
+
|
|
265
|
+
/* ── Status bar ───────────────────────────────── */
|
|
266
|
+
.status-bar {
|
|
267
|
+
text-align: center; padding: 14px 24px; margin-bottom: 24px;
|
|
268
|
+
border-radius: 16px; font-size: 0.95rem; font-weight: 600;
|
|
269
|
+
border: 1px solid var(--border-light); transition: .3s;
|
|
270
|
+
box-shadow: var(--shadow-soft);
|
|
271
|
+
}
|
|
272
|
+
.status-bar.idle { background: var(--bg-card); color: var(--text-muted); }
|
|
273
|
+
.status-bar.running { background: var(--accent-gold); color: #fff; animation: pulse 1.5s infinite; }
|
|
274
|
+
.status-bar.done { background: var(--accent-green); color: #fff; }
|
|
275
|
+
.status-bar.error { background: var(--accent-red); color: #fff; }
|
|
276
|
+
@keyframes pulse { 0%,100% { opacity:1 } 50% { opacity:0.7 } }
|
|
277
|
+
|
|
278
|
+
/* ── Board ────────────────────────────────────── */
|
|
279
|
+
.kanban-container {
|
|
280
|
+
display: grid; grid-template-columns: 220px repeat(5, 1fr); gap: 16px;
|
|
281
|
+
width: 100%; max-width: 1500px; background-color: var(--bg-board);
|
|
282
|
+
padding: 24px; border-radius: 24px; border: 1px solid var(--border-light);
|
|
283
|
+
box-shadow: var(--shadow-soft); overflow-x: auto;
|
|
284
|
+
transition: background-color 0.4s ease, border-color 0.4s ease;
|
|
285
|
+
}
|
|
286
|
+
.row-headers-column { display: grid; grid-template-rows: 60px repeat(4, 1fr); gap: 16px; }
|
|
287
|
+
.board-corner { height: 60px; }
|
|
288
|
+
.row-header-card {
|
|
289
|
+
background-color: transparent; border-right: 2px solid var(--border-strong);
|
|
290
|
+
display: flex; flex-direction: column; justify-content: center;
|
|
291
|
+
padding-right: 15px; text-align: right;
|
|
292
|
+
}
|
|
293
|
+
.row-header-card h3 { margin: 0; font-family: 'Playfair Display', serif; font-size: 1.1rem; font-weight: 600; }
|
|
294
|
+
.row-header-card span { font-size: 0.75rem; color: var(--text-muted); margin-top: 4px; text-transform: uppercase; letter-spacing: 2px; }
|
|
295
|
+
|
|
296
|
+
.kanban-column { display: grid; grid-template-rows: 60px repeat(4, 1fr); gap: 16px; }
|
|
297
|
+
.column-header {
|
|
298
|
+
display: flex; flex-direction: column; justify-content: center; align-items: center;
|
|
299
|
+
background-color: var(--bg-column); border-radius: 12px;
|
|
300
|
+
font-family: 'Playfair Display', serif; font-size: 1.1rem;
|
|
301
|
+
border: 1px solid var(--border-light);
|
|
302
|
+
box-shadow: inset 0 2px 5px rgba(255,255,255,0.05);
|
|
303
|
+
}
|
|
304
|
+
.column-header span {
|
|
305
|
+
font-family: 'Inter', sans-serif; font-size: 0.7rem; font-weight: 600;
|
|
306
|
+
text-transform: uppercase; letter-spacing: 2px; color: var(--gold); margin-top: 2px;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
.kanban-card, .empty-slot { cursor: pointer; transition: all 0.3s cubic-bezier(0.16, 1, 0.3, 1); }
|
|
310
|
+
.kanban-card {
|
|
311
|
+
background-color: var(--bg-card); border-radius: 16px; padding: 20px;
|
|
312
|
+
box-shadow: var(--shadow-soft); display: flex; flex-direction: column;
|
|
313
|
+
border: 1px solid var(--border-light); position: relative; overflow: hidden;
|
|
314
|
+
}
|
|
315
|
+
.kanban-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-hover); border-color: var(--gold); }
|
|
316
|
+
.kanban-card::after {
|
|
317
|
+
content: "\\2726"; position: absolute; top: 15px; right: 15px;
|
|
318
|
+
font-size: 0.9rem; color: var(--gold); opacity: 0.4; transition: opacity 0.3s;
|
|
319
|
+
}
|
|
320
|
+
.kanban-card:hover::after { opacity: 1; }
|
|
321
|
+
|
|
322
|
+
.kanban-card.phase-active { box-shadow: 0 0 0 3px var(--accent-gold), var(--shadow-hover); }
|
|
323
|
+
.kanban-card.phase-done { box-shadow: 0 0 0 3px var(--accent-green), var(--shadow-soft); }
|
|
324
|
+
.kanban-card.phase-failed { box-shadow: 0 0 0 3px var(--accent-red), var(--shadow-soft); }
|
|
325
|
+
|
|
326
|
+
.kanban-card.high-priority {
|
|
327
|
+
background-color: var(--accent-red); color: #ffffff;
|
|
328
|
+
border-color: var(--accent-red); box-shadow: 0 8px 24px var(--accent-glow);
|
|
329
|
+
}
|
|
330
|
+
.kanban-card.high-priority::after { color: #ffffff; opacity: 0.8; }
|
|
331
|
+
.kanban-card.high-priority .card-desc, .kanban-card.high-priority .card-title { color: #ffffff; }
|
|
332
|
+
|
|
333
|
+
.priority-badge {
|
|
334
|
+
font-size: 0.65rem; text-transform: uppercase; letter-spacing: 1.5px; font-weight: 700;
|
|
335
|
+
margin-bottom: 12px; display: inline-block; background: var(--bg-base);
|
|
336
|
+
color: var(--text-main); padding: 4px 10px; border-radius: 20px; border: 1px solid var(--border-light);
|
|
337
|
+
}
|
|
338
|
+
.kanban-card.high-priority .priority-badge {
|
|
339
|
+
background: rgba(255,255,255,0.15); color: #ffffff; border-color: rgba(255,255,255,0.3);
|
|
340
|
+
}
|
|
341
|
+
.card-title { font-family: 'Playfair Display', serif; font-size: 1.1rem; margin: 0 0 8px 0; font-weight: 600; line-height: 1.3; }
|
|
342
|
+
.card-desc { font-size: 0.85rem; line-height: 1.5; margin: 0 0 16px 0; color: var(--text-muted); }
|
|
343
|
+
.card-footer { display: flex; justify-content: space-between; align-items: center; font-size: 0.8rem; border-top: 1px solid var(--border-light); padding-top: 12px; margin-top: auto; }
|
|
344
|
+
.kanban-card.high-priority .card-footer { border-top-color: rgba(255,255,255,0.2); }
|
|
345
|
+
.provider-tag { font-weight: 600; letter-spacing: 0.5px; color: var(--gold); }
|
|
346
|
+
.kanban-card.high-priority .provider-tag { color: #ffffff; }
|
|
347
|
+
.avatar {
|
|
348
|
+
width: 26px; height: 26px; border-radius: 50%; background-color: var(--bg-base);
|
|
349
|
+
display: flex; align-items: center; justify-content: center;
|
|
350
|
+
font-weight: 700; font-size: 0.65rem; border: 1px solid var(--border-strong);
|
|
351
|
+
}
|
|
352
|
+
.empty-slot {
|
|
353
|
+
border: 1px dashed var(--border-strong); border-radius: 16px; display: flex;
|
|
354
|
+
align-items: center; justify-content: center; color: var(--text-muted);
|
|
355
|
+
font-size: 0.8rem; font-weight: 500; letter-spacing: 1px; position: relative;
|
|
356
|
+
}
|
|
357
|
+
.empty-slot::before { content: "+"; font-size: 1.5rem; margin-right: 8px; font-weight: 300; }
|
|
358
|
+
.empty-slot:hover { border-style: solid; border-color: var(--gold); background-color: rgba(179, 139, 89, 0.05); color: var(--gold); }
|
|
359
|
+
|
|
360
|
+
/* ── Report panel ─────────────────────────────── */
|
|
361
|
+
#report-panel {
|
|
362
|
+
display: none; max-width: 1000px; margin: 0 auto 20px;
|
|
363
|
+
background: var(--bg-card); border-radius: 24px; padding: 32px;
|
|
364
|
+
box-shadow: var(--shadow-soft); border: 1px solid var(--border-light);
|
|
365
|
+
}
|
|
366
|
+
#report-panel h2 { font-family: 'Playfair Display', serif; margin-bottom: 16px; }
|
|
367
|
+
#report-panel pre {
|
|
368
|
+
background: #2c1e14; color: #ede0cc; padding: 16px; border-radius: 12px;
|
|
369
|
+
font-size: 0.85rem; line-height: 1.6; overflow-x: auto; white-space: pre-wrap;
|
|
370
|
+
}
|
|
371
|
+
.report-stats { display: flex; gap: 20px; margin-bottom: 16px; flex-wrap: wrap; }
|
|
372
|
+
.stat-box {
|
|
373
|
+
background: var(--bg-column); padding: 12px 20px; border-radius: 12px;
|
|
374
|
+
text-align: center; min-width: 100px; border: 1px solid var(--border-light);
|
|
375
|
+
}
|
|
376
|
+
.stat-box .num { font-size: 1.8rem; font-weight: 700; font-family: 'Playfair Display', serif; }
|
|
377
|
+
.stat-box .label { font-size: 0.75rem; text-transform: uppercase; letter-spacing: 1px; color: var(--text-muted); }
|
|
378
|
+
|
|
379
|
+
/* ── Progress log ─────────────────────────────── */
|
|
380
|
+
#progress-log {
|
|
381
|
+
max-width: 1000px; margin: 0 auto 20px; background: #2c1e14; color: #ede0cc;
|
|
382
|
+
border-radius: 12px; padding: 16px; font-family: monospace; font-size: 0.8rem;
|
|
383
|
+
max-height: 200px; overflow-y: auto; display: none;
|
|
384
|
+
}
|
|
385
|
+
.log-line { padding: 2px 0; border-bottom: 1px solid rgba(255,255,255,0.05); }
|
|
386
|
+
.log-line.start { color: var(--accent-gold); }
|
|
387
|
+
.log-line.done { color: var(--accent-green); }
|
|
388
|
+
.log-line.fail { color: var(--accent-red); }
|
|
389
|
+
|
|
390
|
+
footer {
|
|
391
|
+
margin-top: 50px; font-family: 'Playfair Display', serif; font-size: 1.2rem;
|
|
392
|
+
font-style: italic; color: var(--text-muted); letter-spacing: 2px;
|
|
393
|
+
display: flex; align-items: center; gap: 15px;
|
|
394
|
+
}
|
|
395
|
+
footer::before, footer::after {
|
|
396
|
+
content: ""; display: block; width: 40px; height: 1px;
|
|
397
|
+
background: var(--gold); opacity: 0.5;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
/* ── Modal ────────────────────────────────────── */
|
|
401
|
+
.modal-overlay {
|
|
402
|
+
position: fixed; top: 0; left: 0; width: 100%; height: 100%;
|
|
403
|
+
background: rgba(0, 0, 0, 0.6); backdrop-filter: blur(8px);
|
|
404
|
+
display: flex; align-items: center; justify-content: center;
|
|
405
|
+
z-index: 1000; opacity: 0; pointer-events: none;
|
|
406
|
+
transition: opacity 0.3s ease;
|
|
407
|
+
}
|
|
408
|
+
.modal-overlay.active { opacity: 1; pointer-events: auto; }
|
|
409
|
+
.modal-box {
|
|
410
|
+
background-color: var(--bg-card); padding: 40px; border-radius: 24px;
|
|
411
|
+
border: 1px solid var(--border-light); width: 100%; max-width: 500px;
|
|
412
|
+
box-shadow: 0 24px 60px rgba(0,0,0,0.4);
|
|
413
|
+
transform: translateY(20px) scale(0.95);
|
|
414
|
+
transition: all 0.4s cubic-bezier(0.16, 1, 0.3, 1);
|
|
415
|
+
}
|
|
416
|
+
.modal-overlay.active .modal-box { transform: translateY(0) scale(1); }
|
|
417
|
+
.modal-box h2 {
|
|
418
|
+
font-family: 'Playfair Display', serif; margin: 0 0 24px 0;
|
|
419
|
+
color: var(--text-main); font-size: 1.8rem; font-weight: 400; text-align: center;
|
|
420
|
+
}
|
|
421
|
+
.form-group { margin-bottom: 20px; display: flex; flex-direction: column; }
|
|
422
|
+
.form-group label {
|
|
423
|
+
font-size: 0.75rem; text-transform: uppercase; letter-spacing: 2px;
|
|
424
|
+
margin-bottom: 8px; font-weight: 600; color: var(--text-muted);
|
|
425
|
+
}
|
|
426
|
+
.form-group input, .form-group textarea, .form-group select {
|
|
427
|
+
padding: 14px; border-radius: 12px; border: 1px solid var(--border-strong);
|
|
428
|
+
background: var(--bg-base); font-family: 'Inter', sans-serif;
|
|
429
|
+
font-size: 0.95rem; color: var(--text-main); transition: all 0.2s ease;
|
|
430
|
+
}
|
|
431
|
+
.form-group input:focus, .form-group textarea:focus, .form-group select:focus {
|
|
432
|
+
outline: none; border-color: var(--gold);
|
|
433
|
+
box-shadow: 0 0 0 3px rgba(179, 139, 89, 0.15);
|
|
434
|
+
}
|
|
435
|
+
.form-group textarea { resize: vertical; min-height: 100px; }
|
|
436
|
+
.modal-actions { display: flex; justify-content: flex-end; gap: 12px; margin-top: 30px; }
|
|
437
|
+
.btn-cancel { background: var(--bg-board); color: var(--text-main); }
|
|
438
|
+
.btn-cancel:hover { background: var(--border-strong); }
|
|
439
|
+
.btn-save { background: var(--gold); color: var(--btn-text); }
|
|
440
|
+
.btn-save:hover { transform: translateY(-2px); box-shadow: 0 4px 15px rgba(179, 139, 89, 0.4); }
|
|
441
|
+
.btn-clear {
|
|
442
|
+
background: transparent; color: var(--accent-red); margin-right: auto;
|
|
443
|
+
border: 1px dashed var(--accent-red);
|
|
444
|
+
}
|
|
445
|
+
.btn-clear:hover { background: rgba(163, 76, 56, 0.05); }
|
|
446
|
+
</style>
|
|
447
|
+
</head>
|
|
448
|
+
<body>
|
|
449
|
+
|
|
450
|
+
<div class="theme-toggle-wrapper">
|
|
451
|
+
<button id="themeToggle" class="theme-toggle">
|
|
452
|
+
<span id="themeIcon">\\uD83C\\uDF19</span> <span id="themeText">Dark Mode</span>
|
|
453
|
+
</button>
|
|
454
|
+
</div>
|
|
455
|
+
|
|
456
|
+
<header>
|
|
457
|
+
<div class="project-subtitle">Autonomous Coding Agent</div>
|
|
458
|
+
<h1>AURA</h1>
|
|
459
|
+
<div class="project-motto">"I don't try. I verify."</div>
|
|
460
|
+
</header>
|
|
461
|
+
|
|
462
|
+
<div class="controls">
|
|
463
|
+
<button class="btn btn-run" id="runBtn" onclick="runPipeline()">\\u25B6 Execute Pipeline</button>
|
|
464
|
+
<button class="btn btn-report" id="reportBtn" onclick="showReport()" style="display:none">\\uD83D\\uDCCB Show Report</button>
|
|
465
|
+
</div>
|
|
466
|
+
|
|
467
|
+
<div class="status-bar idle" id="statusBar">Ready \\u2014 Click "Execute Pipeline" to run all tasks through Read \\u2192 Plan \\u2192 Execute \\u2192 Verify \\u2192 Report</div>
|
|
468
|
+
|
|
469
|
+
<div id="progress-log"></div>
|
|
470
|
+
|
|
471
|
+
<div class="kanban-container" id="board">
|
|
472
|
+
<div class="row-headers-column">
|
|
473
|
+
<div class="board-corner"></div>
|
|
474
|
+
${rowHeaders}
|
|
475
|
+
</div>
|
|
476
|
+
${columnsHtml}
|
|
477
|
+
</div>
|
|
478
|
+
|
|
479
|
+
<div id="report-panel">
|
|
480
|
+
<h2>\\uD83D\\uDCCA Pipeline Execution Report</h2>
|
|
481
|
+
<div class="report-stats" id="reportStats"></div>
|
|
482
|
+
<pre id="reportContent"></pre>
|
|
483
|
+
</div>
|
|
484
|
+
|
|
485
|
+
<footer>let me be your Aura.</footer>
|
|
486
|
+
|
|
487
|
+
<!-- Edit / Create Modal -->
|
|
488
|
+
<div class="modal-overlay" id="editModal">
|
|
489
|
+
<div class="modal-box">
|
|
490
|
+
<h2 id="modalTitleHeader">Edit Crystal</h2>
|
|
491
|
+
<form id="editForm">
|
|
492
|
+
<div class="form-group">
|
|
493
|
+
<label for="taskBadge">Context Badge</label>
|
|
494
|
+
<input type="text" id="taskBadge" placeholder="e.g., Active Coder">
|
|
495
|
+
</div>
|
|
496
|
+
<div class="form-group">
|
|
497
|
+
<label for="taskTitle">Objective Title</label>
|
|
498
|
+
<input type="text" id="taskTitle" required placeholder="What needs to be done?">
|
|
499
|
+
</div>
|
|
500
|
+
<div class="form-group">
|
|
501
|
+
<label for="taskDesc">Details</label>
|
|
502
|
+
<textarea id="taskDesc" placeholder="Provide deeper architectural context..."></textarea>
|
|
503
|
+
</div>
|
|
504
|
+
<div class="form-group">
|
|
505
|
+
<label for="taskTag">System Tag</label>
|
|
506
|
+
<input type="text" id="taskTag" placeholder="e.g., GPT-4o, Vitest">
|
|
507
|
+
</div>
|
|
508
|
+
<div class="form-group">
|
|
509
|
+
<label for="taskPriority">Energy Level</label>
|
|
510
|
+
<select id="taskPriority">
|
|
511
|
+
<option value="normal">Standard (Base Flow)</option>
|
|
512
|
+
<option value="high">Ignited (High Priority)</option>
|
|
513
|
+
</select>
|
|
514
|
+
</div>
|
|
515
|
+
<div class="modal-actions">
|
|
516
|
+
<button type="button" class="btn btn-clear" id="clearCardBtn" style="display:none">Clear Slot</button>
|
|
517
|
+
<button type="button" class="btn btn-cancel" id="closeModalBtn">Cancel</button>
|
|
518
|
+
<button type="submit" class="btn btn-save">Imprint Changes</button>
|
|
519
|
+
</div>
|
|
520
|
+
</form>
|
|
521
|
+
</div>
|
|
522
|
+
</div>
|
|
523
|
+
|
|
524
|
+
<script>
|
|
525
|
+
// Theme toggle
|
|
526
|
+
(function() {
|
|
527
|
+
var tt = document.getElementById('themeToggle');
|
|
528
|
+
var ti = document.getElementById('themeIcon');
|
|
529
|
+
var tx = document.getElementById('themeText');
|
|
530
|
+
if (localStorage.getItem('aura-theme') === 'dark') {
|
|
531
|
+
document.documentElement.setAttribute('data-theme', 'dark');
|
|
532
|
+
ti.textContent = '\\u2600\\uFE0F'; tx.textContent = 'Light Mode';
|
|
533
|
+
}
|
|
534
|
+
tt.addEventListener('click', function() {
|
|
535
|
+
var r = document.documentElement;
|
|
536
|
+
if (r.getAttribute('data-theme') === 'dark') {
|
|
537
|
+
r.setAttribute('data-theme', 'light');
|
|
538
|
+
localStorage.setItem('aura-theme', 'light');
|
|
539
|
+
ti.textContent = '\\uD83C\\uDF19'; tx.textContent = 'Dark Mode';
|
|
540
|
+
} else {
|
|
541
|
+
r.setAttribute('data-theme', 'dark');
|
|
542
|
+
localStorage.setItem('aura-theme', 'dark');
|
|
543
|
+
ti.textContent = '\\u2600\\uFE0F'; tx.textContent = 'Light Mode';
|
|
544
|
+
}
|
|
545
|
+
});
|
|
546
|
+
})();
|
|
547
|
+
|
|
548
|
+
// Pipeline
|
|
549
|
+
var ws;
|
|
550
|
+
var logEl = document.getElementById('progress-log');
|
|
551
|
+
var statusBar = document.getElementById('statusBar');
|
|
552
|
+
|
|
553
|
+
function connect() {
|
|
554
|
+
ws = new WebSocket('ws://' + location.host);
|
|
555
|
+
ws.onmessage = function(e) { handleProgress(JSON.parse(e.data)); };
|
|
556
|
+
ws.onclose = function() { setTimeout(connect, 2000); };
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
function handleProgress(ev) {
|
|
560
|
+
if (ev.type === 'phase_start') {
|
|
561
|
+
setStatus('running', 'Running: ' + ev.phase.toUpperCase() + ' \\u2014 ' + ev.taskId);
|
|
562
|
+
highlightCard(ev.taskId, 'active');
|
|
563
|
+
addLog('\\u25B6 ' + ev.phase.toUpperCase() + ' \\u2192 ' + ev.taskId, 'start');
|
|
564
|
+
} else if (ev.type === 'phase_done') {
|
|
565
|
+
var icon = ev.status === 'done' ? '\\u2713' : ev.status === 'failed' ? '\\u2717' : '\\u25CB';
|
|
566
|
+
highlightCard(ev.taskId, ev.status === 'done' ? 'done' : ev.status === 'failed' ? 'failed' : '');
|
|
567
|
+
addLog(icon + ' ' + ev.phase.toUpperCase() + ' \\u2192 ' + ev.taskId + ' [' + ev.status + ']', ev.status === 'done' ? 'done' : 'fail');
|
|
568
|
+
} else if (ev.type === 'row_done') {
|
|
569
|
+
addLog('\\u2500\\u2500 Row ' + ev.row + ' complete: ' + ev.status, 'done');
|
|
570
|
+
} else if (ev.type === 'pipeline_done') {
|
|
571
|
+
setStatus('done', 'Pipeline complete!');
|
|
572
|
+
document.getElementById('runBtn').disabled = false;
|
|
573
|
+
document.getElementById('runBtn').textContent = '\\u25B6 Execute Pipeline';
|
|
574
|
+
document.getElementById('reportBtn').style.display = 'inline-block';
|
|
575
|
+
loadReport();
|
|
576
|
+
} else if (ev.type === 'error') {
|
|
577
|
+
setStatus('error', 'Error: ' + ev.message);
|
|
578
|
+
document.getElementById('runBtn').disabled = false;
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
function setStatus(cls, text) { statusBar.className = 'status-bar ' + cls; statusBar.textContent = text; }
|
|
583
|
+
|
|
584
|
+
function highlightCard(taskId, cls) {
|
|
585
|
+
var el = document.querySelector('[data-id="' + taskId + '"]');
|
|
586
|
+
if (!el) return;
|
|
587
|
+
el.classList.remove('phase-active', 'phase-done', 'phase-failed');
|
|
588
|
+
if (cls) el.classList.add('phase-' + cls);
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
function addLog(text, cls) {
|
|
592
|
+
logEl.style.display = 'block';
|
|
593
|
+
var line = document.createElement('div');
|
|
594
|
+
line.className = 'log-line ' + (cls || '');
|
|
595
|
+
line.textContent = text;
|
|
596
|
+
logEl.appendChild(line);
|
|
597
|
+
logEl.scrollTop = logEl.scrollHeight;
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
function runPipeline() {
|
|
601
|
+
var btn = document.getElementById('runBtn');
|
|
602
|
+
btn.disabled = true; btn.textContent = '\\u23F3 Running...';
|
|
603
|
+
document.getElementById('reportBtn').style.display = 'none';
|
|
604
|
+
logEl.innerHTML = ''; logEl.style.display = 'block';
|
|
605
|
+
setStatus('running', 'Starting pipeline execution...');
|
|
606
|
+
addLog('Pipeline started', 'start');
|
|
607
|
+
document.querySelectorAll('.kanban-card').forEach(function(c) {
|
|
608
|
+
c.classList.remove('phase-active', 'phase-done', 'phase-failed');
|
|
609
|
+
});
|
|
610
|
+
fetch('/api/execute', { method: 'POST' })
|
|
611
|
+
.then(function(r) { return r.json(); })
|
|
612
|
+
.then(function(report) {
|
|
613
|
+
if (report.error) {
|
|
614
|
+
setStatus('error', 'Error: ' + report.error);
|
|
615
|
+
btn.disabled = false; btn.textContent = '\\u25B6 Execute Pipeline';
|
|
616
|
+
}
|
|
617
|
+
})
|
|
618
|
+
.catch(function(e) {
|
|
619
|
+
setStatus('error', 'Network error: ' + e.message);
|
|
620
|
+
btn.disabled = false; btn.textContent = '\\u25B6 Execute Pipeline';
|
|
621
|
+
});
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
function loadReport() {
|
|
625
|
+
fetch('/api/report').then(function(r) { return r.json(); }).then(function(report) { renderReport(report); });
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
function renderReport(report) {
|
|
629
|
+
document.getElementById('report-panel').style.display = 'block';
|
|
630
|
+
document.getElementById('reportStats').innerHTML =
|
|
631
|
+
'<div class="stat-box"><div class="num">' + report.stats.totalTasks + '</div><div class="label">Total Tasks</div></div>' +
|
|
632
|
+
'<div class="stat-box"><div class="num" style="color:var(--accent-green)">' + report.stats.completed + '</div><div class="label">Completed</div></div>' +
|
|
633
|
+
'<div class="stat-box"><div class="num" style="color:var(--accent-red)">' + report.stats.failed + '</div><div class="label">Failed</div></div>' +
|
|
634
|
+
'<div class="stat-box"><div class="num" style="color:var(--accent-gold)">' + Math.round(report.totalDurationMs / 1000) + 's</div><div class="label">Duration</div></div>';
|
|
635
|
+
var lines = [];
|
|
636
|
+
lines.push('\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550');
|
|
637
|
+
lines.push(' AURA \\u2014 PIPELINE EXECUTION REPORT');
|
|
638
|
+
lines.push(' Generated: ' + report.generatedAt);
|
|
639
|
+
lines.push(' Duration: ' + Math.round(report.totalDurationMs / 1000) + ' seconds');
|
|
640
|
+
lines.push('\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550');
|
|
641
|
+
report.rows.forEach(function(row) {
|
|
642
|
+
lines.push('');
|
|
643
|
+
lines.push('\\u250C\\u2500 ' + row.label + ' [' + row.status.toUpperCase() + ']');
|
|
644
|
+
row.executions.forEach(function(exec) {
|
|
645
|
+
var icon = exec.status === 'done' ? '\\u2713' : exec.status === 'failed' ? '\\u2717' : '\\u25CB';
|
|
646
|
+
lines.push('\\u2502');
|
|
647
|
+
lines.push('\\u2502 ' + icon + ' ' + exec.task.title);
|
|
648
|
+
lines.push('\\u2502 Badge: ' + exec.task.badge + ' | Tag: ' + exec.task.tag);
|
|
649
|
+
exec.phases.forEach(function(phase) {
|
|
650
|
+
var pIcon = phase.status === 'done' ? '\\u2713' : phase.status === 'failed' ? '\\u2717' : '\\u2580';
|
|
651
|
+
lines.push('\\u2502 [' + pIcon + ' ' + phase.phase.toUpperCase() + '] ' + phase.status + ' (' + phase.durationMs + 'ms)');
|
|
652
|
+
if (phase.output) phase.output.split('\\n').forEach(function(l) { lines.push('\\u2502 ' + l); });
|
|
653
|
+
});
|
|
654
|
+
lines.push('\\u2502');
|
|
655
|
+
});
|
|
656
|
+
lines.push('\\u2514\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500');
|
|
657
|
+
});
|
|
658
|
+
lines.push('');
|
|
659
|
+
lines.push(' SUMMARY: ' + report.stats.totalTasks + ' tasks, ' + report.stats.completed + ' completed, ' + report.stats.failed + ' failed');
|
|
660
|
+
document.getElementById('reportContent').textContent = lines.join('\\n');
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
function showReport() { document.getElementById('report-panel').scrollIntoView({ behavior: 'smooth' }); }
|
|
664
|
+
|
|
665
|
+
// ── Board interaction: click card → modal, click empty → modal, save/clear ──
|
|
666
|
+
(function() {
|
|
667
|
+
var currentTarget = null;
|
|
668
|
+
var board = document.getElementById('board');
|
|
669
|
+
var modal = document.getElementById('editModal');
|
|
670
|
+
var editForm = document.getElementById('editForm');
|
|
671
|
+
var taskBadge = document.getElementById('taskBadge');
|
|
672
|
+
var taskTitle = document.getElementById('taskTitle');
|
|
673
|
+
var taskDesc = document.getElementById('taskDesc');
|
|
674
|
+
var taskTag = document.getElementById('taskTag');
|
|
675
|
+
var taskPriority = document.getElementById('taskPriority');
|
|
676
|
+
var closeModalBtn = document.getElementById('closeModalBtn');
|
|
677
|
+
var clearCardBtn = document.getElementById('clearCardBtn');
|
|
678
|
+
|
|
679
|
+
board.addEventListener('click', function(e) {
|
|
680
|
+
var square = e.target.closest('.kanban-card, .empty-slot');
|
|
681
|
+
if (!square) return;
|
|
682
|
+
currentTarget = square;
|
|
683
|
+
var isCard = square.classList.contains('kanban-card');
|
|
684
|
+
|
|
685
|
+
if (isCard) {
|
|
686
|
+
taskBadge.value = square.querySelector('.priority-badge') ? square.querySelector('.priority-badge').innerText : '';
|
|
687
|
+
taskTitle.value = square.querySelector('.card-title') ? square.querySelector('.card-title').innerText : '';
|
|
688
|
+
taskDesc.value = square.querySelector('.card-desc') ? square.querySelector('.card-desc').innerText : '';
|
|
689
|
+
taskTag.value = square.querySelector('.provider-tag') ? square.querySelector('.provider-tag').innerText : '';
|
|
690
|
+
taskPriority.value = square.classList.contains('high-priority') ? 'high' : 'normal';
|
|
691
|
+
clearCardBtn.style.display = 'block';
|
|
692
|
+
} else {
|
|
693
|
+
taskBadge.value = '';
|
|
694
|
+
taskTitle.value = '';
|
|
695
|
+
taskDesc.value = '';
|
|
696
|
+
taskTag.value = '';
|
|
697
|
+
taskPriority.value = 'normal';
|
|
698
|
+
clearCardBtn.style.display = 'none';
|
|
699
|
+
}
|
|
700
|
+
modal.classList.add('active');
|
|
701
|
+
});
|
|
702
|
+
|
|
703
|
+
function closeModal() { modal.classList.remove('active'); currentTarget = null; }
|
|
704
|
+
closeModalBtn.addEventListener('click', closeModal);
|
|
705
|
+
modal.addEventListener('click', function(e) { if (e.target === modal) closeModal(); });
|
|
706
|
+
|
|
707
|
+
clearCardBtn.addEventListener('click', function() {
|
|
708
|
+
if (!currentTarget) return;
|
|
709
|
+
var rowAttr = currentTarget.getAttribute('data-row');
|
|
710
|
+
var emptySlot = document.createElement('div');
|
|
711
|
+
emptySlot.className = 'empty-slot';
|
|
712
|
+
if (rowAttr) emptySlot.setAttribute('data-row', rowAttr);
|
|
713
|
+
emptySlot.textContent = 'Empty';
|
|
714
|
+
currentTarget.replaceWith(emptySlot);
|
|
715
|
+
closeModal();
|
|
716
|
+
});
|
|
717
|
+
|
|
718
|
+
editForm.addEventListener('submit', function(e) {
|
|
719
|
+
e.preventDefault();
|
|
720
|
+
if (!currentTarget) return;
|
|
721
|
+
var rowAttr = currentTarget.getAttribute('data-row');
|
|
722
|
+
var card = document.createElement('div');
|
|
723
|
+
card.className = 'kanban-card';
|
|
724
|
+
if (taskPriority.value === 'high') card.classList.add('high-priority');
|
|
725
|
+
if (rowAttr) card.setAttribute('data-row', rowAttr);
|
|
726
|
+
|
|
727
|
+
var topDiv = document.createElement('div');
|
|
728
|
+
if (taskBadge.value.trim()) {
|
|
729
|
+
var badge = document.createElement('span');
|
|
730
|
+
badge.className = 'priority-badge';
|
|
731
|
+
badge.innerText = taskBadge.value;
|
|
732
|
+
topDiv.appendChild(badge);
|
|
733
|
+
}
|
|
734
|
+
var h4 = document.createElement('h4');
|
|
735
|
+
h4.className = 'card-title';
|
|
736
|
+
h4.innerText = taskTitle.value || 'New Objective';
|
|
737
|
+
topDiv.appendChild(h4);
|
|
738
|
+
|
|
739
|
+
var p = document.createElement('p');
|
|
740
|
+
p.className = 'card-desc';
|
|
741
|
+
p.innerText = taskDesc.value || 'No description provided.';
|
|
742
|
+
topDiv.appendChild(p);
|
|
743
|
+
|
|
744
|
+
var footer = document.createElement('div');
|
|
745
|
+
footer.className = 'card-footer';
|
|
746
|
+
var tagSpan = document.createElement('span');
|
|
747
|
+
tagSpan.className = 'provider-tag';
|
|
748
|
+
tagSpan.innerText = taskTag.value || 'System';
|
|
749
|
+
footer.appendChild(tagSpan);
|
|
750
|
+
var avatar = document.createElement('div');
|
|
751
|
+
avatar.className = 'avatar';
|
|
752
|
+
avatar.innerText = (taskTitle.value || 'XX').substring(0, 2).toUpperCase();
|
|
753
|
+
footer.appendChild(avatar);
|
|
754
|
+
|
|
755
|
+
card.appendChild(topDiv);
|
|
756
|
+
card.appendChild(footer);
|
|
757
|
+
currentTarget.replaceWith(card);
|
|
758
|
+
closeModal();
|
|
759
|
+
});
|
|
760
|
+
})();
|
|
761
|
+
|
|
762
|
+
connect();
|
|
763
|
+
</script>
|
|
764
|
+
</body>
|
|
765
|
+
</html>`;
|
|
766
|
+
}
|
|
767
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
768
|
+
// Markdown report renderer
|
|
769
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
770
|
+
function renderReportMarkdown(report) {
|
|
771
|
+
const lines = [];
|
|
772
|
+
lines.push('# Aura Code — Pipeline Execution Report');
|
|
773
|
+
lines.push('');
|
|
774
|
+
lines.push(`**Generated:** ${report.generatedAt}`);
|
|
775
|
+
lines.push(`**Duration:** ${(report.totalDurationMs / 1000).toFixed(1)}s`);
|
|
776
|
+
lines.push('');
|
|
777
|
+
lines.push('## Summary');
|
|
778
|
+
lines.push('');
|
|
779
|
+
lines.push(`| Metric | Count |`);
|
|
780
|
+
lines.push(`|--------|-------|`);
|
|
781
|
+
lines.push(`| Total Tasks | ${report.stats.totalTasks} |`);
|
|
782
|
+
lines.push(`| Completed | ${report.stats.completed} |`);
|
|
783
|
+
lines.push(`| Failed | ${report.stats.failed} |`);
|
|
784
|
+
lines.push(`| Skipped | ${report.stats.skipped} |`);
|
|
785
|
+
lines.push('');
|
|
786
|
+
for (const row of report.rows) {
|
|
787
|
+
lines.push(`## ${row.label} — ${row.status.toUpperCase()}`);
|
|
788
|
+
lines.push('');
|
|
789
|
+
for (const exec of row.executions) {
|
|
790
|
+
const icon = exec.status === 'done' ? '✅' : exec.status === 'failed' ? '❌' : '⏭️';
|
|
791
|
+
lines.push(`### ${icon} ${exec.task.title}`);
|
|
792
|
+
lines.push('');
|
|
793
|
+
lines.push(`- **Badge:** ${exec.task.badge}`);
|
|
794
|
+
lines.push(`- **Tag:** ${exec.task.tag}`);
|
|
795
|
+
lines.push(`- **Priority:** ${exec.task.highPriority ? 'HIGH' : 'Normal'}`);
|
|
796
|
+
lines.push(`- **Status:** ${exec.status}`);
|
|
797
|
+
lines.push('');
|
|
798
|
+
for (const phase of exec.phases) {
|
|
799
|
+
const pIcon = phase.status === 'done' ? '✓' : phase.status === 'failed' ? '✗' : '⊘';
|
|
800
|
+
lines.push(`**${pIcon} ${phase.phase.toUpperCase()}** (${phase.durationMs}ms) — ${phase.status}`);
|
|
801
|
+
if (phase.output) {
|
|
802
|
+
lines.push('```');
|
|
803
|
+
lines.push(phase.output);
|
|
804
|
+
lines.push('```');
|
|
805
|
+
}
|
|
806
|
+
lines.push('');
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
lines.push('---');
|
|
811
|
+
lines.push('*Generated by Aura Code Kanban Pipeline Server*');
|
|
812
|
+
return lines.join('\n');
|
|
813
|
+
}
|
|
814
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
815
|
+
// Helpers
|
|
816
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
817
|
+
function esc(s) {
|
|
818
|
+
return s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
|
819
|
+
}
|
|
820
|
+
//# sourceMappingURL=server.js.map
|