mcpField
W
wokitoki

wokitoki

github.com/upex-galaxyAgent workflows065 installsUpdated 3w ago
Repository

About wokitoki

WokiToki (`toki`) is a local, blocking feedback CLI invoked by an AI during a conversation. It suits multi-part questions and feedback tied to specific text, presenting forms in a browser and returning block-mapped Result JSON on stdout.

Key features

  1. 01Local browser-based feedback
  2. 02Mix questions and report blocks
  3. 03Map answers by block ID
  4. 04Capture quotes, text, and images
  5. 05Write Result JSON to stdout

Use cases

  1. 01Collect feedback across multiple decisions
  2. 02Get responses to individual report passages
  3. 03Anchor replies to their source text
  4. 04Keep interaction files outside a repository

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/upex-galaxy/agentic-user-skills --skill wokitoki

After installing, type/wokitokiin Claude Code to confirm it loaded.

Bundled files

References and scripts installed along with SKILL.md.

cli/
assets.d.ts
index.ts
markdown.ts
README.md
render.ts
schema.ts
server.ts
cli/ui/
app.css
app.js
references/
examples.md
schema.md
setup.md

Details

From the project README

WokiToki (toki)

WokiToki is a local, blocking feedback CLI the AI invokes mid-conversation. It serves a dark web UI, opens the browser, waits for the user to answer, and on submit prints a single Result JSON to stdout that the AI parses the same turn. The branding is "walkie-talkie": back-and-forth, one answer per thing. Command = toki; all tool output lands under ~/.toki/.

This skill is installed user-level (global): it loads automatically in every project, with no per-repo wiring. Because every file it writes goes under ~/.toki/ (never the cwd), running toki inside any repo leaves zero footprint in that repo — no .gitignore edits needed.

Everything is one engine: a spec is a list of blocks. A block with controls is a question; a block without controls is a report paragraph; mixing them in one spec is a hybrid form — for free.

Phase 0 — first-run binary check (before the first invocation in a session)

toki ships as source and is compiled to a single global binary on first use. Before invoking it the first time, ensure the binary exists; build it if missing:

command -v toki >/dev/null 2>&1 || bun build --compile "<skill-dir>/cli/index.ts" --outfile "$HOME/.bun/bin/toki"
  • <skill-dir> is this skill's install directory — user-level that is ~/.claude/skills/wokitoki.
  • ~/.bun/bin is already on PATH for Bun installs, so the freshly built toki is immediately runnable.
  • Fallback (if --compile is unavailable or the binary can't be written): run from source with bun "<skill-dir>/cli/index.ts" <specPath> — identical behavior, just a slower cold start.

Full first-run details (sizes, PATH, rebuild) → references/setup.md.

When to use vs AskUserQuestion vs inline prose

SituationUse
1–2 option pick, single yes/no, ≤3 simple decisionsAskUserQuestion
>3 decision points at once (mix of single/multi/toggle)WokiToki
A long multi-section explanation/report the user may want to react to one point at a timeWokiToki
You need the reply ANCHORED to the exact phrase it is aboutWokiToki (highlight-to-quote)
Non-interactive / CI / no human at a browserneither — emit plain output

Why not the alternatives:

  • AskUserQuestion is capped (~4 questions × ~4 options), terminal-bound, has no rich free-text, and cannot display the reference content while the user answers.
  • Inline prose questionnaire produces unanchored replies: the AI has to guess which paragraph/point each sentence of the reply maps to. WokiToki returns per-block answers keyed by a stable id, so the mapping is exact.

Spec schema in brief

{
  "title": "Auth plan — decisions",      // required, non-empty
  "intro": "Optional markdown at top",   // optional
  "submitLabel": "Submit answers",        // optional (default "Submit")
  "blocks": [                              // required, non-empty
    {
      "id": "q1",                          // required, unique within the spec
      "content": "Which token strategy?",  // markdown string (may be empty "")
      "controls": {                        // OMIT for a report paragraph
        "type": "single",                  // single | multi | toggle
        "options": [                        // required for single/multi, FORBIDDEN for toggle
          { "value": "jwt", "label": "JWT stateless" },
          { "value": "session", "label": "Server-side session" }
        ],
        "required": true                    // optional (default false)
      },
      "text": { "required": true, "placeholder": "Justify" }  // text ALWAYS present at runtime; required decided per-block
    }
  ]
}
  • controls absent → report paragraph. Present → question. Mixed list → hybrid.
  • controls.type: single (radio), multi (checkbox), toggle (boolean switch, no options).
  • controls.required and text.required are independent — either, both, or neither can be required per block.
  • id is the stable AI-assigned key the answer is mapped back to.

Full contract (every field, defaults, validation rules) → references/schema.md. Worked copy-pasteable specs → references/examples.md.

Exact invocation

  1. Write the spec to a JSON file. Convention: ~/.toki/spec-<name>.json (a spec-<name>.json filename makes the backup land at ~/.toki/result-<name>.json). Keeping the spec under ~/.toki/ — not the repo — keeps the whole footprint out of whatever repo you are working in.
  2. Run it (blocking): toki <specPath>. This serves the UI, opens the browser, and waits. (First run in a session: do the Phase 0 binary check above.)
    • Flags: --port <n> (default 4747, auto-increments if busy), --timeout <min> (default 1440 = 24h, fractional ok), --no-open (print the URL but do not open the browser), --help.
  3. Parse stdout. stdout carries ONLY the Result JSON — one object, no banner. All progress lines, the waiting URL, and errors go to stderr. Read stdout, JSON.parse it, continue the same turn.

Exit codes:

CodeMeaning
0submitted OK — Result JSON is on stdout
1timeout (no submit within --timeout) or runtime error — nothing usable on stdout
2bad spec (file unreadable or failed validation) — [toki] invalid spec at <path>: … on stderr

A backup of the Result is also written to ~/.toki/result-<name>.json, but the stdout copy is authoritative for the AI.

User-absence protocol

A long session is expected — the default --timeout is 24h (1440 min), adjustable via --timeout <min>. A person may step away and leave the session open, so a non-zero exit is not necessarily an error:

ExitMeaningWhat the AI does
0submitted — Result JSON on stdoutparse it, continue the same turn
1timeout elapsed with NO submission (or runtime error)treat as the user being AWAY, not a failure — see below
2bad spec (unreadable / failed validation)fix the spec, then re-run
130Ctrl-C (SIGINT)the user cancelled — ask what they want next

On exit code 1, do not error out or move on silently. Treat it as the user being away from the keyboard: post a brief standby message and offer to relaunch — e.g. "Dejé toki esperando, no llegó respuesta; sigo disponible — decime y lo relanzo." Keep toki ready to re-run with the same spec the moment the user is back.

Reading the Result

{
  "submittedAt": "2026-05-29T12:34:56.000Z",
  "blocks": [
    { "id": "q1", "controlAnswer": "jwt", "text": "Prefer JWT for scale", "quotes": ["token strategy"] }
  ],
  "meta": { "answered": 5, "total": 8 }
}

Per ResultBlock, decode controlAnswer by the block's control type:

  • single → string (the chosen option value) or null if unanswered.
  • multi → string[] (chosen option values; [] if none).
  • toggle → boolean.
  • report block / no controls → null.

Other fields:

  • text — the user's free-text for that block (empty string "" if untouched).
  • quotes — string[] of exact phrases the user highlighted from that block's content. These tell you precisely which words the reply emphasizes; weight them when interpreting text.
  • images — present only when the user pasted at least one image onto that block (or table row). Each entry is an absolute file path under ~/.toki/ the AI can Read — never inline base64.
  • meta.answered — count of blocks with any answer (a control selection and/or non-empty text); meta.total — block count.

Match each blocks[].id back to the id you assigned in the spec to anchor every answer to its decision/paragraph.

Notes

  • UI chrome is English (repo-artifact rule); the block content is whatever language you authored it in.
  • The CLI is decoupled (Bun built-ins only, zero external deps) so it ships as a standalone global binary — see cli/README.md.

Comments

Markdown supported