Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions apps/web/src/composer-logic.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,40 @@ describe("detectComposerTrigger", () => {
});
});

it("detects slash command trigger in the middle of existing text", () => {
const text = "Fix the tests /rev";
const trigger = detectComposerTrigger(text, text.length);

expect(trigger).toEqual({
kind: "slash-command",
query: "rev",
rangeStart: "Fix the tests ".length,
rangeEnd: text.length,
});
});

it("detects a bare slash mid-text as an empty slash command query", () => {
const text = "Fix the tests /";
const trigger = detectComposerTrigger(text, text.length);

expect(trigger).toEqual({
kind: "slash-command",
query: "",
rangeStart: "Fix the tests ".length,
rangeEnd: text.length,
});
});

it("ignores slashes inside a word", () => {
const text = "check src/components";
expect(detectComposerTrigger(text, text.length)).toBeNull();
});

it("ignores slashes inside URLs", () => {
const text = "see https://example.com/docs";
expect(detectComposerTrigger(text, text.length)).toBeNull();
});

it("detects $skill trigger at cursor", () => {
const text = "Use $gh-fi";
const trigger = detectComposerTrigger(text, text.length);
Expand Down
8 changes: 8 additions & 0 deletions apps/web/src/composer-logic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,14 @@ export function detectComposerTrigger(text: string, cursorInput: number): Compos

const tokenStart = tokenStartForCursor(text, cursor);
const token = text.slice(tokenStart, cursor);
if (token.startsWith("/")) {
return {
kind: "slash-command",
query: token.slice(1),
rangeStart: tokenStart,
rangeEnd: cursor,
};
}
if (token.startsWith("$")) {
return {
kind: "skill",
Expand Down
48 changes: 47 additions & 1 deletion packages/shared/src/composerTrigger.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { describe, expect, it } from "vite-plus/test";

import { serializeComposerFileLink, serializeComposerMentionPath } from "./composerTrigger.ts";
import {
detectComposerTrigger,
serializeComposerFileLink,
serializeComposerMentionPath,
} from "./composerTrigger.ts";

describe("serializeComposerMentionPath", () => {
it("keeps simple mention paths unquoted", () => {
Expand All @@ -16,6 +20,48 @@ describe("serializeComposerMentionPath", () => {
});
});

describe("detectComposerTrigger", () => {
it("detects a slash command at the start of the message", () => {
const text = "/rev";
expect(detectComposerTrigger(text, text.length)).toEqual({
kind: "slash-command",
query: "rev",
rangeStart: 0,
rangeEnd: text.length,
});
});

it("detects a slash command trigger in the middle of existing text", () => {
const text = "Fix the tests /rev";
expect(detectComposerTrigger(text, text.length)).toEqual({
kind: "slash-command",
query: "rev",
rangeStart: "Fix the tests ".length,
rangeEnd: text.length,
});
});

it("detects /model mid-text as the model trigger", () => {
const text = "switch it up /model";
expect(detectComposerTrigger(text, text.length)).toEqual({
kind: "slash-model",
query: "",
rangeStart: "switch it up ".length,
rangeEnd: text.length,
});
});

it("ignores slashes inside a word", () => {
const text = "check src/components";
expect(detectComposerTrigger(text, text.length)).toBeNull();
});

it("ignores slashes inside URLs", () => {
const text = "see https://example.com/docs";
expect(detectComposerTrigger(text, text.length)).toBeNull();
});
});

describe("serializeComposerFileLink", () => {
it("uses the basename as the markdown label", () => {
expect(serializeComposerFileLink("path/to/package.json")).toBe(
Expand Down
17 changes: 17 additions & 0 deletions packages/shared/src/composerTrigger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,23 @@ export function detectComposerTrigger(
const tokenStart = tokenIdx + 1;

const token = text.slice(tokenStart, cursor);
if (token.startsWith("/")) {
const commandQuery = token.slice(1);
if (commandQuery.toLowerCase() === "model") {
return {
kind: "slash-model",
query: "",
rangeStart: tokenStart,
rangeEnd: cursor,
};
}
return {
kind: "slash-command",
query: commandQuery,
rangeStart: tokenStart,
rangeEnd: cursor,
};
}
if (token.startsWith("$")) {
return {
kind: "skill",
Expand Down
Loading