Files
agent-radar 2ed3415fb7
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
源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
2026-09-01 20:17:27 +08:00

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)
];
}