İçeriğe geç
↑↓Gezin ↵Aç escKapat

Eklenti oluşturma

OpenChamber’a kendi panelinizi eklemek için @openchamber/sdk kullanın. Eklenti, OpenChamber’ın sağ şeritte gösterdiği küçük bir web sayfasıdır. Uygulamayla connectHost() üzerinden konuşur: geçerli projeyi ve oturumu okuyabilir, bildirim gösterebilir, sohbet kutusuna metin koyabilir, bir oturuma görev iliştirebilir ve kullanıcının onayıyla oturum başlatıp istem gönderebilir.

Eklentiler OpenChamber web ve masaüstünde çalışır. VS Code ve mobil henüz eklenti yüklemiyor.

Eklenti nedir

Üç dosyalı bir klasör:

  • openchamber bloğu (manifest) içeren package.json
  • panel/index.html, OpenChamber’ın gösterdiği sayfa
  • panel/main.js, tek bir klasik dosya olarak derlenmiş betiğiniz (sayfa sandbox’lı bir iframe içinde yüklendiği için ES modülü değil, IIFE)

OpenChamber kodunuzu asla derlemez. Derlenmiş .js dosyasını yayınlayın. SDK bir paketleme komutu içerir; IIFE üreten herhangi bir paketleyici de olur.

Terminal window
npm install @openchamber/sdk
bunx openchamber-guest-bundle panel/main.ts panel/main.js

Paketleme komutu Bun üzerinde çalışır. Bun yoksa esbuild’i ya da başka bir paketleyiciyi --format=iife --platform=browser ile kullanın.

Üç dosyanın tamamıyla çalışan eksiksiz bir eklenti Örnek sayfasında. Kopyalayın, API’yi ve listeyi değiştirin.

index.html içinde main.js dosyasına normal bir <script src="main.js"></script> ile bağlanın.

Çalışırken kurma

  1. OpenChamber’ı web veya masaüstünde çalıştırın.
  2. Ayarlar → Uzantılar sayfasını açın.
  3. Klasörünüzün mutlak yolunu yapıştırıp Ekle’ye tıklayın.

OpenChamber manifesti okur ve eklentinin ne istediğini listeleyen bir pencere gösterir (bkz. Yetenekler). Onaylayın, simgeniz şeritte belirir. Tıklayın, sayfanız yüklenir.

Yerel bir .zip dosyası ya da bir git deposuna veya zip dosyasına giden https bağlantısı da ekleyebilirsiniz. Yalnızca git kurulumu güncellenebilir: package.json içindeki version değerini yükseltip push edin; OpenChamber açıldıktan kısa süre sonra ve birkaç saatte bir denetler, kullanıcıya bir kez haber verir ve güncellemeyi Ayarlar → Uzantılar sayfasında sunar. Herhangi bir sayfadaki openchamber://extensions/install?url=<encoded repository URL> bağlantısı, masaüstü uygulamasını bu depo ekleme iletişim kutusunda hazır olacak şekilde açar; böylece bir kurulum düğmesi sunabilirsiniz. URL’deki #tag ya da #branch neyi izleyeceğini sabitler. Bunlar OpenChamber’ın veri klasörüne kopyalanır ve o kopyadan çalışır; bu yüzden node_modules veya TypeScript kaynaklarını değil, derlenmiş dosyaları yayınlayın. Eklentiyi kaldırmak kopyayı siler. Klasörden kurulum doğrudan sizin klasörünüzden çalışır; düzenleyip yeniden derleyip yeniden yükleyebilirsiniz.

Manifest

{
"name": "@acme/hello",
"version": "1.0.0",
"openchamber": {
"apiVersion": 1,
"engines": { "openchamber": ">=1.24.0" },
"id": "acme-hello",
"name": "Hello",
"icon": "window",
"contributes": {
"panel": { "entry": "panel/index.html" },
"attach": "dialog",
"page": true,
"capabilities": ["prompt", "sessions"],
"integration": {
"name": "Acme",
"description": "Tasks from Acme",
"token": {
"apiOrigin": "https://api.acme.example",
"account": { "path": "/me", "name": "login" },
"scheme": "bearer"
},
"settings": [{ "id": "list-id", "label": "List ID" }]
}
}
}
}

version zorunludur ve semver olmalıdır. Ayarlar → Uzantılar bunu kartta gösterir.

apiVersion değeri 1’dir. OpenChamber başka değerleri reddeder.

engines.openchamber isteğe bağlıdır. Eklentinizin çalıştığı en eski OpenChamber sürümünü 1.24.0 veya >=1.24.0 biçiminde yazın. Daha eski sürümler sonradan hata vermek yerine kurulumu reddeder.

id, name ve icon eklentiyi adlandırır. id kebab-case olmalı ve kurulu eklentiler arasında benzersiz olmalıdır. icon bir Remixicon adı (RiWindowLine için window) ya da klasörünüzdeki bir SVG dosyasıdır, örneğin icon.svg. contributes.panel eklentinin şeritteki panelidir: entry değeri klasörünüzdeki HTML dosyasıdır. Şeritte paneli olmayan bir eklenti panel alanını atlar. Eski paketler id, name ve icon alanlarını panel içinde tutar ve bu çalışmaya devam eder.

contributes.attach isteğe bağlıdır. Eklentinizi sohbet kutusunun yanındaki + menüsüne ekler; kullanıcı buradan bir görev seçip oturuma iliştirebilir.

  • "dialog" sayfanızı bir pencerede açar
  • true veya "panel" bunun yerine şerit panelini açar
  • { "mode": "dialog", "entry": "panel/attach.html" } pencerede size ait ayrı bir sayfa açar; böylece seçicinin şerit paneliyle kod paylaşması gerekmez
  • atlarsanız eklenti o menüde görünmez

ctx.surface, panel, dialog, page, status veya block olur. İliştirilmiş bir öğeye tıklanınca verileri ctx.item içinde gelir; diğer durumlarda değer null olur.

contributes.page: true, paneli oturum listesinin üstündeki Uzantı sayfaları menüsünden tam ekran açılabilir yapar. { "entry": "panel/page.html", "title": "Board" } ayrı HTML ve isteğe bağlı başlık kullanır. panel.entry zorunludur; yalıtım ve izinler aynıdır. Sayfayı yalnızca kullanıcı açar. Yenileme, duraklatma, kaldırma veya sunucu değiştirme sayfayı kapatır.

Panolar host.storage ile proje, worktree ve oturum listelerini ve canlı durumları kullanabilir. startSession, panoyu kapatmadan başka bir projeyi hedefleyebilir. Bkz. Host API.

contributes.integration isteğe bağlıdır. Ayarlar → Entegrasyonlar sayfasına kullanıcının hesap bağladığı bir kart ekler. Bkz. Hesaplar ve ağ.

contributes.service isteğe bağlıdır. OpenChamber’ın eklentinin yanında başlattığı yerel bir süreç tanımlar; bir web sayfasının ulaşamadığı şeyler için, örneğin bir Docker soketi. Bu süreç kullanıcının tam erişimiyle ve sandbox olmadan çalışır, bu yüzden onay iletişim kutusu bunu uyarır; sayfa işi yapamadığında bir tane tanımlayın. Paket dosyası GUEST_SERVICES.md dosyasına bakın. provides: ["browser"] içeren bir hizmet ajanın tarayıcısının yerine de geçebilir: browser.* eylemlerini sunucuda yanıtlar, böylece ajanlar açık bir masaüstü uygulaması olmadan gezinir; kullanıcı bunu Ayarlar → OpenChamber Araçları’ndan seçer. Böyle bir hizmetin panele ihtiyacı yoktur. Bir hizmete kullanıcının oturumlarında olanlar da bildirilebilir: yanına contributes.sessionEvents tanımlayın, OpenChamber biten ya da başarısız olan her turu ve ajanın sorduğu her izni ya da soruyu, her projeden ve açık bir pencere olmadan hizmete gönderir. Bkz. Oturum olayları. provides: ["notifications"] içeren bir hizmet ise kullanıcının bildirimlerini masaüstü ve telefonun yanında Slack’e, Matrix’e ya da kendi sunucunuza iletir; kullanıcı hesabı Ayarlar → Entegrasyonlar’da bağlar ve token OpenChamber’da kalır. Bkz. Bildirim kanalları. provides: ["tracker"] olan bir servis, Linear’ın yanında bir iş öğesi izleyicisidir ve hesap kartı Uzantı hesapları altında durur; bkz. İzleyiciler. provides: ["quota"] olan bir servis ise yerleşik sağlayıcıların yanında kullanımı bildirir ve bunun için OpenCode’un manifestte listelenen sağlayıcılar için sakladığı kimlik bilgilerini okur; bkz. Kullanım sağlayıcıları.

Yetenekler

Panel çizmek ve geçerli oturumu okumak izin gerektirmez. Kullanıcı adına bir şey yapan her şey gerektirir. Bunları contributes.capabilities içinde listeleyin:

YetenekNeye izin verir
promptkullanıcının oturumuna mesaj göndermek (prompt({ send: true }), text ile startSession)
sessionsprojeleri, worktree ve oturum durumlarını listelemek; kayıtlı projelerde oturum oluşturmak ve açmak
filesaçık projedeki dosyaları okuyup yazmak (göreli yol ile readFile, writeFile, listDir, stat)
modelkullanıcının Small Model’iyle tek seferlik metin üretimi (generate), herhangi bir oturumun dışında

On bir tanesi sizin için otomatik eklenir: bir integration tanımladığınızda network, bir service tanımladığınızda service, filesystem desenleri tanımladığınızda filesystem, origins tanımladığınızda origins, bir oturum eylemi mesajları istediğinde conversation (bkz. Eylemler, komutlar ve rozet), sessionEvents veya sessionControl content istediğinde transcript (bkz. Oturum olayları), servisiniz oturumlar üzerinde işlem yaptığında sessionControl (bkz. OpenChamber’ı çağırma), servisiniz kullanıcı adına ajanın izin isteklerini ve formlarını yanıtladığında sessionAnswers (sessionControl: { answers: true }), ajanların okuduklarına ekleme yaptığında instructions ve contributes.skills tanımladığınızda skills. contributes.skills, eklenti açıkken her ajana ulaşan skill’lerin bulunduğu bir paket klasörüdür. contributes.opencodePlugin tanımladığınızda opencodePlugin de eklenir (aşağıya bakın).

Kullanıcı tam listeyi bir kez, eklentiyi kurarken görür ve ya onaylar ya da eklentiyi kaldırır. Yeni bir sürüm daha fazlasını isterse pencere yeniden görünür. Kullanıcının onaylamadığı bir yeteneği gerektiren çağrı NOT_GRANTED ile başarısız olur.

Paketinizde bir OpenCode eklentisi

Bir uzantı bir OpenCode eklentisi getirebilir; böylece insanlar iki şey yerine tek şey kurar. "opencodePlugin": "plugin" tanımlayın: paketin içinde, kökünde index.js veya server.js bulunan bir klasör. OpenCode main alanını okumaz, bu yüzden giriş dosyası başka bir yerdeyse klasörün package.json dosyasında name ve exports tanımlayın. Giriş dosyası, OpenCode’un yüklediği biçim olan { id, setup } nesnesini varsayılan olarak dışa aktarır; hiçbir şey içe aktarmaz, çünkü OpenCode onu hiçbir şeyin kurulu olmadığı klasörünüzden düz bir import() ile yükler. Bir aracın input alanı düz JSON Schema’dır ve execute işlevi { content } döndürür.

{
"contributes": {
"panel": { "id": "teapot-tools", "name": "Teapot Tools", "icon": "cup" },
"opencodePlugin": "plugin"
}
}

Onay iletişim kutusuna bir satır daha gelir: OpenCode’a eklenti ekleme. Bu satır, eklenti kodunun kullanıcının tüm erişimiyle OpenCode’un içinde çalıştığını açıkça söyler. İzin verildikten sonra OpenChamber, klasörünüzü yönettiği OpenCode yapılandırmasına, yani contributes.skills ile aynı dosyaya ekler; OpenChamber’ın çalıştırdığı OpenCode bu dosyayı izler ve eklentiyi birkaç saniye içinde yükler. Uzantıyı kapatmak veya kaldırmak eklentiyi aynı yoldan çıkarır. Kullanıcının kendi opencode.json dosyasına hiçbir şey yazılmaz: o dosya kullanıcıya aittir ve oradaki bir eklenti uzantınızdan uzun yaşar, makinedeki her OpenCode’da çalışırdı.

Bu dosyanın OpenCode’a ulaşmadığı yerde uzantının ekranı bunu söyler ve Genel yapılandırmaya ekle seçeneğini sunar; bu, klasörünüzü kullanıcının genel OpenCode yapılandırmasına, o andan itibaren kullanıcıya ait bir kayıt olarak yazar. Bu durum, OpenChamber konuştuğu OpenCode’u başlatmadığında ya da sunucunun ortamı kendi OPENCODE_CONFIG değerini ayarladığında olur (eklenti o zaman OpenCode’un bir sonraki başlatılışında yüklenir). Başka bir makinedeki OpenCode bu makinedeki bir klasörü yükleyemez; ekran bunu söyler ve hiçbir şey sunmaz. Yüklenemeyen bir eklentiyi, orada bir kaydı varsa OpenCode Ayarlar → Eklentiler altında bildirir; uzantınız her durumda çalışmaya devam eder. Kurulum, eklenti klasörü olmayan ya da package.json dosyası bir giriş dosyası belirtmeyen paketi reddeder.

VS Code ve mobil uygulamalar uzantı yüklemez, bu yüzden onlara eklenti ulaşmaz. Yalıtılmış bir alandaki oturum kendi OpenCode’unu çalıştırır ve ana makinenin yapılandırmasını hiç okumaz. Kurumsal mod eklentiyi yerel bir servis gibi ele alır: yalnızca yöneticinin listelediği bir depodan kurulur. SDK’da çalışan bir örnek vardır: examples/opencode-plugin.

Metin üretme

model yeteneğiyle host.generate, kullanıcının Small Model’inden tek seferlik bir yanıt ister: bir özet, bir başlık, bir taslak. Hiçbir şey bir oturuma girmez, geçmiş tutulmaz ve eklenti asla bir sağlayıcı seçmez. OpenChamber, kendi arka plan işleri için kullandığı aynı modeli kullanır; bu model Ayarlar → Oturumlar → Small Model üzerinden seçilen model, kullanıcının çalıştığı sağlayıcının küçük modeli ya da kullanıcının OpenCode yapılandırmasındaki varsayılan modeldir.

const { text } = await host.generate({
prompt: task.description,
system: "Write a one-line summary. Return only the summary.",
maxOutputTokens: 200,
});

Hiçbir model kullanılamadığında çağrı NO_MODEL ile başarısız olur; hata veren bir model MODEL_FAILED olur. İstemler 64.000 karakterle sınırlıdır ve çağrı en fazla 90 saniye bekler. Kullanıcı bu izni “Small Model’inizi kullanma” olarak görür ve bu ona jetona mal olur, bu yüzden istemleri kısa tutun ve her tuş vuruşunda değil, bir tıklamada çağırın.

Hesaplar ve ağ

Sayfanız bir sandbox içinde çalışır ve ağa kendi başına erişemez: betikler, stiller, görseller, yazı tipleri ve medya yalnızca paketinizden yüklenir, fetch de yalnızca paketinizdeki dosyalara ulaşır. Yazı tiplerini ve görselleri bir CDN’den yüklemek yerine paketin içinde gönderin.

Dışarıdaki bir hizmetle konuşmak için bir integration tanımlayın; OpenChamber çağrıları host.request üzerinden, kullanıcının token’ı ekli olarak sizin yerinize yapar. Token sayfanıza asla ulaşmaz.

Sayfanızın doğrudan ihtiyaç duyduğu diğer her şey için, örneğin bir CDN’den yazı tipleri veya görseller ya da herkese açık bir API için, en fazla 8 https kaynağı listeleyin:

"origins": ["https://fonts.example.com"]

Kullanıcı bunları onay penceresinde eklentinizin veri gönderip veri alabileceği adresler olarak görür ve bir güncelleme yenisini eklerse yeniden onaylar. Onaylanan kaynaklar fetch, görseller, yazı tipleri, stiller ve medya için açıktır ama betikler için asla: kod paketinizle birlikte gelmelidir. Sayfanın kaynağı null olduğundan, bir fetch yanıtını okuyabilmeniz için sunucunun bu kaynağa CORS izni vermesi gerekir.

Kurumsal modda origins, integration ya da service içeren bir eklenti yalnızca yöneticinin listeye eklediği bir Git deposundan kurulur. Eklentiniz bunlar olmadan çalışabiliyorsa, bu ekipler için kurulabilir kalır. Böyle bir makinede eklenti geliştirmek için yöneticiden allowLocalExtensions isteyin; bununla eklentiyi kendi klasöründen kurabilirsiniz.

  • token: kullanıcı Ayarlar → Entegrasyonlar kartına bir API token’ı yapıştırır. apiOrigin, request çağrısının erişebileceği tek kaynaktır. account isteğe bağlıdır: bir GET yolu ve bir alan adı; kart böylece kimin bağlı olduğunu gösterebilir. scheme, token’ın nasıl gönderileceğini belirler; aşağıdaki tabloya bakın. Hangi başlığı beklediğini sağlayıcının API belgelerinden kontrol edin.
  • oauth: kullanıcı bir client id yapıştırır, yetkilendirme akışını OpenChamber yürütür. authorizeUrl, tokenUrl ve apiOrigin gerekir.
  • host: { "provider": "linear" }: OpenChamber’da zaten bağlı olan Linear hesabını yeniden kullanır. Client id gerekmez.

Her scheme ne gönderir:

schemeOpenChamber’ın gönderdiği başlıkNe zaman kullanılır
atlanmışAuthorization: <token>API başlıkta çıplak bir token belgeliyorsa
"bearer"Authorization: Bearer <token>API bearer veya personal access token belgeliyorsa
"basic"Authorization: Basic base64(username:token)API kullanıcı adı (çoğunlukla e-posta) ve API token’ı ile HTTP Basic auth belgeliyorsa; kart ikisini de sorar ve usernameLabel ilk alanı adlandırır

settings karta düz metin alanları ekler. Değerleri ctx.settings içinde gelir. "secret": true olan bir alan kartta maskelenir ve hiçbir sayfaya ulaşmaz; servisiniz onu readSettings() ile okur.

Dosyalar

Sayfanız diske kendisi dokunamaz. OpenChamber onun yerine, kullanıcının onayladığı sınırlar içinde okur ve yazar.

  • Göreli bir yol (README.md, src/index.ts, .) açık projeyi ifade eder. files yeteneği gerektirir. Açık proje yoksa NO_DIRECTORY olur.
  • / veya ~/ ile başlayan bir yol başka herhangi bir yeri ifade eder. contributes.filesystem içinde tanımladığınız desenlerden biriyle eşleşmelidir ve kullanıcı onay penceresinde tam olarak bu desenleri görür:
"filesystem": ["~/.config/opencode/opencode.json", "~/notes/**"]

Desenlerde * tek bir yol parçasını, ** herhangi bir derinliği karşılar. Bunların dışındaki her şey, onaydan sonra bile BAD_PATH olur. .. hiçbir zaman izinli değildir.

const config = await host.readFile("~/.config/opencode/opencode.json");
await host.writeFile("~/.config/opencode/opencode.json", nextJson);
const { entries } = await host.listDir(".");

Yazmalar atomiktir: OpenChamber geçici bir dosya yazıp yeniden adlandırır, böylece okuyan taraf hiçbir zaman yarım yazılmış bir dosya görmez. Dosyalar UTF-8 metin olarak, en fazla 2 MB’a kadar okunur ve yazılır.

Work Status’ta bir bölüm

contributes.statusSection, sohbetin yanındaki Work Status paneline kendi bölümünüzü ekler. Kullanıcılar onu yerleşik bölümler gibi o panelin bölüm listesinde açıp kapatır ve taşır.

"statusSection": { "entry": "status/index.html", "title": "Recent commits", "height": 160 }
  • true, panel.entry sayfasını kullanır.
  • entry, klasörünüzdeki ayrı bir HTML sayfasıdır. Bununla panel.entry gerekmez, yani eklenti şeritte simgesi olmadan yalnızca bu bölümden oluşabilir.
  • title, bölüm başlığındaki panel adının yerini alır, en fazla 60 karakter.
  • height, piksel cinsinden başlangıç yüksekliğidir, 24 ile 320 arası (varsayılan 120). İçeriğinizin boyutu değişince host.setHeight() çağırın.

Sayfanız ctx.surface değerini status olarak görür. OpenChamber sayfayı yalnızca Work Status paneli görünürken ve bölümünüz açıkken yükler, kullanıcı bölümü kapatınca kaldırır. Bu yüzden orada yeniden kuramayacağınız bir şey tutmayın. Yalnızca bölümden oluşan bir eklenti izinleri, bir servisi, bir entegrasyonu ve dosyaları kullanabilir, ama page, attach, actions veya commands kullanamaz. Yalnızca web ve masaüstü. git-graph-status örneği eksiksiz bir bölümdür.

Dosya türünüz için bir düzenleyici

contributes.fileEditors, dosyaları metin düzenleyici yerine sayfanızda açar. Kullanıcı Files içinde eşleşen bir dosyayı açtığında OpenChamber orada düzenleyicinizi gösterir; yerleşik görüntüleyicilerdeki kaynak geçişi, tam ekran düğmesi ve kaydet düğmesi de aynen bulunur.

"fileEditors": [
{ "id": "canvas", "title": "Excalidraw", "match": ["*.excalidraw", "*.excalidraw.md"], "entry": "editor/index.html" }
]
  • match yalnızca dosya adlarını karşılaştırır ve büyük/küçük harfi yok sayar. * herhangi bir karakter dizisiyle, ? tek bir karakterle eşleşir. Bir desen / içeremez ve yalnızca joker karakterlerden oluşamaz.
  • entry, klasörünüzdeki bir HTML sayfasıdır. panel.entry gerekmez, yani eklenti şeritte simgesi olmadan yalnızca düzenleyiciden oluşabilir.
  • content, "text" (varsayılan) ya da "binary" olur, aşağıya bakın.
  • Eklenti başına en fazla 8 düzenleyici, her birinde en fazla 16 desen.

Dosyayı OpenChamber yönetir. Sayfanız dosyayı hiçbir zaman okumaz veya yazmaz ve bunun için bir izne ihtiyaç duymaz. OpenChamber size metni verir, kaydederken düzenlenmiş metni ister ve Cmd/Ctrl+S, otomatik kaydetme, kaydedilmemiş değişiklik uyarısı, satır sonları ve diskte yapılan değişikliklerle kendisi ilgilenir:

import { connectHost, createFileSaveTracker } from "@openchamber/sdk";
const host = connectHost();
let tracker = createFileSaveTracker(null);
host.onFileOpen((file) => {
if (file.encoding !== "text") return; // bir metin düzenleyici her zaman metin alır
load(file.content); // file.path, file.name, file.readOnly da var
tracker = createFileSaveTracker(versionOf(currentText()));
});
// Her düzenlemeden sonra bunu çağırın. `edited`, kullanıcı durana kadar otomatik kaydetmeyi bekletir.
const changed = () => host.reportFileChange(tracker.observe(versionOf(currentText())));
host.onFileSnapshot(() => ({ content: currentText(), version: versionOf(currentText()) }));
// OpenChamber yazarken yapılan düzenlemeler dosyayı kaydedilmemiş bırakır.
host.onFileSaved((version) => host.reportFileChange({ dirty: tracker.markSaved(version), edited: false }));

version, belge değiştiğinde değişen herhangi bir kısa dizedir, örneğin bir hash. Bir dosya düzenleyicinizin açabileceği bir şey değilse host.reportFileUnsupported() çağırın; OpenChamber dosyanın kaynağını bir uyarıyla gösterir. 20 MB’tan büyük dosyalar kaynak görünümünde kalır.

İkili dosyalar

Elektronik tablolar, belgeler veya görseller gibi metin olmayan dosyaları açmak için "content": "binary" ayarlayın. Düzenleyiciniz dosyanın baytlarını alır ve bayt geri verir; geri kalan her şey aynı şekilde çalışır.

host.onFileOpen((file) => {
if (file.encoding !== "binary") return;
open(file.bytes); // diskteki haliyle birebir bir Uint8Array
});
host.onFileSnapshot(() => ({ bytes: currentBytes(), version: versionOf(currentBytes()) }));

İkili bir düzenleyici, desenlerinin eşleştiği her dosyayı üstlenebilir; görseller ve PDF’ler gibi OpenChamber’ın kendisinin önizlediği dosyalar da buna dahildir. Kaynak görünümü yoktur ve kullanıcı onu kaydedilmemiş değişikliklerle tam ekrana aldığında veya tam ekrandan çıkardığında OpenChamber önce değişiklikleri kaydeder. Biçimi okumak ve yazmak düzenleyicinizin işidir: OpenChamber döndürdüğünüz baytları olduğu gibi geri yazar.

Sayfanız ctx.surface değerini file olarak görür. Dosya diskte değiştiğinde, kullanıcı değişiklikleri attığında ya da düzenleyici tam ekrana geçtiğinde veya tam ekrandan çıktığında OpenChamber sayfayı yeniden yükler ve dosyayı tekrar verir. Deseni eşleşen ilk etkin eklenti kazanır ve OpenChamber’ın kendi önizlemelerinden önce gelir. Yalnızca düzenleyiciden oluşan bir eklenti izinleri, bir servisi, bir entegrasyonu ve dosyaları kullanabilir, ama page, attach, actions veya commands kullanamaz. Yalnızca web ve masaüstü. checklist-editor örneği eksiksiz bir düzenleyicidir.

Eylemler, komutlar ve rozet

Şerit ve + menüsünün ötesinde, bir eklenti üç yerde daha görünebilir. Hepsi eklentiye, bir etiket tıklamasının yaptığı gibi bir item verir.

Mesajlar ve oturumlar üzerindeki eylemler. Menü girdileri tanımlayın, OpenChamber bunları yerleşik olanların yanında gösterir:

"actions": [
{ "id": "create-task", "label": "Create task", "icon": "add-line", "where": "message", "roles": ["assistant"] },
{ "id": "summarize", "label": "Summarize session", "where": "session", "payload": ["messages"] }
]

where ayrıca selection (bir mesajda seçilen metin), file (Files içindeki bir satır) ve diff (bir dosyanın veya diff’in seçili satırları) değerlerini de alır. Bunların öğeleri aynı adda bir kind taşır: selection metni, file yolu, diff yolu ve satır aralığını içerir. Seçimde, display eylemin nasıl görüneceğini belirler: label (varsayılan), label metni ipucu olan icon veya both.

Bir mesaj eylemi, eklentinizi kind: "message" olan bir ctx.item ile açar: oturum id’si ve başlığı, proje dizini, mesaj id’si, rolü ve metni. Bir oturum eylemi ise kind: "session" ile, oturum id’si, başlığı ve dizini ile açar. "payload": ["messages"] ekleyin, öğe tüm konuşmayı da taşır, en eskisi önce olmak üzere, Markdown dışa aktarmanın ürettiği metnin aynısı. Bu, kullanıcının onay iletişim kutusunda ayrı bir satır olarak gördüğü conversation yeteneğini gerektirir. item.action hangi girdiye tıklandığını söyler.

İliştiren eğik çizgi komutları. Bir komut tanımlayın ve sayfada işleyin:

"commands": [{ "name": "task", "description": "Attach a task by id" }]
host.onResolve(async ({ command, args }) => {
const task = await findTask(args.trim());
return task ? { providerId: "acme-tasks", id: task.id, title: task.title, url: task.url } : null;
});

Kullanıcı sohbet kutusuna /task ABC-12 yazdığında OpenChamber eklentinizden bunu çözmesini ister ve döndürdüğünüzü, hiçbir şey açmadan, etiket olarak iliştirir. “Bir şey bulunamadı” için null döndürün. Paneliniz kapalıysa OpenChamber bu çağrı için onu arka planda yükler. OpenChamber’ın veya OpenCode’un zaten kullandığı bir ad yok sayılır.

Şerit simgesindeki rozet. host.setBadge(3) simgenize bir nokta koyar ve sayıyı ipucunda gösterir, örneğin açık görevler; host.setBadge(null) onu temizler. Paneli açmak da temizler.

Sohbetteki araçlarınız

OpenCode eklentiniz veya MCP sunucunuz bir araç eklediğinde sohbet, çağrılarını genel bir simge ve ham çıktıyla gösterir. Bunun yerine, kod yazmadan nasıl görünmeleri gerektiğini bildirin:

"tools": [
{
"match": "mcp.jira.*",
"name": "Jira",
"icon": "task-line",
"title": "{input.key}",
"subtitle": "{output.status}",
"output": "table",
"columns": ["key", "summary", "status"]
}
]

match, OpenCode’un bildirdiği haliyle aracın adıdır; sondaki * bir öneki eşleştirir. icon, panel.icon gibi bir Remixicon adı ya da paketinizdeki bir .svg dosyasıdır. title ve subtitle, çağrının input, output ve metadata değerleri üzerinde çalışan şablonlardır. output, gövdenin nasıl çizileceğini seçer: text, json (ağaç), markdown, language ile code, columns ile table (satırlar çıktı dizisinden veya output.items içinden gelir) ya da varsayılan için auto. Tam bir match joker karakteri yener; eşitlikte ilk yüklenen eklenti kazanır. İzin gerekmez: bu yalnızca sohbette zaten bulunan verilerin nasıl çizildiğini değiştirir.

Yalnızca araçları biçimlendiren bir eklentinin sayfaya hiç ihtiyacı yoktur: panel.entry öğesini atlayın, şeritte simgesi olmaz, sadece Ayarlar → Uzantılar içinde bir kart görünür. Sayfası olmadan yalnızca tools tanımlayabilir, başka bir şey tanımlamaz. Diğer istisna, kendi entry sayfası olan bir Work Status bölümü veya dosya düzenleyicisidir, yukarıya bakın.

Paneldeki ilk satırlar

import { connectHost } from "@openchamber/sdk";
const host = connectHost();
host.onReady((ctx) => {
document.body.dataset.theme = ctx.theme.mode;
document.body.dataset.surface = ctx.surface;
});

connectHost yalnızca OpenChamber içinde çalışır. Sayfa düz bir dosya olarak açıldığında her çağrı HOST_UNAVAILABLE ile reddedilir.

Paneli önce @openchamber/sdk/ui yapı taşlarıyla kurun: düğmeler, alanlar, açılır listeler, sekmeler, listeler ve daha fazlası, uygulamanın renkleri ve yazı tipleriyle; böylece panel OpenChamber’ın bir parçası gibi hissedilir. Kendi HTML ve CSS’inizi yalnızca kitte olmayanlar için yazın. Bkz. UI kiti.

İlgili sayfalar

  • SSH kurulumu ve sunucunun Git kimliği seçimi için Uzantılar
  • Host API: her connectHost metodu, sınırları ve hata kodları
  • UI kiti: yapı taşları
  • Örnek: kopyalanacak eksiksiz üç dosyalı bir eklenti