refactor(coding-agent/slash-commands): removed collab qrcode slash commands

- Removed qrcode and qrcode-view subcommands from the collab command.
- Updated showCollabLink to always trigger QR code display.
- Refactored internal verb logic to simplify session sharing flow.
This commit is contained in:
can1357
2026-06-19 01:24:35 +02:00
parent a7fdd0b4ed
commit 8588aa5802
6 changed files with 25 additions and 59 deletions
+3 -5
View File
@@ -20,7 +20,7 @@ Collab session started!
The browser line is click-to-join (an OSC 8 hyperlink to the full `https://` deep link): the relay serves the web guest client at `/`, and the room id + key ride in the URL fragment. From another omp (any directory, any machine), either form works:
Run `/collab qrcode` to start or re-print hosting with a QR code for the full-control browser link; use `/collab qrcode-view` for a read-only QR code (`/collab qr-view` is a short alias).
Running `/collab` or `/collab view` starts or displays the active hosting session, rendering both the terminal/browser join links and their corresponding QR codes.
```
/join my.omp.sh/#mgAYTZwEnpRQtca0CTgn-Q.gdJU…
@@ -32,11 +32,9 @@ The guest's previous session is restored on `/leave` (or when the host stops).
| Command | Effect |
|---|---|
| `/collab` | Start sharing (or re-print the link when already hosting) |
| `/collab` | Start sharing full-control (or re-print the link/QR when already hosting) |
| `/collab <relay>` | Start sharing through a specific relay (`relay.example.com`, `ws://localhost:7475`) |
| `/collab view` | Print a read-only (view-only) link (starts sharing first if needed) |
| `/collab qrcode` | Print a QR code for a full-control browser link (starts sharing first if needed) |
| `/collab qrcode-view` | Print a QR code for a read-only browser link (starts sharing first if needed); `/collab qr-view` is an alias |
| `/collab view` | Start sharing read-only (or re-print the link/QR when already hosting) |
| `/collab status` | Show link + participants |
| `/collab stop` | Stop sharing |
| `/join <link>` | Join a shared session as a guest |
+8 -8
View File
@@ -164,26 +164,26 @@ describe("kimi think tags (<think>…</think>)", () => {
});
});
describe("pi native thinking channel (<thinking>…</thinking>)", () => {
it("routes <thinking> to thinking, keeping it out of the reply and calls", () => {
const events = scan("pi", "<thinking>reasoning</thinking><call:foo x=1/>");
describe("pi native thinking channel (¤…¤)", () => {
it("routes ¤ to thinking, keeping it out of the reply and calls", () => {
const events = scan("pi", "¤reasoning¤§foo x=1\n");
expect(thinkingText(events)).toBe("reasoning");
expect(callNames(events)).toEqual([{ name: "foo", arguments: { x: 1 } }]);
expect(visibleText(events)).not.toContain("<thinking>");
expect(visibleText(events)).not.toContain("¤");
});
it("round-trips renderThinking through the scanner", () => {
const rendered = getDialectDefinition("pi").renderThinking("reasoning");
expect(rendered).toBe("<thinking>\nreasoning\n</thinking>");
expect(rendered).toBe("¤\nreasoning\n¤");
const events = scan("pi", `${rendered}visible`);
expect(thinkingText(events).trim()).toBe("reasoning");
expect(visibleText(events)).toBe("visible");
});
it("treats <thinking> as plain text when parseThinking is disabled", () => {
const events = scan("pi", "<thinking>x</thinking>answer", { options: { parseThinking: false } });
it("treats ¤ as plain text when parseThinking is disabled", () => {
const events = scan("pi", "¤x¤answer", { options: { parseThinking: false } });
expect(thinkingBoundaries(events)).toBe(0);
expect(visibleText(events)).toContain("<thinking>x</thinking>");
expect(visibleText(events)).toContain("¤x¤");
});
});
+1 -3
View File
@@ -50,9 +50,7 @@ describe("renderToolExamples", () => {
};
const rendered = renderToolExamples(tool, "pi");
expect(rendered).toContain("<call:find>");
expect(rendered).toContain("<paths>");
expect(rendered).toContain("src/**/*.ts");
expect(rendered).toContain('§find paths=["src/**/*.ts"]');
});
it("renders call example in hermes format", () => {
+1 -1
View File
@@ -5,7 +5,7 @@
### Added
- Updated the `pi` option of the `tools.format` setting to use the new compact sigil-delimited owned tool-calling dialect (`§`/`«…»`/`¤`/`‡‡`) that uses ~46% fewer tokens than the legacy format on typical calls.
- Added `/collab qrcode` and `/collab qrcode-view` one-shot terminal QR output for browser join links and a `collab.webUrl` setting for separately hosted collab web clients.
- Integrated terminal QR codes directly into `/collab` and `/collab view` to display both deep links and scannable codes, and added a `collab.webUrl` setting for separately hosted collab web clients.
### Changed
@@ -108,15 +108,9 @@ function showCollabQrCode(ctx: InteractiveModeContext, webLink: string): void {
}
}
function showCollabLink(
ctx: InteractiveModeContext,
host: CollabHost,
heading: string,
view = false,
options?: { forceQr?: boolean },
): void {
function showCollabLink(ctx: InteractiveModeContext, host: CollabHost, heading: string, view = false): void {
ctx.showStatus(collabLinkHint(host, heading, view), { dim: false });
if (options?.forceQr) showCollabQrCode(ctx, view ? host.webViewLink : host.webLink);
showCollabQrCode(ctx, view ? host.webViewLink : host.webLink);
}
function formatFreshSessionResult(result: FreshSessionResult): string {
@@ -598,13 +592,11 @@ const BUILTIN_SLASH_COMMAND_REGISTRY: ReadonlyArray<SlashCommandSpec> = [
{
name: "collab",
description: "Share this session live via a relay",
inlineHint: "[start|view|stop|status|qrcode|qrcode-view] [relayUrl]",
inlineHint: "[start|view|stop|status] [relayUrl]",
subcommands: [
{ name: "view", description: "Share a read-only link (guests can watch, not prompt)" },
{ name: "status", description: "Show link + participants" },
{ name: "stop", description: "Stop sharing" },
{ name: "qrcode", description: "Print a QR code for a full-control browser link" },
{ name: "qrcode-view", description: "Print a QR code for a read-only browser link" },
],
allowArgs: true,
handleTui: async (command, runtime) => {
@@ -642,23 +634,14 @@ const BUILTIN_SLASH_COMMAND_REGISTRY: ReadonlyArray<SlashCommandSpec> = [
ctx.showError("Already in a collab session as a guest (/leave first)");
return;
}
const knownStartVerb =
verb === "start" || verb === "view" || verb === "qrcode" || verb === "qrcode-view" || verb === "qr-view";
const view = verb === "view" || verb === "qrcode-view" || verb === "qr-view";
const forceQr = verb === "qrcode" || verb === "qrcode-view" || verb === "qr-view";
const knownStartVerb = verb === "start" || verb === "view";
const view = verb === "view";
if (ctx.collabHost) {
showCollabLink(
ctx,
ctx.collabHost,
forceQr
? view
? "Read-only collab QR code"
: "Collab QR code"
: view
? "Read-only collab link"
: "Collab session active",
view ? "Read-only collab session active" : "Collab session active",
view,
{ forceQr },
);
return;
}
@@ -681,7 +664,7 @@ const BUILTIN_SLASH_COMMAND_REGISTRY: ReadonlyArray<SlashCommandSpec> = [
return;
}
ctx.collabHost = host;
showCollabLink(ctx, host, "Collab session started!", view, { forceQr });
showCollabLink(ctx, host, "Collab session started!", view);
},
},
{
@@ -78,12 +78,12 @@ function mockStartedHostLinks() {
});
}
describe("/collab qrcode slash command", () => {
describe("/collab slash command QR code rendering", () => {
it("starts hosting and prints a one-shot full-control QR", async () => {
const startSpy = mockStartedHostLinks();
const harness = createRuntimeHarness();
const handled = await executeBuiltinSlashCommand("/collab qrcode", harness.runtime);
const handled = await executeBuiltinSlashCommand("/collab", harness.runtime);
expect(handled).toBe(true);
expect(harness.setText).toHaveBeenCalledWith("");
@@ -103,7 +103,7 @@ describe("/collab qrcode slash command", () => {
const startSpy = mockStartedHostLinks();
const harness = createRuntimeHarness();
const handled = await executeBuiltinSlashCommand("/collab qrcode-view", harness.runtime);
const handled = await executeBuiltinSlashCommand("/collab view", harness.runtime);
expect(handled).toBe(true);
expect(startSpy).toHaveBeenCalledWith("wss://relay.example.com", "");
@@ -121,7 +121,7 @@ describe("/collab qrcode slash command", () => {
it("prints the active full-control browser QR when hosting", async () => {
const harness = createRuntimeHarness({ collabHost: fakeHost() });
const handled = await executeBuiltinSlashCommand("/collab qrcode", harness.runtime);
const handled = await executeBuiltinSlashCommand("/collab", harness.runtime);
expect(handled).toBe(true);
const statusText = harness.showStatus.mock.calls[0]?.[0] as string;
@@ -138,7 +138,7 @@ describe("/collab qrcode slash command", () => {
const webViewLink = "https://my.omp.sh/#read-only";
const harness = createRuntimeHarness({ collabHost: fakeHost({ webLink, webViewLink }) });
const handled = await executeBuiltinSlashCommand("/collab qrcode-view", harness.runtime);
const handled = await executeBuiltinSlashCommand("/collab view", harness.runtime);
expect(handled).toBe(true);
const statusText = harness.showStatus.mock.calls[0]?.[0] as string;
@@ -151,17 +151,4 @@ describe("/collab qrcode slash command", () => {
expect(component.url).toBe(webViewLink);
expect(component.render(10).join("\n")).toContain("QR code hidden");
});
it("accepts qr-view as an alias for qrcode-view", async () => {
const webLink = "https://my.omp.sh/#full-control";
const webViewLink = "https://my.omp.sh/#read-only";
const harness = createRuntimeHarness({ collabHost: fakeHost({ webLink, webViewLink }) });
const handled = await executeBuiltinSlashCommand("/collab qr-view", harness.runtime);
expect(handled).toBe(true);
const presented = harness.present.mock.calls[0]?.[0] as readonly unknown[];
expect(presented[1]).toBeInstanceOf(CollabQrCodeComponent);
expect((presented[1] as CollabQrCodeComponent).url).toBe(webViewLink);
});
});