Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
133 lines
3.9 KiB
TypeScript
133 lines
3.9 KiB
TypeScript
import { Extension, type Extensions } from "@tiptap/core";
|
|
import { NodeSelection, TextSelection } from "@tiptap/pm/state";
|
|
import { Plugin } from "@tiptap/pm/state";
|
|
import StarterKit from "@tiptap/starter-kit";
|
|
import {
|
|
createAgentFileMentionExtension,
|
|
type AgentFileMentionExtensionOptions
|
|
} from "./agentFileMentionExtension";
|
|
import {
|
|
createAgentCapabilityTokenExtension,
|
|
type AgentCapabilityTokenExtensionOptions
|
|
} from "./agentCapabilityTokenExtension";
|
|
import {
|
|
createAgentSkillTokenExtension,
|
|
type AgentSkillTokenExtensionOptions
|
|
} from "./agentSkillTokenExtension";
|
|
|
|
function createAgentPromptStarterKit(): Extensions[0] {
|
|
return StarterKit.configure({
|
|
blockquote: false,
|
|
bold: false,
|
|
bulletList: false,
|
|
code: false,
|
|
codeBlock: false,
|
|
dropcursor: false,
|
|
gapcursor: false,
|
|
heading: false,
|
|
horizontalRule: false,
|
|
italic: false,
|
|
link: false,
|
|
listItem: false,
|
|
listKeymap: false,
|
|
orderedList: false,
|
|
strike: false,
|
|
trailingNode: false,
|
|
underline: false
|
|
});
|
|
}
|
|
|
|
function createAgentTokenKeyboardExtension(): Extensions[0] {
|
|
return Extension.create({
|
|
name: "agentTokenKeyboard",
|
|
|
|
addProseMirrorPlugins() {
|
|
return [
|
|
new Plugin({
|
|
props: {
|
|
handleKeyDown(view, event) {
|
|
if (event.key !== "Backspace" && event.key !== "ArrowLeft") {
|
|
return false;
|
|
}
|
|
const { doc, selection } = view.state;
|
|
if (
|
|
selection instanceof NodeSelection &&
|
|
isSelectableAgentToken(selection.node)
|
|
) {
|
|
event.preventDefault();
|
|
if (event.key === "ArrowLeft") {
|
|
view.dispatch(
|
|
view.state.tr.setSelection(
|
|
TextSelection.create(doc, selection.from)
|
|
)
|
|
);
|
|
} else {
|
|
view.dispatch(
|
|
view.state.tr.delete(selection.from, selection.to)
|
|
);
|
|
}
|
|
return true;
|
|
}
|
|
if (!selection.empty) {
|
|
return false;
|
|
}
|
|
const nodeBefore = selection.$from.nodeBefore;
|
|
if (!nodeBefore || !isSelectableAgentToken(nodeBefore)) {
|
|
return false;
|
|
}
|
|
event.preventDefault();
|
|
view.dispatch(
|
|
view.state.tr.setSelection(
|
|
NodeSelection.create(
|
|
doc,
|
|
selection.from - nodeBefore.nodeSize
|
|
)
|
|
)
|
|
);
|
|
return true;
|
|
}
|
|
}
|
|
})
|
|
];
|
|
}
|
|
});
|
|
}
|
|
|
|
function isSelectableAgentToken(
|
|
node: { type: { name: string }; nodeSize: number } | null
|
|
): boolean {
|
|
return (
|
|
node?.type.name === "agentSkillToken" ||
|
|
node?.type.name === "agentCapabilityToken"
|
|
);
|
|
}
|
|
|
|
export function createAgentRichTextInputExtensions(
|
|
fileMentionOptions?: AgentFileMentionExtensionOptions,
|
|
skillTokenOptions?: AgentSkillTokenExtensionOptions,
|
|
capabilityTokenOptions?: AgentCapabilityTokenExtensionOptions
|
|
): Extensions {
|
|
return [
|
|
createAgentTokenKeyboardExtension(),
|
|
createAgentPromptStarterKit(),
|
|
createAgentFileMentionExtension(fileMentionOptions),
|
|
createAgentCapabilityTokenExtension(capabilityTokenOptions),
|
|
createAgentSkillTokenExtension(skillTokenOptions)
|
|
];
|
|
}
|
|
|
|
export function createAgentRichTextReadonlyExtensions(
|
|
skillTokenOptions?: AgentSkillTokenExtensionOptions,
|
|
capabilityTokenOptions?: AgentCapabilityTokenExtensionOptions
|
|
): Extensions {
|
|
return [
|
|
createAgentPromptStarterKit(),
|
|
createAgentFileMentionExtension({
|
|
enableSuggestions: false,
|
|
renderAsLink: true
|
|
}),
|
|
createAgentCapabilityTokenExtension(capabilityTokenOptions),
|
|
createAgentSkillTokenExtension(skillTokenOptions)
|
|
];
|
|
}
|