Saltar al contenido principal

OpenCode kit/IDE variant — exploration & recommendation (#878)

:::note Contenido en inglés Esta página del wiki se sincroniza desde la base de conocimiento en inglés y todavía no está traducida. :::

reference · tech-lead · updated 2026-06-28 · source

Spike output for effort #878. Should we pursue a non-Claude OpenCode + Ollama kit? José wants OpenCode support but is wary of maintaining a second parallel kit. This doc evaluates the superseded prior art (draft PR #877 / branch feat/kit-shared-opencode-kit) against the current Kit v2 design (#770/#850, c64149f), assesses the maintenance cost, and recommends a path.

Recommendation: PARTIAL — drop the parallel kit, salvage the one net-new asset, defer a real OpenCode surface to a derive-at-export model (not a second hand-maintained kit).

TL;DR

Verdict
packages/kit-shared (SoT package)Drop — inverts Kit v2's "the plugin IS the source of truth"; re-introduces a build-time derivation + a second editable-truth boundary the redesign deliberately removed.
packages/opencode-kit (parallel kit)Drop — a forked scaffold engine + duplicate agent/rule/profile sets + a second composition model. Highest-cost, lowest-leverage.
kit-export-training.sh + commandSalvage (done in this PR) — net-new, tool-agnostic, independent of the OpenCode decision.
IF-flag convention + training-pipeline conceptKeep as documented direction — already exists in claude-kit; no code to add now.
OpenCode TUI themesDrop — only meaningful with an OpenCode TUI we are not building.

1 · PR #877 design vs current Kit v2 (#879)

What PR #877 built (the three-layer model)

A tool-agnostic SoT package feeding two derived kits, kept in sync by a build step:

  • packages/kit-shared/ — canonical agents/ (13), rules/ (6 universal), profiles/ (5), and scripts/kit-sync.mjs. The single editable truth.
  • packages/claude-kit-plugin/ — re-cast as a derived layer whose templates/agents + templates/rules are generated from kit-shared by pnpm kit:sync.
  • packages/opencode-kit/ — a second derived kit: scripts/init.sh (562 lines), templates/agents (13), templates/rules (10), profiles/ (5), themes/ (2), opencode.json.template.
  • Mechanism: kit-shared holds canonical files with kit-specific passages wrapped in <!-- IF:FLAG --> blocks; each kit's init.sh resolves its own flags (claude → MEMORY/PROJECTS_V2 ON; opencode → OLLAMA/BASH_SAFETY ON, IDE flags OFF). kit-sync.mjs --check is the CI drift gate.

Full plan: docs/kit-system-master-plan.md on the branch (2026-06-17, pre-Kit-v2).

What Kit v2 did instead (the opposite direction)

Kit v2 (#770/#850, c64149f) made packages/claude-kit-plugin/ self-contained: the full lifecycle ships in skills/ + scripts/ and runs via ${CLAUDE_PLUGIN_ROOT} with no per-project scripts/ checkout (see .claude-plugin/plugin.json). Composition is modules/*.json manifests (#379/#387) — opt-in islands (modules/software.json), the parent workspace untouched (D4). There is no kit-shared; the plugin directory IS the source of truth.

Reusable vs conflicting (file-level)

Conflicts head-on with Kit v2:

  • packages/kit-shared/ — directly contradicts "the plugin is the SoT." Adopting it would make the plugin's templates/agents + templates/rules generated artifacts again, re-adding a build step (kit:sync) and a CI drift gate (kit-sync.mjs --check) on a repo that has no CI (Vercel + local gates only). This is the multi-editable-truth drift the self-contained redesign killed.
  • packages/kit-shared/agents/* (13) + rules/* (6) — stale 2026-06-17 forks of this repo's live .claude/agents/* and .claude/rules/*, which have since diverged substantially (the live rule set now includes effort-model.md, react-style-guidelines.md, kit-engine-boundary.md, etc., absent from the fork). Re-homing them means reconciling + then perpetually syncing 19 files.
  • packages/opencode-kit/scripts/init.sh (562 lines) — self-describes as "Mirrors claude-kit's init.sh: same Perl render engine." That is exactly the second implementation forbidden by .claude/rules/kit-engine-boundary.md rule #1 ("no second implementation"; a repeated op gets extracted, never copied).
  • opencode-kit profiles/*.json + IF-flag composition vs Kit v2 modules/*.jsontwo parallel, incompatible composition models to maintain.

Reusable / non-conflicting:

  • packages/claude-kit-plugin/scripts/kit-export-training.sh + commands/kit-export-training.md — the one genuinely net-new asset. Tool-agnostic (operates on ~/.claude/projects transcripts via chat-datasets/build_dataset.py), independent of OpenCode. Salvaged in this PR (builder path made config-driven, see §3).
  • The <!-- IF:FLAG --> + {{VAR}} convention — already exists in claude-kit's init.sh; the lever PR #877 leaned on needs no new code.
  • The training-pipeline concept (sessions → build_dataset.py → MLX-LoRA on M4 → eval/ab.py groundedness gate → GGUF → Ollama; "fine-tune = voice, RAG = facts") — valuable as a documented direction. The salvaged script is its consent gate; the chat-datasets/ + tedos-builder/ sibling repos already exist on disk.

2 · Maintenance cost + go/no-go (#880)

Cost of a second parallel kit

  • Duplicate agent/rule templates. Even with build-time sync, opencode needs terminal-flavored overlays (curl examples, no MemPalace/Agentation/Projects). That is 3 editable touchpoints per agent (kit-shared canonical + 2 kit overlays) and a divergence surface that grows with every agent.
  • A second composition model. modules/*.json (Kit v2) and IF-flags + profiles (opencode) are two engines doing the same job — a permanent fork in how a kit is assembled.
  • A forked scaffold engine. opencode-kit/scripts/init.sh mirrors claude-kit's init.sh; every upgrade-safe-write / render fix must land in both. Violates the kit-engine-boundary rule.
  • Net-new CI infra. kit-sync.mjs --check must gate every agent/rule edit forever; the repo has no CI today, so this is a new always-on obligation, not a free check.
  • A moving third-party target. OpenCode (plugin/agent schema, opencode.json) evolves independently of Claude Code and can break the kit on its own cadence.

Value

  • A non-Claude IDE option + local, $0-API, private model serving (Ollama) + a self-improving "voice" fine-tune loop. Real, but: the loop's value piece (the export script) is salvageable without the OpenCode kit. What the parallel kit uniquely buys is the OpenCode surface itself — and demand is one stated preference, not repeated, blocking need.

Go / no-go

PARTIAL.

  • Drop now: kit-shared, packages/opencode-kit, the forked init.sh, the duplicate agent/rule/profile/theme sets. They conflict with Kit v2's self-contained + modules model and re-introduce the drift it removed — high cost, low marginal value.
  • Salvage now: kit-export-training.sh (§3) — net-new, tool-agnostic, decision-independent.
  • Defer (revive criteria, not now): if a real OpenCode surface is ever wanted, build it as a derive-at-export target of the self-contained plugin — extend the existing scripts/kit-export-project.sh tier model (it already emits Cowork / claude.ai flavors) to emit an .opencode/ flavor from the single plugin SoT. No kit-shared, no second init.sh, no second composition engine. Revisit only when (a) there is concrete, repeated demand for an OpenCode/local workflow, and (b) that export-derivation path can generate it with zero duplicated mechanism.

Keep branch feat/kit-shared-opencode-kit + draft PR #877 as the reference record (the master plan and templates are the starting point if the deferred path is taken); do not rebase or land them.

3 · kit-export-training.sh salvage (#881)

The one net-new, independently valuable script — the opt-in consent gate that exports Claude Code sessions to redacted training JSONL. Lifted onto develop, generalized off any one machine:

  • packages/claude-kit-plugin/scripts/kit-export-training.sh — handler.
  • packages/claude-kit-plugin/commands/kit-export-training.md/kit-export-training command.
  • packages/claude-kit-plugin/scripts/kit-export-training-test.sh — bash + zsh self-test.

Key fix — builder path is now config-driven (was a hardcoded user absolute path). Resolution order: --builder PATHKIT_DATASET_BUILDER env → sibling chat-datasets/build_dataset.py next to the git repo root (then $PWD). Fails closed with guidance if none resolve. Redaction stays ON always (the script never passes --no-redact, the builder's masking default). Sourceable for tests via the repo's kit_is_main guard; bash -n clean; test green under bash and zsh.

See also

  • knowledge/decisions/log.md — decision record.
  • .claude/rules/kit-engine-boundary.md — "no second implementation" (the rule a parallel scaffold engine would violate).
  • .claude/rules/effort-model.md — workflow doubles as training trace (why the export script matters).
  • docs/kit-system-master-plan.md on branch feat/kit-shared-opencode-kit — the superseded plan.