SuperAPI AI Directory

yakit-rightclick-plugin

General & other

View repository

Updated 10-16 01:32

About this skill

SKILL: Yakit right-click plugin (codec) usage and programming

AI LOAD INSTRUCTION: codec plugins are the lowest-cost way to write "small tools" in Yakit—Only need one handle(input) function. Set the plugin type to codec and turn on the "used for packet right-click" switch, and it will appear in the right-click menu of all HTTP editors such as MITM/History/Web Fuzzer, passing the currently selected text as input and displaying the return value of handle . This page covers the enabling method, programming contract, the two-level menu of Web Fuzzer right-click, and the command-line verification loop.

0. Related routes

1. The only contract of a codec plugin: handle(input)

// 一个最小可用的 codec 插件: 把选中文本 Base64 编码
handle = func(input /* string: 当前选中的文本 */) {
    return codec.EncodeBase64(input)   // 返回值即右键执行后的结果
}
  • The entry function is fixed as handle, the input parameter is the selected text (string), and it returns a string.
  • When there is no selection, the entire editor content is passed in.
  • handle Insidecodec / str / json / re / poc ...)。
  • Backend execution is exactly handle(input) this statement (SafeCallYakFunction(ctx, "handle", [input])), CLI and Yakit UI follow thecompletely identicalexecution path.

2. How to make it appear in the right-click menu (key: one tag)

In the Yakit plugin editor:

  1. Select plugin type codec。
  2. Turn on the switch "used for packet right-click"。

This switch essentially adds a tag to YakScript.Tags :

Switch text tag value Effect
Used for packet right-click allow-custom-context-menu-execute Appears in right-click → Plugin Extensions submenu (codec plugin)
HTTP packet transformation allow-custom-http-packet-mutate Appears in right-click → HTTP Packet Transformation (transforms the entire packet)
Single history record processing allow-custom-single-history-mutate Available in the right-click of a single History record
Multiple history record processing allow-custom-multiple-history-mutate Available in the right-click of multiple selected History records

When right-clicking in the editor, Yakit uses QueryYakScript({Type:'codec', Tag:['allow-custom-context-menu-execute']}) To pull out all codec plugins with this tag and inject them into Plugin Extensions / AI Tools menu. After saving the plugin, it triggers onRefPluginCodecMenu to reload the menu.

3. What happens after clicking (execution chain)

选中文本 → 右键 → 插件扩展 → 你的插件
   → onOpenFuzzerModal { text(选中文本), scriptName }
   → DebugPlugin { Input: text, PluginName, PluginType: 'codec' }
   → 引擎执行脚本并调用 handle(input)
   → 结果流式回显在 "Codec结果" 面板

Important behavioral difference:

  • The result of a codec right-click plugin is displayed in the panel (Codec result), and is not automatically written back to the editor—manual copy is required.
  • Built-in "encode/decode" (right-click → Encode/Decode, no plugin needed) and HTTP packet transformation plugin (allow-custom-http-packet-mutate) only then directly replace the editor content/entire packet.
  • To "select and replace" directly, usethe encode/decode in the selection floating menuin Web Fuzzer for the smoothest experience (see Section 5).

4. Programming Tips (writing a good right-click plugin)

  • Keep it a pure function: handle depend only on input, without reading external state, so results are predictable and easy to verify.
  • Be fault-tolerant, don't throw: when decoding fails, return a friendly prompt string instead of panicking, for a better right-click experience.
    handle = func(input) {
        raw, err = codec.DecodeBase64Url(input)
        if err != nil { return "decode failed: " + input }
        return string(raw)
    }
    
  • Make good use of the codec library: EncodeBase64/DecodeBase64/EncodeBase64Url/DecodeBase64Url、UnicodeDecode, all kinds of hash/symmetric encryption are in codec , and most small tools can be done in one line.
  • Prefer reversibility: for encode/decode types, try to ensure handle(handle(x)) or paired encode/decode, making it easy to switch back and forth.
  • Self-test before publishing: write if YAK_MAIN { runSelfTest() }, use yak file.yak to run assertions; note that handle should not be wrapped by YAK_MAIN (it needs to stay registered), only put the self-test inside the guard block.

5. Right-click in the Web Fuzzer editor (two-level menu)

The Web Fuzzer request editor has two sets of interactions, both of which can call encode/decode/plugins:

A. Monaco native right-click menu

Right-click to pop up, grouped to include:

  • Encode / Decode: built-in encode/decode (base64/url/hex/...), after selecting you can "replace content" to write back to the editor.
  • HTTP packet transformation: call the plugin with allow-custom-http-packet-mutate to transform the entire packet.
  • Plugin extensions / AI tools: call the codec plugin with allow-custom-context-menu-execute (results go to the panel).
  • Insert tag/dictionary: insert null bytes, temporary/Fuzz dictionaries,{{yak:dyn(...)}} hot-load tags, file tags, etc.

B. Selection floating action bar (most commonly used)

When you select a piece of text, an action bar floats up beside it:

  • Encode: wrap the selected text into a fuzztag andreplace the selection, for example selecting admin → {{base64enc(admin)}}, rendered by the Fuzzer engine when sending the packet.
  • Decode / Smart decode: go through AutoDecode to automatically identify the encoding and decode the plaintext, click "replace" to write back.
  • Plugin / AI: likewise feed the selected text to the codec plugin (results go to the panel).

Rule of thumb: if you want "select and replace with fuzztag" usefloating bar encode; if you want "take a look at the decoded result" usefloating bar decode/smart decode; if you want "run your own complex transformation" useright-click plugin extensions → codec plugin。

6. Command-line verification (same handle execution as the UI)

# 用 yaklang 源码引擎构建一次
cd /Users/v1ll4n/Projects/yaklang && go build -o /tmp/yak ./common/yak/cmd/yak.go

# 验证 codec 插件: 把 input 喂给 handle, 打印返回值
/tmp/yak codec-plugin --script skills/yakit-rightclick-plugin/examples/codec-base64-wrap.yak --input "admin:123456"
# -> output: YWRtaW46MTIzNDU2

# 也支持从文件读取 input
/tmp/yak codec-plugin --script x.yak --input-file /tmp/payload.bin

yak codec-plugin and Yakit right-click execution both call handle(input), so "the command runs successfully == right-click can also run successfully".

7. History right-click: input is the flow id, not text (important contract)

When right-clicking in a normal HTTP editor, input is the selected text; but in the History table row right-click , when running a codec plugin, the input passed in by Yakit is this record's flow id(verified, see yakit source code components/HTTPFlowTable/useHTTPFlowTableContextMenu.tsx):

Scenario tag (switch) input passed to handle
History single right-click allow-custom-single-history-mutate(used for history right-click (single selection)) single id, e.g. "1287"
History multi-select right-click allow-custom-multiple-history-mutate(used for history right-click (multi-select)) comma-joined ids, e.g. "1287,1290,1305"

The frontend, in the onOpenFuzzerModal event: single-select text = \${rowData.Id}`, 多选 text = selectedRowKeys.join(','), 同时携带脚本声明的 params` (cli parameters).

After getting the id, use db's Yield channel to look up the data packet, then perform extraction:

handle = func(input) {
    ids = parseIds(input)                          // "1287,1290" -> [1287, 1290]
    for flow in db.QueryHTTPFlowsByID(ids...) {     // Yield 通道, 底层 yakit.YieldHTTPFlows
        host = hostOf(flow.Url)
        for f in db.QueryHTTPFlowsByKeyword(host) { // 该 host 的全部历史流量
            req = codec.StrconvUnquote(f.Request)~  // flow.Request 是 quote 后的, 需还原
            // ... 提取 path / 参数名 / cookie
        }
    }
}

Progress bar: yakit.SetProgress

When the extraction volume is large, use yakit.SetProgress(0~1) to show progress in the execution panel (SetProgressEx(id, f) can be multiple):

total = len(hosts); done = 0
for host in hosts {
    yakit.SetProgress(float(done) / float(total))   // 注意 yak 的 for i,v in slice 给的是(元素,nil), 索引要自己数
    // ... 提取
    done++
}
yakit.SetProgress(1.0)

Fully runnable: examples/codec-history-extract-paths.yak (yak <file> self-test pure logic; --real <id> use real History to run the full chain of flow id -> data packet -> extraction).

8. codec plugin + cli parameters (let users choose "what to extract")

codec plugins can also declare cli parameters: on History right-click, Yakit will first pop up a parameter form, and after the user fills it in, execute handle. Use cli.StringSlice + setSelectOption + setMultipleSelect(false) to make an "extraction item" dropdown:

MODE_SEL = cli.StringSlice("mode",
    cli.setVerboseName("提取项"),
    cli.setSelectOption("提取 Path", "path"),
    cli.setSelectOption("提取 参数名", "param"),
    cli.setSelectOption("提取 Cookie", "cookie"),
    cli.setMultipleSelect(false), cli.setDefault("path"))
cli.check()
MODE = "path"
if len(MODE_SEL) > 0 { MODE = MODE_SEL[0] }

handle = func(input) {     // input 仍是 flow id; MODE 由表单决定提取什么
    // ... 按 MODE 提取, 可选 db.SavePayload 落字典, db.YieldPayload 回读复用
}

Fully runnable: examples/codec-cli-extract-selector.yak (self-test the three modes + Payload dictionary SavePayload/YieldPayload roundtrip; --real <id> --mode param run against the real database). For details on the cli parameter system, see yakit-native-plugin。

9. Web Fuzzer selection for "weird transformations"

In Web Fuzzer, select a segment (e.g. payload), right-click -> plugin extension -> codec plugin, input is the selected text, and any transformation can be performed and returned. A practical example: character-by-character mixed encoding (url %xx / html &#d; / unicode \uXXXX / original text alternating), to obtain "semantically equivalent but morphologically strange" variants for probing/bypassing simple WAFs:

handle = func(input) { return weirdTransform(input) }   // "admin" -> a%64&#109;\u0069n

Fully runnable: examples/codec-fuzzer-transform.yak. For selection "encode into fuzztag and replace", use the floating bar encoding (see Section 5 B); for complex transformations, use the right-click plugin extension. Tip: log.info is printf-style; to print content containing % , use the log.info("%s", x) placeholder; do not directly concatenate strings.

10. Examples (examples/)

File handle purpose input Verification
codec-base64-wrap.yak Base64-encode selected text Selected text --input "admin:123456"
codec-jwt-decode.yak One-click JWT decode header+payload Selected text --input "eyJ...header.eyJ...payload.sig"
codec-unicode-unescape.yak \uXXXX restore Chinese Selected text --input '\u4e2d\u6587abc'
codec-timestamp-to-date.yak Convert Unix timestamp to UTC date Selected text --input "1700000000"
codec-history-extract-paths.yak flow id lookup packet -> extract all host paths/parameter names (progress bar) flow id yak <file> / --real 1
codec-cli-extract-selector.yak codec + cli dropdown to select extraction of Path/parameter names/Cookie + save to dictionary flow id + cli yak <file> / --real 1 --mode param
codec-fuzzer-transform.yak Web Fuzzer selection character-by-character mixed encoding transformation Selected text --input "<script>alert(1)</script>"

Every example comes with a YAK_MAIN self-test block; yak <file>.yak is enough to self-verify; editor selection-type examples can be reproduced as evidence by the yak codec-plugin command. History extraction-type examples use synthetic data to self-test pure logic; --real <id> can run the real database chain.