feat(coding-agent): added collaborative sessions with host and guest command support

- Added AES-GCM room-key crypto, relay link parsing, and invalid-link validation.
- Added `/collab`, `/join`, and `/leave` command handling for collaborative sessions.
- Added startup `join` argument wiring to execute `/join` during interactive launch.
- Added status-line, prompt, and command-routing updates for guest/host collaboration UX.
This commit is contained in:
can1357
2026-06-12 10:54:28 +02:00
parent 9f79c5e353
commit 3e90371f5c
32 changed files with 2225 additions and 28 deletions
@@ -124,6 +124,16 @@ export class InputController {
if (this.ctx.hasActiveOmfg() && this.ctx.handleOmfgEscape()) {
return;
}
if (this.ctx.collabGuest) {
// Guest Esc: ask the host to interrupt its agent; the local replica
// session is never streaming, so the native abort path below would
// no-op.
if (this.ctx.collabGuest.state?.isStreaming || this.ctx.loadingAnimation) {
this.ctx.notifyInterrupting();
this.ctx.collabGuest.sendAbort();
}
return;
}
if (this.ctx.loadingAnimation) {
if (this.ctx.cancelPendingSubmission()) {
return;
@@ -391,6 +401,32 @@ export class InputController {
text = slashResult;
}
// Collab guest: prompts execute on the host; local slash/skill/bash/
// python execution is host-only (builtins are gated inside
// executeBuiltinSlashCommand, which already consumed allowed ones).
if (this.ctx.collabGuest) {
if (text.startsWith("/")) {
this.ctx.showStatus(`${text.split(/\s+/, 1)[0]} is host-only during a collab session`);
this.ctx.editor.setText("");
return;
}
if (text.startsWith("!") || text.startsWith("$")) {
this.ctx.showStatus("Local execution is host-only during a collab session");
this.ctx.editor.setText("");
return;
}
this.ctx.editor.addToHistory(text);
this.ctx.editor.setText("");
this.ctx.editor.imageLinks = undefined;
const images = inputImages && inputImages.length > 0 ? [...inputImages] : undefined;
this.ctx.pendingImages = [];
this.ctx.pendingImageLinks = [];
// No local render: the prompt comes back from the host as a
// collab-prompt event/entry and renders with the author badge.
this.ctx.collabGuest.sendPrompt(text, images);
return;
}
// Handle skill commands (/skill:name [args]). Enter ⇒ steer (matches the
// free-text Enter semantics applied a few lines below at the streaming
// branch). Ctrl+Enter routes through `handleFollowUp` and dispatches the