feat(cli): skill factory — openkb skill new + /skill new + auto marketplace.json#57
Open
KylinMountain wants to merge 25 commits into
Open
feat(cli): skill factory — openkb skill new + /skill new + auto marketplace.json#57KylinMountain wants to merge 25 commits into
KylinMountain wants to merge 25 commits into
Conversation
The previous c.islower() check accepted Unicode lowercase letters like 'é' and 'ü', contradicting the [a-z0-9-] docstring promise. Names are used as filesystem directories and YAML frontmatter, so the slug must stay ASCII. Add explicit a-z / 0-9 range check + 2 regression tests.
The plan-verbatim implementation omitted the 'owner' field at the top level. Some marketplace consumers (Claude Code's /plugin marketplace add) expect 'owner' for listing/attribution. Derive from git config; fall back to 'openkb-user' if git isn't configured. Mirror as plugin-level 'author' to match the existing repo convention.
The plan called for verifying that wiki/concepts/ or wiki/summaries/ has actual files before allowing skill compilation. Earlier impl loosened this to 'any file in wiki/', which silently accepted freshly-init'd KBs (openkb init pre-creates empty concepts/ + summaries/ dirs). Restore the strict check + populate test fixture + add regression test for the freshly-init'd case.
- /skill new: catch shlex.split ValueError on unclosed quotes so a typo doesn't crash the chat REPL - write_kb_file: reject bare directory paths (e.g. 'output') that would otherwise raise IsADirectoryError on write_text - chat.py: drop stale build_query_agent import (chat now uses build_chat_agent) - test_chat_slash_commands.py: update patch target from build_query_agent -> build_chat_agent so the test exercises the right symbol - Add tests/test_write_kb_file.py covering allow-list, traversal, bare-directory rejection
C1: /skill new in chat had only name validation — no wiki-exists check, no wiki-content check, no overwrite guard. The CLI had all three. Extract the gates into _preflight_skill_new and call from both. Add explicit 'remove existing skill first' message in chat (no -y equivalent there). C2: System prompt advertised tool names (list_wiki_dir, read_wiki_file, write_skill_file) that didn't match what was registered with @function_tool (list_wiki, read_wiki, write_skill). LLM saw the registered names; prompt references would confuse it. Rename the wrappers to match. I1: query_wiki was a sync @function_tool calling asyncio.run() on run_query — works only because openai-agents SDK runs sync tools on worker threads. Convert to async @function_tool so the runner awaits it in the same loop, eliminating the nested-asyncio fragility. Add 2 regression tests for the chat safety gates.
The previous impl used the KB directory name as both the marketplace 'name' and the plugin 'name', and stitched together a metadata description by truncating the first skill's SKILL.md description at 200 chars (often mid-word). Lock the convention to match skills/openkb/.claude-plugin/marketplace.json from the official skill: - marketplace name: 'vectify' (always) - plugin name: 'openkb' (always) - description: fixed string, no SKILL.md content injection, no truncation Different KBs are distinguished by <owner>/<repo> URL, not manifest name. Users get one canonical install command (/plugin install openkb@vectify) regardless of which KB they're consuming. Also fix _git_owner to pass cwd=kb_dir so 'openkb --kb-dir ... skill new' run from anywhere reads the KB's git config, not the process CWD.
Collaborator
Author
Code reviewFound 1 issue:
OpenKB/openkb/agent/skill_compiler.py Lines 124 to 131 in 7467200 Call sites that catch only Lines 1490 to 1495 in 7467200 Lines 540 to 546 in 7467200 Generated with Claude Code - If this code review was useful, please react with 👍. Otherwise, react with 👎. |
…ator - Rename openkb/agent/skill_compiler.py → skill_creator.py (and associated symbols + prompt file). The existing openkb/agent/compiler.py owns 'compile' for raw → wiki; this module generates a skill from compiled wiki content, which is closer to 'create' / 'distill'. Disambiguates the verb in one package. - Translate MaxTurnsExceeded into a friendly RuntimeError inside run_skill_create. Both the CLI and chat call sites only catch RuntimeError; the SDK exception leaked a Python traceback before. - Defer the rmtree-on-overwrite until after _setup_llm_key and load_config succeed. Previously an unset API key would wipe the existing skill output with nothing to replace it. - Fix marketplace.py module docstring: don't claim chat-side SKILL.md edits regenerate the manifest (they don't). - Drop unused yes_flag from _preflight_skill_new + rewrite its docstring to match what the function actually does. - Clean up github-code-quality bot findings: unused pytest imports in 2 test files, unused 'manifest' local in test_marketplace.py (replaced with the assertion the test intended), redundant in-function stdlib imports in openkb/cli.py. Add 2 regression tests: - test_run_skill_create_translates_max_turns_to_runtime_error - test_skill_new_keeps_existing_skill_when_key_setup_fails
Reframe the project mental model: the wiki is the substrate, and several primitives (query, chat, skill new) generate output from it. Add 'Drop in a book. Out comes a digital expert.' slogan to the Skill Factory subsection. - Features list split into 'Wiki foundation' (compile + maintain) and 'Generators' (query / chat / Skill Factory) - Quick Start adds step 6 — distill a skill - Architecture diagram extended to show the wiki branching into query/chat + Skill Factory + future generators (ppt/podcast/…) - Usage section regrouped under 🧱 Wiki Foundation and ✨ Generators - Skill Factory subsection promoted with the slogan as its heading and a concrete example folder tree - Chat slash command list updated to include /skill new
Borrows from Anthropic's skill-creator: each time 'openkb skill new -y' would overwrite an existing skill, the old version is copied to <kb>/output/skills/<name>-workspace/iteration-N/ instead of being destroyed. Iteration numbers monotonically increase. Each iteration carries a diff.md showing description + reference-file delta vs the previous version. New commands: openkb skill history <name> list past iterations openkb skill rollback <name> restore latest iteration openkb skill rollback --to N restore specific iteration Tests cover: iteration numbering, restore-from-N, restore-from-latest, diff content (description / added refs / removed refs).
Borrows from Codex skill-creator's quick_validate.py: catches the common failure modes that would make a skill unloadable before distribution — missing/malformed frontmatter, name/dir mismatch, oversized files, broken references/* wikilinks, non-stdlib imports in scripts/* (strict mode). New CLI: openkb skill validate validate all compiled skills openkb skill validate <name> validate one openkb skill validate --strict treat warnings as failures openkb skill new auto-runs validation after compile and surfaces errors + warnings so the user knows whether the freshly-compiled skill is well-formed. Doesn't block marketplace.json regeneration — the files are on disk and the user can fix or rollback.
Borrows from Anthropic skill-creator's evaluation loop, simplified for
v0.3: measure whether a skill's description: field actually fires when
it should and stays quiet when it shouldn't. The description is the
activation signal other agents read; a vague description silently fails
to load when it ought to.
Flow:
1. LLM generates N should-trigger + N should-not prompts from the
description only
2. Grader LLM scores each: 'should this description activate this
skill for this question?'
3. Compare to ground truth, print pass rate + misses
New CLI:
openkb skill eval <name> run eval (10+10 default)
openkb skill eval <name> --save persist prompts to disk
openkb skill eval <name> --eval-set X reuse saved prompts
openkb skill eval <name> --count N override prompt count
Tests mock Runner.run for both generator and grader — no real LLM
calls in CI. Saved eval sets live at .openkb/eval-sets/<name>.json
for reproducibility.
Skill Factory section now lists the 4 quality-gate commands borrowed from Codex (validate) and Anthropic skill-creator (eval + iteration): openkb skill validate structural lint (frontmatter, sizes, refs) openkb skill eval trigger-accuracy test of the description openkb skill history list past iterations openkb skill rollback restore a previous iteration The slogan promised a 'digital expert' — these commands are what makes the output worth that label.
Code review (round 2, on commits 7467200..a5fe567)Found 1 issue:
Generated with Claude Code - If this code review was useful, please react with 👍. Otherwise, react with 👎. |
Code review round-2 flagged the eval pipeline reintroducing the MaxTurnsExceeded/JSONDecodeError traceback leak that round-1 caught for skill new. Apply the same shim inside skill_evaluator + 4 other carryover items: - Translate MaxTurnsExceeded and json.JSONDecodeError to RuntimeError inside generate_eval_set and grade_one. CLI catch (RuntimeError) now covers both. - Wrap _setup_llm_key in skill_eval with the same try/except/exit pattern as skill_new / query / chat. - Move openkb/skill_evaluator.py -> openkb/agent/skill_evaluator.py. Modules that construct Agent live under openkb/agent/ per repo convention; top-level openkb/ keeps marketplace + generator (no agents SDK). - Validator: reject '<' / '>' in description (Anthropic parser requirement); warn on unknown frontmatter keys (Anthropic spec allows a fixed set). - Drop redundant in-function 'import asyncio' from skill_eval (already at module top). - Drop unused EvalMiss import from tests. - Validator module docstring updated to enumerate all checks. Also delete community contribution scaffolding (CONTRIBUTING.md + .github/PULL_REQUEST_TEMPLATE/skill_submission.md) - premature for the project's current stage; will revisit when real contributors arrive.
All skill-related code now lives in a single openkb/skill/ subpackage (7 modules + __init__). Drop the redundant 'skill_' prefix on filenames since the package qualifies them already. Moves: openkb/generator.py -> openkb/skill/generator.py openkb/marketplace.py -> openkb/skill/marketplace.py openkb/skill_validator.py -> openkb/skill/validator.py openkb/skill_workspace.py -> openkb/skill/workspace.py openkb/agent/skill_creator.py -> openkb/skill/creator.py openkb/agent/skill_tools.py -> openkb/skill/tools.py openkb/agent/skill_evaluator.py -> openkb/skill/evaluator.py generator.py + marketplace.py go under skill/ for now (v0.x only has skills); they're nominally generic primitives but YAGNI -- when a second artifact type (ppt / podcast / report) actually lands, those two will move back out to openkb/<shared>/. No behavioral changes. All imports + test patch targets updated. Test suite stays at 494 passed.
The Features list at the top duplicated everything already covered by Quick Start (step-by-step feature tour) + Usage (Wiki Foundation + Generators tables). It also duplicated the Skill Factory slogan that now lives canonically in the Skill Factory subsection. Replace 17 lines with a one-sentence pointer to Usage. 405 → 389 lines. Slogan now appears exactly once (in the Skill Factory subsection) instead of 5 places. Other duplicates (PageIndex mentions, cross-CLI install instructions, Karpathy comparison table) left for now — they target different audiences (scanners vs deep readers) and aren't worth touching in this pass.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
openkb skill new <name> "<prompt>"compiles the wiki into anAnthropic-Skills directory at
<kb>/output/skills/<name>/./skill newslash command insideopenkb chat— same primitive,conversational front end, lets users iterate via natural-language
follow-ups (chat agent now has Write access to
<kb>/output/**+<kb>/wiki/explorations/**).<kb>/.claude-plugin/marketplace.jsonlists allcompiled skills; pushing the KB to GitHub makes
npx skills@latest add <owner>/<repo>work end-to-end.Generatorprimitive (openkb/generator.py) is architected so futureppt/podcast/reporttargets slot in without restructuring.skill_submission PR template) — no new CLI surface needed for
submission.
Architecture
Reuses the existing
openai-agentsSDK + LiteLLM stack fromopenkb.agent.query.The skill-compile agent is constructed via
build_skill_compile_agentwitha system prompt from
openkb/prompts/skill_compile.mdinterpolated withthe user's intent + skill name + wiki schema. Tools are scoped: read wiki,
query wiki, write only within
<kb>/output/skills/<name>/. Marketplace.jsonregenerates synchronously after the agent finishes (no LLM call).
Test plan
uv run pytest— full suite green (430+ tests)overwrite logic, marketplace.json regen all covered by unit tests
/skill newcovered by 3 dedicated tests + write_kb_fileallow-list covered by 9 dedicated tests
openkb skill new <name> "<intent>" -yagainst a real KB with compiled wiki content, verify the resulting
output/skills/<name>/SKILL.mdactivates appropriately in ClaudeCode after
cp -r output/skills/<name> ~/.claude/skills/. Speccriteria from
docs/superpowers/specs/2026-05-18-skill-factory-design.md§11 success criteria.
openkb chat, run/skill new, then ask theagent to tweak the description or a references/ file; verify the
file actually changes on disk.
Spec:
docs/superpowers/specs/2026-05-18-skill-factory-design.md(gitignored locally; design notes in PR review)