Skip to content
Closed
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
35 changes: 33 additions & 2 deletions docs-site/src/content/docs/guides/integrations.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
---
title: Integrations
description: Connect opencodex to OpenCode, Pi, OMP, Hermes, OpenClaw, Kimi Code, gjc, DeepSeek Harness, MiniMax Code, ZCode, Prime Agent, Aside, Raycast, omo, Cline CLI, Kilo, Command Code and Factory Droid from the dashboard — one switch per client, with a backup taken before every write.
description: Connect opencodex to OpenCode, Pi, Gentle Shell, OMP, Hermes, OpenClaw, Kimi Code, gjc, DeepSeek Harness, MiniMax Code, ZCode, Prime Agent, Aside, Raycast, omo, Cline CLI, Kilo, Command Code and Factory Droid from the dashboard — one switch per client, with a backup taken before every write.
---

The **Connect** page writes opencodex's provider block into a client's own config
file, and removes it again. Nineteen clients work this way, each with a switch:
file, and removes it again. Twenty clients work this way, each with a switch:

| Client | Config file | Format | When the change takes effect | Credential |
|---|---|---|---|---|
| OpenCode | `~/.config/opencode/opencode.json` | JSON | next direct launch | `OPENCODEX_OPENCODE_API_KEY` |
| Pi | `~/.pi/agent/models.json` | JSON | new sessions | loopback placeholder |
| Gentle Shell | `~/.gentle-shell/agent/models.json` (persistent selected home) | JSON | after restarting Gentle Shell | loopback placeholder |
| OMP | `~/.omp/agent/models.yml` | YAML | after restarting OMP | `opencodex-loopback` placeholder |
| Hermes | `~/.hermes/config.yaml` | YAML | new sessions | `OPENCODEX_HERMES_API_KEY` |
| OpenClaw | `~/.openclaw/openclaw.json` | JSON5 | immediately, on a running gateway | `OPENCODEX_OPENCLAW_API_KEY` |
Expand All @@ -28,6 +29,36 @@ file, and removes it again. Nineteen clients work this way, each with a switch:
| Command Code | `~/.commandcode/providers.json` (on Windows with the default home: use `HOME ?? USERPROFILE` only if nonblank and Windows-absolute, otherwise `homedir()`; a separately supplied home is preserved; append `.commandcode\providers.json`) | JSON | next launch of Command Code | none — keyless loopback (`apiKey: false`) |
| Factory Droid | `~/.factory/settings.json` (`%USERPROFILE%\.factory\settings.json` on Windows) | JSON | immediately via file watching | none — keyless loopback |

## Gentle Shell

Choose **Connect → Gentle Shell**, or use the same managed-integration commands:

```bash
ocx export --client gentle-shell --json
ocx integration client enable --client gentle-shell
ocx integration client disable --client gentle-shell
```

Gentle Shell has a separate destination and rollback history from Pi. Only
`providers.opencodex` is managed; other providers and preferences stay intact.
Catalog changes refresh an already connected, unchanged block. An existing manually
copied block is a conflict, not permission to overwrite it: inspect the preview and
use the explicit overwrite confirmation only if you intend to replace it.

The saved `home` in `~/.gentle-shell/config.json` selects the destination. A saved
custom path wins; isolated/default mode uses `GENTLE_SHELL_HOME` or
`~/.gentle-shell/agent`. `GENTLE_SHELL_CONFIG` selects an alternate launcher config.
These environment variables must be set on the **OpenCodex process**, not just in a
later shell. Selectors must be absolute paths; literal `~` and relative paths refuse.
One-off `gentle-shell --home` flags cannot be discovered by a background proxy.

Link mode or a home aliasing Pi refuses with a Pi-integration remedy; use **Connect → Pi**
for that shared file instead. OpenCodex does not change launcher preferences. An
unreadable/unsafe launcher config refuses; malformed JSON falls back to isolated,
matching the launcher. If you move a connected home, disable it using its original
selectors before reconnecting the new one. Restart Gentle Shell after a catalog update.
This integration retains Pi’s loopback-only export policy and stores no real API key.

"omo" names three products that share the `~/.omo` folder. The **omo** tab manages Pi-based omo
(the senpi engine) through `~/.omo/agent/models.json`, as in the table above. Codex-based omo
(LazyCodex) gets its own section on the same tab, shown only when LazyCodex is detected, described in
Expand Down
1 change: 1 addition & 0 deletions gui/src/app-routing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ export const INTEGRATION_TAB_HASHES = [
"integrations/cursor",
"integrations/opencode",
"integrations/pi",
"integrations/gentle-shell",
"integrations/omp",
"integrations/hermes",
"integrations/openclaw",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@
* with EXPORT_CLIENT_IDS by hand; adding a client server-side renders no row
* until this tuple changes.
*/
export const CLIENTS = ["qoder", "opencode", "pi", "omp", "hermes", "openclaw", "kimi", "gajae", "dsh", "mcode", "zcode", "commandcode", "prime", "aside", "raycast", "omo", "cline", "kilo", "droid"] as const;
export const CLIENTS = ["qoder", "opencode", "pi", "omp", "hermes", "openclaw", "kimi", "gajae", "dsh", "mcode", "zcode", "commandcode", "prime", "aside", "raycast", "omo", "cline", "kilo", "droid", "gentle-shell"] as const;
export type ExportClientId = (typeof CLIENTS)[number];

export const CLIENT_LABEL_KEYS = {
qoder: "api.clientConfig.clientQoder",
opencode: "api.clientConfig.clientOpencode",
pi: "api.clientConfig.clientPi",
"gentle-shell": "integrations.tab.gentleShell",
omp: "api.clientConfig.clientOmp",
hermes: "api.clientConfig.clientHermes",
openclaw: "api.clientConfig.clientOpenclaw",
Expand Down
2 changes: 2 additions & 0 deletions gui/src/components/integration-marks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ export const INTEGRATION_MARKS: Record<OverviewClientId, string | null> = {
...NATIVE_MARKS,
opencode: CLIENT_MARKS.opencode ?? null,
pi: CLIENT_MARKS.pi ?? null,
// No verified square Gentle Shell asset: use its own monogram, not Pi\'s mark.
"gentle-shell": null,
omp: CLIENT_MARKS.omp ?? null,
hermes: CLIENT_MARKS.hermes ?? null,
openclaw: CLIENT_MARKS.openclaw ?? null,
Expand Down
2 changes: 2 additions & 0 deletions gui/src/i18n/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1558,6 +1558,8 @@ export const de: Record<TKey, string> = {
"integrations.tab.grok": "Grok Build",
"integrations.tab.opencode": "OpenCode",
"integrations.tab.pi": "Pi",
"integrations.tab.gentleShell": "Gentle Shell",
"integrations.semantics.gentleShell": "Gentle Shell neu starten, um den Katalog im gespeicherten Verzeichnis zu laden. Für Link-/gemeinsame Verzeichnisse die Pi-Integration verwenden.",
"integrations.tab.omp": "OMP",
"integrations.tab.hermes": "Hermes",
"integrations.tab.openclaw": "OpenClaw",
Expand Down
2 changes: 2 additions & 0 deletions gui/src/i18n/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2124,6 +2124,8 @@ export const en = {
"integrations.tab.cursor": "Cursor",
"integrations.tab.opencode": "OpenCode",
"integrations.tab.pi": "Pi",
"integrations.tab.gentleShell": "Gentle Shell",
"integrations.semantics.gentleShell": "Restart Gentle Shell to load the catalog in its saved home. Link/shared homes use the Pi integration.",
"integrations.tab.omp": "OMP",
"integrations.tab.hermes": "Hermes",
"integrations.tab.openclaw": "OpenClaw",
Expand Down
2 changes: 2 additions & 0 deletions gui/src/i18n/fr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2096,6 +2096,8 @@ export const fr: Record<TKey, string> = {
"integrations.tab.grok": "Grok Build",
"integrations.tab.opencode": "OpenCode",
"integrations.tab.pi": "Pi",
"integrations.tab.gentleShell": "Gentle Shell",
"integrations.semantics.gentleShell": "Redémarrez Gentle Shell pour charger le catalogue du répertoire enregistré. Pour un répertoire lié ou partagé, utilisez l’intégration Pi.",
"integrations.tab.omp": "OMP",
"integrations.tab.hermes": "Hermes",
"integrations.tab.openclaw": "OpenClaw",
Expand Down
2 changes: 2 additions & 0 deletions gui/src/i18n/ja.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1991,6 +1991,8 @@ export const ja: Record<TKey, string> = {
"integrations.tab.grok": "Grok Build",
"integrations.tab.opencode": "OpenCode",
"integrations.tab.pi": "Pi",
"integrations.tab.gentleShell": "Gentle Shell",
"integrations.semantics.gentleShell": "Gentle Shell を再起動すると保存済みホームのカタログが読み込まれます。リンク/共有ホームには Pi 連携を使用してください。",
"integrations.tab.omp": "OMP",
"integrations.tab.hermes": "Hermes",
"integrations.tab.openclaw": "OpenClaw",
Expand Down
2 changes: 2 additions & 0 deletions gui/src/i18n/ko.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1602,6 +1602,8 @@ export const ko: Record<TKey, string> = {
"integrations.tab.grok": "Grok Build",
"integrations.tab.opencode": "OpenCode",
"integrations.tab.pi": "Pi",
"integrations.tab.gentleShell": "Gentle Shell",
"integrations.semantics.gentleShell": "저장된 홈의 카탈로그를 불러오려면 Gentle Shell을 재시작하세요. 연결/공유 홈은 Pi 연동을 사용하세요.",
"integrations.tab.omp": "OMP",
"integrations.tab.hermes": "Hermes",
"integrations.tab.openclaw": "OpenClaw",
Expand Down
2 changes: 2 additions & 0 deletions gui/src/i18n/pt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2108,6 +2108,8 @@ export const pt: Record<TKey, string> = {
"integrations.tab.cursor": "Cursor",
"integrations.tab.opencode": "OpenCode",
"integrations.tab.pi": "Pi",
"integrations.tab.gentleShell": "Gentle Shell",
"integrations.semantics.gentleShell": "Reinicie o Gentle Shell para carregar o catálogo no diretório salvo. Para diretórios vinculados ou compartilhados, use a integração Pi.",
"integrations.tab.omp": "OMP",
"integrations.tab.hermes": "Hermes",
"integrations.tab.openclaw": "OpenClaw",
Expand Down
2 changes: 2 additions & 0 deletions gui/src/i18n/ru.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2082,6 +2082,8 @@ export const ru: Record<TKey, string> = {
"integrations.tab.grok": "Grok Build",
"integrations.tab.opencode": "OpenCode",
"integrations.tab.pi": "Pi",
"integrations.tab.gentleShell": "Gentle Shell",
"integrations.semantics.gentleShell": "Перезапустите Gentle Shell для загрузки каталога из сохранённого каталога. Для связанных или общих каталогов используйте интеграцию Pi.",
"integrations.tab.omp": "OMP",
"integrations.tab.hermes": "Hermes",
"integrations.tab.openclaw": "OpenClaw",
Expand Down
2 changes: 2 additions & 0 deletions gui/src/i18n/tr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2109,6 +2109,8 @@ export const tr: Record<TKey, string> = {
"integrations.tab.grok": "Grok Build",
"integrations.tab.opencode": "OpenCode",
"integrations.tab.pi": "Pi",
"integrations.tab.gentleShell": "Gentle Shell",
"integrations.semantics.gentleShell": "Kayıtlı ana dizindeki kataloğu yüklemek için Gentle Shell’i yeniden başlatın. Bağlı/ortak dizinler için Pi entegrasyonunu kullanın.",
"integrations.tab.omp": "OMP",
"integrations.tab.hermes": "Hermes",
"integrations.tab.openclaw": "OpenClaw",
Expand Down
2 changes: 2 additions & 0 deletions gui/src/i18n/vi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2072,6 +2072,8 @@ export const vi: Record<TKey, string> = {
"integrations.tab.cursor": "Cursor",
"integrations.tab.opencode": "OpenCode",
"integrations.tab.pi": "Pi",
"integrations.tab.gentleShell": "Gentle Shell",
"integrations.semantics.gentleShell": "Khởi động lại Gentle Shell để tải danh mục trong thư mục đã lưu. Với thư mục liên kết/dùng chung, hãy dùng tích hợp Pi.",
"integrations.tab.omp": "OMP",
"integrations.tab.hermes": "Hermes",
"integrations.tab.openclaw": "OpenClaw",
Expand Down
2 changes: 2 additions & 0 deletions gui/src/i18n/zh-TW.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3018,6 +3018,8 @@ export const zhTW: Record<TKey, string> = {
"integrations.tab.grok": "Grok Build",
"integrations.tab.opencode": "OpenCode",
"integrations.tab.pi": "Pi",
"integrations.tab.gentleShell": "Gentle Shell",
"integrations.semantics.gentleShell": "重新啟動 Gentle Shell 以載入已儲存目錄中的模型清單。連結或共用目錄請使用 Pi 整合。",
"integrations.tab.omp": "OMP",
"integrations.tab.hermes": "Hermes",
"integrations.tab.openclaw": "OpenClaw",
Expand Down
2 changes: 2 additions & 0 deletions gui/src/i18n/zh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1575,6 +1575,8 @@ export const zh: Record<TKey, string> = {
"integrations.tab.grok": "Grok Build",
"integrations.tab.opencode": "OpenCode",
"integrations.tab.pi": "Pi",
"integrations.tab.gentleShell": "Gentle Shell",
"integrations.semantics.gentleShell": "重启 Gentle Shell 以加载已保存目录中的模型目录。链接或共享目录请使用 Pi 集成。",
"integrations.tab.omp": "OMP",
"integrations.tab.hermes": "Hermes",
"integrations.tab.openclaw": "OpenClaw",
Expand Down
2 changes: 2 additions & 0 deletions gui/src/pages/integrations/FileIntegrationPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ const DISABLE_COPY: ConsequenceCopy = {
const SEMANTICS_KEY: Record<FileIntegrationClientId, TKey> = {
opencode: "integrations.semantics.opencode",
pi: "integrations.semantics.pi",
"gentle-shell": "integrations.semantics.gentleShell",
omp: "integrations.semantics.omp",
hermes: "integrations.semantics.hermes",
openclaw: "integrations.semantics.openclaw",
Expand All @@ -94,6 +95,7 @@ const SEMANTICS_KEY: Record<FileIntegrationClientId, TKey> = {
const TAB_LABEL_KEY: Record<FileIntegrationClientId, TKey> = {
opencode: "integrations.tab.opencode",
pi: "integrations.tab.pi",
"gentle-shell": "integrations.tab.gentleShell",
omp: "integrations.tab.omp",
hermes: "integrations.tab.hermes",
openclaw: "integrations.tab.openclaw",
Expand Down
1 change: 1 addition & 0 deletions gui/src/pages/integrations/integration-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export const FILE_INTEGRATION_CLIENTS = [
"cline",
"kilo",
"droid",
"gentle-shell",
] as const;

export type FileIntegrationClientId = (typeof FILE_INTEGRATION_CLIENTS)[number];
Expand Down
2 changes: 2 additions & 0 deletions gui/src/pages/integrations/integration-tabs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export const TABS: readonly TabDefinition[] = [
{ id: "cursor", hash: "integrations/cursor", labelKey: "integrations.tab.cursor" },
{ id: "opencode", hash: "integrations/opencode", labelKey: "integrations.tab.opencode" },
{ id: "pi", hash: "integrations/pi", labelKey: "integrations.tab.pi" },
{ id: "gentle-shell", hash: "integrations/gentle-shell", labelKey: "integrations.tab.gentleShell" },
{ id: "omp", hash: "integrations/omp", labelKey: "integrations.tab.omp" },
{ id: "hermes", hash: "integrations/hermes", labelKey: "integrations.tab.hermes" },
{ id: "openclaw", hash: "integrations/openclaw", labelKey: "integrations.tab.openclaw" },
Expand All @@ -62,6 +63,7 @@ export const TABS: readonly TabDefinition[] = [
export const FILE_CLIENTS = new Set<FileIntegrationClientId>([
"opencode",
"pi",
"gentle-shell",
"omp",
"hermes",
"openclaw",
Expand Down
1 change: 1 addition & 0 deletions gui/src/pages/integrations/overview-clients.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ export interface OverviewSources {
const FILE_LABEL_KEY: Record<FileIntegrationClientId, TKey> = {
opencode: "integrations.tab.opencode",
pi: "integrations.tab.pi",
"gentle-shell": "integrations.tab.gentleShell",
omp: "integrations.tab.omp",
hermes: "integrations.tab.hermes",
openclaw: "integrations.tab.openclaw",
Expand Down
6 changes: 3 additions & 3 deletions gui/tests/integration-marks.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,15 @@ test("every Integrations row has a mark that resolves to a committed file", () =

/*
* A null value is a legitimate answer -- it renders a monogram -- but none of the
* current rows should be taking it. If one does, either an asset was dropped or a
* existing rows should be taking it, except Gentle Shell (no verified square asset). If one does, either an asset was dropped or a
* client was added without a mark decision, and both look like a rendering bug
* from the outside.
*/
test("no Integrations row falls back to a monogram today", () => {
test("only Gentle Shell deliberately falls back to its own monogram", () => {
const monogram = Object.entries(INTEGRATION_MARKS)
.filter(([, src]) => src === null)
.map(([id]) => id);
expect(monogram).toEqual([]);
expect(monogram).toEqual(["gentle-shell"]);
});

/*
Expand Down
5 changes: 5 additions & 0 deletions gui/tests/integrations-tab-coverage.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ test("every tab hash is routable, so a tab can actually be reached", () => {
expect(unroutable.map(tab => tab.hash)).toEqual([]);
});

test("Gentle Shell has a separate routable Connect tab", () => {
expect(TABS.find(tab => (tab.id as string) === "gentle-shell")?.hash).toBe("integrations/gentle-shell");
expect(resolveAppHashChange("integrations/pi").replaceTo).toBeNull();
});

test("FILE_CLIENTS carries no id the API does not know", () => {
const known = new Set<string>(FILE_INTEGRATION_CLIENTS);
expect([...FILE_CLIENTS].filter(id => !known.has(id))).toEqual([]);
Expand Down
2 changes: 2 additions & 0 deletions scripts/test-layout/layout-clients.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
{
"gentle-shell-path.test.ts": "clients",
"gentle-shell-client.test.ts": "clients",
"droid-managed-reasoning-defaults.test.ts": "clients",
"droid-normalized-reasoning-defaults.test.ts": "clients",
"desktop-app-server-shim.test.ts": "clients",
Expand Down
2 changes: 1 addition & 1 deletion src/cli/help.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ Usage:
ocx api-key <sub> Alias of ocx access key
ocx access <sub> External API keys and endpoint information
ocx api <sub> Protocol paths: vocabulary, request-path preview, and policy
ocx export --client <id> Print a client config wired to the running proxy (19 clients)
ocx export --client <id> Print a client config wired to the running proxy (20 clients)
ocx integration client <sub> Enable, disable, inspect or roll back a client integration
ocx grok <sub> Grok Build model selection and apply
ocx system <sub> Runtime settings, startup, sync, OpenCodex updates, and Codex CLI inspection
Expand Down
1 change: 1 addition & 0 deletions src/cli/integration-plan-dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export const FILE_INTEGRATION_CLIENTS = [
"kilo",
"droid",
"qoder",
"gentle-shell",
] as const;

export const INTEGRATION_REFUSAL_REASONS: ReadonlySet<string> = new Set<IntegrationRefusalReason>([
Expand Down
5 changes: 3 additions & 2 deletions src/cli/registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -488,13 +488,14 @@ export const CLI_COMMANDS: CliCommandEntry[] = [
},
{
name: "export",
usage: "ocx export --client <qoder|opencode|pi|omp|hermes|openclaw|kimi|gajae|dsh|mcode|zcode|commandcode|prime|aside|raycast|omo|cline|kilo|droid> [--json] [--out <path>] [--force]",
summary: "Print a client config (OpenCode, Pi, OMP, Hermes, OpenClaw, Kimi Code, gjc, DeepSeek Harness, MiniMax Code, ZCode, Command Code, Prime Agent, Aside, Raycast, omo, Cline, Kilo, Factory Droid, Qoder) wired to the running proxy.",
usage: "ocx export --client <qoder|opencode|pi|omp|hermes|openclaw|kimi|gajae|dsh|mcode|zcode|commandcode|prime|aside|raycast|omo|cline|kilo|droid|gentle-shell> [--json] [--out <path>] [--force]",
summary: "Print a client config (OpenCode, Pi, OMP, Hermes, OpenClaw, Kimi Code, gjc, DeepSeek Harness, MiniMax Code, ZCode, Command Code, Prime Agent, Aside, Raycast, omo, Cline, Kilo, Factory Droid, Qoder, Gentle Shell) wired to the running proxy.",
details: [
"--json prints the generated document as JSON on stdout; use --out for the client's native format.",
"--out <path> writes the native config there and refuses to replace an existing file without --force.",
"Cline exports a two-document bundle: settings for providers.json and catalog for sibling models.json. Use integration client enable --client cline for a journaled write.",
"Droid exports documented customModels for settings.json; use integration client enable --client droid for a journaled write.",
"Gentle Shell uses its persistent selected home; use integration client enable --client gentle-shell for a journaled write, or Pi for link/shared homes.",
"The config never contains a real key; it carries a documented env reference or a non-secret loopback placeholder.",
"The destination path is printed for merging by hand — ocx never writes your real client config.",
],
Expand Down
16 changes: 16 additions & 0 deletions src/clients/config-export.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
* targeting it is the caller's explicit act.
*/
import { homedir } from "node:os";
import { gentleShellPaths } from "./gentle-shell-path";
import { existsSync, lstatSync, readFileSync, realpathSync, statSync } from "node:fs";
import { basename, dirname, isAbsolute, join, resolve, win32 } from "node:path";
import { shouldInjectApiAuthHeader, standaloneCodexRoutingTarget } from "../codex/inject";
Expand Down Expand Up @@ -1711,6 +1712,21 @@ export const EXPORT_CLIENTS: Record<ExportClientId, ExportClientSpec> = {
buildContribution: buildDroidContribution,
loopbackOnly: true,
},
"gentle-shell": {
id: "gentle-shell",
filename: "gentle-shell-models.json",
destination: env => gentleShellPaths(env).configPath,
apiKeyEnv: "",
exportHint: "Gentle Shell uses its persistent selected home; restart the shell to load the catalog. Link/shared homes use the Pi integration.",
build: ctx => buildPiClientConfig(ctx, PI_EXPORT_OPTIONS),
format: "json",
summarize: summarizePi,
buildContribution: ctx => {
const doc = buildPiClientConfig(ctx, PI_EXPORT_OPTIONS);
return singleFragment("gentle-shell", ["providers", OPENCODE_PROVIDER_ID], doc.providers[OPENCODE_PROVIDER_ID]);
},
loopbackOnly: true,
},
};

export const EXPORT_CLIENT_IDS: readonly ExportClientId[] = Object.keys(EXPORT_CLIENTS) as ExportClientId[];
Expand Down
3 changes: 2 additions & 1 deletion src/clients/config-export/contracts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,8 @@ export type ExportClientId =
| "cline"
| "commandcode"
| "kilo"
| "droid";
| "droid"
| "gentle-shell";

export interface ExportClientSpec {
id: ExportClientId;
Expand Down
Loading
Loading