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
4 changes: 4 additions & 0 deletions doc/changes/unreleased.md
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
# Unreleased

## Bug Fixes

* #237: Fixed the opencode plugin in the user guide.
103 changes: 80 additions & 23 deletions doc/user_guide/integration.rst

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

General: untested code in documentation. Would it be possible to

  • extract the code into .js files
  • add a small js project with tests
  • run tests in CI
  • include code from .js files into this documentation?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree it will be better, but it's a bit tricky, especially with the second script that downloads skills from GitHub. The skills might not be there at the time CI runs. It will probably be an overkill. After all, such a script is outside the scope of this project. It's only a kind of advice or suggestion.

Original file line number Diff line number Diff line change
Expand Up @@ -53,16 +53,40 @@ automatically at the start of every session.

.. code-block:: javascript

// .opencode/plugins/install-exasol-skills.js
export default function (ctx) {
return {
"session:start": async () => {
await ctx.shell(
"exasol-install-skills --target-dir ~/.config/opencode/skills/"
);
},
};
}
import { execSync } from "node:child_process";
import { createInterface } from "node:readline";

const TARGET = `${process.env.HOME}/.config/opencode/skills`;

const pressAnyKey = () =>
new Promise((resolve) => {
if (!process.stdin.isTTY) return resolve();
const rl = createInterface({ input: process.stdin });
rl.once("line", () => {
rl.close();
resolve();
});
});

const installExasolPlugins = async () => {
console.log("[install-exasol-skills] Installing Exasol skills...");
try {
execSync(`exasol-install-skills --target-dir ${TARGET}`, {
stdio: "inherit",
});
} catch {
console.log(
"[install-exasol-skills] Failed to install skills.",
);
Comment on lines +78 to +80

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also log stdout & stderr of the executed tool to simplify debugging.

console.log(
"[install-exasol-skills] Press any key to continue loading opencode...",
);
await pressAnyKey();
}
return {};
};

export default installExasolPlugins;

**Option B — fetch directly from GitHub** (no Python required):

Expand All @@ -72,7 +96,7 @@ can download them with a plain ``fetch`` call — no additional tools needed.

.. code-block:: javascript

// .opencode/plugins/install-exasol-skills.js
import { createInterface } from "node:readline";
import { mkdirSync, writeFileSync } from "node:fs";

const SKILLS = [
Expand All @@ -89,19 +113,52 @@ can download them with a plain ``fetch`` call — no additional tools needed.
"/exasol/ai/mcp/server/skills";
const TARGET = `${process.env.HOME}/.config/opencode/skills`;

export default function (_ctx) {
return {
"session:start": async () => {
for (const skill of SKILLS) {
const res = await fetch(`${BASE_URL}/${skill}/SKILL.md`);
if (res.ok) {
mkdirSync(`${TARGET}/${skill}`, { recursive: true });
writeFileSync(`${TARGET}/${skill}/SKILL.md`, await res.text());
}
const pressAnyKey = () =>
new Promise((resolve) => {
if (!process.stdin.isTTY) return resolve();
const rl = createInterface({ input: process.stdin });
rl.once("line", () => {
rl.close();
resolve();
});
});

const downloadSkills = async () => {
let failed = false;
console.log("[install-exasol-skills] Installing Exasol skills...");
mkdirSync(TARGET, { recursive: true });
for (const skill of SKILLS) {
try {
const url = `${BASE_URL}/${skill}/SKILL.md`;
console.log(`[install-exasol-skills] fetching ${skill}...`);
const res = await fetch(url);
if (res.ok) {
const text = await res.text();
mkdirSync(`${TARGET}/${skill}`, { recursive: true });
writeFileSync(`${TARGET}/${skill}/SKILL.md`, text);
console.log(`[install-exasol-skills] ✓ ${skill} installed`);
} else {
failed = true;
console.warn(`[install-exasol-skills] ✗ ${skill} skipped (HTTP ${res.status})`);
}
},
};
}
} catch (err) {
failed = true;
console.error(`[install-exasol-skills] ✗ ${skill} failed:`, err);
}
}
if (failed) {
console.log("[install-exasol-skills] One or more skills failed to install.");
console.log("[install-exasol-skills] Press any key to continue loading opencode...");
await pressAnyKey();
}
};

const installExasolPlugins = async () => {
await downloadSkills();
return {};
};

export default installExasolPlugins;

To pin to a specific release instead of ``main``, replace ``main`` in ``BASE_URL``
with the desired tag, e.g. ``refs/tags/1.9.0``.