pi-sdk-web 0.3.5 → 0.3.6
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/server.js +16 -1
- package/dist/static/app.js +23 -0
- package/dist/static/style.css +23 -0
- package/package.json +1 -1
package/dist/server.js
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
*/
|
|
11
11
|
import { execFileSync } from "node:child_process";
|
|
12
12
|
import { existsSync, readFileSync } from "node:fs";
|
|
13
|
-
import { readFile } from "node:fs/promises";
|
|
13
|
+
import { readFile, unlink } from "node:fs/promises";
|
|
14
14
|
import { createServer } from "node:http";
|
|
15
15
|
import { dirname, join, resolve, sep } from "node:path";
|
|
16
16
|
import { fileURLToPath } from "node:url";
|
|
@@ -567,6 +567,21 @@ export class PiWebServer {
|
|
|
567
567
|
await this.resumeSession(path);
|
|
568
568
|
break;
|
|
569
569
|
}
|
|
570
|
+
case "delete_session": {
|
|
571
|
+
const path = typeof data.path === "string" && data.path ? data.path : "";
|
|
572
|
+
if (!path)
|
|
573
|
+
throw new Error("Missing 'path'");
|
|
574
|
+
// Safety: only allow deleting known session files (never arbitrary paths)
|
|
575
|
+
const known = (await listSessions()).some((s) => s.path === path);
|
|
576
|
+
if (!known)
|
|
577
|
+
throw new Error("Not a known session file");
|
|
578
|
+
// Align with TUI: cannot delete the currently active session
|
|
579
|
+
if (this.session.sessionFile === path) {
|
|
580
|
+
throw new Error("Cannot delete the currently active session");
|
|
581
|
+
}
|
|
582
|
+
await unlink(path);
|
|
583
|
+
break;
|
|
584
|
+
}
|
|
570
585
|
default:
|
|
571
586
|
throw new Error(`Unsupported command: ${cmdType}`);
|
|
572
587
|
}
|
package/dist/static/app.js
CHANGED
|
@@ -1630,12 +1630,35 @@ class PiWebClient {
|
|
|
1630
1630
|
this.modalList.innerHTML = '<div class="modal-message">No other sessions available</div>';
|
|
1631
1631
|
return;
|
|
1632
1632
|
}
|
|
1633
|
+
this.resumeSessions = sessions;
|
|
1633
1634
|
this.renderModalItems(
|
|
1634
1635
|
sessions.map((s) => ({ name: s.name || s.id, desc: s.cwd, value: s.path })),
|
|
1635
1636
|
(item) => {
|
|
1636
1637
|
this.send({ type: 'resume', path: item.value });
|
|
1637
1638
|
},
|
|
1638
1639
|
);
|
|
1640
|
+
// Add delete buttons to each item (stopPropagation so clicks don't resume)
|
|
1641
|
+
this.modalList.querySelectorAll('.modal-item').forEach((el, i) => {
|
|
1642
|
+
const session = sessions[i];
|
|
1643
|
+
el.classList.add('resume-item');
|
|
1644
|
+
const del = document.createElement('span');
|
|
1645
|
+
del.className = 'resume-delete';
|
|
1646
|
+
del.title = 'Delete this session';
|
|
1647
|
+
del.textContent = '🗑';
|
|
1648
|
+
del.addEventListener('click', (e) => {
|
|
1649
|
+
e.stopPropagation();
|
|
1650
|
+
this.deleteSession(session);
|
|
1651
|
+
});
|
|
1652
|
+
el.appendChild(del);
|
|
1653
|
+
});
|
|
1654
|
+
}
|
|
1655
|
+
|
|
1656
|
+
deleteSession(session) {
|
|
1657
|
+
const label = session.name || session.id;
|
|
1658
|
+
if (!window.confirm(`Delete session "${label}"?\nThis cannot be undone.`)) return;
|
|
1659
|
+
this.send({ type: 'delete_session', path: session.path });
|
|
1660
|
+
// Refresh the list after delete (errors surface via toast/error message)
|
|
1661
|
+
setTimeout(() => this.send({ type: 'get_sessions' }), 300);
|
|
1639
1662
|
}
|
|
1640
1663
|
|
|
1641
1664
|
// ------------------------------------------------------------------
|
package/dist/static/style.css
CHANGED
|
@@ -710,6 +710,29 @@ body {
|
|
|
710
710
|
font-size: 13px;
|
|
711
711
|
}
|
|
712
712
|
|
|
713
|
+
/* Resume picker items: delete icon pushed to the right, away from the path */
|
|
714
|
+
.modal-item.resume-item {
|
|
715
|
+
display: flex;
|
|
716
|
+
align-items: baseline;
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
.modal-item.resume-item .resume-delete {
|
|
720
|
+
margin-left: auto;
|
|
721
|
+
padding-left: 16px;
|
|
722
|
+
cursor: pointer;
|
|
723
|
+
opacity: 0.6;
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
.modal-item.resume-item .resume-delete:hover {
|
|
727
|
+
opacity: 1;
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
.modal-item.resume-item .modal-item-desc {
|
|
731
|
+
overflow: hidden;
|
|
732
|
+
text-overflow: ellipsis;
|
|
733
|
+
white-space: nowrap;
|
|
734
|
+
}
|
|
735
|
+
|
|
713
736
|
.modal-item:hover {
|
|
714
737
|
background: var(--accent-hover);
|
|
715
738
|
}
|