// Geliştirici Kılavuzu

Eklenti Geliştirici Belgeleri

AnBoWork masaüstü uygulaması için eklentiler oluşturun: AI için yeni araçlar ekleyin, kendi panelinizi bir oturumun yanına yerleştirin, sistem bildirimleri gönderin, yeni dosya formatlarını ayrıştırın. Başlamak için bir manifest.json artı bir giriş komut dosyası yeterlidir.

01Genel Bakış

AnBoWork eklentisi sade bir Node.js programıdır. Kurulumdan sonra uygulama bunu bağımsız bir alt süreç olarak çatallar (saf Node, Electron API yok) ve süreçler arası mesajlar üzerinden onunla konuşur. Hiçbir SDK paketine gerek yoktur; tek ihtiyacınız olan process.on('message') ve process.send().

Bir eklentinin yapabileceği her şey manifest.json'de statik olarak bildirilir: kurulum öncesi onay sayfası ve pazar incelemesi, herhangi bir eklenti kodu çalıştırmadan eklentinin hangi araçları eklediğini ve hangi izinlere ihtiyaç duyduğunu söyleyebilir. Tüm kullanıcı arayüzü (araç çubuğu simgeleri, ayarlar, komut paleti, bağlam menüleri), bildirimden ana bilgisayar tarafından oluşturulur; eklenti kodu hiçbir zaman ana pencerenin içinde çalışmaz. Yalnızca sabitlenmiş görünümler ve kayan paneller kendi HTML'nizdir ve yalıtılmış korumalı alan sayfalarında çalışırlar.

Bir bakışta yetenekler

Bildirim alanıYetenekKullanıcıların bunu nerede göreceği
toolsYapay zeka için çağrılabilir araçlar ekleyinYapay zeka, konuşma sırasında onları otomatik olarak arar; araç çağrıları oturumda gösterilir
viewsKalıcı görünüm oturumun sağ kenar çubuğuna yerleştirildiOturum araç çubuğundaki ekstra bir simge sayfanızı sağda açar
uiBağımsız kayan pencereEklenti listesindeki "⋯" menüsünden açıldı
sessionActionOturum araç çubuğunda kalıcı eylem simgesiTek tıklamayla belirttiğiniz aracı çalıştırır
configurationAyarlar sayfasındaki girişlerAyarlar → Eklenti yapılandırması; değerler her çağrıda iletilir
commandsCtrl/Cmd+K komut paleti girişleriKomut paleti
keybindingsGenel klavye kısayollarıBir tuş kombinasyonu bir komutu tetikler
menusOturum içerik menüsü öğeleriOturum satırındaki "⋯" / sağ tıklama menüsü
documentParsersGiriş kutusuna bırakılan dosyaları ayrıştırmaKullanıcı eşleşen bir dosyayı bıraktığında otomatik olarak çağrılır
activationEventsUygulamayla birlikte başlayınGörünmez; arka plan zamanlayıcılarına ihtiyaç duyan eklentiler için
permissionsGerekli izinleri bildirinÖn yükleme izin sayfası

02Hızlı Başlangıç

Minimal bir eklenti yalnızca iki dosyaya ihtiyaç duyar.

my-plugin/
├── manifest.json   # plugin manifest (required)
├── index.js        # entry script, referenced by manifest.main (required)
├── view.html       # docked view page (optional, manifest.views[].entry)
└── ui.html         # floating panel page (optional, manifest.ui.entry)

1. manifest.json yazın

{
  "id": "com.example.hello",
  "name": "Hello Plugin",
  "version": "1.0.0",
  "description": "Say hello to the user.",
  "main": "index.js",
  "permissions": [],
  "tools": [
    {
      "name": "say_hello",
      "summary": "Greet the user by name",
      "description": "Return a greeting for the given name. Call this when the user explicitly asks the plugin to say hello.",
      "parameters": {
        "type": "object",
        "properties": {
          "name": { "type": "string", "description": "Who to greet." }
        },
        "required": ["name"]
      }
    }
  ]
}

2. Giriş komut dosyasını yazın

// The entry script runs in a standalone Node.js child process (ELECTRON_RUN_AS_NODE=1).
// Only Node built-ins and dependencies shipped inside the plugin folder are available;
// there is no Electron API.
process.on('message', (msg) => {
  if (!msg || msg.type !== 'call_tool') return;
  const { requestId, toolName, params } = msg;
  try {
    if (toolName !== 'say_hello') throw new Error(`unknown tool: ${toolName}`);
    process.send({
      type: 'tool_result',
      requestId,
      content: [{ type: 'text', text: `Hello, ${params.name}!` }],
    });
  } catch (err) {
    process.send({ type: 'tool_error', requestId, message: err.message });
  }
});

3. Uygulamaya yükleyin

Sağ üst köşedeki AnBoWork → üst çubuk "Araçlar" → "Eklentiler" → "Yerel olarak yükle" seçeneğini açın, ardından eklenti klasörünü (veya bir zip dosyasını) seçin. Bir izin sayfası, beyan edilen izinleri ve kurulumdan önce her aracı listeler; etkinleştirmek için onaylayın.

4. Deneyin

Herhangi bir oturumda yapay zekaya "eklentiden Alice'e merhaba demesini isteyin" deyin. Araç açıklamasına göre yapay zeka say_hello'yi aramaya karar verir ve çağrı ve sonucu oturumda görünür.

UÇ
AnBoWork içindeki yapay zeka ayrıca sizin için eklentiler de oluşturabilir ("bana X yapan bir eklenti yazın" deyin ve o, create_local_plugin'i çağırır). Oluşturulan eklentiler, siz eklenti sayfasındaki kodu inceleyip manuel olarak etkinleştirene kadar varsayılan olarak devre dışıdır. Bu kılavuz, yapay zeka tarafından oluşturulan eklentilerin okunması ve değiştirilmesi için de aynı şekilde geçerlidir.

03Bildirim Alanları

AlanTipGerekliTanım
idstringEvetTers etki alanı stili, ör. com.example.my-plugin. Yalnızca harfler, rakamlar, noktalar ve kısa çizgiler. Bir kez yaratıldığında değişmez; Aynı kimliğin tekrar yüklenmesi, yeniden yükleme olarak değerlendirilir.
namestringEvetEklenti adı. description ile birlikte modele bağlam olarak beslenir, dolayısıyla İngilizce önerilir.
versionstringEvetAnlamsal versiyon; pazar bunu güncellemeleri tespit etmek için kullanır.
descriptionstringEvetEklentinin ne yaptığını açıklayan bir cümle (İngilizce).
authorstringHAYIRYazar.
readmestringHAYIRPazar yeri ayrıntı sayfasında gösterilen uzun biçimli açıklama, Markdown'ı destekler. İçindeki görseller https URL olmalıdır; zip dosyasında paketlenen dosyalara yönelik göreceli yollar desteklenmez.
iconstringHAYIRPazar yeri listesinde ve ayrıntı sayfasında gösterilen simge — zip'te paketlenmiş bir dosyanın göreli yolu (ör. icon.png). En az 128×128 boyutunda, SVG değil, PNG olmalıdır.
mainstringEvetEklenti klasörüne göre giriş komut dosyası. .. klasörden kaçışa izin verilmez.
permissionsstring[]Evetnetwork / filesystem / notifications; boş bir dizi olabilir. Bkz. "İzin Modeli".
toolsobject[]EvetAraç bildirimleri; boş bir dizi olabilir. Bkz. "Araçlar ve Çağrı Protokolü".
documentParsersobject[]HAYIRDosya ayrıştırma özelliği.
uiobjectHAYIRYüzen panel:{ entry, title }
viewsobject[]HAYIRYerleştirilmiş görünümler:{ id, title, icon, entry, width? }
sessionActionobjectHAYIRAraç çubuğu simgesi, eklenti başına en fazla bir tane.
configurationobject[]HAYIRAyar girişlerinin listesi.
commandsobject[]HAYIRKomut paleti girişleri.
keybindingsobject[]HAYIRKısayollar. command, commands[]'deki bir girişin tool'sine referans vermelidir, aksi takdirde kurulum reddedilir.
menusobjectHAYIRŞimdilik yalnızca session/context konumu mevcut.
activationEventsstring[]HAYIRŞimdilik sadece onStartupFinished.

Metin için dil kuralları

Manifestteki metnin iki hedef kitlesi var. modeli için: name, description, tools[].description, tools[].parameters.*.description. Bunları İngilizce yazın; modeller İngilizce araç açıklamalarını anlar ve parametreleri daha güvenilir şekilde doldurur. Kişiler için: tools[].summary (izin sayfasında tek satırlık özet), ui.title, views[].title, sessionAction.tooltip, configuration[].label, commands[].title ve title, menus içinde. Bunları hedef kullanıcılarınızın dilinde yazın.

{
  "id": "com.example.full",
  "name": "Full Example",
  "version": "1.2.0",
  "description": "Every contribution point in one manifest.",
  "author": "Example Inc.",
  "readme": "## Full Example\n\nLonger Markdown shown on the marketplace detail page. Images must be https URLs.",
  "icon": "icon.png",
  "main": "index.js",
  "permissions": ["filesystem", "network", "notifications"],
  "activationEvents": ["onStartupFinished"],
  "tools": [
    {
      "name": "do_something",
      "summary": "Do one thing to the current project",
      "description": "…English. State clearly when to call this and when not to…",
      "parameters": { "type": "object", "properties": {}, "required": [] },
      "renderAs": "checklist"
    },
    { "name": "is_available", "summary": "Whether the current folder applies", "description": "…", "parameters": { "type": "object", "properties": {} } },
    { "name": "list_modes", "summary": "List selectable modes", "description": "…", "parameters": { "type": "object", "properties": {} } }
  ],
  "documentParsers": [
    { "mimeType": "text/markdown", "toolName": "parse_markdown" }
  ],
  "ui": { "entry": "ui.html", "title": "Example Panel" },
  "views": [
    { "id": "board", "title": "Example Board", "icon": "checklist", "entry": "view.html", "width": 380 }
  ],
  "sessionAction": {
    "tool": "do_something",
    "icon": "git-branch",
    "tooltip": "Do one thing to the current project",
    "visibleTool": "is_available"
  },
  "configuration": [
    { "id": "mode", "label": "Mode", "type": "select", "optionsTool": "list_modes", "defaultValue": "auto" },
    { "id": "verbose", "label": "Verbose output", "type": "boolean", "defaultValue": false },
    { "id": "prefix", "label": "Prefix", "type": "string", "defaultValue": "" },
    { "id": "limit", "label": "Max items", "type": "number", "defaultValue": 20 }
  ],
  "commands": [
    { "tool": "do_something", "icon": "git-branch", "title": "Do one thing to the current project" }
  ],
  "keybindings": [
    { "command": "do_something", "key": "mod+shift+d" }
  ],
  "menus": {
    "session/context": [
      { "tool": "do_something", "icon": "git-branch", "title": "Do one thing to this session" }
    ]
  }
}

04İzin Modeli

permissions kodun gerçekte ne yaptığını dürüstçe yansıtmalıdır. Yükleme öncesi izin sayfası her birini listeler; böylece kullanıcılar yükleme yapıp yapmayacaklarına karar verebilir; Pazaryeri incelemesi aynı zamanda beyanı koda göre de kontrol eder.

İzinNe zaman beyan edilmesi gerektiğiEv sahibinin ona nasıl davrandığı
filesystemKullanıcı dosyalarını okuma veya yazma (proje kodunu okuma, belge oluşturma, verileri ana klasörde saklama)Kullanıcıya gösterilen bilgilendirilmiş onay.
networkHerhangi bir ağ isteğinde bulunma (üçüncü taraf API'ler, indirmeler)Kullanıcıya gösterilen bilgilendirilmiş onay.
notificationsshow_notification ters RPC aracılığıyla sistem bildirimleri gösteriliyorEnforced: bildirim olmadan çağrıldığında host_error değeri döndürülür ve herhangi bir bildirim gösterilmez.
NOT
Eklenti alt süreci tam bir Node.js ortamıdır. filesystem ve network şu anda çalışma zamanı sanal alanı değil, izin düzeyi bildirimleridir: ana bilgisayar fs veya fetch'yi engellemez. İşte tam da bu nedenle beyanların dürüst olması gerekir. Eksik beyan edilen eklentiler, pazar incelemesinde reddedilir ve keşfedildiğinde kullanıcının güvenini kaybeder. Aşırı beyanda bulunmayın (kullanılmayan izinler kullanıcıların tereddüt etmesine neden olur).

Gizlilik ve veriler

context.cwd kullanıcının proje klasörüdür ve kaynak kodu ve hassas konfigürasyonu içerebilir; araç argümanları kullanıcının konuşmasını içerebilir. Özellik gerektirmedikçe bu verileri ağ üzerinden göndermeyin ve gönderdiğinizde neyin kime gönderildiğini description ve summary'de belirtin. Eklentinin kendi kalıcı verilerini, kullanıcının ana klasörü altında, eklenti kimliğinin adını taşıyan bir dosyada saklayın, böylece kaldırma sırasında bulunması kolaydır.

05Araçlar ve Çağrı Protokolü

beyan

AlanTanım
nameUygulamanın tamamında benzersiz olan, küçük harfler ve alt çizgilerle yazılan araç adı (yerleşik araçlar ve diğer eklenti araçlarının yanı sıra modele kayıtlıdır).
descriptionModelin açıklaması (İngilizce). Üç şeyi belirtin: aracın ne yaptığını, ne zaman çağrılması gerektiğini ve ne zaman çağrılmaması gerektiğini kullanıcının ne söylediğini. Bu, yapay zekanın eklentinizi kullanıp kullanmadığına ilişkin en önemli alandır.
summaryİzin sayfasında gösterilen, insanlar tarafından okunabilen tek satırlık özet. İsteğe bağlıdır ancak şiddetle tavsiye edilir; aksi takdirde bunun yerine kısaltılmış bir açıklama gösterilir.
parametersHer özellikte description bulunan standart JSON Schema nesnesi. Model, bağımsız değişkenleri kendisi doldurur ve ana bilgisayar bunları ekstra doğrulamaya gerek kalmadan iletir; bu nedenle kodunuzdaki gerekli alanları kontrol edin.
renderAsİsteğe bağlı; şu anda yalnızca checklist: ana bilgisayar, çağrı bağımsız değişkenlerinden todos dizisini bir kontrol listesi kartı olarak işler, aşağıya bakın.
Not
Model yalnızca tools[]'de belirtilen araç adlarını çağırabilir; burada sessionAction.tool, commands[].tool ve menus içindeki tool alanı yalnızca yükleme sırasında boş olmayan dizeler olarak kontrol edilir; toplantı sahibi, adın tools[]'de bildirildiğini not doğrulamaz ve düğme, kısayol veya menü öğesi tetiklendiğinde yine de bu ad altında bir çağrı gönderir. Yani tamamen kullanıcı arayüzü tarafından tetiklenen bir eylem, tools[]'de hiç görünmeden tamamen kendi index.js'nizde gerçekleştirilebilir - ancak bu durumda yapay zeka bunu asla göremez veya çağıramaz. Aynı eylemin hem tıklanarak hem de bir sohbet isteğine göre hareket eden yapay zeka tarafından tetiklenebilmesini istiyorsanız, aynı adı tools[]'da da bildirin, böylece her iki giriş noktası da bir işleyiciyi paylaşır; yalnızca kullanıcı arayüzü olarak kalması gerekiyorsa, bunu belirtmeden bırakın; yalnızca eksiksiz görünmesi için bir giriş eklemenize gerek yoktur.

Mesaj protokolü

Toplantı sahibi call_tool gönderir; eklenti aynı requestId'yi taşıyan tool_result veya tool_error ile yanıt vermelidir. 30 saniye içinde yanıtlanmayan çağrı zaman aşımına uğrar ve model bir hata alır.

// host → plugin
{
  "type": "call_tool",
  "requestId": "0b2d…",          // unique per call, echo it back unchanged
  "toolName": "do_something",
  "params": { "name": "…" },     // arguments validated against tools[].parameters
  "context": {
    "cwd": "/Users/me/project",  // project folder of the calling session; a temp folder for chat sessions; empty string for document parsing
    "config": { "mode": "auto", "verbose": false }   // present only when configuration is declared; keys are configuration[].id
  }
}

content yalnızca text ve image blokları kabul eder (base64 data artı mimeType olarak görüntü); diğer türler bırakılır. details modele hiçbir zaman beslenmeyen keyfi yapılandırılmış verilerdir; ana bilgisayar kullanıcı arayüzü oluşturma ve kendi yerleştirilmiş görünümleriniz içindir.

Dosya sonuçları: dosya kartları

// When the result is a file: include the absolute path and file name. The session
// renders a clickable file card that previews in-app (docx/xlsx/pdf/markdown/code…).
process.send({
  type: 'tool_result',
  requestId,
  content: [{ type: 'text', text: `Generated [${fileName}](${filePath})` }],
  details: { filePath, fileName },
});

Kontrol listesi oluşturma: renderAs kontrol listesi

// For tools with renderAs: "checklist", the host renders the todos array from the call arguments:
{
  "todos": [
    { "id": "1", "content": "Initialize repository", "status": "completed" },
    { "id": "2", "content": "Write unit tests", "status": "in_progress" },
    { "id": "3", "content": "Publish", "status": "pending" }
  ]
}

İyi bir açıklama yazmak

Emir cümlesindeki tetikleyiciyi açıklayın ("Kullanıcı şunu istediğinde bunu ara...") ve hariç tutmaları belirtin ("Bunu şunun için çağırma..."). Sonuç bir dosya ise modelden, bunun oluşturulduğunu iddia etmek yerine, döndürülen dosya bağlantısına referans vermesini isteyin. Bağımsız değişkenler harici bir nesil API'ye iletilirse, bunların hangi dilde olması gerektiğini söyleyin. "Yapılacakları yönet" gibi tek satırlık ifadelerden kaçının; model, aracı ne zaman kullanacağını bilemeyecektir.

06Sabitlenmiş görünümler (görünümler)

Yerleştirilmiş görünüm, oturumun sağ kenar çubuğundaki kalıcı bir sayfadır: oturum araç çubuğunda fazladan bir simge görünür ve açıldığında HTML'niz sağda gösterilir. Sayfa durumu (kaydırma konumu, taslaklar), VS Code kenar çubuğu görünümüyle aynı anlambilimi kullanarak oturum değiştirme ve daraltma/genişlemeden sağ çıkar.

AlanTanım
idEklentinin içinde benzersiz.
titleSimgeye ilişkin ipucu metni (insan tarafından okunabilir).
iconAna makine izin verilenler listesinden seçim yapın: git-branch, checklist. Simgelerin uygulama genelinde tutarlı olmasını sağlar; özel görseller kabul edilmez.
entryEklenti klasörüne göre HTML dosyası.
widthPiksel cinsinden isteğe bağlı varsayılan panel genişliği, 240 - 640, varsayılan 360. Kullanıcılar yeniden boyutlandırmak için sürükleyebilir ve boyut hatırlanır.

Sayfa çalışma zamanı

Sayfa bir korumalı alanda çalışır (sandbox + contextIsolation, Düğüm yok, ana uygulama verilerine erişim yok) ve window.pluginHost'deki birkaç yöntemle yalnızca kendi eklenti süreciyle konuşabilir. Kendi stillerinizi getirin; Aşağıdaki örnekte olduğu gibi uygulamanın aydınlık/karanlık düzeninin takip edilmesi önerilir.

interface PluginHost {
  // Call a tool declared in this plugin's manifest.tools; same call_tool channel the AI uses
  invoke(toolName: string, params: unknown): Promise<
    { content: unknown[]; details?: unknown } | { error: string }
  >;
  // Subscribe to ui_push messages from the plugin process; returns an unsubscribe function
  onPush(callback: (channel: string, payload: unknown) => void): () => void;
  // Current light/dark scheme and subsequent changes
  getColorScheme(): Promise<'light' | 'dark'>;
  onColorSchemeChange(callback: (scheme: 'light' | 'dark') => void): () => void;
}
declare const pluginHost: PluginHost; // exposed as window.pluginHost

Önerilen model: ilk yüklemede invoke() ile kendi sorgu araçlarınızdan birini çağırın ve details'de yapılandırılmış veri döndürmesini sağlayın; daha sonra eklenti sürecindeki her değişikliği yoklama yerine ui_push ile aktarın. Yapay zeka görüşmedeki verileri değiştirdiğinde panel hemen yenilenir.

07Yüzen panel (ui)

ui: { entry, title } kullanıcıların eklenti listesindeki "⋯" menüsünden açacağı bağımsız bir kayan pencere (900×700) bildirir; yaklaştıkça yok edilir. Sayfa ortamı ve window.pluginHost API, sabitlenmiş görünümlerle aynıdır ve ui_push hem kayan panele hem de sabitlenmiş görünümlere sunulur. Ara sıra açılan büyük panellere uygundur; Oturumun yanında kalması gereken içerik için views tuşunu kullanın.

08Oturum araç çubuğu simgesi (sessionAction)

Eklenti başına en fazla bir kalıcı simge. Tıklandığında boş argümanlarla tool çağrılır, dolayısıyla aracın parametreler olmadan anlamlı bir şey yapması gerekir.

AlanTanım
toolTıklandığında çağrılacak araç.
iconİzin verilenler listesine eklenen simge adı.
tooltipMetnin üzerine gelin.
visibleToolİsteğe bağlı. Ayarlandığında, oluşturmadan önce boş argümanlarla çağrılır ve sonuçtaki boolean details.visible simgenin gösterilip gösterilmeyeceğine karar verir. "Geçerli klasör bir git deposu mu?" gibi çalışma zamanı kontrolleri için kullanışlıdır.
// The host calls visibleTool with empty params and shows the icon based on details.visible
process.send({
  type: 'tool_result',
  requestId,
  content: [{ type: 'text', text: isGitRepo ? 'git repo' : 'not a git repo' }],
  details: { visible: isGitRepo },
});

09Ayarlar (yapılandırma)

Bildirilen girişler, ayarlar sayfasındaki eklenti yapılandırması altında görünür. Ana bilgisayar, kullanıcı tarafından değiştirilen değerleri saklar ve çağrının yapay zekadan, araç çubuğu simgesinden veya panelinizden gelmesine bakılmaksızın bunları her call_tool'de (id ile anahtarlanır, defaultValue'ye geri dönerek) context.config olarak iletir. Bunları asla sormanıza gerek yok.

typeŞu şekilde oluşturuldu:varsayılanDeğer türü
selectTek seçenekli liste; seçenekler optionsTool'dan gelirstring
booleanGeçiş anahtarıboolean
stringBulanıklaştırmaya dayalı metin girişistring
numberSayı girişinumber
// For type: "select" settings, the host calls optionsTool with empty params to fetch options
process.send({
  type: 'tool_result',
  requestId,
  content: [{ type: 'text', text: '2 options' }],
  details: {
    options: [
      { value: 'fast', label: 'Fast' },
      { value: 'accurate', label: 'Accurate' },
    ],
  },
});
// The host automatically prepends an "Auto" option whose value equals this
// configuration entry's defaultValue; the plugin must not return it again.

10Komut paleti / kısayollar / içerik menüsü

Üçü de "boş argümanlarla bir aracı çağırmak" için farklı giriş noktalarıdır; bir eklenti birkaç tane bildirebilir.

AlanŞekilTanım
commands{ tool, icon, title }[]Ctrl/Cmd+K komut paletinde gösterilir ve kullanıcı onu aradıktan sonra tetiklenir.
keybindings{ command, key }[]command, commands[]'deki bir girişin tool'sine eşit olmalıdır. key, mod+shift+g gösterimini kullanır; burada mod, macOS'de Cmd ve başka yerde Ctrl'dir. Diğer kısayollarla olan çakışmalar statik olarak kontrol edilmediğinden alışılmadık kombinasyonlar seçin.
menus{ "session/context": { tool, icon, title }[] }Bir oturum satırındaki menüye eklendi. Şimdilik yalnızca bu konum mevcut.

11Belge ayrıştırıcılar (documentParsers)

Kullanıcı giriş kutusuna bir dosya bıraktığında, ana bilgisayar MIME türüne göre etkin eklentiler tarafından bildirilen ayrıştırıcıları arar ve dosya içeriğini eşleşen toolName'ye base64 olarak iletir. Bu, AI'nın çağırmaya karar verdiği bir araç değildir, bu nedenle ayrıca ayrıştırıcı aracını tools altında listelemeyin, aksi takdirde AI tarafından çağrılabilir bir araç olarak ortaya çıkacaktır.

// The toolName declared in documentParsers is called when the user drops a file into the input:
// params = { base64: "<file content as base64>" }
// Return: details must be { success: true, text } or { success: false, reason }
process.on('message', (msg) => {
  if (msg.type !== 'call_tool' || msg.toolName !== 'parse_markdown') return;
  const text = Buffer.from(msg.params.base64, 'base64').toString('utf8');
  process.send({
    type: 'tool_result',
    requestId: msg.requestId,
    content: [{ type: 'text', text: 'parsed' }],
    details: { success: true, text },
  });
});

12Ters RPC (host_request)

Eklenti işleminin Electron API'si yoktur. Gerçek bir sistem yeteneğine ihtiyaç duyduğunda ana bilgisayara host_request gönderir ve ana bilgisayar host_response veya host_error ile yanıt verir. Bu kanal call_tool'den tamamen bağımsızdır; bunu bir alet çağrısı yaparken veya bir zamanlayıcıdan kullanabilirsiniz.

capabilityparamsresultÖnkoşul
show_notification{ title, body?, viewId? }{ shown: true } / { shown: false, reason: "disabled" | "unsupported" }notifications iznini gerektirir. Kullanıcı ayarlarda masaüstü bildirimlerini kapattığında hata yerine devre dışı ifadesini döndürür. viewId sabitlenmiş görünümlerinizden birini işaret ettiğinde, bildirime tıklamak uygulamayı öne çıkarır ve o görünümü genişletir.
render_pdf{ outputPath, title, content }{}içerik Markdown'dur; ana bilgisayar, yerleşik oluşturucusu ile bir PDF'yi çıktıPath'e dönüştürür.
const crypto = require('crypto');
const pending = new Map();

function requestHost(capability, params) {
  const requestId = crypto.randomUUID();
  return new Promise((resolve, reject) => {
    const timer = setTimeout(() => {
      pending.delete(requestId);
      reject(new Error(`host capability "${capability}" timed out`));
    }, 30_000);
    pending.set(requestId, { resolve, reject, timer });
    process.send({ type: 'host_request', requestId, capability, params });
  });
}

process.on('message', (msg) => {
  if (msg.type === 'host_response' || msg.type === 'host_error') {
    const p = pending.get(msg.requestId);
    if (!p) return;
    pending.delete(msg.requestId);
    clearTimeout(p.timer);
    if (msg.type === 'host_error') p.reject(new Error(msg.message));
    else p.resolve(msg.result);
  }
});

// usage
await requestHost('show_notification', {
  title: '3 todos for today',
  body: '• Write weekly report\n• Reply to emails',
  viewId: 'board',      // optional: expand this docked view when the notification is clicked
});
// => { shown: true } or { shown: false, reason: 'disabled' | 'unsupported' }

await requestHost('render_pdf', {
  outputPath: '/abs/path/report.pdf',
  title: 'Report',
  content: '# Title\n\nBody (Markdown)',
});

13Yaşam döngüsü

SahneDavranış
BaşlangıçVarsayılan olarak tembel: uygulamayla başlatılmadı, araçlarınızdan birine (AI, araç çubuğu simgesi, panel, komut, belge ayrıştırma) ilk çağrı yapıldığında çatallandı. activationEvents: ["onStartupFinished"] bildiren eklentiler, uygulamanın başlatılması tamamlandıktan hemen sonra başlar; bunu sıradan araç eklentileri için değil, yalnızca arka plan zamanlayıcılarına (hatırlatıcılar, yoklama) ihtiyaç duyan eklentiler için kullanın.
İkamet eden kişiSüreç bir kez başlatıldığında canlı kalır ve araç çağrılarında yeniden kullanılır. Durumu bellekte önbelleğe alabilirsiniz, ancak herhangi bir zamanda yeniden başlatılabileceğini varsayın.
Kazaİşlem beklenmedik bir şekilde sonlandırılırsa ana bilgisayar işlemi yeniden başlatır: hemen, ardından 5 ve 15 saniye sonra. Art arda 3 başarısızlıktan sonra "çöktü" olarak işaretlenir ve artık yeniden denenmez; kullanıcılar durumu eklenti sayfasında görür. Uçuş sırasında tüm dönüş hatalarını çağırır.
Devre dışı bırak / kaldır / yeniden yükleİşlem sonlandırılır ve sabitlenmiş görünümler ve yüzen paneller yok edilir; yeniden yükleme tüm klasörü değiştirir.
Günlüklerstdout/stderr'niz, eklenti kimliği ön ekiyle uygulama günlük dosyasına yazılır. Düz console.log hata ayıklama için yeterlidir; bkz. "Hata Ayıklama ve SSS".
ENV
Alt süreç ELECTRON_RUN_AS_NODE=1 ile başlar, cwd eklenti yükleme klasörüdür ve Node sürümü, uygulamayla birlikte verilen Electron ile eşleşir. Global olarak kurulu herhangi bir pakete güvenmeyin ve npx'nin var olduğunu varsaymayın.

14Paketleme ve Yayınlama

Ambalajlama

Eklenti klasörünü arşiv kökündeki manifest.json ile sıkıştırın. Üçüncü taraf bağımlılıklarınız varsa, node_modules'in tamamını göndermek yerine ilk önce bunları esbuild/webpack ile tek bir dosyada paketleyin.

my-plugin.zip
├── manifest.json     # must be at the archive root
├── icon.png          # optional, referenced by manifest.icon
├── index.js
├── view.html
└── node_modules/…    # include dependencies if any (bundling into a single file is recommended)

Pazarda yayınlama

AnBoWork → Araçlar → Eklentiler → "Pazaryeri" sekmesi → sağ üst köşedeki "Eklentiyi yayınla" seçeneğini seçin ve ardından zip dosyasını yükleyin. Gönderimler, bildirim bildiriminin kodla (özellikle izinlerle) eşleştiğini kontrol eden incelemeye girer. Onaylandıktan sonra, diğer kullanıcılar onu piyasada bulabilir ve yükleyebilir ve AI, gerekli gördüğünde kullanıcılar için doğrulanmış eklentileri otomatik olarak yükleyebilir.

Güncellemeler

version'yi artırın ve tekrar yayınlayın. Uygulama, yüklü sürümü Market sürümüyle karşılaştırır ve güncelleme ister; yeniden yükleme kullanıcının etkin durumunu ve ayar değerlerini korur.

15Tam örnek: Yapılacaklar Çeyreği

Gerçek, çalışan bir eklenti (kırpılmış): Yapay zeka yapılacak işleri ekleyip kaldırabilir, sağ kenar çubuğu gerçek zamanlı olarak yenilenen bir pano gösterir ve sistem bildirim hatırlatıcıları gönderebilir. Bu üçünün zincirlenmesi, araç protokolünü, sabitlenmiş görünüm itmelerini ve ters RPC'yi kapsar.

{
  "id": "local.todo-quadrant",
  "name": "Todo Quadrant",
  "version": "1.2.0",
  "description": "Daily todo list organized by the Eisenhower matrix. Install this whenever the user wants to track tasks or asks to be reminded about something…",
  "main": "index.js",
  "permissions": ["filesystem", "notifications"],
  "activationEvents": ["onStartupFinished"],
  "tools": [{
    "name": "manage_todo_quadrant",
    "summary": "Add, list, complete, delete and update todos in an urgent/important matrix",
    "description": "Manage the user's daily todo list… Actions: add / list / complete / delete / update / set_reminder / remind_now. add/update also accept remind_at to schedule a one-time reminder for that specific todo. Call this whenever the user talks about their todos…",
    "parameters": {
      "type": "object",
      "properties": {
        "action": { "type": "string", "enum": ["add", "list", "complete", "delete", "update", "set_reminder", "remind_now"] },
        "id": { "type": "string" },
        "content": { "type": "string" },
        "quadrant": { "type": "string", "enum": ["urgent_important", "important_not_urgent", "urgent_not_important", "not_urgent_not_important"] },
        "due_date": { "type": "string", "description": "YYYY-MM-DD" },
        "remind_at": { "type": "string", "description": "YYYY-MM-DD HH:MM — a one-time reminder for this todo, independent of the daily digest" }
      },
      "required": ["action"]
    }
  }],
  "views": [{ "id": "quadrant", "title": "Todo Quadrant", "icon": "checklist", "entry": "view.html", "width": 380 }]
}

16Hata ayıklama ve SSS

BelirtiNedeni ve çözümü
Yükleme sırasında bildirim doğrulaması başarısız oluyorMesajda belirtilen her alanı "Bildirim Alanları" tablosuna göre kontrol edin: kimlik biçimi, ana/giriş .. içermemelidir, simge izin verilenler listesinde olmalıdır, tuş bağlamaları komutu komutlarda mevcut bir araca işaret etmelidir, genişlik 240 ile 640 arasındadır.
Yapay zeka asla aracımı çağırmazNeredeyse her zaman bir description sorunu: tetikleyici net değil veya İngilizce yazılmamış. Bkz. "İyi bir açıklama yazma". Ayrıca takım adının başka bir takımla çakışmadığını da kontrol edin.
Arama zaman aşımı (30 sn)Giriş komut dosyası tool_result ile yanıt vermedi. Genellikle requestId geri yansımaz, type mesajı yanlış yazılır veya komut dosyası başlangıçta atılıp çıkılır. Uygulama günlüğünde [plugin:your-id] ön eki olan satırları arayın.
Eklenti durumu "çöktü" olarak görünüyorArt arda 3 başarısız başlatma. Genellikle eksik bir paketin require'si; eklenti klasöründe node index.js komutunu çalıştırmak onu yeniden üretir. Düzelttikten sonra eklenti sayfasında eklentiyi kapatıp tekrar açın.
Panel boş açılıyorYanlış entry yolu veya sayfada bir JS hatası. Sayfa, Node'un require'si olmayan bir korumalı alanda çalışır; yalnızca window.pluginHost mevcuttur.
Bildirim görünmüyorSırayla kontrol edin: bildirimde notifications belirtilir; sonuç shown:false değildir (kullanıcı masaüstü bildirimlerini kapatmıştır); işletim sistemi AnBoWork'den gelen bildirimlere izin verir.
Ayar değerleri okunamıyorDeğerler params değil, message.context.config[id] cinsindendir.

Günlük dosyası konumu

İşletim SistemiYol
macOS~/Library/Logs/AnBoWork/main.log
Windows%USERPROFILE%\AppData\Roaming\AnBoWork\logs\main.log
API entegrasyonu belgelerine bakın