vtx-coding-agent 0.1.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. vtx/__init__.py +63 -0
  2. vtx/async_utils.py +40 -0
  3. vtx/builtin_skills/github/SKILL.md +139 -0
  4. vtx/builtin_skills/init/SKILL.md +74 -0
  5. vtx/builtin_skills/review/SKILL.md +73 -0
  6. vtx/builtin_skills/skill-builder/SKILL.md +133 -0
  7. vtx/cli.py +90 -0
  8. vtx/config.py +741 -0
  9. vtx/context/__init__.py +15 -0
  10. vtx/context/_xml.py +8 -0
  11. vtx/context/agent_mds.py +128 -0
  12. vtx/context/git.py +64 -0
  13. vtx/context/loader.py +41 -0
  14. vtx/context/skills.py +423 -0
  15. vtx/core/__init__.py +47 -0
  16. vtx/core/compaction.py +89 -0
  17. vtx/core/errors.py +17 -0
  18. vtx/core/handoff.py +51 -0
  19. vtx/core/scratchpad.py +54 -0
  20. vtx/core/types.py +197 -0
  21. vtx/defaults/__init__.py +0 -0
  22. vtx/defaults/config.yml +53 -0
  23. vtx/diff_display.py +12 -0
  24. vtx/events.py +224 -0
  25. vtx/gh_cli.py +82 -0
  26. vtx/git_branch.py +90 -0
  27. vtx/headless.py +127 -0
  28. vtx/llm/__init__.py +93 -0
  29. vtx/llm/base.py +217 -0
  30. vtx/llm/context_length.py +150 -0
  31. vtx/llm/dynamic_models.py +735 -0
  32. vtx/llm/model_fetcher.py +279 -0
  33. vtx/llm/models.py +78 -0
  34. vtx/llm/oauth/__init__.py +59 -0
  35. vtx/llm/oauth/copilot.py +358 -0
  36. vtx/llm/oauth/dynamic.py +236 -0
  37. vtx/llm/oauth/openai.py +400 -0
  38. vtx/llm/phase_parser.py +270 -0
  39. vtx/llm/provider.yaml +280 -0
  40. vtx/llm/provider_catalog.py +230 -0
  41. vtx/llm/providers/__init__.py +45 -0
  42. vtx/llm/providers/anthropic_sdk.py +256 -0
  43. vtx/llm/providers/mock.py +249 -0
  44. vtx/llm/providers/openai_sdk.py +246 -0
  45. vtx/llm/providers/sanitize.py +14 -0
  46. vtx/llm/sdk/__init__.py +13 -0
  47. vtx/llm/sdk/anthropic.py +382 -0
  48. vtx/llm/sdk/base.py +82 -0
  49. vtx/llm/sdk/openai.py +344 -0
  50. vtx/llm/tool_parser.py +161 -0
  51. vtx/loop.py +272 -0
  52. vtx/notify.py +109 -0
  53. vtx/permissions.py +114 -0
  54. vtx/prompts/__init__.py +45 -0
  55. vtx/prompts/builder.py +86 -0
  56. vtx/prompts/env.py +58 -0
  57. vtx/prompts/identity.py +166 -0
  58. vtx/prompts/tooling.py +36 -0
  59. vtx/py.typed +0 -0
  60. vtx/runtime.py +580 -0
  61. vtx/session.py +868 -0
  62. vtx/sounds/completion.wav +0 -0
  63. vtx/sounds/error.wav +0 -0
  64. vtx/sounds/permission.wav +0 -0
  65. vtx/themes.py +1104 -0
  66. vtx/tools/__init__.py +68 -0
  67. vtx/tools/_read_image.py +106 -0
  68. vtx/tools/_tool_utils.py +90 -0
  69. vtx/tools/base.py +36 -0
  70. vtx/tools/bash.py +371 -0
  71. vtx/tools/edit.py +261 -0
  72. vtx/tools/find.py +132 -0
  73. vtx/tools/read.py +238 -0
  74. vtx/tools/skill.py +278 -0
  75. vtx/tools/web.py +238 -0
  76. vtx/tools/write.py +88 -0
  77. vtx/tools_manager.py +216 -0
  78. vtx/turn.py +789 -0
  79. vtx/ui/__init__.py +0 -0
  80. vtx/ui/agent_runner.py +417 -0
  81. vtx/ui/app.py +665 -0
  82. vtx/ui/app_protocol.py +29 -0
  83. vtx/ui/autocomplete.py +440 -0
  84. vtx/ui/blocks.py +735 -0
  85. vtx/ui/chat.py +613 -0
  86. vtx/ui/clipboard.py +59 -0
  87. vtx/ui/commands/__init__.py +100 -0
  88. vtx/ui/commands/auth.py +306 -0
  89. vtx/ui/commands/base.py +122 -0
  90. vtx/ui/commands/models.py +144 -0
  91. vtx/ui/commands/sessions.py +388 -0
  92. vtx/ui/commands/settings.py +286 -0
  93. vtx/ui/completion_ui.py +313 -0
  94. vtx/ui/export.py +703 -0
  95. vtx/ui/floating_list.py +370 -0
  96. vtx/ui/formatting.py +287 -0
  97. vtx/ui/input.py +760 -0
  98. vtx/ui/latex.py +349 -0
  99. vtx/ui/launch.py +108 -0
  100. vtx/ui/path_complete.py +228 -0
  101. vtx/ui/prompt_history.py +102 -0
  102. vtx/ui/queue_ui.py +141 -0
  103. vtx/ui/selection_mode.py +18 -0
  104. vtx/ui/session_ui.py +235 -0
  105. vtx/ui/startup.py +124 -0
  106. vtx/ui/styles.py +327 -0
  107. vtx/ui/tool_output.py +34 -0
  108. vtx/ui/tree.py +437 -0
  109. vtx/ui/welcome.py +51 -0
  110. vtx/ui/widgets.py +558 -0
  111. vtx/update_check.py +49 -0
  112. vtx/version.py +22 -0
  113. vtx_coding_agent-0.1.1.dist-info/METADATA +259 -0
  114. vtx_coding_agent-0.1.1.dist-info/RECORD +117 -0
  115. vtx_coding_agent-0.1.1.dist-info/WHEEL +4 -0
  116. vtx_coding_agent-0.1.1.dist-info/entry_points.txt +2 -0
  117. vtx_coding_agent-0.1.1.dist-info/licenses/LICENSE +201 -0
vtx/__init__.py ADDED
@@ -0,0 +1,63 @@
1
+ from vtx.config import (
2
+ AVAILABLE_BINARIES,
3
+ CONFIG_DIR_NAME,
4
+ Config,
5
+ consume_config_warnings,
6
+ get_agents_dir,
7
+ get_config,
8
+ get_config_dir,
9
+ reload_config,
10
+ reset_config,
11
+ set_colored_tool_badge,
12
+ set_config,
13
+ set_git_context,
14
+ set_notifications_enabled,
15
+ set_permissions_mode,
16
+ set_show_welcome_shortcuts,
17
+ set_theme,
18
+ set_thinking_lines,
19
+ update_available_binaries,
20
+ )
21
+ from vtx.context._xml import escape_xml
22
+ from vtx.core.scratchpad import get_scratchpad_dir, init_scratchpad, is_scratchpad_path
23
+
24
+
25
+ class _ConfigProxy(Config):
26
+ """Proxy that delegates to get_config() for runtime reloading and test injection."""
27
+
28
+ def __init__(self) -> None:
29
+ # Do not call super().__init__(): all attribute access is delegated to
30
+ # the live config returned by get_config() via __getattr__ below.
31
+ pass
32
+
33
+ def __getattr__(self, name: str):
34
+ return getattr(get_config(), name)
35
+
36
+
37
+ config = _ConfigProxy()
38
+
39
+ __all__ = [
40
+ "AVAILABLE_BINARIES",
41
+ "CONFIG_DIR_NAME",
42
+ "Config",
43
+ "config",
44
+ "consume_config_warnings",
45
+ "escape_xml",
46
+ "get_agents_dir",
47
+ "get_config",
48
+ "get_config_dir",
49
+ "get_scratchpad_dir",
50
+ "init_scratchpad",
51
+ "is_scratchpad_path",
52
+ "reload_config",
53
+ "reset_config",
54
+ "set_colored_tool_badge",
55
+ "set_config",
56
+ "set_git_context",
57
+ "set_notifications_enabled",
58
+ "set_permissions_mode",
59
+ "set_show_welcome_shortcuts",
60
+ "set_theme",
61
+ "set_thinking_lines",
62
+ "update_available_binaries",
63
+ ]
vtx/async_utils.py ADDED
@@ -0,0 +1,40 @@
1
+ import asyncio
2
+ from contextlib import suppress
3
+ from typing import Any
4
+
5
+
6
+ class OperationCancelledError(Exception):
7
+ pass
8
+
9
+
10
+ async def cancel_and_await(task: asyncio.Future[Any]) -> None:
11
+ if task.done():
12
+ return
13
+ task.cancel()
14
+ with suppress(asyncio.CancelledError):
15
+ await task
16
+
17
+
18
+ async def await_or_cancel[T](work: asyncio.Future[T], cancel_event: asyncio.Event | None) -> T:
19
+ if not cancel_event:
20
+ return await work
21
+
22
+ if cancel_event.is_set():
23
+ await cancel_and_await(work)
24
+ raise OperationCancelledError
25
+
26
+ cancel = asyncio.create_task(cancel_event.wait())
27
+ try:
28
+ done, pending = await asyncio.wait({work, cancel}, return_when=asyncio.FIRST_COMPLETED)
29
+
30
+ for task in pending:
31
+ await cancel_and_await(task)
32
+
33
+ if cancel in done and cancel_event.is_set():
34
+ if not work.done():
35
+ await cancel_and_await(work)
36
+ raise OperationCancelledError
37
+
38
+ return work.result()
39
+ finally:
40
+ await cancel_and_await(cancel)
@@ -0,0 +1,139 @@
1
+ ---
2
+ name: github
3
+ description: Run GitHub CLI commands, manage repositories, issues, PRs, releases, actions, or call arbitrary REST/GraphQL endpoints using `gh api`
4
+ register_cmd: true
5
+ ---
6
+
7
+ # GitHub CLI & API Skill
8
+
9
+ Use this skill when you need to interact with GitHub repositories, pull requests, issues, releases, actions, or configure GitHub settings. This skill relies on the GitHub CLI (`gh`) and the GitHub REST/GraphQL APIs.
10
+
11
+ ---
12
+
13
+ ## 🔐 Authentication & Setup
14
+
15
+ Before running commands, verify your login status and configure authentication if needed.
16
+
17
+ ### Check login status
18
+ ```bash
19
+ gh auth status
20
+ ```
21
+
22
+ ### Authenticate
23
+ If not authenticated, or if you need a token in a script:
24
+ - **Interactive login:** `gh auth login`
25
+ - **Non-interactive token login:**
26
+ ```bash
27
+ echo "YOUR_GITHUB_TOKEN" | gh auth login --with-token
28
+ ```
29
+ - **Environment variable:** Expose `GITHUB_TOKEN` in your environment. Many tools and commands automatically read `GITHUB_TOKEN`.
30
+
31
+ ---
32
+
33
+ ## 🛠️ GitHub CLI Command Reference
34
+
35
+ Below are the most common GitHub CLI operations. Always prefer using built-in `gh` subcommands over direct `gh api` queries for standard actions.
36
+
37
+ ### 📦 Repository Management
38
+ * **List Repositories:** `gh repo list [owner] --limit 50`
39
+ * **Create Repository:** `gh repo create [name] --public --clone`
40
+ * **Fork Repository:** `gh repo fork --clone`
41
+ * **Clone Repository:** `gh repo clone OWNER/REPO`
42
+ * **View Repo Info:** `gh repo view --web`
43
+
44
+ ### 🔧 Issues
45
+ * **List Issues:** `gh issue list --state open --assignee @me`
46
+ * **Create Issue:** `gh issue create --title "Title" --body "Body content" --label "bug,help-wanted"`
47
+ * **View/Comment Issue:**
48
+ * View issue: `gh issue view 123`
49
+ * Comment on issue: `gh issue comment 123 --body "Nice fix!"`
50
+ * **Close/Reopen Issue:**
51
+ * Close issue: `gh issue close 123 --reason "completed"`
52
+ * Reopen issue: `gh issue reopen 123`
53
+
54
+ ### 🔀 Pull Requests
55
+ * **List PRs:** `gh pr list --state open --limit 20`
56
+ * **Create PR:** `gh pr create --title "Title" --body "Body description" --base main --head feature-branch`
57
+ * **Checkout PR:** `gh pr checkout 123`
58
+ * **Review PR:** `gh pr review 123 --approve --body "Looks good to go!"`
59
+ * **Merge PR:** `gh pr merge 123 --merge --delete-branch`
60
+ * **Check Status:** `gh pr checks 123`
61
+ * **View Diff:** `gh pr diff 123`
62
+
63
+ ### 🚀 Releases
64
+ * **List Releases:** `gh release list`
65
+ * **Create Release:** `gh release create v1.0.0 --title "v1.0.0" --notes "Release notes text"`
66
+ * **Upload Assets:** `gh release create v1.0.0 ./dist/bundle.tar.gz ./dist/metadata.json`
67
+
68
+ ### ⚙️ Secrets & Environments
69
+ * **List Secrets:** `gh secret list`
70
+ * **Set Repository Secret:** `gh secret set MY_SECRET --body "secret_value"`
71
+ * **Set Environment Secret:** `gh secret set MY_SECRET --env production --body "secret_value"`
72
+
73
+ ### 🔄 GitHub Actions & Workflows
74
+ * **List Workflows:** `gh workflow list`
75
+ * **List Runs:** `gh run list --workflow=ci.yml --limit 5`
76
+ * **View Run Logs:** `gh run view 123456 --log`
77
+ * **Trigger Workflow:** `gh workflow run ci.yml -f ref=main -f environment=staging`
78
+
79
+ ---
80
+
81
+ ## 📡 Advanced GitHub API Integration (`gh api`)
82
+
83
+ When built-in `gh` commands do not support the operation, use `gh api` to talk directly to GitHub's REST or GraphQL endpoints.
84
+
85
+ ### Key Features of `gh api`
86
+ 1. **Automatic Placeholders:** The API command automatically expands `{owner}` and `{repo}` with the details of your current repository directory (e.g. `repos/{owner}/{repo}/issues` maps to `repos/OEvortex/vtx-coding-agent/issues`).
87
+ 2. **Method Detection:** Defaults to `GET`. Automatically switches to `POST` if request parameters (`-f`/`-F`) are passed. You can override with `--method DELETE` or `--method PUT`.
88
+ 3. **Type Binding:**
89
+ * `-f / --raw-field` maps parameters as raw strings.
90
+ * `-F / --field` parses fields to their JSON representations (numbers, booleans, arrays). To load content from a file, prefix the value with `@` (e.g., `-F body=@issue_template.md`).
91
+
92
+ ### Common `gh api` Examples
93
+
94
+ #### 1. Retrieve current user details
95
+ ```bash
96
+ gh api user
97
+ ```
98
+
99
+ #### 2. Create a comment on an issue/PR (REST)
100
+ ```bash
101
+ gh api repos/{owner}/{repo}/issues/123/comments -f body="Automated comment via API"
102
+ ```
103
+
104
+ #### 3. List workflow runs in a repository
105
+ ```bash
106
+ gh api repos/{owner}/{repo}/actions/runs --jq '.workflow_runs[] | {id, status, conclusion}'
107
+ ```
108
+
109
+ #### 4. Run a GraphQL Query
110
+ ```bash
111
+ gh api graphql -f query='
112
+ query {
113
+ viewer {
114
+ login
115
+ createdAt
116
+ }
117
+ }
118
+ '
119
+ ```
120
+
121
+ #### 5. Fetch a file content via API
122
+ ```bash
123
+ gh api repos/{owner}/{repo}/contents/path/to/file.py --jq '.content' | base64 --decode
124
+ ```
125
+
126
+ ---
127
+
128
+ ## 💡 Best Practices
129
+
130
+ 1. **Disable Interactive Prompts:** By default, commands like `gh pr create` or `gh repo create` can prompt for inputs interactively. In scripts or unattended environments, always add the non-interactive flags (e.g., `-y`, `--confirm`, or provide all arguments such as `--title` and `--body` explicitly).
131
+ 2. **Filter Output with `jq`:** GitHub API responses are large JSON structures. Use the CLI's built-in `--jq` flag or pipe to external `jq` for readability.
132
+ ```bash
133
+ gh issue list --json number,title --jq '.[] | "#\(.number) \(.title)"'
134
+ ```
135
+ 3. **Environment Variables for Context:** If you need to target a repository outside the current git working directory, set the `GH_REPO` variable:
136
+ ```bash
137
+ GH_REPO="other-owner/other-repo" gh issue list
138
+ ```
139
+ 4. **Rate Limit Handling:** Use `gh api rate_limit` to check your current REST/GraphQL API rate limits if executing a loop or batch task.
@@ -0,0 +1,74 @@
1
+ ---
2
+ name: init
3
+ description: Create or update AGENTS.md for this repository
4
+ register_cmd: true
5
+ cmd_info: guided AGENTS.md setup
6
+ category: setup
7
+ ---
8
+
9
+ Create or update `AGENTS.md` for this repository.
10
+
11
+ The goal is a compact instruction file that helps future Vtx sessions avoid mistakes and ramp up quickly. Every line should answer: "Would an agent likely miss this without help?" If not, leave it out.
12
+
13
+ User-provided focus or constraints (honor these):
14
+ $ARGUMENTS
15
+
16
+ ## How to investigate
17
+
18
+ Read the highest-value sources first:
19
+ - `README*`, root manifests, workspace config, lockfiles
20
+ - build, test, lint, formatter, typecheck, and codegen config
21
+ - CI workflows and pre-commit / task runner config
22
+ - existing instruction files (`AGENTS.md`, `CLAUDE.md`, `.cursor/rules/`, `.cursorrules`, `.github/copilot-instructions.md`)
23
+ - repo-local Vtx config and conventions
24
+
25
+ If architecture is still unclear after reading config and docs, inspect a small number of representative code files to find the real entrypoints, package boundaries, and execution flow. Prefer reading the files that explain how the system is wired together over random leaf files.
26
+
27
+ Prefer executable sources of truth over prose. If docs conflict with config or scripts, trust the executable source and only keep what you can verify.
28
+
29
+ ## What to extract
30
+
31
+ Look for the highest-signal facts for an agent working in this repo:
32
+ - exact developer commands, especially non-obvious ones
33
+ - how to run a single test, a single package, or a focused verification step
34
+ - required command order when it matters, such as `lint -> typecheck -> test`
35
+ - monorepo or multi-package boundaries, ownership of major directories, and the real app/library entrypoints
36
+ - framework or toolchain quirks: generated code, migrations, codegen, build artifacts, special env loading, dev servers, infra deploy flow
37
+ - repo-specific style or workflow conventions that differ from defaults
38
+ - testing quirks: fixtures, integration test prerequisites, snapshot workflows, required services, flaky or expensive suites
39
+ - important constraints from existing instruction files worth preserving
40
+
41
+ Good `AGENTS.md` content is usually hard-earned context that took reading multiple files to infer.
42
+
43
+ ## Questions
44
+
45
+ Only ask the user questions if the repo cannot answer something important. Use the question tool for one short batch at most.
46
+
47
+ Good questions:
48
+ - undocumented team conventions
49
+ - branch / PR / release expectations
50
+ - missing setup or test prerequisites that are known but not written down
51
+
52
+ Do not ask about anything the repo already makes clear.
53
+
54
+ ## Writing rules
55
+
56
+ Include only high-signal, repo-specific guidance such as:
57
+ - exact commands and shortcuts the agent would otherwise guess wrong
58
+ - architecture notes that are not obvious from filenames
59
+ - conventions that differ from language or framework defaults
60
+ - setup requirements, environment quirks, and operational gotchas
61
+ - references to existing instruction sources that matter
62
+
63
+ Exclude:
64
+ - generic software advice
65
+ - long tutorials or exhaustive file trees
66
+ - obvious language conventions
67
+ - speculative claims or anything you could not verify
68
+ - content better stored in another file referenced via Vtx config or another instruction file
69
+
70
+ When in doubt, omit.
71
+
72
+ Prefer short sections and bullets. If the repo is simple, keep the file simple. If the repo is large, summarize the few structural facts that actually change how an agent should work.
73
+
74
+ If `AGENTS.md` already exists, improve it in place rather than rewriting blindly. Preserve verified useful guidance, delete fluff or stale claims, and reconcile it with the current codebase.
@@ -0,0 +1,73 @@
1
+ ---
2
+ name: review
3
+ description: Review code changes and return prioritized, actionable findings
4
+ register_cmd: true
5
+ cmd_info: review code changes
6
+ category: review
7
+ ---
8
+
9
+ Review the requested code changes as if you are reviewing another engineer's PR.
10
+
11
+ User-provided target or constraints (honor these):
12
+ $ARGUMENTS
13
+
14
+ ## Target selection
15
+
16
+ - If no target is provided, review the current code changes: staged, unstaged, and untracked files.
17
+ - If the user provides a base branch, review the changes that would merge into that branch. Find the merge base and inspect the diff from that commit.
18
+ - If the user provides a commit SHA, review only the changes introduced by that commit.
19
+ - If the user provides a PR number, PR URL, or text like `PR#68 feat/headless-mode "feat: add non-interactive prompt mode"`, assume the GitHub CLI is available. Use `gh pr view` to inspect PR metadata, resolve the base/head branches, fetch as needed, compute the merge base, and review the PR diff. Do not checkout a different branch unless the user explicitly asks or confirms.
20
+ - For PRs, do not assume the head branch exists on `origin`; it may live on a contributor fork. Prefer `gh pr checkout --detach <number>` only if checkout is acceptable, or fetch the head repository/ref reported by `gh pr view --json headRepository,headRefName` into a temporary remote/ref before diffing.
21
+ - For a PR scenario such as `/review PR#68 feat/headless-mode "feat: add non-interactive prompt mode"`, use the PR number/title/branch as hints, verify them with `gh pr view 68`, then review the code changes relative to the PR base branch.
22
+
23
+ ## Review rubric
24
+
25
+ Only report issues the original author would likely fix if they knew about them.
26
+
27
+ Flag a finding only when:
28
+ - it meaningfully affects correctness, security, performance, reliability, or maintainability;
29
+ - it is discrete and actionable;
30
+ - it appears introduced by the reviewed change;
31
+ - you can identify the affected code path or user scenario;
32
+ - it is not merely a style preference, nit, or intentional behavior change.
33
+
34
+ Do not stop at the first issue. Return all qualifying findings. If there are no findings worth fixing, say so clearly.
35
+
36
+ ## Investigation guidance
37
+
38
+ Use repository tools to inspect the actual diff and surrounding code. Prefer precise commands such as:
39
+ - `git status --short`
40
+ - `git diff --staged`
41
+ - `git diff`
42
+ - `git diff <merge-base>...HEAD`
43
+ - `git show <sha>`
44
+ - `gh pr view <number> --json number,title,body,baseRefName,headRefName,url,author`
45
+
46
+ Read nearby implementation and tests when needed to prove whether a suspected issue is real. Avoid speculative findings.
47
+
48
+ ## Priority rubric
49
+
50
+ Use these severity levels for finding titles:
51
+ - `[P0]` — Drop everything to fix. Blocking release, operations, or major usage. Only use for universal issues that do not depend on assumptions about inputs.
52
+ - `[P1]` — Urgent. Should be addressed in the next cycle.
53
+ - `[P2]` — Normal. Should be fixed eventually.
54
+ - `[P3]` — Low. Nice to have.
55
+
56
+ ## Finding format
57
+
58
+ For each finding, include:
59
+ - priority tag in the title: `[P0]`, `[P1]`, `[P2]`, or `[P3]`;
60
+ - concise title;
61
+ - file path and line range;
62
+ - one short paragraph explaining why this is a bug and when it matters;
63
+ - confidence score if useful.
64
+
65
+ Keep line ranges as short as possible and make sure they overlap the reviewed diff when possible.
66
+
67
+ End with an overall verdict:
68
+ - `patch is correct` if existing code/tests should not break and no blocking issues were found;
69
+ - `patch is incorrect` if the patch has blocking correctness, security, reliability, or maintainability issues that should prevent merging.
70
+
71
+ Do not mark a patch incorrect for non-blocking issues such as style, formatting, typos, documentation nits, or ordinary `[P2]`/`[P3]` follow-ups unless they still indicate the patch should not merge.
72
+
73
+ Do not fix the code unless the user asks after the review.
@@ -0,0 +1,133 @@
1
+ ---
2
+ name: skill-builder
3
+ description: Create a new Vtx skill (SKILL.md) with the correct frontmatter, body, and conventions
4
+ register_cmd: true
5
+ cmd_info: scaffold a new skill
6
+ category: meta
7
+ ---
8
+
9
+ Create a new Vtx skill at the right location with the right shape.
10
+
11
+ A skill is a directory containing a `SKILL.md`. Vtx auto-discovers skills from `<cwd-or-ancestor>/.agents/skills/` (project) and `~/.agents/skills/` (user). Project skills shadow user skills with the same name. The skill name MUST match the directory name.
12
+
13
+ User-provided focus or constraints (honor these):
14
+ $ARGUMENTS
15
+
16
+ ## Where to put it
17
+
18
+ - Project skill (preferred for repo-specific workflows): `<repo>/.agents/skills/<name>/SKILL.md`. Use this when the skill encodes conventions, commands, or escape hatches that only make sense in this repo.
19
+ - User skill (preferred for personal workflows): `~/.agents/skills/<name>/SKILL.md`. Use this for cross-repo utilities (e.g. "release-checklist", "draft-pr").
20
+ - Never put a skill at the repo root or in a non-`.agents/skills/` path — Vtx will not discover it.
21
+
22
+ ## Frontmatter (YAML between `---` markers)
23
+
24
+ Required:
25
+ - `name` — lowercase letters, digits, hyphens. Must equal the directory name. Max 64 chars. No leading/trailing hyphen, no `--`.
26
+
27
+ Recommended:
28
+ - `description` — required (the loader rejects skills without one). One short sentence, max 1024 chars. Describe the trigger, not the implementation. The agent uses this to decide when to load the skill.
29
+ - `category` — one of `setup`, `review`, `workflows`, `meta`, `general`, etc. Categories group skills in the `<available_skills>` index. Default is `general` if omitted. Max 32 chars.
30
+ - `register_cmd: true` — expose the skill as a slash command (`/<name>`) and include it in the `/` menu. Add this when the skill is something the user would invoke explicitly.
31
+ - `register_cmd: only` — register the slash command but do NOT inject the skill into the system prompt. Use for heavy skills that should be loaded on demand only.
32
+ - `cmd_info` — short label shown in the slash menu (max 32 chars). Required when `register_cmd` is true.
33
+
34
+ Minimal valid frontmatter:
35
+
36
+ ```yaml
37
+ ---
38
+ name: my-skill
39
+ description: Do the X thing when the user asks for X
40
+ ---
41
+ ```
42
+
43
+ Full frontmatter:
44
+
45
+ ```yaml
46
+ ---
47
+ name: my-skill
48
+ description: Do the X thing when the user asks for X
49
+ register_cmd: true
50
+ cmd_info: run the X thing
51
+ category: workflows
52
+ ---
53
+ ```
54
+
55
+ ## Body
56
+
57
+ The body is plain Markdown, shown verbatim when the skill loads. Treat it as instructions to a future agent.
58
+
59
+ Conventions:
60
+ - Open with a one-line summary of what the skill does.
61
+ - Include `User-provided focus or constraints (honor these):` followed by `$ARGUMENTS` so the slash-command arguments are passed through.
62
+ - Use `##` and `###` sections. Vtx renders them as headings; the agent uses them to skim.
63
+ - Prefer concrete commands, file paths, and decision rules over prose.
64
+ - Keep it focused. A skill that tries to cover everything is worse than several focused skills. Move long reference material to a separate file in the skill directory and link to it.
65
+
66
+ ## Validating
67
+
68
+ After writing, sanity-check:
69
+ 1. `name` matches the directory name.
70
+ 2. Description is non-empty, one sentence, names the trigger condition.
71
+ 3. If `register_cmd: true` is set, `cmd_info` is set and under 32 chars.
72
+ 4. Category (if set) is short and reusable across skills.
73
+ 5. No required frontmatter field is missing.
74
+
75
+ Vtx logs warnings to stderr on load for invalid skills. Restart Vtx or run `/new` to reload the index after creating a new skill.
76
+
77
+ ## What to write vs. what to skip
78
+
79
+ Write:
80
+ - exact commands the agent would otherwise guess wrong
81
+ - repo or workflow-specific decision rules
82
+ - escape hatches for known gotchas
83
+ - the user-provided arguments passthrough line (`$ARGUMENTS`)
84
+
85
+ Skip:
86
+ - generic coding advice (the base system prompt already covers it)
87
+ - long tutorials that belong in README or docs
88
+ - speculative or unverifiable claims
89
+ - duplicated content that is already in `AGENTS.md` (reference it instead)
90
+
91
+ ## Example
92
+
93
+ For a skill that drafts release notes from the recent git log:
94
+
95
+ Path: `~/.agents/skills/draft-release-notes/SKILL.md`
96
+
97
+ ```markdown
98
+ ---
99
+ name: draft-release-notes
100
+ description: Draft release notes from `git log` between the last tag and HEAD
101
+ register_cmd: true
102
+ cmd_info: draft release notes
103
+ category: workflows
104
+ ---
105
+
106
+ Draft release notes for the next release.
107
+
108
+ User-provided focus or constraints (honor these):
109
+ $ARGUMENTS
110
+
111
+ ## Steps
112
+
113
+ 1. Find the last release tag: `git describe --tags --abbrev=0`.
114
+ 2. Collect commits since that tag: `git log <tag>..HEAD --oneline --no-merges`.
115
+ 3. Group by area (use the conventional-commit prefix or the directories touched).
116
+ 4. Write a short bullet list under `## Highlights` and `## Fixes`, mirroring the user's requested tone.
117
+ 5. Print the result; do not write to a file unless the user asked.
118
+
119
+ ## Style
120
+
121
+ - One bullet per change. Lead with the user-facing effect, not the implementation.
122
+ - Group by area, not by commit order.
123
+ - Skip dependency bumps and pure refactors unless they affect behavior.
124
+ ```
125
+
126
+ ## Common mistakes to avoid
127
+
128
+ - Setting `description` to a list of features instead of a trigger condition. The agent reads the description to decide whether to load the skill — a vague description means the skill rarely fires.
129
+ - Putting long body content in `description`. Description is a summary, not the body.
130
+ - Forgetting `$ARGUMENTS`. Without it, slash-command arguments are dropped.
131
+ - Naming the skill `foo` but putting it in `.agents/skills/foo-bar/`. The loader warns and may not surface the skill.
132
+ - Setting `register_cmd: true` without `cmd_info`. The slash menu will show an empty entry.
133
+ - Writing a skill that duplicates an existing one. Run `/` and check the menu first; if a similar skill exists, extend it or add a category to disambiguate.
vtx/cli.py ADDED
@@ -0,0 +1,90 @@
1
+ import argparse
2
+ import asyncio
3
+
4
+ from vtx import config
5
+
6
+ from .llm import PROVIDER_API_BY_NAME
7
+ from .version import VERSION
8
+
9
+
10
+ def build_parser() -> argparse.ArgumentParser:
11
+ parser = argparse.ArgumentParser(description="Vtx")
12
+ parser.add_argument("--model", "-m", help="Model to use")
13
+ parser.add_argument("--provider", choices=sorted(PROVIDER_API_BY_NAME), help="Provider to use")
14
+ parser.add_argument(
15
+ "--prompt",
16
+ "-p",
17
+ nargs="?",
18
+ const="-",
19
+ default=None,
20
+ help="Run a single prompt non-interactively, then exit "
21
+ "(omit the value or pipe stdin to read the prompt from stdin)",
22
+ )
23
+ parser.add_argument("--api-key", "-k", help="API key")
24
+ parser.add_argument("--base-url", "-u", help="Base URL for API")
25
+ parser.add_argument(
26
+ "--openai-compat-auth",
27
+ choices=("auto", "required", "none"),
28
+ help="Auth mode for OpenAI-compatible endpoints",
29
+ )
30
+ parser.add_argument(
31
+ "--anthropic-compat-auth",
32
+ choices=("auto", "required", "none"),
33
+ help="Auth mode for Anthropic-compatible endpoints",
34
+ )
35
+ parser.add_argument(
36
+ "--insecure-skip-verify",
37
+ action="store_true",
38
+ help="Skip TLS verification (e.g. self-signed certs on local providers)",
39
+ )
40
+ parser.add_argument(
41
+ "--continue",
42
+ "-c",
43
+ action="store_true",
44
+ dest="continue_recent",
45
+ help="Resume the most recent session",
46
+ )
47
+ parser.add_argument(
48
+ "--resume",
49
+ "-r",
50
+ dest="resume_session",
51
+ help="Resume a specific session by ID (full or unique prefix)",
52
+ )
53
+ parser.add_argument("--version", action="version", version=f"vtx {VERSION}")
54
+ return parser
55
+
56
+
57
+ def main() -> None:
58
+ parser = build_parser()
59
+ args = parser.parse_args()
60
+
61
+ if args.prompt is not None and (args.continue_recent or args.resume_session):
62
+ parser.error("-c/--continue and -r/--resume are not supported with -p/--prompt")
63
+
64
+ if args.insecure_skip_verify:
65
+ config.llm.tls.insecure_skip_verify = True
66
+
67
+ if args.prompt is not None:
68
+ from .headless import run_headless
69
+
70
+ raise SystemExit(
71
+ asyncio.run(
72
+ run_headless(
73
+ prompt_arg=args.prompt,
74
+ model=args.model,
75
+ provider=args.provider,
76
+ api_key=args.api_key,
77
+ base_url=args.base_url,
78
+ openai_compat_auth_mode=args.openai_compat_auth,
79
+ anthropic_compat_auth_mode=args.anthropic_compat_auth,
80
+ )
81
+ )
82
+ )
83
+
84
+ from .ui.launch import run_tui
85
+
86
+ run_tui(args)
87
+
88
+
89
+ if __name__ == "__main__":
90
+ main()