Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions config.example.toml
Original file line number Diff line number Diff line change
Expand Up @@ -1238,8 +1238,12 @@ exec_policy = true
# Set false to remove it from the model's tool catalog.
# extension_host = false # EXPERIMENTAL. Run reviewed plugins' `native` host code
# (TypeScript/JavaScript, Cordis/DSH plugin model) in a
# Node.js sidecar. Tools only in this phase; every
# extension tool always asks for approval. On macOS
# Node.js sidecar. Tools only in this phase. Every
# extension tool is always Required and never
# read-only; like any Required tool it runs without
# a prompt under Full Access, under Bypass, or with a
# matching session grant, which is bound to the
# plugin's reviewed build (an update asks again). On macOS
# the host runs under Seatbelt (no network, no reads of
# ~/.codewhale secrets/credentials/config/sessions,
# writes only to its data dir and temp dirs); on Linux
Expand Down
7 changes: 7 additions & 0 deletions crates/localization/locales/ca.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
{
"CmdPluginOwnerReport": "Amfitrió d’extensions:\n Estat: {state}\n Eines actives ({count}): {tools}",
"CmdPluginOwnerActivating": "S’està activant",
"CmdPluginOwnerActive": "Actiu",
"CmdPluginOwnerFailed": "Ha fallat: {reason}",
"CmdPluginOwnerFaulted": "Amb errors: {reason}",
"CmdPluginOwnerRevoked": "Revocat",
"CmdPluginOwnerInactive": "Inactiu",
"MobileStreamReplayFailed": "El Runtime no ha pogut llegir l'historial d'aquesta conversa — tornant-ho a provar",
"MobileStreamCatchUpFailed": "El Runtime s'ha endarrerit i no s'ha pogut posar al dia — tornant-ho a provar",
"MobileStreamRuntimeShutdown": "El Runtime s'està tancant — reconnectant",
Expand Down
7 changes: 7 additions & 0 deletions crates/localization/locales/de.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
{
"CmdPluginOwnerReport": "Erweiterungshost:\n Status: {state}\n Aktive Werkzeuge ({count}): {tools}",
"CmdPluginOwnerActivating": "Wird aktiviert",
"CmdPluginOwnerActive": "Aktiv",
"CmdPluginOwnerFailed": "Fehlgeschlagen: {reason}",
"CmdPluginOwnerFaulted": "Gestört: {reason}",
"CmdPluginOwnerRevoked": "Widerrufen",
"CmdPluginOwnerInactive": "Nicht aktiv",
"MobileStreamReplayFailed": "Runtime konnte den Verlauf dieser Unterhaltung nicht lesen — erneuter Versuch",
"MobileStreamCatchUpFailed": "Runtime ist zurückgefallen und konnte nicht aufholen — erneuter Versuch",
"MobileStreamRuntimeShutdown": "Runtime wird heruntergefahren — Verbindung wird wiederhergestellt",
Expand Down
7 changes: 7 additions & 0 deletions crates/localization/locales/en.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
{
"CmdPluginOwnerReport": "Extension host:\n State: {state}\n Live tools ({count}): {tools}",
"CmdPluginOwnerActivating": "Activating",
"CmdPluginOwnerActive": "Active",
"CmdPluginOwnerFailed": "Failed: {reason}",
"CmdPluginOwnerFaulted": "Faulted: {reason}",
"CmdPluginOwnerRevoked": "Revoked",
"CmdPluginOwnerInactive": "Not active",
"MobileStreamReplayFailed": "Runtime could not read this conversation's history — retrying",
"MobileStreamCatchUpFailed": "Runtime fell behind and could not catch up — retrying",
"MobileStreamRuntimeShutdown": "Runtime is shutting down — reconnecting",
Expand Down
7 changes: 7 additions & 0 deletions crates/localization/locales/es-419.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
{
"CmdPluginOwnerReport": "Host de extensiones:\n Estado: {state}\n Herramientas activas ({count}): {tools}",
"CmdPluginOwnerActivating": "Activando",
"CmdPluginOwnerActive": "Activo",
"CmdPluginOwnerFailed": "Falló: {reason}",
"CmdPluginOwnerFaulted": "Con errores: {reason}",
"CmdPluginOwnerRevoked": "Revocado",
"CmdPluginOwnerInactive": "Inactivo",
"MobileStreamReplayFailed": "El Runtime no pudo leer el historial de esta conversación — reintentando",
"MobileStreamCatchUpFailed": "El Runtime se atrasó y no pudo ponerse al día — reintentando",
"MobileStreamRuntimeShutdown": "El Runtime se está cerrando — reconectando",
Expand Down
7 changes: 7 additions & 0 deletions crates/localization/locales/fr.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
{
"CmdPluginOwnerReport": "Hôte des extensions :\n État : {state}\n Outils actifs ({count}) : {tools}",
"CmdPluginOwnerActivating": "Activation en cours",
"CmdPluginOwnerActive": "Actif",
"CmdPluginOwnerFailed": "Échec : {reason}",
"CmdPluginOwnerFaulted": "En défaut : {reason}",
"CmdPluginOwnerRevoked": "Révoqué",
"CmdPluginOwnerInactive": "Inactif",
"MobileStreamReplayFailed": "Le Runtime n’a pas pu lire l’historique de cette conversation — nouvelle tentative",
"MobileStreamCatchUpFailed": "Le Runtime a pris du retard et n’a pas pu le rattraper — nouvelle tentative",
"MobileStreamRuntimeShutdown": "Le Runtime est en cours d’arrêt — reconnexion",
Expand Down
7 changes: 7 additions & 0 deletions crates/localization/locales/hi.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
{
"CmdPluginOwnerReport": "एक्सटेंशन होस्ट:\n स्थिति: {state}\n सक्रिय टूल ({count}): {tools}",
"CmdPluginOwnerActivating": "सक्रिय किया जा रहा है",
"CmdPluginOwnerActive": "सक्रिय",
"CmdPluginOwnerFailed": "विफल: {reason}",
"CmdPluginOwnerFaulted": "त्रुटिग्रस्त: {reason}",
"CmdPluginOwnerRevoked": "अनुमति रद्द",
"CmdPluginOwnerInactive": "निष्क्रिय",
"MobileStreamReplayFailed": "Runtime इस बातचीत का इतिहास नहीं पढ़ सका — फिर से कोशिश हो रही है",
"MobileStreamCatchUpFailed": "Runtime पीछे रह गया और छूटी हुई घटनाएँ प्राप्त नहीं कर सका — फिर से कोशिश हो रही है",
"MobileStreamRuntimeShutdown": "Runtime बंद हो रहा है — फिर से कनेक्ट हो रहा है",
Expand Down
7 changes: 7 additions & 0 deletions crates/localization/locales/id.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
{
"CmdPluginOwnerReport": "Host ekstensi:\n Status: {state}\n Alat aktif ({count}): {tools}",
"CmdPluginOwnerActivating": "Sedang diaktifkan",
"CmdPluginOwnerActive": "Aktif",
"CmdPluginOwnerFailed": "Gagal: {reason}",
"CmdPluginOwnerFaulted": "Bermasalah: {reason}",
"CmdPluginOwnerRevoked": "Dicabut",
"CmdPluginOwnerInactive": "Tidak aktif",
"MobileStreamReplayFailed": "Runtime tidak dapat membaca riwayat percakapan ini — mencoba lagi",
"MobileStreamCatchUpFailed": "Runtime tertinggal dan tidak dapat mengejar — mencoba lagi",
"MobileStreamRuntimeShutdown": "Runtime sedang dimatikan — menghubungkan kembali",
Expand Down
7 changes: 7 additions & 0 deletions crates/localization/locales/ja.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
{
"CmdPluginOwnerReport": "拡張機能ホスト:\n 状態: {state}\n 有効なツール ({count}): {tools}",
"CmdPluginOwnerActivating": "有効化中",
"CmdPluginOwnerActive": "有効",
"CmdPluginOwnerFailed": "失敗: {reason}",
"CmdPluginOwnerFaulted": "異常: {reason}",
"CmdPluginOwnerRevoked": "許可取消済み",
"CmdPluginOwnerInactive": "無効",
"MobileStreamReplayFailed": "Runtime がこの会話の履歴を読み込めませんでした — 再試行中",
"MobileStreamCatchUpFailed": "Runtime のイベント処理が遅れ、追いつけませんでした — 再試行中",
"MobileStreamRuntimeShutdown": "Runtime は終了処理中です — 再接続中",
Expand Down
7 changes: 7 additions & 0 deletions crates/localization/locales/ko.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
{
"CmdPluginOwnerReport": "확장 호스트:\n 상태: {state}\n 활성 도구 ({count}): {tools}",
"CmdPluginOwnerActivating": "활성화 중",
"CmdPluginOwnerActive": "활성",
"CmdPluginOwnerFailed": "실패: {reason}",
"CmdPluginOwnerFaulted": "오류 발생: {reason}",
"CmdPluginOwnerRevoked": "권한 철회됨",
"CmdPluginOwnerInactive": "비활성",
"MobileStreamReplayFailed": "Runtime이 이 대화의 기록을 읽지 못했습니다 — 다시 시도 중",
"MobileStreamCatchUpFailed": "Runtime의 이벤트 처리가 지연되어 따라잡지 못했습니다 — 다시 시도 중",
"MobileStreamRuntimeShutdown": "Runtime을 종료하고 있습니다 — 다시 연결 중",
Expand Down
7 changes: 7 additions & 0 deletions crates/localization/locales/pt-BR.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
{
"CmdPluginOwnerReport": "Host de extensões:\n Estado: {state}\n Ferramentas ativas ({count}): {tools}",
"CmdPluginOwnerActivating": "Ativando",
"CmdPluginOwnerActive": "Ativo",
"CmdPluginOwnerFailed": "Falhou: {reason}",
"CmdPluginOwnerFaulted": "Com erro: {reason}",
"CmdPluginOwnerRevoked": "Revogado",
"CmdPluginOwnerInactive": "Inativo",
"MobileStreamReplayFailed": "O Runtime não conseguiu ler o histórico desta conversa — tentando novamente",
"MobileStreamCatchUpFailed": "O Runtime ficou para trás e não conseguiu recuperar os eventos — tentando novamente",
"MobileStreamRuntimeShutdown": "O Runtime está sendo encerrado — reconectando",
Expand Down
7 changes: 7 additions & 0 deletions crates/localization/locales/ru.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
{
"CmdPluginOwnerReport": "Хост расширений:\n Состояние: {state}\n Активные инструменты ({count}): {tools}",
"CmdPluginOwnerActivating": "Активация",
"CmdPluginOwnerActive": "Активен",
"CmdPluginOwnerFailed": "Сбой: {reason}",
"CmdPluginOwnerFaulted": "Неисправен: {reason}",
"CmdPluginOwnerRevoked": "Доступ отозван",
"CmdPluginOwnerInactive": "Неактивен",
"MobileStreamReplayFailed": "Runtime не удалось прочитать историю этой беседы — повторная попытка",
"MobileStreamCatchUpFailed": "Runtime отстал и не смог получить пропущенные события — повторная попытка",
"MobileStreamRuntimeShutdown": "Runtime завершает работу — переподключение",
Expand Down
7 changes: 7 additions & 0 deletions crates/localization/locales/uk.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
{
"CmdPluginOwnerReport": "Хост розширень:\n Стан: {state}\n Активні інструменти ({count}): {tools}",
"CmdPluginOwnerActivating": "Активація",
"CmdPluginOwnerActive": "Активний",
"CmdPluginOwnerFailed": "Збій: {reason}",
"CmdPluginOwnerFaulted": "Несправний: {reason}",
"CmdPluginOwnerRevoked": "Доступ відкликано",
"CmdPluginOwnerInactive": "Неактивний",
"MobileStreamReplayFailed": "Runtime не вдалося прочитати історію цієї розмови — повторна спроба",
"MobileStreamCatchUpFailed": "Runtime відстав і не зміг отримати пропущені події — повторна спроба",
"MobileStreamRuntimeShutdown": "Runtime завершує роботу — повторне підключення",
Expand Down
7 changes: 7 additions & 0 deletions crates/localization/locales/vi.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
{
"CmdPluginOwnerReport": "Máy chủ tiện ích mở rộng:\n Trạng thái: {state}\n Công cụ đang hoạt động ({count}): {tools}",
"CmdPluginOwnerActivating": "Đang kích hoạt",
"CmdPluginOwnerActive": "Đang hoạt động",
"CmdPluginOwnerFailed": "Thất bại: {reason}",
"CmdPluginOwnerFaulted": "Gặp lỗi: {reason}",
"CmdPluginOwnerRevoked": "Đã thu hồi",
"CmdPluginOwnerInactive": "Chưa hoạt động",
"MobileStreamReplayFailed": "Runtime không thể đọc lịch sử cuộc trò chuyện này — đang thử lại",
"MobileStreamCatchUpFailed": "Runtime bị chậm và không thể bắt kịp — đang thử lại",
"MobileStreamRuntimeShutdown": "Runtime đang tắt — đang kết nối lại",
Expand Down
7 changes: 7 additions & 0 deletions crates/localization/locales/zh-Hans.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
{
"CmdPluginOwnerReport": "扩展宿主:\n 状态:{state}\n 活动工具({count}):{tools}",
"CmdPluginOwnerActivating": "正在激活",
"CmdPluginOwnerActive": "已激活",
"CmdPluginOwnerFailed": "失败:{reason}",
"CmdPluginOwnerFaulted": "故障:{reason}",
"CmdPluginOwnerRevoked": "已撤销",
"CmdPluginOwnerInactive": "未激活",
"MobileStreamReplayFailed": "Runtime 无法读取此对话的历史记录 — 正在重试",
"MobileStreamCatchUpFailed": "Runtime 处理落后且无法追赶 — 正在重试",
"MobileStreamRuntimeShutdown": "Runtime 正在关闭 — 正在重新连接",
Expand Down
7 changes: 7 additions & 0 deletions crates/localization/locales/zh-Hant.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
{
"CmdPluginOwnerReport": "擴充功能主機:\n 狀態:{state}\n 活動工具({count}):{tools}",
"CmdPluginOwnerActivating": "正在啟用",
"CmdPluginOwnerActive": "已啟用",
"CmdPluginOwnerFailed": "失敗:{reason}",
"CmdPluginOwnerFaulted": "故障:{reason}",
"CmdPluginOwnerRevoked": "已撤銷",
"CmdPluginOwnerInactive": "未啟用",
"MobileStreamReplayFailed": "Runtime 無法讀取此對話的歷史記錄 — 正在重試",
"MobileStreamCatchUpFailed": "Runtime 處理落後且無法追趕 — 正在重試",
"MobileStreamRuntimeShutdown": "Runtime 正在關閉 — 正在重新連線",
Expand Down
45 changes: 45 additions & 0 deletions crates/localization/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -707,6 +707,13 @@ pub enum MessageId {
PluginSuggestionReason,
PagerActionConfirm,
CmdPluginBundleDetail,
CmdPluginOwnerReport,
CmdPluginOwnerActivating,
CmdPluginOwnerActive,
CmdPluginOwnerFailed,
CmdPluginOwnerFaulted,
CmdPluginOwnerRevoked,
CmdPluginOwnerInactive,
CmdPluginBundleDiagnosticsHeader,
CmdPluginBundleMutationSuccess,
CmdPluginActionFailed,
Expand Down Expand Up @@ -3238,6 +3245,13 @@ pub const ALL_MESSAGE_IDS: &[MessageId] = &[
MessageId::PluginSuggestionReason,
MessageId::PagerActionConfirm,
MessageId::CmdPluginBundleDetail,
MessageId::CmdPluginOwnerReport,
MessageId::CmdPluginOwnerActivating,
MessageId::CmdPluginOwnerActive,
MessageId::CmdPluginOwnerFailed,
MessageId::CmdPluginOwnerFaulted,
MessageId::CmdPluginOwnerRevoked,
MessageId::CmdPluginOwnerInactive,
MessageId::CmdPluginBundleDiagnosticsHeader,
MessageId::CmdPluginBundleMutationSuccess,
MessageId::CmdPluginActionFailed,
Expand Down Expand Up @@ -5524,6 +5538,37 @@ mod tests {
.collect()
}

#[test]
fn plugin_owner_report_keeps_translated_state_and_placeholder_parity() {
let english = raw_locale_messages(Locale::En);
let keys: Vec<_> = english
.keys()
.filter(|key| key.starts_with("CmdPluginOwner"))
.collect();
assert_eq!(keys.len(), 7);
for locale in Locale::shipped_complete() {
let pack = raw_locale_messages(*locale);
for key in &keys {
let original = english[*key].as_str().unwrap();
let translated = pack[*key].as_str().unwrap();
assert_eq!(
message_placeholders(translated),
message_placeholders(original),
"{} changed placeholders for {key}",
locale.tag()
);
if *locale != Locale::En {
assert_ne!(
translated,
original,
"{} left {key} in English",
locale.tag()
);
}
}
}
}

/// #5906: the parked-agent vocabulary is new copy on the busiest rows in
/// the product, so it gets the same hard parity gate coordination copy
/// has — and the recovery line must keep the tool tokens it names, or it
Expand Down
2 changes: 1 addition & 1 deletion crates/tui/assets/skills-catalog-matrix.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"in_model_catalogue": "true when the skill renders as an ambient catalogue line",
"shadowed_aliases": "aliases that collide with another canonical bundled name; the canonical skill wins resolution"
},
"generation": "15",
"generation": "17",
"skills": [
{
"name": "skill-creator",
Expand Down
62 changes: 62 additions & 0 deletions crates/tui/assets/skills/plugin-creator/SKILL.generation-15.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
---
name: plugin-creator
description: Scaffold a local Codewhale plugin bundle with a versioned manifest, namespaced Skills, and an explicit trust review.
---

# Plugin Creator

Use this skill when a user wants a local Codewhale plugin bundle. Trusted and
enabled bundles may add declarative Skills, commands, agents, hooks, and MCP
servers (stdio and remote) through the existing engines. LSP, native
extensions, filesystem roots, and lifecycle mutation are inventory-only.

## Workflow

1. Pick a Codewhale-owned location:
- User bundle: `~/.codewhale/plugins/<plugin-name>/`
- Workspace bundle: `<workspace>/.codewhale/plugins/<plugin-name>/`
2. Normalize the bundle name to lowercase hyphen-case.
3. Create `plugin.toml`:

```toml
schema_version = 1

[plugin]
name = "my-plugin"
version = "0.1.0"
description = "What this bundle provides"

[skills]
path = "skills"
```

4. Put each Skill under `skills/<skill-name>/SKILL.md`. Codewhale exposes it
as `my-plugin:<skill-name>`, never as an unqualified command.
5. Add `[mcp_servers.<name>]` only when the bundle needs an existing MCP
engine. Keep stdio commands and paths inside the bundle. Map local
environment values only as exact `${SOURCE_ENV}` references. For remote MCP,
use HTTPS (or loopback HTTP), forbid URL user information/query/fragment,
use only environment-backed headers or bearer tokens, and declare the exact
normalized endpoint host set in `[capabilities].network_hosts`. Never place
credentials in the manifest.
6. Commands (`commands/*.md`), agents (`agents/*.toml`), and hooks
(`hooks/*.toml`) activate under the current policy — workspace bundles win
same-name collisions over user and built-in bundles. LSP, native
extensions, filesystem roots, and lifecycle mutation are inventory-only:
declare them only when inventorying future work. A bundle that declares
only unsupported surfaces cannot be enabled.
7. Validate and review without executing bundle content:
- `/plugin validate <plugin-name>`
- `/plugin show <plugin-name>`
- `/plugin enable <plugin-name>` to open the content/capability review
- run the exact `/plugin trust ...` confirmation shown, then enable again
8. Verify `/skills inspect` reports plugin provenance and `/plugin list`
reports the expected trust and activation state. Trust stages the reviewed
content but does not activate it. After enablement, follow the host's
reload notice: use `/reload` or a new session to apply changes to a live
session's pinned skills and tools.

Every user and workspace bundle starts untrusted and disabled. Reuse the
existing `/plugin marketplace`, install, update, review and reload surfaces;
do not add a parallel installer, registry or automatic trust flow. Catalog
membership alone never installs, trusts or enables a plugin.
Loading
Loading