ninja-terminals 2.1.0 → 2.1.1
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/package.json +1 -1
- package/public/app.js +66 -0
- package/public/index.html +2 -0
- package/public/style.css +57 -0
package/package.json
CHANGED
package/public/app.js
CHANGED
|
@@ -339,11 +339,23 @@ function createTerminalUI(termData) {
|
|
|
339
339
|
progressFill.style.width = `${progress || 0}%`;
|
|
340
340
|
progressTrack.appendChild(progressFill);
|
|
341
341
|
|
|
342
|
+
// Close button (X)
|
|
343
|
+
const closeBtn = document.createElement('button');
|
|
344
|
+
closeBtn.className = 'close-btn';
|
|
345
|
+
closeBtn.innerHTML = '×';
|
|
346
|
+
closeBtn.title = 'Close terminal';
|
|
347
|
+
closeBtn.addEventListener('mousedown', (e) => {
|
|
348
|
+
e.preventDefault();
|
|
349
|
+
e.stopPropagation();
|
|
350
|
+
removeTerminal(id);
|
|
351
|
+
});
|
|
352
|
+
|
|
342
353
|
header.appendChild(labelEl);
|
|
343
354
|
header.appendChild(stateEl);
|
|
344
355
|
header.appendChild(elapsedEl);
|
|
345
356
|
header.appendChild(spacer);
|
|
346
357
|
header.appendChild(actionsEl);
|
|
358
|
+
header.appendChild(closeBtn);
|
|
347
359
|
header.appendChild(progressTrack);
|
|
348
360
|
|
|
349
361
|
// Double-click header to maximize/restore
|
|
@@ -1010,6 +1022,13 @@ async function startApp() {
|
|
|
1010
1022
|
setupSidebar();
|
|
1011
1023
|
setupAddTask();
|
|
1012
1024
|
setupLearnings();
|
|
1025
|
+
setupAddTerminal();
|
|
1026
|
+
|
|
1027
|
+
// Clear all button
|
|
1028
|
+
const clearBtn = document.getElementById('clear-all-btn');
|
|
1029
|
+
if (clearBtn) {
|
|
1030
|
+
clearBtn.addEventListener('click', clearAllTerminals);
|
|
1031
|
+
}
|
|
1013
1032
|
|
|
1014
1033
|
// Load existing terminals
|
|
1015
1034
|
try {
|
|
@@ -1047,6 +1066,53 @@ async function startApp() {
|
|
|
1047
1066
|
|
|
1048
1067
|
// ── Learnings Module ───────────────────────────────────────────
|
|
1049
1068
|
|
|
1069
|
+
function setupAddTerminal() {
|
|
1070
|
+
const btn = document.getElementById('add-terminal-btn');
|
|
1071
|
+
if (!btn) return;
|
|
1072
|
+
|
|
1073
|
+
// Store last used directory
|
|
1074
|
+
let lastCwd = localStorage.getItem('ninja-last-cwd') || '/Users/davidmini/Desktop/Projects';
|
|
1075
|
+
|
|
1076
|
+
btn.addEventListener('click', async () => {
|
|
1077
|
+
try {
|
|
1078
|
+
const cwd = prompt('Working directory:', lastCwd);
|
|
1079
|
+
if (!cwd) return;
|
|
1080
|
+
|
|
1081
|
+
lastCwd = cwd;
|
|
1082
|
+
localStorage.setItem('ninja-last-cwd', cwd);
|
|
1083
|
+
|
|
1084
|
+
const res = await fetch(`${API_BASE}/api/terminals`, {
|
|
1085
|
+
method: 'POST',
|
|
1086
|
+
headers: { 'Content-Type': 'application/json', ...auth.getAuthHeader() },
|
|
1087
|
+
body: JSON.stringify({ cwd }),
|
|
1088
|
+
});
|
|
1089
|
+
|
|
1090
|
+
if (!res.ok) {
|
|
1091
|
+
const err = await res.json();
|
|
1092
|
+
alert(`Failed to create terminal: ${err.error || 'Unknown error'}`);
|
|
1093
|
+
return;
|
|
1094
|
+
}
|
|
1095
|
+
|
|
1096
|
+
const terminal = await res.json();
|
|
1097
|
+
createTerminalUI(terminal);
|
|
1098
|
+
addFeedEntry(`Terminal added: T${terminal.id}`);
|
|
1099
|
+
} catch (err) {
|
|
1100
|
+
console.error('Failed to add terminal:', err);
|
|
1101
|
+
alert('Failed to add terminal');
|
|
1102
|
+
}
|
|
1103
|
+
});
|
|
1104
|
+
}
|
|
1105
|
+
|
|
1106
|
+
async function clearAllTerminals() {
|
|
1107
|
+
if (!confirm('Close all terminals and start fresh?')) return;
|
|
1108
|
+
|
|
1109
|
+
const ids = Array.from(state.terminals.keys());
|
|
1110
|
+
for (const id of ids) {
|
|
1111
|
+
await removeTerminal(id);
|
|
1112
|
+
}
|
|
1113
|
+
addFeedEntry('All terminals cleared');
|
|
1114
|
+
}
|
|
1115
|
+
|
|
1050
1116
|
function setupLearnings() {
|
|
1051
1117
|
const btn = document.getElementById('learnings-btn');
|
|
1052
1118
|
const overlay = document.getElementById('learnings-overlay');
|
package/public/index.html
CHANGED
|
@@ -60,6 +60,8 @@
|
|
|
60
60
|
<div class="logo-card">
|
|
61
61
|
<span class="logo">NINJA TERMINALS</span>
|
|
62
62
|
<span class="logo-sub">Multi-Agent Orchestrator</span>
|
|
63
|
+
<button id="add-terminal-btn" class="add-terminal-btn" title="Add Terminal">+</button>
|
|
64
|
+
<button id="clear-all-btn" class="clear-all-btn" title="Clear All Terminals">🗑</button>
|
|
63
65
|
<button id="learnings-btn" class="learnings-btn" title="View Session Learnings">🧠</button>
|
|
64
66
|
<button id="logout-btn" class="logout-btn" title="Sign out">Logout</button>
|
|
65
67
|
</div>
|
package/public/style.css
CHANGED
|
@@ -976,3 +976,60 @@ main {
|
|
|
976
976
|
.learnings-btn:hover {
|
|
977
977
|
background: var(--border);
|
|
978
978
|
}
|
|
979
|
+
|
|
980
|
+
/* ── Terminal Close Button ─────────────────────── */
|
|
981
|
+
|
|
982
|
+
.close-btn {
|
|
983
|
+
background: none;
|
|
984
|
+
border: none;
|
|
985
|
+
color: var(--text-muted);
|
|
986
|
+
font-size: 20px;
|
|
987
|
+
line-height: 1;
|
|
988
|
+
padding: 2px 8px;
|
|
989
|
+
cursor: pointer;
|
|
990
|
+
opacity: 0.5;
|
|
991
|
+
transition: opacity 0.15s, color 0.15s;
|
|
992
|
+
margin-left: 8px;
|
|
993
|
+
}
|
|
994
|
+
|
|
995
|
+
.close-btn:hover {
|
|
996
|
+
opacity: 1;
|
|
997
|
+
color: #ff6b6b;
|
|
998
|
+
}
|
|
999
|
+
|
|
1000
|
+
/* ── Add Terminal Button ─────────────────────────── */
|
|
1001
|
+
|
|
1002
|
+
.add-terminal-btn {
|
|
1003
|
+
background: var(--feed-t1);
|
|
1004
|
+
border: none;
|
|
1005
|
+
color: var(--bg);
|
|
1006
|
+
font-size: 20px;
|
|
1007
|
+
font-weight: bold;
|
|
1008
|
+
line-height: 1;
|
|
1009
|
+
padding: 4px 10px;
|
|
1010
|
+
border-radius: 4px;
|
|
1011
|
+
cursor: pointer;
|
|
1012
|
+
transition: background 0.15s, transform 0.15s;
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
.add-terminal-btn:hover {
|
|
1016
|
+
background: var(--feed-t2);
|
|
1017
|
+
transform: scale(1.1);
|
|
1018
|
+
}
|
|
1019
|
+
|
|
1020
|
+
/* ── Clear All Button ─────────────────────────────── */
|
|
1021
|
+
|
|
1022
|
+
.clear-all-btn {
|
|
1023
|
+
background: none;
|
|
1024
|
+
border: none;
|
|
1025
|
+
font-size: 16px;
|
|
1026
|
+
padding: 4px 8px;
|
|
1027
|
+
cursor: pointer;
|
|
1028
|
+
opacity: 0.6;
|
|
1029
|
+
transition: opacity 0.15s, transform 0.15s;
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
.clear-all-btn:hover {
|
|
1033
|
+
opacity: 1;
|
|
1034
|
+
transform: scale(1.1);
|
|
1035
|
+
}
|