Skip to content

uiPotion/potion-kit

Repository files navigation

Potion Kit

CLI to build static sites with Handlebars, Markdown, and SCSS only. Chat with the AI to design and build your site; the model uses the UIPotion catalog and potion-kit project conventions, can only suggest components from real specs, can safely inspect or move allowed project directories, can delete empty allowed project directories, can safely move or delete allowed project files inside the current working directory, and can optionally search current web topics with Tavily-backed web research or read a public URL as plain text.

Note: potion-kit is actively vibe coded — we’re improving and optimizing it over time. For the best experience we recommend the newest OpenAI or Anthropic models; they handle the outcome quality best. For a good cheaper option, use Kimi K2.5. Extensive use consumes API tokens and costs depend on your provider’s pricing. By using the tool you accept it as-is; only you decide whether and how much to use it. We hope you enjoy building with it.

Commands

  • potion-kit init <directory> — Scaffold a new static site project with pages, partials, SCSS, and a sample post.
  • potion-kit chat — Interactive chat.
  • potion-kit chat "message" — Send one message and exit (one-shot).
  • potion-kit doctor — Validate LLM configuration, provider connectivity, project structure, remote dependencies, and optional Tavily web research when configured.
  • potion-kit clear — Clear chat state for this project (history, summary cache, and event trace ledger).
  • potion-kit or potion-kit --help — Show usage and available commands. Unknown commands (e.g. potion-kit clean) also show help and do not call the API.

Usage (from npm)

Use potion-kit as an installed CLI: run it from any directory where you have a .env with your LLM API key. No need to clone this repo.

Install

Option A — npx (no install):

npx potion-kit chat

Option B — global install:

npm install -g potion-kit
potion-kit chat

Start a new project

  1. Scaffold a site with init:

    npx potion-kit init my-site
    cd my-site

    This creates a ready-to-build project with pages, partials, SCSS, a sample post, and package scripts.

  2. Create a .env file in that directory with your LLM provider and API key. Minimal contents:

    POTION_KIT_PROVIDER=openai
    OPENAI_API_KEY=sk-your-key-here

    For Anthropic use POTION_KIT_PROVIDER=anthropic and ANTHROPIC_API_KEY=.... For Kimi (by Moonshot) use POTION_KIT_PROVIDER=moonshot and MOONSHOT_API_KEY=.... See .env variables for all options and .env and security.

  3. Check your setup (optional but recommended):

    npx potion-kit doctor
  4. Start chatting:

    npx potion-kit chat
    # or, if installed globally:
    potion-kit chat

    The tool reads .env from the current working directory, so always run potion-kit from the directory that contains your .env (and where you want the AI to read/write files).

You can also run potion-kit chat in any existing project directory or empty folder — init is not required.

Usage examples

Interactive chat (recommended):

cd my-project
npx potion-kit chat
# or: potion-kit chat

Type your message at the You: prompt, press Enter; the model replies. Type exit, quit, or q (or Ctrl+C) to quit. Your conversation is saved for the next run.

One-shot (single message then exit):

npx potion-kit chat "I want a blog with a header and footer"
npx potion-kit chat "Add the navbar potion to the layout"

Scaffold and go:

npx potion-kit init my-blog
cd my-blog
# add .env with your provider + key
npx potion-kit chat "Add a navbar and about page"

Start a new conversation (clear history for this directory):

npx potion-kit clear
npx potion-kit chat "Let's build a docs site"

Check configuration before chatting:

npx potion-kit doctor

Current web research (optional)

If you set TAVILY_API_KEY, chat can search the public web for current information and then read selected pages as plain text. Even without Tavily, chat can still read a public URL that you provide directly.

Example prompts:

npx potion-kit chat "Research the latest CSS nesting support and summarize the sources"
npx potion-kit chat "Read https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_nesting and summarize the key points"

The web reader is text-only: it does not execute page JavaScript, does not download binary files, and blocks localhost, private IPs, and other internal-only addresses.

Project file and directory operations

Chat can safely work with project files and directories inside the current working directory.

  • File operations — search, read, write, targeted edit, move, and delete allowed project files.
  • Directory operations — inspect directory trees, move allowed directories, and delete empty allowed directories.
  • Destructive safety — file delete/move requires a fresh file hash from read_project_file; directory move/delete requires a fresh treeHash from inspect_project_directory.
  • Directory limits in v1 — recursive directory delete is not supported, destination overwrite is not supported, and empty-directory delete is the only delete mode for directories.

Example prompts:

npx potion-kit chat "Rename src/components to src/ui/components"
npx potion-kit chat "Inspect src/sections and tell me whether it is safe to move"
npx potion-kit chat "Delete the empty src/tmp directory"
npx potion-kit chat "Move src/posts/draft.md to src/posts/archive/draft.md"

Config

Config precedence (highest to lowest):

  1. Environment variables already present in your shell/process (e.g. OPENAI_API_KEY, POTION_KIT_PROVIDER).
  2. .env in the current working directory (loaded by dotenv only for variables not already set).
  3. ./config.json (in the current working directory) — provider, model, optional maxHistoryMessages, maxToolSteps, maxOutputTokens, and optional Tavily web-research defaults under webSearch; do not put API keys there.

If config.json contains invalid webSearch fields, potion-kit warns and ignores only the invalid web-search values; valid LLM settings in the same file still load.

.env variables

Variable Required Description
POTION_KIT_PROVIDER yes openai, anthropic, or moonshot
OPENAI_API_KEY, ANTHROPIC_API_KEY, or MOONSHOT_API_KEY one required API key for the chosen provider
POTION_KIT_MODEL no Chat model id (defaults: gpt-5.2 / claude-sonnet-4-5 / kimi-k2.5). Must be a chat model.
POTION_KIT_API_KEY no Fallback key if provider-specific key is not set
POTION_KIT_BASE_URL no Custom base URL for the chosen provider (e.g. proxy, LiteLLM)
POTION_KIT_MAX_HISTORY_MESSAGES no Max conversation turns sent to the API (default 10)
POTION_KIT_MAX_TOOL_STEPS no Max tool steps per turn (default 16)
POTION_KIT_MAX_OUTPUT_TOKENS no Max output tokens per turn (default 16384)
TAVILY_API_KEY no Enables optional current-topic web research using Tavily
POTION_KIT_WEB_SEARCH_MAX_RESULTS no Default max results for optional Tavily web research when not otherwise specified
POTION_KIT_WEB_SEARCH_COUNTRY no Optional country boost for Tavily web research

Minimal .env:

POTION_KIT_PROVIDER=openai
OPENAI_API_KEY=sk-your-key-here

With optional model:

POTION_KIT_PROVIDER=openai
POTION_KIT_MODEL=gpt-5.2
OPENAI_API_KEY=sk-your-key-here

With optional web search:

POTION_KIT_PROVIDER=openai
OPENAI_API_KEY=sk-your-key-here
TAVILY_API_KEY=tvly-your-key-here
POTION_KIT_WEB_SEARCH_COUNTRY=united states

Example config.json:

{
  "provider": "openai",
  "model": "gpt-5.2",
  "maxHistoryMessages": 10,
  "maxToolSteps": 16,
  "maxOutputTokens": 16384,
  "webSearch": {
    "maxResults": 5,
    "country": "united states"
  }
}

.env and security

  • potion-kit never sends .env or API keys to the model. Keys are read only by the CLI and used for authentication with the LLM provider (OpenAI, Anthropic, or Moonshot). They are not included in the system prompt, chat history, or any message content sent to the model. The only way a key could appear in the conversation is if you paste it yourself in a chat message — so don’t.
  • Never commit .env. It contains secrets. Add .env to your .gitignore. If the AI scaffolds a project for you, ensure .env is in that project’s .gitignore too.
  • Never put API keys in config.json. That file is for non-secret provider/model/search settings only. Use .env or environment variables for keys.
  • Never paste API keys in logs, issues, or chat. If you paste a key into a chat message, it becomes part of the conversation and history.
  • Where to put .env: In the directory from which you run potion-kit (usually your project root). One .env per project.
  • Project tool safety: Project file and directory tools are limited to the current working directory, reject sensitive or generated paths such as .env, .potion-kit/, .git/, build/, dist/, and node_modules/, and do not operate on symlinked paths. Directory move/delete operations always validate the whole tree, require a fresh treeHash from directory inspection, reject the project root, and only support empty-directory delete in v1.
  • Web research safety: Public web search requires TAVILY_API_KEY. Direct web page reads are GET-only, text-only, block localhost/private/internal hosts, reject binary content, and do not execute page JavaScript or save fetched content to disk.

Chat history

Conversation is stored in .potion-kit/chat-history.json in the directory where you run potion-kit chat. The model uses it for context on the next run. Each request sends: the first user message (always kept), a condensed summary of the middle conversation (when history exceeds capacity), and the last N messages (default 10). Summary state is cached in .potion-kit/chat-summary.json and updated incrementally to avoid re-summarizing the same old turns every request. Per-turn tool traces are stored in .potion-kit/chat-events.json, and when a turn records verified project reads or changes the CLI prints a small turn-result footer from the same trace so path changes are verified from tool activity instead of reply wording. Set POTION_KIT_MAX_HISTORY_MESSAGES or maxHistoryMessages in ./config.json to change the tail size, and tune generation with POTION_KIT_MAX_TOOL_STEPS / POTION_KIT_MAX_OUTPUT_TOKENS. Add .potion-kit/ to .gitignore if you don’t want to commit chat state. Use potion-kit clear to reset chat state for that project.

File formats (.potion-kit/):

  • chat-history.json — Array of { role: "user" | "assistant", content: string }. Raw conversation in order.
  • chat-summary.json — Object: summary (string), summarizedUntil (number, exclusive index into history), firstUserMessage (string, for cache validation), incrementalUpdates (number).
  • chat-events.json — Array of per-turn events. Each: timestamp (ISO string), trace (stepsUsed, finishReason, toolEvents: entries with toolName, ok, and optional metadata such as path, query, url, finalUrl, resultCount, contentType, entryCount, treeHash), hasVerifiedChange (true if this turn had a successful project-file or project-directory mutation such as write, edit, move, or delete), optional summarySource.

Summaries: The middle-conversation summary is generated by the same model as chat (one extra API call when history exceeds the tail). The model is asked for at least 2–3 sentences or 3–5 bullet points. If it returns a valid plain-text summary of at least 80 characters it is stored and reused; if the response is empty or too short, a local fallback (condensed last messages) is used instead so the cache never stores stub summaries. Use a capable chat model (e.g. GPT-4o, Claude Sonnet) for best summary quality; very small or completion-only models may often trigger the fallback.

Legal

potion-kit uses UIPotion specifications and catalog. By using potion-kit you are using UIPotion’s service and agree to the UIPotion legal disclaimer and privacy policy. That page covers disclaimers on AI-generated code, liability, and user responsibility. Please read it before use.

AI providers and your data. You choose the model and provider (e.g. OpenAI, Anthropic, Kimi/Moonshot) in config. You are aware what is sent in each request. By using a provider you agree to that provider’s terms of service, acceptable use, and data policies. potion-kit does not control how providers retain, process, or review your prompts and responses.

Sensitive data and cloud LLM risk. If your prompts include proprietary code, secrets, customer data, financials, or internal docs, the main risk is that you are voluntarily sending sensitive material to a third party. The precise risk depends on the provider’s retention, access controls, internal review practices, and breach likelihood. This is the general “cloud LLM” risk; consider what you send and which provider you use.


Development (potion-kit repo)

For contributing to potion-kit or running from source.

Setup

git clone <repo>
cd potion-kit
npm install
npm run build

Run locally

node dist/index.js --help
node dist/index.js chat

Put a .env in the repo (or in a test directory) and run from there. Copy .env.example to .env and set your API key.

Scripts

  • npm run build — Compile TypeScript to dist/.
  • npm run lint — ESLint on src/ and test/. npm run lint:fix to auto-fix.
  • npm run format — Prettier on src/**/*.ts and test/**/*.ts. npm run format:check to only check.
  • npm run typecheck — TypeScript project check (tsc -p tsconfig.eslint.json).
  • npm run test — Run tests (Node built-in test runner; tests live in test/).