Skip to content
Automation
Skill

/extension-upload

Package a script tool under ~/.config/agenvoy/tools/script/ into a tar.gz and publish to pkg.agenvoy.com registry. Keyword picker, dep/key detection, config-stored email (ask + lowercase + persist), ask version, email verification gate, multipart upload with downgrade/unique

From plugin
agenvoy
3739 skills
Install
$ npx -y skills add agenvoy/Agenvoy --skill extension-upload --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/extension-upload

Context preview

The summary Claude sees to decide when to auto-load this skill.

Package a script tool under ~/.config/agenvoy/tools/script/ into a tar.gz and publish to pkg.agenvoy.com registry. Keyword picker, dep/key detection, config-stored email (ask + lowercase + persist), ask version, email verification gate, multipart upload with downgrade/unique

SKILL.md

extension-upload.SKILL.md
name: extension-upload
description: Package a script tool under ~/.config/agenvoy/tools/script/ into a tar.gz and publish to pkg.agenvoy.com registry. Keyword picker, dep/key detection, config-stored email (ask + lowercase + persist), ask version, email verification gate, multipart upload with downgrade/unique guards.

Extension Uploader

Packages an Agenvoy script tool directory into a marketplace tarball and uploads it to pkg.agenvoy.com. The source root is fixed at `~/.config/agenvoy/tools/script/`. If the user provides a keyword (e.g. `yt`), only matching subdirectories are listed.

Input

`keyword` (**optional**): substring filter (case-insensitive) over subdirectories under `~/.config/agenvoy/tools/script/`. Examples: `yt`, `dlp`, `tts`.

  • **With keyword** → list filtered matches
  • **Without keyword** (e.g. plain `/extension-upload`) → **list ALL subdirectories for the user to pick**; do not ask for a keyword

0. Select `extension_dir` (picker)

Fixed source root:

SCRIPT_ROOT=~/.config/agenvoy/tools/script

`list_files` lists all first-level subdirectories under `SCRIPT_ROOT` (non-recursive). **Skip names starting with `.` or `_`.**

Branch by input:

| Has keyword? | Candidate set | |---|---| | No | All subdirectories | | Yes | Subdirectories whose name (lowercased) contains `keyword` (lowercased) |

Branch by candidate count:

| Count | Action | |---|---| | 0 | Abort. With keyword: "No directory matching `<keyword>` under `SCRIPT_ROOT`". Without keyword: "`SCRIPT_ROOT` is empty — create a script tool first using `write_tool`" | | 1 | Use that directory as `extension_dir` directly; report "auto-selected `<basename>`" | | ≥ 2 | `ask_user` singleSelect listing all candidates; user picks one as `extension_dir` |

`extension_dir` is the **absolute path** `<SCRIPT_ROOT>/<basename>`, used by every step below.

> Note: this skill only packages script tools (fixed `type: "script"`). Packaging api tools requires a separate skill. The worker does not accept `mcp` type.

Flow

1. Read the directory

`list_files` enumerates every file under `extension_dir` (relative paths, recursive).

**Collect into `raw_files`, excluding:**

  • `.DS_Store`, `Thumbs.db`, `.git*`
  • `*.tar`, `*.tar.gz`, `*.tgz`, `*.zip`
  • An existing `manifest.json` (this skill will regenerate it)

`read_file` reads (if present):

  • `tool.json` (**required** — if missing, abort with "tool.json missing in <extension_dir>, refuse to package")
  • All `script.{js,py,sh}` / `*.js` / `*.py` / `*.sh`

1.5 Generic structure check (gate)

Check root-level files under `extension_dir`. Abort immediately on any violation:

| Rule | Condition | |---|---| | tool.json must exist | `extension_dir/tool.json` exists and is a regular file | | script mutual exclusion | `script.py` and `script.js` **must not coexist** (both present → abort) |

Abort message:

❌ Structure check failed: script.py and script.js cannot coexist (keep only one).

2. Infer type

Fixed `type: "script"` (this skill only packages tools under `~/.config/agenvoy/tools/script/`).

2.5 Type-specific structure check (gate)

For `type: script`:

| Rule | Condition | |---|---| | script must exist | `script.py` or `script.js` must exist (exactly one); both missing → abort |

Abort message:

❌ Structure check failed: type:script requires script.py or script.js.

2.7 Health check (gate)

Verify the script can be parsed by its interpreter so consumers don't install something that immediately crashes. **Any failure aborts** and prints the stderr.

Branch on the script file confirmed in §2.5:

  • `script.py`:
  python3 -m py_compile <extension_dir>/script.py
  • `script.js`:
  node --check <extension_dir>/script.js

exit code ≠ 0 → abort:

❌ Health check failed: script cannot be parsed by the interpreter.
<first line of stderr>

> Note: only syntax-level. Top-level code is not executed; import errors / runtime errors / missing API keys are not checked. The author must test runtime behavior before packaging.

3. Detect `dependence` and `api_key_name`

Dependence (system binary names)

Scan every script file for these patterns to extract binaries:

  • JavaScript: `spawn("X"` / `exec("X"` / `execSync("X"` / `spawnSync("X"`
  • Python: `subprocess.run(["X"` / `subprocess.Popen(["X"` / `os.system("X "` / `shell=True` + `"X "`
  • Shell: the first non-reserved-word token

**Exclude:**

  • Shell builtins: `cd`, `echo`, `test`, `[`, `export`, `set`, `shift`, `pwd`, `true`, `false`
  • Interpreters themselves: `node`, `python`, `python3`, `bash`, `sh`, `/usr/bin/env`
  • Tools whitelisted by default: `ls`, `cat`, `head`, `tail`, `mkdir`, `cp`, `mv`, `rm`, `grep`, `sed`, `awk`, `find`, `jq`, `which`, `date`, `git` (almost always present; not counted as a dependence)

What remains (e.g. `yt-dlp`, `ffmpeg`, `imagemagick`, `pandoc`, `tesseract`) is the `dependence` candidate set.

Api_key_name (keychain key names)

Scan every script file for these patterns to extract key names:

  • `localhost:17989/v1/key?key=([A-Z][A-Z0-9_]*_API_KEY)`
  • `process\.env\.([A-Z][A-Z0-9_]*_API_KEY)`
  • `os\.environ\[["']([A-Z][A-Z0-9_]*_API_KEY)["']\]`
  • `os\.environ\.get\(["']([A-Z][A-Z0-9_]*_API_KEY)["']`
  • `\$([A-Z][A-Z0-9_]*_API_KEY)` (shell scripts)

Dedupe and sort all hits.

Confirm detection results

Call `ask_user`. Put the detection list in the `detail` field (hint-style subtitle); keep `question` short:

{
  "questions": [
    {
      "question": "Are the detections above correct?",
      "detail": "dependence: [yt-dlp, ffmpeg]\napi_key_name: []",
      "options": ["Yes, continue", "No, let me edit dependence", "No, let me edit api_key_name", "No, edit both"]
    }
  ]
}

`detail` is multi-line hint text; `question` is the short prompt. The popup renders `detail` with hint style (subtitle) and `question` with bold (title). **Never** stuff `detail` content into `question` — they will render togethe

Read more
Ships withagenvoy

Make AI actually work for you — a personal AI harness that writes and repairs its own tools, and lets Claude Code and Codex build and share them via MCP.

Get the whole plugin
Stats
374
Stars
37
Forks
Active
Maintenance
Go
Language
Apache-2.0
License
7h ago
Last commit
6mo ago
Created

Repo: agenvoy/Agenvoy

Other skills on agenvoy.