agentnet-cli 0.2.4__tar.gz → 0.3.0__tar.gz
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.
- agentnet_cli-0.3.0/CHANGELOG.md +9 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/CLAUDE.md +2 -1
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/PKG-INFO +4 -1
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/README.md +3 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/pyproject.toml +1 -1
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/cli/core/setup_wizard.py +19 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/cli/main.py +53 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/connectors/claude.py +50 -20
- agentnet_cli-0.3.0/src/agentnet_cli/connectors/claude_search_hook.py +150 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/connectors/templates/SKILL.hosted.md +1 -1
- agentnet_cli-0.3.0/src/agentnet_cli/connectors/templates/codex/skill.md +10 -0
- agentnet_cli-0.3.0/src/agentnet_cli/connectors/templates/cursor/agentnet.mdc +6 -0
- agentnet_cli-0.3.0/src/agentnet_cli/connectors/templates/shared/context.md +48 -0
- agentnet_cli-0.3.0/src/agentnet_cli/connectors/templates/vscode/instructions.md +1 -0
- agentnet_cli-0.3.0/src/agentnet_cli/integrations/claude/plugin/agents/marketplace.md +23 -0
- agentnet_cli-0.3.0/src/agentnet_cli/integrations/claude/plugin/hooks/hooks.json +49 -0
- agentnet_cli-0.3.0/src/agentnet_cli/integrations/claude/plugin/skills/agentnet/SKILL.md +33 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/integrations/openclaw/openclaw.plugin.json +1 -1
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/integrations/openclaw/package.json +1 -1
- agentnet_cli-0.3.0/src/agentnet_cli/integrations/openclaw/skills/agentnet/SKILL.md +32 -0
- agentnet_cli-0.3.0/src/agentnet_cli/integrations/shared/discovery-skill.base.md +48 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/marketplace/client.py +22 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/tools/hermes/plugin.yaml +1 -1
- agentnet_cli-0.3.0/src/agentnet_cli/tools/hermes/skills/agentnet/SKILL.md +39 -0
- agentnet_cli-0.3.0/src/agentnet_cli/tools/hook.py +674 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/tests/test_claude.py +28 -2
- agentnet_cli-0.3.0/tests/test_claude_search_hook.py +142 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/tests/test_discovery_skill.py +1 -2
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/tests/test_platform_client.py +37 -0
- agentnet_cli-0.3.0/tests/test_skill_hook.py +583 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/uv.lock +1 -1
- agentnet_cli-0.2.4/src/agentnet_cli/connectors/templates/codex/skill.md +0 -12
- agentnet_cli-0.2.4/src/agentnet_cli/connectors/templates/cursor/agentnet.mdc +0 -8
- agentnet_cli-0.2.4/src/agentnet_cli/connectors/templates/shared/context.md +0 -82
- agentnet_cli-0.2.4/src/agentnet_cli/connectors/templates/vscode/instructions.md +0 -5
- agentnet_cli-0.2.4/src/agentnet_cli/integrations/claude/plugin/agents/marketplace.md +0 -23
- agentnet_cli-0.2.4/src/agentnet_cli/integrations/claude/plugin/hooks/hooks.json +0 -22
- agentnet_cli-0.2.4/src/agentnet_cli/integrations/claude/plugin/skills/agentnet/SKILL.md +0 -35
- agentnet_cli-0.2.4/src/agentnet_cli/integrations/openclaw/skills/agentnet/SKILL.md +0 -32
- agentnet_cli-0.2.4/src/agentnet_cli/integrations/shared/discovery-skill.base.md +0 -82
- agentnet_cli-0.2.4/src/agentnet_cli/tools/hermes/skills/agentnet/SKILL.md +0 -45
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/.github/workflows/ci.yml +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/.github/workflows/publish.yml +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/.gitignore +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/ARCHITECTURE.md +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/docs/archive/superpowers/plans/2026-05-09-hermes-native-plugin.md +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/docs/archive/superpowers/plans/2026-05-09-marketplace-cli-and-skill.md +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/docs/archive/superpowers/plans/2026-05-10-claude-native-plugin.md +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/docs/archive/superpowers/plans/2026-05-10-openclaw-native-plugin.md +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/docs/archive/superpowers/specs/2026-05-09-hermes-native-plugin-design.md +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/docs/archive/superpowers/specs/2026-05-09-marketplace-cli-and-skill-design.md +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/docs/archive/superpowers/specs/2026-05-10-claude-native-plugin-design.md +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/docs/archive/superpowers/specs/2026-05-10-openclaw-native-plugin-design.md +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/__init__.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/cli/__init__.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/cli/core/__init__.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/cli/core/connect.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/cli/core/detect.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/cli/core/disconnect.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/cli/core/register.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/cli/core/status.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/cli/core/updater.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/cli/marketplace/__init__.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/cli/marketplace/agent.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/cli/marketplace/discover.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/connectors/README.md +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/connectors/__init__.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/connectors/base.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/connectors/codex.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/connectors/copilot.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/connectors/cursor.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/connectors/hermes.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/connectors/openclaw.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/connectors/registry.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/connectors/shims.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/connectors/templates/README.md +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/connectors/templates/copilot/agentnet.agent.md +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/connectors/templates/cursor/agent.md +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/connectors/templates/shared/default-chat.md +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/connectors/vscode.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/infra/__init__.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/infra/config.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/infra/manifest.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/infra/package_paths.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/infra/paths.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/infra/platform.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/integrations/claude/.claude-plugin/marketplace.json +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/integrations/claude/plugin/.claude-plugin/plugin.json +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/integrations/claude/plugin/.mcp.json +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/integrations/openclaw/.mcp.json +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/integrations/openclaw/index.js +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/marketplace/__init__.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/marketplace/auth.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/marketplace/catalogs/__init__.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/marketplace/catalogs/claude_marketplace.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/marketplace/catalogs/clawhub.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/marketplace/skills/__init__.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/marketplace/skills/client.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/marketplace/skills/discovery.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/marketplace/skills/skillsmp.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/tools/__init__.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/tools/handlers.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/tools/hermes/__init__.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/tools/hermes/handlers.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/tools/hermes/schemas.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/src/agentnet_cli/tools/mcp_server.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/tests/__init__.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/tests/conftest.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/tests/test_agent_cmd.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/tests/test_claude_marketplace.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/tests/test_clawhub_client.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/tests/test_cli.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/tests/test_codex.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/tests/test_config.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/tests/test_copilot.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/tests/test_cursor.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/tests/test_detect.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/tests/test_discover_cmd.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/tests/test_discovery.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/tests/test_e2e.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/tests/test_hermes.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/tests/test_hermes_plugin.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/tests/test_manifest.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/tests/test_marketplace.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/tests/test_mcp_tools.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/tests/test_openclaw.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/tests/test_paths.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/tests/test_platform_config.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/tests/test_register.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/tests/test_server.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/tests/test_skills_client.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/tests/test_skillsmp_client.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/tests/test_updater.py +0 -0
- {agentnet_cli-0.2.4 → agentnet_cli-0.3.0}/tests/test_vscode.py +0 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.3.0 - 2026-07-18
|
|
4
|
+
|
|
5
|
+
- Add Claude Code search-fire hook support so AgentNet can surface relevant marketplace skills during search workflows.
|
|
6
|
+
- Add `agentnet enable-search-fire` for one-command Claude hook installation.
|
|
7
|
+
- Preserve malformed Claude settings files instead of overwriting them during connector setup.
|
|
8
|
+
- Add setup telemetry hooks and a platform client telemetry helper.
|
|
9
|
+
- Bump bundled Hermes, hosted skill, and OpenClaw integration metadata to match the CLI release.
|
|
@@ -8,7 +8,7 @@ CLI tool that detects AI coding agents on your system and connects them to the [
|
|
|
8
8
|
- **Package manager:** uv
|
|
9
9
|
- **CLI framework:** Typer + Rich
|
|
10
10
|
- **HTTP client:** httpx
|
|
11
|
-
- **Testing:** pytest (
|
|
11
|
+
- **Testing:** pytest (406 tests), pytest-cov
|
|
12
12
|
- **CI:** GitHub Actions (lint + test matrix on 3.11/3.12/3.13)
|
|
13
13
|
- **Publish:** PyPI via trusted publisher (tag `v*`)
|
|
14
14
|
|
|
@@ -44,6 +44,7 @@ uv run agentnet --help # Run locally
|
|
|
44
44
|
- **Hermes Plugin:** `agentnet connect hermes` copies the plugin to `~/.hermes/plugins/agentnet/` and skills to `~/.hermes/skills/agentnet/`, using Hermes's native plugin system.
|
|
45
45
|
- **OpenClaw Plugin:** `agentnet connect openclaw` delegates to `openclaw plugins install` + `openclaw plugins uninstall` instead of writing files directly. The plugin at `openclaw-plugin/` is a native OpenClaw plugin with `openclaw.plugin.json` manifest, publishable to ClawHub.
|
|
46
46
|
- **Plugin hint:** The CLI emits a `<claude-code-hint>` tag on stderr when `CLAUDECODE=1` is set, prompting Claude Code users to install the plugin.
|
|
47
|
+
- **Every-prompt skill hook (Claude Code):** `agentnet enable-skill-fire` (and `connect claude`) install three hooks in `~/.claude/settings.json` (also bundled in the plugin's `hooks/hooks.json`). `UserPromptSubmit` → `agentnet skill-hook --pre` spawns a detached worker (0 latency). The worker discovers **installable skill candidates** (`discover_skills` → skills.sh, each carrying a `<repo>@<slug>`) + runs a cheap no-tool `claude -p` **classifier** (Haiku) as the reliable relevance **gate** (a bare yes/no gate isn't — the model just answers). Two-phase so the outcome reaches the hooks fast: **Phase 1** caches the **recommendation list** (relevant skills by name + why + skills.sh link) the moment the gate opens (~12s); **Phase 2** *appends* the top match fetched via `npx skills use <repo>@<slug>` (which downloads the skill — SKILL.md + references — to a temp dir; single-file skills are materialized to a temp `SKILL.md`) as a **concise header (name + description) + the on-disk path**, not a full SKILL.md dump. The injected outcome is thus the list *then* "Applying the top match now:" + that block — the agent surfaces the list and reads/applies the methodology from disk, which is what makes it *act* on the skill rather than just mention it. No files are written to the repo. If content is unavailable (no `npx`/all fetches miss), Phase 2 falls back — behind the same open gate — to the live **Skills Agent** over **brokered A2A**: `PlatformClient.use_agent(agent_id="agentnet-skills-agent", task=…)` with the user's `setup` identity; the platform relays A2A and returns `{status:"settled", agent_response}` in one call. **No skills-agent token is ever held client-side.** Only a `settled` response is used. Injection is layered: `PostToolUse` (matcher `*`) → `agentnet skill-hook --peek` force-steers the agent **mid-flight** once the outcome is ready (`{"decision":"block","reason":…}`, inject-once via an `injected` flag); `Stop` → `agentnet skill-hook --post` is the guaranteed fallback (`{"decision":"block", …additionalContext}`) for no-tool answers. Because the hooks are registered in **both** `settings.json` (via `connect`/`enable-skill-fire`) and the plugin's `hooks.json`, Claude Code may run each twice in parallel — so idempotence is enforced with **atomic `O_EXCL` once-claims**: a per-`(session,prompt)` **spawn marker** so duplicate `--pre` hooks spawn exactly one worker (not 2× classifier cost), and a per-prompt **emit marker** shared by peek + post so exactly one steer fires (and a re-fired `Stop` no-ops). Session-keyed JSON cache `$TMPDIR/agentnet-skill/<session>.json` (`{outcome}`) + sibling `.emitted`/`.<hash>.spawn` markers; `AGENTNET_SKILL_SUBAGENT=1` guards recursion. All best-effort — no token/binary/candidates/unreachable-platform/timeout injects nothing. `agent_id` overridable via `AGENTNET_SKILLS_AGENT_ID`/config. Implemented in `tools/hook.py` + `connectors/claude_search_hook.py`.
|
|
47
48
|
|
|
48
49
|
## Testing Patterns
|
|
49
50
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agentnet-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: Detect AI agents and connect them to the Agent-net marketplace
|
|
5
5
|
Project-URL: Homepage, https://agentnet.market
|
|
6
6
|
Project-URL: Repository, https://github.com/TheAgent-net/agentnet-cli
|
|
@@ -65,6 +65,9 @@ Requires Python 3.11+.
|
|
|
65
65
|
# Install from PyPI
|
|
66
66
|
pip install agentnet-cli
|
|
67
67
|
|
|
68
|
+
# Install this release exactly
|
|
69
|
+
pip install agentnet-cli==0.3.0
|
|
70
|
+
|
|
68
71
|
# Or run without installing
|
|
69
72
|
uvx agentnet
|
|
70
73
|
|
|
@@ -11,6 +11,8 @@ from rich.console import Console
|
|
|
11
11
|
from rich.table import Table
|
|
12
12
|
|
|
13
13
|
from ...infra.config import load_config
|
|
14
|
+
from ...infra.platform import resolve_platform_url
|
|
15
|
+
from ...marketplace.client import PlatformClient
|
|
14
16
|
from .connect import connect_command
|
|
15
17
|
from .detect import detect_all
|
|
16
18
|
from ...infra.paths import AgentName, agent_display_name
|
|
@@ -19,7 +21,23 @@ from .register import default_agent_name, register_command
|
|
|
19
21
|
console = Console()
|
|
20
22
|
|
|
21
23
|
|
|
24
|
+
def _send_telemetry(event_type: str, **metadata: str) -> None:
|
|
25
|
+
"""Best-effort telemetry to platform; never blocks setup."""
|
|
26
|
+
try:
|
|
27
|
+
import httpx
|
|
28
|
+
|
|
29
|
+
config = load_config() or {}
|
|
30
|
+
base = resolve_platform_url(config=config)
|
|
31
|
+
token = config.get("api_token", "")
|
|
32
|
+
http_client = httpx.Client(timeout=5.0)
|
|
33
|
+
with PlatformClient(base_url=base, api_token=token, http_client=http_client) as client:
|
|
34
|
+
client.send_telemetry(event_type=event_type, metadata=metadata or None)
|
|
35
|
+
except Exception:
|
|
36
|
+
pass
|
|
37
|
+
|
|
38
|
+
|
|
22
39
|
def setup_command(platform_url: str | None = None, *, choose: bool = False) -> None:
|
|
40
|
+
_send_telemetry("cli_setup")
|
|
23
41
|
config = load_config()
|
|
24
42
|
if not config or not config.get("api_token"):
|
|
25
43
|
console.print()
|
|
@@ -62,6 +80,7 @@ def setup_command(platform_url: str | None = None, *, choose: bool = False) -> N
|
|
|
62
80
|
f" [bold]Step 3:[/bold] Configuring all detected agents ({len(targets)})"
|
|
63
81
|
)
|
|
64
82
|
connect_command(connect_all=True)
|
|
83
|
+
_send_telemetry("cli_setup_complete", connectors=",".join(targets))
|
|
65
84
|
|
|
66
85
|
|
|
67
86
|
def _available_targets(results) -> list[str]:
|
|
@@ -301,6 +301,59 @@ def mcp_serve() -> None:
|
|
|
301
301
|
serve()
|
|
302
302
|
|
|
303
303
|
|
|
304
|
+
@app.command(name="skill-hook", hidden=True)
|
|
305
|
+
def skill_hook(
|
|
306
|
+
pre: bool = typer.Option(False, "--pre", help="UserPromptSubmit: spawn the discovery worker"),
|
|
307
|
+
peek: bool = typer.Option(False, "--peek", help="PostToolUse: steer the agent mid-flight"),
|
|
308
|
+
post: bool = typer.Option(False, "--post", help="Stop: fold in relevant AgentNet skills"),
|
|
309
|
+
fetch: bool = typer.Option(False, "--fetch", help="Detached worker: discover + cache (internal)"),
|
|
310
|
+
session: str = typer.Option("", "--session", help="Session id (worker)"),
|
|
311
|
+
query: str = typer.Option("", "--query", help="Prompt text (worker)"),
|
|
312
|
+
limit: int = typer.Option(5, "--limit", help="Max skills to suggest"),
|
|
313
|
+
hook_timeout: float = typer.Option(
|
|
314
|
+
3.0, "--timeout", help="Max seconds a hook waits for the subagent's result",
|
|
315
|
+
),
|
|
316
|
+
) -> None:
|
|
317
|
+
"""Claude Code every-prompt hooks — surface relevant AgentNet skills (internal).
|
|
318
|
+
|
|
319
|
+
``--pre`` (UserPromptSubmit) spawns a detached skill-scout worker; ``--peek`` (PostToolUse)
|
|
320
|
+
steers the agent mid-flight once the outcome is ready; ``--post`` (Stop) is the guaranteed
|
|
321
|
+
fallback. Best-effort: nothing/exit 0 on error.
|
|
322
|
+
"""
|
|
323
|
+
from ..tools.hook import run_fetch, run_peek, run_post, run_pre
|
|
324
|
+
|
|
325
|
+
if fetch:
|
|
326
|
+
run_fetch(session=session, query=query, limit=limit, timeout=hook_timeout)
|
|
327
|
+
elif pre:
|
|
328
|
+
run_pre(limit=limit, timeout=hook_timeout)
|
|
329
|
+
elif peek:
|
|
330
|
+
run_peek(limit=limit, timeout=hook_timeout)
|
|
331
|
+
else: # default and --post
|
|
332
|
+
run_post(limit=limit, timeout=hook_timeout)
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
@app.command(name="enable-skill-fire")
|
|
336
|
+
def enable_skill_fire(
|
|
337
|
+
remove: bool = typer.Option(False, "--remove", help="Remove the hook instead of installing"),
|
|
338
|
+
) -> None:
|
|
339
|
+
"""Fire AgentNet on every Claude Code prompt (writes ~/.claude/settings.json)."""
|
|
340
|
+
from ..connectors.claude_search_hook import SettingsHookError, install, uninstall
|
|
341
|
+
|
|
342
|
+
try:
|
|
343
|
+
changed, path = uninstall() if remove else install()
|
|
344
|
+
except SettingsHookError as exc:
|
|
345
|
+
console.print(f"[red]✗[/red] {exc}")
|
|
346
|
+
raise typer.Exit(1) from exc
|
|
347
|
+
action = "removed" if remove else "installed"
|
|
348
|
+
if changed:
|
|
349
|
+
console.print(f"[green]✓[/green] AgentNet skill hook {action} in [bold]{path}[/bold]")
|
|
350
|
+
if not remove:
|
|
351
|
+
console.print(" [dim]Restart Claude Code — every prompt now fires AgentNet.[/dim]")
|
|
352
|
+
else:
|
|
353
|
+
state = "not present" if remove else "already installed"
|
|
354
|
+
console.print(f"[dim]No change ({state}): {path}[/dim]")
|
|
355
|
+
|
|
356
|
+
|
|
304
357
|
# -- Marketplace commands --
|
|
305
358
|
from .marketplace.agent import agent as _agent_fn # noqa: E402
|
|
306
359
|
from .marketplace.discover import discover as _discover_fn # noqa: E402
|
|
@@ -45,34 +45,64 @@ class ClaudeConnector(AgentConnector):
|
|
|
45
45
|
errors=["Claude Code not found. Install it from https://code.claude.com"],
|
|
46
46
|
)
|
|
47
47
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
48
|
+
# 1. Install the AgentNet every-prompt hook straight into settings.json.
|
|
49
|
+
# This is the reliable path: every prompt fires AgentNet (discover +
|
|
50
|
+
# fold in relevant skills). It does NOT depend on the plugin marketplace
|
|
51
|
+
# flow (which errors on some Claude Code versions), so connect succeeds
|
|
52
|
+
# even if that fails.
|
|
53
|
+
from .claude_search_hook import SettingsHookError
|
|
54
|
+
from .claude_search_hook import install as install_search_hook
|
|
55
|
+
|
|
56
|
+
errors: list[str] = []
|
|
57
|
+
try:
|
|
58
|
+
install_search_hook()
|
|
59
|
+
except SettingsHookError as exc:
|
|
60
|
+
# A malformed settings.json must not be overwritten; report and preserve it, but let
|
|
61
|
+
# the rest of connect (MCP + plugin) still run.
|
|
62
|
+
errors.append(str(exc))
|
|
63
|
+
|
|
64
|
+
# 2. Best-effort: install the plugin for the discovery MCP tools and
|
|
65
|
+
# session hooks. `marketplace add` takes only <source> (no --scope).
|
|
66
|
+
# Failures here are non-fatal — the prompt hook above is already live.
|
|
67
|
+
try:
|
|
68
|
+
marketplace_src = _marketplace_source()
|
|
69
|
+
proc = subprocess.run(
|
|
70
|
+
["claude", "plugin", "marketplace", "add", marketplace_src],
|
|
71
|
+
capture_output=True,
|
|
72
|
+
timeout=_SUBPROCESS_TIMEOUT,
|
|
73
|
+
)
|
|
74
|
+
if proc.returncode == 0:
|
|
75
|
+
proc = subprocess.run(
|
|
76
|
+
["claude", "plugin", "install", _PLUGIN_ID, "--scope", "user"],
|
|
77
|
+
capture_output=True,
|
|
78
|
+
timeout=_SUBPROCESS_TIMEOUT,
|
|
79
|
+
)
|
|
80
|
+
if proc.returncode != 0:
|
|
81
|
+
errors.append(
|
|
82
|
+
"plugin install (discovery tools) failed: "
|
|
83
|
+
+ proc.stderr.decode(errors="replace").strip()
|
|
84
|
+
)
|
|
85
|
+
else:
|
|
86
|
+
errors.append(
|
|
87
|
+
"plugin marketplace add (discovery tools) failed: "
|
|
88
|
+
+ proc.stderr.decode(errors="replace").strip()
|
|
89
|
+
)
|
|
90
|
+
except Exception as exc: # noqa: BLE001 — plugin step is best-effort
|
|
91
|
+
errors.append(f"plugin step skipped: {exc}")
|
|
67
92
|
|
|
68
93
|
self._cleanup_legacy()
|
|
69
94
|
|
|
70
95
|
return ConnectionResult(
|
|
71
96
|
success=True,
|
|
72
|
-
mcp_entry={"scope": "
|
|
97
|
+
mcp_entry={"scope": "settings-hook", "search_fire": True},
|
|
98
|
+
errors=errors,
|
|
73
99
|
)
|
|
74
100
|
|
|
75
101
|
def disconnect(self, connection_manifest: dict[str, Any]) -> bool:
|
|
102
|
+
from .claude_search_hook import uninstall as uninstall_search_hook
|
|
103
|
+
|
|
104
|
+
uninstall_search_hook()
|
|
105
|
+
|
|
76
106
|
claude_bin = shutil.which("claude")
|
|
77
107
|
if not claude_bin:
|
|
78
108
|
return True
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
"""Install the AgentNet every-prompt hooks directly into Claude Code's settings.json.
|
|
2
|
+
|
|
3
|
+
Registers three hooks: ``UserPromptSubmit`` (spawn a background discovery worker),
|
|
4
|
+
``PostToolUse`` (steer the agent mid-flight once the outcome is ready), and ``Stop``
|
|
5
|
+
(guaranteed fallback that folds the outcome in). Same effect as the bundled plugin, but
|
|
6
|
+
written straight into ``~/.claude/settings.json`` so it works in one command regardless of
|
|
7
|
+
Claude Code version.
|
|
8
|
+
|
|
9
|
+
``PostToolUse`` is tool-scoped so its block carries a ``*`` matcher (all tools);
|
|
10
|
+
``UserPromptSubmit`` and ``Stop`` are not tool-scoped, so their blocks carry no matcher.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
import json
|
|
16
|
+
from typing import Any
|
|
17
|
+
|
|
18
|
+
from ..infra.paths import AgentName, agent_config_root
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class SettingsHookError(Exception):
|
|
22
|
+
"""Raised when ~/.claude/settings.json exists but is malformed, so it must not be overwritten."""
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
# event -> (command, matcher). matcher=None for non-tool-scoped events.
|
|
26
|
+
_HOOKS: dict[str, tuple[str, str | None]] = {
|
|
27
|
+
"UserPromptSubmit": ("agentnet skill-hook --pre", None),
|
|
28
|
+
"PostToolUse": ("agentnet skill-hook --peek", "*"),
|
|
29
|
+
"Stop": ("agentnet skill-hook --post", None),
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def _settings_path():
|
|
34
|
+
return agent_config_root(AgentName.CLAUDE) / "settings.json"
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def _load(path) -> dict[str, Any]:
|
|
38
|
+
"""Parse an existing settings.json to a dict.
|
|
39
|
+
|
|
40
|
+
Absent file -> ``{}`` (a fresh config). A file that *exists* but is unparseable or not a JSON
|
|
41
|
+
object is NOT the same as empty — overwriting it would erase the user's real config — so raise
|
|
42
|
+
``SettingsHookError`` and let the caller preserve the file untouched.
|
|
43
|
+
"""
|
|
44
|
+
if not path.exists():
|
|
45
|
+
return {}
|
|
46
|
+
try:
|
|
47
|
+
data = json.loads(path.read_text())
|
|
48
|
+
except (json.JSONDecodeError, OSError) as exc:
|
|
49
|
+
raise SettingsHookError(f"{path} is not valid JSON — fix it and re-run") from exc
|
|
50
|
+
if not isinstance(data, dict):
|
|
51
|
+
raise SettingsHookError(f"{path} is not a JSON object — fix it and re-run")
|
|
52
|
+
return data
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def _is_agentnet_cmd(cmd: Any) -> bool:
|
|
56
|
+
return isinstance(cmd, str) and cmd.startswith("agentnet skill-hook")
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def _block(command: str, matcher: str | None) -> dict[str, Any]:
|
|
60
|
+
block: dict[str, Any] = {}
|
|
61
|
+
if matcher is not None:
|
|
62
|
+
block["matcher"] = matcher
|
|
63
|
+
block["hooks"] = [{"type": "command", "command": command}]
|
|
64
|
+
return block
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def _event_has_agentnet(blocks: list[Any]) -> bool:
|
|
68
|
+
for b in blocks:
|
|
69
|
+
if isinstance(b, dict) and any(
|
|
70
|
+
isinstance(h, dict) and _is_agentnet_cmd(h.get("command")) for h in b.get("hooks", [])
|
|
71
|
+
):
|
|
72
|
+
return True
|
|
73
|
+
return False
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def install() -> tuple[bool, str]:
|
|
77
|
+
"""Add the UserPromptSubmit/Stop hooks to settings.json. Returns (changed, path)."""
|
|
78
|
+
path = _settings_path()
|
|
79
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
80
|
+
data = _load(path)
|
|
81
|
+
hooks = data.setdefault("hooks", {})
|
|
82
|
+
if not isinstance(hooks, dict):
|
|
83
|
+
hooks = {}
|
|
84
|
+
data["hooks"] = hooks
|
|
85
|
+
|
|
86
|
+
changed = False
|
|
87
|
+
for event, (command, matcher) in _HOOKS.items():
|
|
88
|
+
blocks = hooks.get(event)
|
|
89
|
+
if blocks is None:
|
|
90
|
+
blocks = []
|
|
91
|
+
hooks[event] = blocks
|
|
92
|
+
elif isinstance(blocks, dict):
|
|
93
|
+
# A single hook block stored as an object — preserve it by wrapping, don't discard it.
|
|
94
|
+
blocks = [blocks]
|
|
95
|
+
hooks[event] = blocks
|
|
96
|
+
elif not isinstance(blocks, list):
|
|
97
|
+
# Some other scalar we don't understand — leave the user's value untouched.
|
|
98
|
+
continue
|
|
99
|
+
if not _event_has_agentnet(blocks):
|
|
100
|
+
blocks.append(_block(command, matcher))
|
|
101
|
+
changed = True
|
|
102
|
+
|
|
103
|
+
if changed:
|
|
104
|
+
path.write_text(json.dumps(data, indent=2) + "\n")
|
|
105
|
+
return changed, str(path)
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def uninstall() -> tuple[bool, str]:
|
|
109
|
+
"""Remove the AgentNet every-prompt hooks from settings.json. Returns (changed, path).
|
|
110
|
+
|
|
111
|
+
A malformed settings file has nothing removable and must not be overwritten, so treat it as
|
|
112
|
+
a no-op rather than raising into the (best-effort) disconnect path.
|
|
113
|
+
"""
|
|
114
|
+
path = _settings_path()
|
|
115
|
+
try:
|
|
116
|
+
data = _load(path)
|
|
117
|
+
except SettingsHookError:
|
|
118
|
+
return False, str(path)
|
|
119
|
+
hooks = data.get("hooks")
|
|
120
|
+
if not isinstance(hooks, dict):
|
|
121
|
+
return False, str(path)
|
|
122
|
+
|
|
123
|
+
changed = False
|
|
124
|
+
for event in list(_HOOKS):
|
|
125
|
+
blocks = hooks.get(event)
|
|
126
|
+
if not isinstance(blocks, list):
|
|
127
|
+
continue
|
|
128
|
+
kept = [
|
|
129
|
+
b
|
|
130
|
+
for b in blocks
|
|
131
|
+
if not (
|
|
132
|
+
isinstance(b, dict)
|
|
133
|
+
and any(
|
|
134
|
+
isinstance(h, dict) and _is_agentnet_cmd(h.get("command"))
|
|
135
|
+
for h in b.get("hooks", [])
|
|
136
|
+
)
|
|
137
|
+
)
|
|
138
|
+
]
|
|
139
|
+
if len(kept) != len(blocks):
|
|
140
|
+
changed = True
|
|
141
|
+
if kept:
|
|
142
|
+
hooks[event] = kept
|
|
143
|
+
else:
|
|
144
|
+
hooks.pop(event, None)
|
|
145
|
+
|
|
146
|
+
if changed:
|
|
147
|
+
if not hooks:
|
|
148
|
+
data.pop("hooks", None)
|
|
149
|
+
path.write_text(json.dumps(data, indent=2) + "\n")
|
|
150
|
+
return changed, str(path)
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agentnet
|
|
3
|
+
description: >-
|
|
4
|
+
Before building a non-trivial capability from scratch (auth, tests, security review,
|
|
5
|
+
deployment, data/PDF parsing, scraping, CI/CD, integrations), find an existing AgentNet
|
|
6
|
+
agent or skill that already does it. Search with agentnet_discover_agents first; skip for
|
|
7
|
+
trivial edits or conversational turns.
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
{{CONTEXT}}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# AgentNet — discovery for the agent network
|
|
2
|
+
|
|
3
|
+
You are connected to **AgentNet**, the discovery/routing layer for AI agents and skills
|
|
4
|
+
("Google for agents"). When you are about to **build a non-trivial capability**, an existing
|
|
5
|
+
agent or skill often already does it — surface that instead of reinventing it.
|
|
6
|
+
|
|
7
|
+
## When to use
|
|
8
|
+
Before you implement something substantive — authentication, tests, a security review, a
|
|
9
|
+
deployment pipeline, PDF/data parsing, web scraping, CI/CD, a third-party integration — call
|
|
10
|
+
`agentnet_discover_agents` (or `agentnet_search`) with the capability you're about to build.
|
|
11
|
+
Skip it for trivial edits, questions, or purely conversational turns — no noise.
|
|
12
|
+
|
|
13
|
+
## How
|
|
14
|
+
1. **Discover** — `agentnet_discover_agents` (agents + skills by capability) or `agentnet_search`
|
|
15
|
+
(unified) with a concrete description of *what you're building*.
|
|
16
|
+
2. **Surface** — briefly present the best match (name, what it does, how to use/install it),
|
|
17
|
+
then continue your work. Let the user choose; don't force it.
|
|
18
|
+
3. **Inspect** — `agentnet_get_agent` only if the user wants detail on a specific agent.
|
|
19
|
+
|
|
20
|
+
## Tools
|
|
21
|
+
|
|
22
|
+
### agentnet_discover_agents
|
|
23
|
+
Agents + skills by capability. **Start here** when you're about to build something.
|
|
24
|
+
- **query** (string, required): the capability you're about to build
|
|
25
|
+
- **limit** (int, default 20): max results
|
|
26
|
+
|
|
27
|
+
### agentnet_search
|
|
28
|
+
Unified search across agents, skills, listings, and plugins. Use for a broad look.
|
|
29
|
+
- **query** (string, required): what you need
|
|
30
|
+
- **type** (string, default "all"): all, agents, skills, plugins, listings, marketplace
|
|
31
|
+
- **category** (string, optional) · **limit** (int, default 20) · **max_price** (int, optional)
|
|
32
|
+
|
|
33
|
+
### agentnet_get_agent
|
|
34
|
+
Full detail on a specific agent (skills, trust score).
|
|
35
|
+
- **agent_id** (string, required): from discovery results
|
|
36
|
+
|
|
37
|
+
### agentnet_discover_skills
|
|
38
|
+
AI-ranked skill discovery by natural-language use case. Use when narrowing to skills.
|
|
39
|
+
- **use_case** (string, required) · **limit** (int, default 10)
|
|
40
|
+
|
|
41
|
+
Other catalogs (only when you need a specific source): `agentnet_discover`,
|
|
42
|
+
`agentnet_search_skills`, `agentnet_search_skillsmp`, `agentnet_search_claude_plugins`,
|
|
43
|
+
`agentnet_search_clawhub`.
|
|
44
|
+
|
|
45
|
+
## Guidelines
|
|
46
|
+
- **Capability-first** — match on *what you're about to build*, not stray keywords.
|
|
47
|
+
- **Present, don't transact** — you surface options; you never hire, pay, or settle.
|
|
48
|
+
- **Stay quiet** when nothing relevant fits.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{{CONTEXT}}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: marketplace
|
|
3
|
+
description: >-
|
|
4
|
+
AgentNet discovery specialist. Use when the user wants to find an existing agent or skill
|
|
5
|
+
for a capability they're about to build.
|
|
6
|
+
model: sonnet
|
|
7
|
+
tools: mcp__agentnet__*
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
You are an AgentNet discovery specialist connected to the agent network ("Google for agents").
|
|
11
|
+
Your job: when the user is about to build a capability, find an existing agent or skill for it.
|
|
12
|
+
|
|
13
|
+
## Workflow
|
|
14
|
+
1. **Discover** → `agentnet_discover_agents` (agents + skills by capability) or `agentnet_search`
|
|
15
|
+
(unified) with a concrete description of what they're building
|
|
16
|
+
2. **Present** → show the best matches with names, what they do, and how to use/install them
|
|
17
|
+
3. **Inspect** → `agentnet_get_agent` only if the user wants more detail on a specific agent
|
|
18
|
+
|
|
19
|
+
## Guidelines
|
|
20
|
+
- **Capability-first** — match on *what the user is about to build*, not stray keywords
|
|
21
|
+
- Present a short ranked list — do not dump raw JSON
|
|
22
|
+
- **Present, don't transact** — you surface options; you never hire, pay, or settle
|
|
23
|
+
- Stay quiet when nothing relevant fits
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"hooks": {
|
|
3
|
+
"SessionStart": [
|
|
4
|
+
{
|
|
5
|
+
"hooks": [
|
|
6
|
+
{
|
|
7
|
+
"type": "command",
|
|
8
|
+
"command": "test -f ~/.agentnet/config.json || echo '[AgentNet] Not authenticated. Run: agentnet setup' >&2"
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"type": "command",
|
|
12
|
+
"command": "agentnet update --quiet 2>/dev/null || true"
|
|
13
|
+
}
|
|
14
|
+
]
|
|
15
|
+
}
|
|
16
|
+
],
|
|
17
|
+
"UserPromptSubmit": [
|
|
18
|
+
{
|
|
19
|
+
"hooks": [
|
|
20
|
+
{
|
|
21
|
+
"type": "command",
|
|
22
|
+
"command": "agentnet skill-hook --pre"
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
}
|
|
26
|
+
],
|
|
27
|
+
"PostToolUse": [
|
|
28
|
+
{
|
|
29
|
+
"matcher": "*",
|
|
30
|
+
"hooks": [
|
|
31
|
+
{
|
|
32
|
+
"type": "command",
|
|
33
|
+
"command": "agentnet skill-hook --peek"
|
|
34
|
+
}
|
|
35
|
+
]
|
|
36
|
+
}
|
|
37
|
+
],
|
|
38
|
+
"Stop": [
|
|
39
|
+
{
|
|
40
|
+
"hooks": [
|
|
41
|
+
{
|
|
42
|
+
"type": "command",
|
|
43
|
+
"command": "agentnet skill-hook --post"
|
|
44
|
+
}
|
|
45
|
+
]
|
|
46
|
+
}
|
|
47
|
+
]
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agentnet
|
|
3
|
+
description: >-
|
|
4
|
+
Before building a non-trivial capability from scratch (auth, tests, security review,
|
|
5
|
+
deployment, data/PDF parsing, scraping, CI/CD, integrations, etc.), find an existing AgentNet
|
|
6
|
+
agent or skill that already does it. Triggers when the user asks to implement / build / set up
|
|
7
|
+
/ add a capability a reusable skill or agent might already cover.
|
|
8
|
+
allowed-tools: mcp__agentnet__*
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# AgentNet — discovery for the agent network
|
|
12
|
+
|
|
13
|
+
You are connected to **AgentNet**, the discovery/routing layer for AI agents and skills
|
|
14
|
+
("Google for agents"). When you are about to **build a non-trivial capability**, an existing
|
|
15
|
+
agent or skill often already does it — surface that instead of reinventing it.
|
|
16
|
+
|
|
17
|
+
## When to use
|
|
18
|
+
Before you implement something substantive — authentication, tests, a security review, a
|
|
19
|
+
deployment pipeline, PDF/data parsing, web scraping, CI/CD, a third-party integration — call
|
|
20
|
+
`agentnet_discover_agents` (or `agentnet_search`) with the capability you're about to build.
|
|
21
|
+
Skip it for trivial edits, questions, or conversational turns.
|
|
22
|
+
|
|
23
|
+
## How
|
|
24
|
+
1. **Discover** — `agentnet_discover_agents` (agents + skills by capability) or `agentnet_search`
|
|
25
|
+
(unified) with a concrete description of what you're building.
|
|
26
|
+
2. **Surface** — briefly present the best match (name, what it does, how to use/install it),
|
|
27
|
+
then continue your work. Let the user choose; don't force it.
|
|
28
|
+
3. **Inspect** — `agentnet_get_agent` only if the user wants detail on a specific agent.
|
|
29
|
+
|
|
30
|
+
## Guidelines
|
|
31
|
+
- **Capability-first** — match on *what you're about to build*, not stray keywords.
|
|
32
|
+
- **Present, don't transact** — you surface options; you never hire, pay, or settle.
|
|
33
|
+
- **Stay quiet** when nothing relevant fits — no noise on trivial turns.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agentnet
|
|
3
|
+
description: >-
|
|
4
|
+
Before building a non-trivial capability from scratch (auth, tests, security review,
|
|
5
|
+
deployment, data/PDF parsing, scraping, CI/CD, integrations), find an existing AgentNet
|
|
6
|
+
agent or skill that already does it. Search with agentnet_discover_agents first; skip for
|
|
7
|
+
trivial edits or conversational turns.
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# AgentNet — discovery for the agent network
|
|
11
|
+
|
|
12
|
+
You are connected to **AgentNet**, the discovery/routing layer for AI agents and skills
|
|
13
|
+
("Google for agents"). When you are about to **build a non-trivial capability**, an existing
|
|
14
|
+
agent or skill often already does it — surface that instead of reinventing it.
|
|
15
|
+
|
|
16
|
+
## When to use
|
|
17
|
+
Before you implement something substantive — authentication, tests, a security review, a
|
|
18
|
+
deployment pipeline, PDF/data parsing, web scraping, CI/CD, a third-party integration — call
|
|
19
|
+
`agentnet_discover_agents` (or `agentnet_search`) with the capability you're about to build.
|
|
20
|
+
Skip it for trivial edits, questions, or conversational turns.
|
|
21
|
+
|
|
22
|
+
## How
|
|
23
|
+
1. **Discover** — `agentnet_discover_agents` (agents + skills by capability) or `agentnet_search`
|
|
24
|
+
(unified) with a concrete description of what you're building.
|
|
25
|
+
2. **Surface** — briefly present the best match (name, what it does, how to use/install it),
|
|
26
|
+
then continue. Let the user choose; don't force it.
|
|
27
|
+
3. **Inspect** — `agentnet_get_agent` only if the user wants detail on a specific agent.
|
|
28
|
+
|
|
29
|
+
## Guidelines
|
|
30
|
+
- **Capability-first** — match on *what you're about to build*, not stray keywords.
|
|
31
|
+
- **Present, don't transact** — you surface options; you never hire, pay, or settle.
|
|
32
|
+
- **Stay quiet** when nothing relevant fits.
|