import "@logseq/libs";
/**
* Lain - AI Assistant for Logseq
*
* "No matter where you go, everyone's connected."
* - Serial Experiments Lain
*
* Provides AI-powered features directly within Logseq:
* - Slash commands for AI operations
* - Sidebar chat interface
* - Block-level AI actions
*/
async function main() {
console.info("Lain plugin loaded");
// Register slash commands
logseq.Editor.registerSlashCommand("lain summarize", async () => {
const block = await logseq.Editor.getCurrentBlock();
if (!block) {
logseq.UI.showMsg("No block selected", "warning");
return;
}
logseq.UI.showMsg("Summarizing... (not yet implemented)", "info");
// TODO: Implement LLM call
});
logseq.Editor.registerSlashCommand("lain expand", async () => {
const block = await logseq.Editor.getCurrentBlock();
if (!block) {
logseq.UI.showMsg("No block selected", "warning");
return;
}
logseq.UI.showMsg("Expanding... (not yet implemented)", "info");
// TODO: Implement LLM call
});
logseq.Editor.registerSlashCommand("lain ask", async () => {
// TODO: Open a dialog to ask a question about the current page/block
logseq.UI.showMsg("Lain is listening... (not yet implemented)", "info");
});
// Register toolbar button
logseq.App.registerUIItem("toolbar", {
key: "logseq-lain",
template: `
<a class="button" data-on-click="openLainPanel" title="Open Lain">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M12 8V4H8"/>
<rect width="16" height="12" x="4" y="8" rx="2"/>
<path d="M2 14h2"/>
<path d="M20 14h2"/>
<path d="M15 13v2"/>
<path d="M9 13v2"/>
</svg>
</a>
`,
});
// Handle toolbar click
logseq.provideModel({
openLainPanel() {
logseq.UI.showMsg("Lain is waking up... (coming soon)", "info");
// TODO: Open sidebar panel with chat interface
},
});
// Register settings
logseq.useSettingsSchema([
{
key: "llmProvider",
type: "enum",
enumChoices: ["anthropic", "openai"],
enumPicker: "select",
default: "anthropic",
title: "LLM Provider",
description: "Choose your AI provider",
},
{
key: "apiKey",
type: "string",
default: "",
title: "API Key",
description: "Your API key for the selected provider",
},
{
key: "model",
type: "string",
default: "claude-3-5-sonnet-20241022",
title: "Model",
description: "Model to use for AI operations",
},
]);
console.info("Lain initialized");
}
// Bootstrap
logseq.ready(main).catch(console.error);