Skip to content

Joule Work Desktop plugin #222

Description

@dhague

Destination

Make the wiki-knowledge plugin's retrieval and ingestion reachable from SAP Joule Work Desktop, published as an AI Skills Library plugin: a host-neutral retrieval SKILL.md + ingestion SKILL.md that teach the Joule host model to invoke the existing enchiridion script layer directly — the esbuild-bundled .cjs + .wasm pair shipped as skill supporting files under scripts/ and run by the already-installed node interpreter on the vault machine (ADR-0017's distribution shape). No hosted MCP server, no streamable-HTTP Connector URL: Joule Desktop grants the skill sandbox read+execute on installed skill directories, so the skill shells out to the bundled pair in place — local exec, not outbound network, so it clears the "custom skills run without outbound network" constraint. Coding-assistant hosts (Claude Code/OpenCode) keep calling enchiridion directly exactly as they do today.

The one unverified premise of this route (EAC-gated, untestable from here): that a Joule Work Desktop–imported skill can actually exec a local scripts/ script as a subprocess. ADR-0017 states Joule Desktop "grants sandbox read+execute on installed skill directories at runtime" (via skill-creator's scripts/ convention), which is the basis for direct exec; if testing inside the EAC falsifies it, the fallback is the #219 thin-MCP-server-over-HTTP architecture this map has re-charted away from. The deciding unknown stays in Not yet specified, not on the route.

Notes

  • Domain: wiki-plugin, wiki-conventions (the contract the ported skills must stay aligned to), enchiridion-ts (the TypeScript script layer the skills shell out to), ADR-0017 (the .cjs/.wasm distribution shape — no binary, no lazy-fetch, node is the prerequisite), ADR-0001 (the "no MCP server" rule, which the direct-exec route never trips — it needs no MCP server at all), ADR-0002 (FTS-first retrieval, no embeddings), ADR-0015 (search index = view of committed HEAD).
  • Skills to consult: wiki-conventions (preloaded contract), wiki-retrieval/wiki-researcher (the retrieval strategy prose to port), wiki-ingest (the IngestPlan authoring contract to port).
  • Delivery vehicle: the AI Skills Library (skills.cloud.sap, bring-your-own-repo, Community trust level, Register-a-New-Skill review). Joule Work / Joule Work Desktop are EAC-only, not GA.
  • Standing decisions (from charting): retrieval + ingestion in scope; ingestion at full IngestPlan contract; direct script exec — the skill invokes the bundled enchiridion subcommands (search, read-page, superseded-by, search --status, discover, ingest, ingest-scan) via scripts/, no MCP layer and no hosted server; two skills, each carrying its own copy of the bundled pair under skills/<slug>/scripts/ (per Ship the .cjs/.wasm pair as Joule skill scripts/ (direct exec) #225 — Joule installs individual skills, not plugins, so the pair is duplicated per skill rather than shared); Cowork deferred (fog); Proper OpenCode install without cloning (npm-based, possibly skills.sh-aligned) #218 npm-OpenCode-install out of scope.
  • Re-chart note (2026-08-21, post-MCP server for the Joule Work Desktop plugin (thin) #219/Research how to create a Joule Work Desktop plugin #220): the earlier route wrapped the then-Go binary in a thin MCP server behind a streamable-HTTP URL, on the finding that JWD could not reach a bundled binary. That premise is retired with the Go binary itself (ADR-0017): there is no binary to distribute, and the .cjs/.wasm pair ships inside the skill's scripts/ dir, so the MCP-connector hop is unnecessary unless EAC testing falsifies local exec.
  • Terminology watch: 'plugin' here is the AI Skills Library bundle (skills + bundled pair), distinct from the Claude Code plugin (.claude-plugin/plugin.json). Don't conflate.

Decisions so far

  • Research how to create a Joule Work Desktop plugin — skills-first: skills/<slug>/SKILL.md (name + trigger-rich description); JWD consumes MCP as HTTP Connectors (pasted URL) — a finding that shaped the old hosted-server route, now moot under direct script exec; Agentic Thinking gives the host multi-step tool use; no install path carries config; plugin registration = public repo → Register-a-New-Skill issue → Community trust; EAC-gated, not GA. Corrects a premise: no install path carries config, and custom skills run sandboxed without outbound network — which is exactly why local script exec (not outbound network) is the viable route. Findings: docs/research/joule-work-desktop-plugin.md on branch research/joule-work-desktop.
  • MCP server for the Joule Work Desktop plugin (thin) — designed a thin enchiridion mcp serve subcommand with 7 plain tools (search, read_page, superseded_by, search_status, discover, ingest, ingest_scan) over streamable-HTTP/stdio, vault root --vault > $WIKI_ROOT > marker-walk > cwd. Partially superseded by the direct-exec re-chart: the MCP server + transport half is dropped (no server, no HTTP Connector) — the host calls the bundled enchiridion subcommands directly; what survives is the tool/subcommand surface (read_page as a needed read-a-page-by-ref subcommand) and the vault-root order.
  • Ship the .cjs/.wasm pair as Joule skill scripts/ (direct exec) — pair ships per-skill at skills/<slug>/scripts/ as enchiridion.cjs + node-sqlite3-wasm.wasm (.cjs renamed at JWD copy time, not in build.mjs/Cut v0.9.0: package the TypeScript artifacts inside the plugin #283; .wasm keeps its hardcoded name — renaming it needs a locateFile override, not worth it); the Joule host execs node scripts/enchiridion.cjs … directly (no shim, no MCP). Real subcommand spellings are hyphenated (superseded-by, ingest-scan, search --status). read-page <ref> must be built — a top-level subcommand that resolves vault root and prints a page's full content by ref (JWD host has no Read tool); library primitives exist, wiring + tests only. Vault root defaults to the working directory (ADR-0004 cwd fallback, no change); a different directory is conveyed via $WIKI_ROOT=<dir> inline — no --vault flag built. Bundle confirmed self-contained (inlines everything but node:*; .wasm co-located). Failure mode: nothing in the skill — Joule ships node, errors surface via Joule. Reverses "one bundled pair per plugin": Joule installs skills, not plugins, so the pair is duplicated per skill.
  • Draft the host-neutral retrieval SKILL.md for the Joule plugindrafted the host-neutral retrieval SKILL.md (temp/joule-retrieval-draft/SKILL.md in this repo, build-time source artifact): removes the wiki-researcher delegation — the Joule host model is the executor and holds the conversation; all calls are node <scripts>/enchiridion.cjs search|read-page|superseded-by|ingest … (no mcp__*, no network); read-page <page_ref> (built Add a read-page subcommand to enchiridion (read a page by vault-relative ref) #320) replaces the missing Read tool. Save = direct write after explicit yes (host can ask the user, so the save-candidate → outer-session-confirms indirection collapses; the "silence isn't yes" gate is preserved). Frontmatter uses the AI Skills Library schema (name/description + compatibility node prerequisite, metadata.author, license). Contract held intact: expansion → FTS5 → frontmatter-first → budget-bounded edges → superseded-by → volatility framing → no recency re-rank → provenance mode. Inline "Typed edges (contract summary)" fallback kept (Joule installs skills individually, so wiki-conventions may not be co-installed). Slug + Joule build-time folder + scripts/ assembly deferred to Follow-on: Joule Desktop scripts/ packaging #294; ingestion-side port → Ingestion plan-authoring contract on Joule (full contract) #224.
  • Ingestion plan-authoring contract on Joule (full contract) — full single-file wiki-ingest procedure ports (read artifact + INGESTION.md hint → semantic-chunk → discover --plan - dedup → finish plan → ingest --plan - → manifest); plan fed over stdin, no temp file; artifact must already sit inside the vault (read-page is the only read; non-text artifacts read by the host's own extraction, else ask the user); inline condensed wiki-conventions contract; single raw artifact per plan; full contract + structural backstop + rerun-after-fix (no rollback); seed a non-git vault on ingest failure after asking the user (init --mode dedicated), with the existing-wiki-without-git conversion as a first-class case — a script-layer change (git-aware isVault + conditional addPaths + gitignore rules for log.md/index.md/_index.md). Both surfaces graduated: Draft the host-neutral ingestion SKILL.md for the Joule plugin (prototype) and Seed a vault from an existing wiki/ tree (git-aware isVault) (task).
  • Add a read-page subcommand to enchiridion (read a page by vault-relative ref) — built and merged (Add read-page subcommand to read a page by vault-relative ref (#320) #321): enchiridion read-page <ref> resolves vault root (ADR-0004 order), prints full page content to stdout. Wiring + tests only, no new library primitives. Needed because the Joule host model has no Read tool.
  • Draft the host-neutral ingestion SKILL.md for the Joule plugindrafted host-neutral ingestion SKILL.md (temp/joule-ingest-draft/SKILL.md); full IngestPlan contract; plan over stdin (discover --plan - / ingest --plan -); Joule host model is the executor; non-text artifacts handled by host extraction or user; seeding path (init --mode dedicated) covers empty-folder and existing-wiki-without-git cases; inline wiki-conventions contract. AI Skills Library frontmatter (name/description + compatibility, metadata.author, license).
  • Seed a vault from an existing wiki/ tree (git-aware isVault) — built and merged (feat: seed a vault from an existing wiki/ tree (git-aware isVault) (#323) #324): enchiridion init <dir> now handles a dir with an existing wiki/ tree but no git repo — git init + stage + conditional addPaths + .gitignore rules for log.md/index.md/_index.md. isVault made git-aware so init no longer refuses a non-git vault.
  • Where does the Joule plugin live — enchiridion repo or dedicated repo? — root skills/wiki-retrieval/ and skills/wiki-ingest/ at enchiridion repo root; SKILL.md committed, scripts/ bundle copies CI-generated by tag-release.yml; same slugs as Claude Code (wiki-retrieval/wiki-ingest) — separate install mechanisms, no collision. Unblocks Assemble the Joule plugin files (Assemble the Joule plugin files in source control #343).
  • Assemble the Joule plugin files in source controlskills/wiki-retrieval/SKILL.md and skills/wiki-ingest/SKILL.md authored and committed; scripts/ dirs seeded with current bundle (enchiridion.cjs + node-sqlite3-wasm.wasm); tag-release.yml wired to rebuild and commit bundle on each plugin.json version bump (CI path requires PAT bypass; fallback documented in CLAUDE.md). PR: feat: assemble Joule plugin files in source control (#343) #348.
  • Obtain EAC tenant + Joule Desktop build to test local script execdirect exec confirmed: Joule Desktop can run enchiridion successfully. Alternate install path discovered: per-skill ZIP (SKILL.md + scripts/ at ZIP root) deployed to joule-desktop/<skill-name>.zip — build wiring outstanding.

Not yet specified

Out of scope

  • Hosted streamable-HTTP MCP server for Joule — the old MCP server for the Joule Work Desktop plugin (thin) #219 route's transport half; re-charted away in favour of direct script exec unless EAC falsifies it. Not a step on the route as currently drawn.
  • Proper OpenCode install without cloning (Proper OpenCode install without cloning (npm-based, possibly skills.sh-aligned) #218) — OpenCode distribution, not a step on the route to Joule; stays open in the tracker as its own effort.
  • Ingestion UX beyond the full contract — no degraded plan-less ingest path (Q6).
  • Bundling an MCP server into wiki-knowledge's plugin.json — ADR-0001 keeps it a separate component; the direct-exec route needs no server at all.
  • MCP prompts/resources carrying the retrieval strategy — strategy lives in SKILL.md; no MCP layer to carry it.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions