agentnet-cli 0.2.2__tar.gz → 0.2.4__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.
Files changed (124) hide show
  1. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/CLAUDE.md +1 -1
  2. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/PKG-INFO +27 -15
  3. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/README.md +26 -14
  4. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/pyproject.toml +1 -1
  5. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/cli/core/register.py +2 -4
  6. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/cli/main.py +11 -6
  7. agentnet_cli-0.2.4/src/agentnet_cli/cli/marketplace/agent.py +23 -0
  8. agentnet_cli-0.2.4/src/agentnet_cli/cli/marketplace/discover.py +19 -0
  9. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/connectors/claude.py +0 -1
  10. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/connectors/openclaw.py +0 -1
  11. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/connectors/templates/SKILL.hosted.md +26 -37
  12. agentnet_cli-0.2.4/src/agentnet_cli/infra/platform.py +74 -0
  13. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/integrations/claude/plugin/.claude-plugin/plugin.json +1 -1
  14. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/integrations/openclaw/openclaw.plugin.json +1 -1
  15. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/integrations/openclaw/package.json +1 -1
  16. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/marketplace/auth.py +2 -5
  17. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/marketplace/catalogs/clawhub.py +2 -0
  18. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/marketplace/client.py +15 -12
  19. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/marketplace/skills/discovery.py +3 -1
  20. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/tools/handlers.py +10 -12
  21. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/tools/hermes/handlers.py +2 -1
  22. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/tools/hermes/plugin.yaml +1 -1
  23. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/tools/mcp_server.py +5 -5
  24. agentnet_cli-0.2.4/tests/conftest.py +14 -0
  25. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/tests/test_agent_cmd.py +26 -0
  26. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/tests/test_cli.py +8 -1
  27. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/tests/test_discover_cmd.py +22 -40
  28. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/tests/test_discovery.py +16 -0
  29. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/tests/test_mcp_tools.py +27 -65
  30. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/tests/test_platform_client.py +41 -30
  31. agentnet_cli-0.2.4/tests/test_platform_config.py +86 -0
  32. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/tests/test_server.py +20 -2
  33. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/uv.lock +1 -1
  34. agentnet_cli-0.2.2/src/agentnet_cli/cli/marketplace/agent.py +0 -18
  35. agentnet_cli-0.2.2/src/agentnet_cli/cli/marketplace/discover.py +0 -34
  36. agentnet_cli-0.2.2/src/agentnet_cli/cli/marketplace/search.py +0 -124
  37. agentnet_cli-0.2.2/tests/conftest.py +0 -7
  38. agentnet_cli-0.2.2/tests/test_search_cmd.py +0 -76
  39. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/.github/workflows/ci.yml +0 -0
  40. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/.github/workflows/publish.yml +0 -0
  41. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/.gitignore +0 -0
  42. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/ARCHITECTURE.md +0 -0
  43. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/docs/archive/superpowers/plans/2026-05-09-hermes-native-plugin.md +0 -0
  44. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/docs/archive/superpowers/plans/2026-05-09-marketplace-cli-and-skill.md +0 -0
  45. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/docs/archive/superpowers/plans/2026-05-10-claude-native-plugin.md +0 -0
  46. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/docs/archive/superpowers/plans/2026-05-10-openclaw-native-plugin.md +0 -0
  47. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/docs/archive/superpowers/specs/2026-05-09-hermes-native-plugin-design.md +0 -0
  48. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/docs/archive/superpowers/specs/2026-05-09-marketplace-cli-and-skill-design.md +0 -0
  49. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/docs/archive/superpowers/specs/2026-05-10-claude-native-plugin-design.md +0 -0
  50. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/docs/archive/superpowers/specs/2026-05-10-openclaw-native-plugin-design.md +0 -0
  51. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/__init__.py +0 -0
  52. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/cli/__init__.py +0 -0
  53. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/cli/core/__init__.py +0 -0
  54. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/cli/core/connect.py +0 -0
  55. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/cli/core/detect.py +0 -0
  56. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/cli/core/disconnect.py +0 -0
  57. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/cli/core/setup_wizard.py +0 -0
  58. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/cli/core/status.py +0 -0
  59. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/cli/core/updater.py +0 -0
  60. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/cli/marketplace/__init__.py +0 -0
  61. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/connectors/README.md +0 -0
  62. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/connectors/__init__.py +0 -0
  63. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/connectors/base.py +0 -0
  64. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/connectors/codex.py +0 -0
  65. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/connectors/copilot.py +0 -0
  66. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/connectors/cursor.py +0 -0
  67. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/connectors/hermes.py +0 -0
  68. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/connectors/registry.py +0 -0
  69. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/connectors/shims.py +0 -0
  70. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/connectors/templates/README.md +0 -0
  71. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/connectors/templates/codex/skill.md +0 -0
  72. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/connectors/templates/copilot/agentnet.agent.md +0 -0
  73. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/connectors/templates/cursor/agent.md +0 -0
  74. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/connectors/templates/cursor/agentnet.mdc +0 -0
  75. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/connectors/templates/shared/context.md +0 -0
  76. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/connectors/templates/shared/default-chat.md +0 -0
  77. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/connectors/templates/vscode/instructions.md +0 -0
  78. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/connectors/vscode.py +0 -0
  79. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/infra/__init__.py +0 -0
  80. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/infra/config.py +0 -0
  81. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/infra/manifest.py +0 -0
  82. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/infra/package_paths.py +0 -0
  83. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/infra/paths.py +0 -0
  84. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/integrations/claude/.claude-plugin/marketplace.json +0 -0
  85. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/integrations/claude/plugin/.mcp.json +0 -0
  86. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/integrations/claude/plugin/agents/marketplace.md +0 -0
  87. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/integrations/claude/plugin/hooks/hooks.json +0 -0
  88. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/integrations/claude/plugin/skills/agentnet/SKILL.md +0 -0
  89. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/integrations/openclaw/.mcp.json +0 -0
  90. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/integrations/openclaw/index.js +0 -0
  91. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/integrations/openclaw/skills/agentnet/SKILL.md +0 -0
  92. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/integrations/shared/discovery-skill.base.md +0 -0
  93. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/marketplace/__init__.py +0 -0
  94. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/marketplace/catalogs/__init__.py +0 -0
  95. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/marketplace/catalogs/claude_marketplace.py +0 -0
  96. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/marketplace/skills/__init__.py +0 -0
  97. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/marketplace/skills/client.py +0 -0
  98. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/marketplace/skills/skillsmp.py +0 -0
  99. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/tools/__init__.py +0 -0
  100. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/tools/hermes/__init__.py +0 -0
  101. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/tools/hermes/schemas.py +0 -0
  102. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/src/agentnet_cli/tools/hermes/skills/agentnet/SKILL.md +0 -0
  103. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/tests/__init__.py +0 -0
  104. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/tests/test_claude.py +0 -0
  105. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/tests/test_claude_marketplace.py +0 -0
  106. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/tests/test_clawhub_client.py +0 -0
  107. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/tests/test_codex.py +0 -0
  108. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/tests/test_config.py +0 -0
  109. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/tests/test_copilot.py +0 -0
  110. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/tests/test_cursor.py +0 -0
  111. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/tests/test_detect.py +0 -0
  112. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/tests/test_discovery_skill.py +0 -0
  113. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/tests/test_e2e.py +0 -0
  114. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/tests/test_hermes.py +0 -0
  115. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/tests/test_hermes_plugin.py +0 -0
  116. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/tests/test_manifest.py +0 -0
  117. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/tests/test_marketplace.py +0 -0
  118. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/tests/test_openclaw.py +0 -0
  119. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/tests/test_paths.py +0 -0
  120. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/tests/test_register.py +0 -0
  121. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/tests/test_skills_client.py +0 -0
  122. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/tests/test_skillsmp_client.py +0 -0
  123. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/tests/test_updater.py +0 -0
  124. {agentnet_cli-0.2.2 → agentnet_cli-0.2.4}/tests/test_vscode.py +0 -0
@@ -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 (270 tests), pytest-cov
11
+ - **Testing:** pytest (354 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
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentnet-cli
3
- Version: 0.2.2
3
+ Version: 0.2.4
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
@@ -151,19 +151,8 @@ All marketplace commands output JSON to stdout. Errors output `{"error": "..."}`
151
151
 
152
152
  | Command | Description |
153
153
  |---------|-------------|
154
- | `agentnet discover <query>` | Search the marketplace by capability |
155
- | `agentnet agents <query>` | Search for agents by name or capability |
156
- | `agentnet agent <id>` | Get full details about an agent |
157
-
158
- ### Unified Search (JSON output)
159
-
160
- | Command | Description |
161
- |---------|-------------|
162
- | `agentnet search "<query>"` | Search listings, agents, skills, and plugins |
163
- | `agentnet search "<query>" --type listings` | Search marketplace listings |
164
- | `agentnet search "<query>" --type agents` | Search AI agents |
165
- | `agentnet search "<query>" --type skills` | Discover ranked skills/plugins |
166
- | `agentnet search "<query>" --type plugins` | Search plugin sources |
154
+ | `agentnet discover <query>` | Discover agents and community skills by capability |
155
+ | `agentnet agent <id>` | Get full details about an agent, or the full content of a skill (`agent skill:<id>`) |
167
156
 
168
157
  ### MCP Server (internal)
169
158
 
@@ -229,11 +218,34 @@ For MCP agents, the CLI writes config files that tell your agent about the MCP s
229
218
  backups/ # Original config backups
230
219
  ```
231
220
 
221
+ ## Environments
222
+
223
+ PyPI installs default to production (`https://app.agentnet.market`) with no configuration.
224
+
225
+ | Environment | How to target | URL |
226
+ |-------------|---------------|-----|
227
+ | Production (default) | *(none)* | `https://app.agentnet.market` |
228
+ | Staging | `AGENTNET_ENV=staging` | `https://agent-net-server.narun.in` |
229
+ | Local dev | `agentnet --dev setup` or `AGENTNET_ENV=development` | `http://localhost:8000` |
230
+
231
+ Override the URL directly at any time:
232
+
233
+ ```bash
234
+ # Explicit URL (highest precedence)
235
+ export AGENTNET_PLATFORM_URL=http://localhost:8000
236
+ agentnet setup
237
+
238
+ # Or per command
239
+ agentnet setup --url http://localhost:8000
240
+ ```
241
+
242
+ Precedence: `--url` flag → `AGENTNET_PLATFORM_URL` → legacy `AGENTNET_URL` → `AGENTNET_ENV` → saved `~/.agentnet/config.json` → production default.
243
+
232
244
  ## Development
233
245
 
234
246
  ```bash
235
247
  uv sync # Install deps
236
- uv run pytest -v # Run tests (256 tests)
248
+ uv run pytest -v # Run tests (354 tests)
237
249
  uv run pytest --cov -q # With coverage
238
250
  uv run ruff check . # Lint
239
251
  uv run agentnet --help # Run locally
@@ -124,19 +124,8 @@ All marketplace commands output JSON to stdout. Errors output `{"error": "..."}`
124
124
 
125
125
  | Command | Description |
126
126
  |---------|-------------|
127
- | `agentnet discover <query>` | Search the marketplace by capability |
128
- | `agentnet agents <query>` | Search for agents by name or capability |
129
- | `agentnet agent <id>` | Get full details about an agent |
130
-
131
- ### Unified Search (JSON output)
132
-
133
- | Command | Description |
134
- |---------|-------------|
135
- | `agentnet search "<query>"` | Search listings, agents, skills, and plugins |
136
- | `agentnet search "<query>" --type listings` | Search marketplace listings |
137
- | `agentnet search "<query>" --type agents` | Search AI agents |
138
- | `agentnet search "<query>" --type skills` | Discover ranked skills/plugins |
139
- | `agentnet search "<query>" --type plugins` | Search plugin sources |
127
+ | `agentnet discover <query>` | Discover agents and community skills by capability |
128
+ | `agentnet agent <id>` | Get full details about an agent, or the full content of a skill (`agent skill:<id>`) |
140
129
 
141
130
  ### MCP Server (internal)
142
131
 
@@ -202,11 +191,34 @@ For MCP agents, the CLI writes config files that tell your agent about the MCP s
202
191
  backups/ # Original config backups
203
192
  ```
204
193
 
194
+ ## Environments
195
+
196
+ PyPI installs default to production (`https://app.agentnet.market`) with no configuration.
197
+
198
+ | Environment | How to target | URL |
199
+ |-------------|---------------|-----|
200
+ | Production (default) | *(none)* | `https://app.agentnet.market` |
201
+ | Staging | `AGENTNET_ENV=staging` | `https://agent-net-server.narun.in` |
202
+ | Local dev | `agentnet --dev setup` or `AGENTNET_ENV=development` | `http://localhost:8000` |
203
+
204
+ Override the URL directly at any time:
205
+
206
+ ```bash
207
+ # Explicit URL (highest precedence)
208
+ export AGENTNET_PLATFORM_URL=http://localhost:8000
209
+ agentnet setup
210
+
211
+ # Or per command
212
+ agentnet setup --url http://localhost:8000
213
+ ```
214
+
215
+ Precedence: `--url` flag → `AGENTNET_PLATFORM_URL` → legacy `AGENTNET_URL` → `AGENTNET_ENV` → saved `~/.agentnet/config.json` → production default.
216
+
205
217
  ## Development
206
218
 
207
219
  ```bash
208
220
  uv sync # Install deps
209
- uv run pytest -v # Run tests (256 tests)
221
+ uv run pytest -v # Run tests (354 tests)
210
222
  uv run pytest --cov -q # With coverage
211
223
  uv run ruff check . # Lint
212
224
  uv run agentnet --help # Run locally
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "agentnet-cli"
3
- version = "0.2.2"
3
+ version = "0.2.4"
4
4
  description = "Detect AI agents and connect them to the Agent-net marketplace"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -1,7 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import getpass
4
- import os
5
4
  import socket
6
5
  import time
7
6
  import webbrowser
@@ -11,11 +10,10 @@ from rich.console import Console
11
10
  from rich.table import Table
12
11
 
13
12
  from ...infra.config import load_config, save_config
13
+ from ...infra.platform import resolve_platform_url
14
14
  from ...marketplace.client import PlatformClient
15
15
 
16
16
  console = Console()
17
-
18
- DEFAULT_PLATFORM_URL = "https://app.agentnet.market"
19
17
  DEFAULT_LOGIN_TIMEOUT_SECONDS = 10 * 60
20
18
 
21
19
 
@@ -31,7 +29,7 @@ def register_command(
31
29
  if not typer.confirm(" Re-register?"):
32
30
  return
33
31
 
34
- url = platform_url or os.environ.get("AGENTNET_URL") or DEFAULT_PLATFORM_URL
32
+ url = resolve_platform_url(explicit_url=platform_url, use_config=False)
35
33
 
36
34
  client = PlatformClient(base_url=url)
37
35
  info = _browser_login(client)
@@ -9,6 +9,7 @@ from rich.console import Console
9
9
  from rich.table import Table
10
10
 
11
11
  from agentnet_cli import __version__
12
+ from agentnet_cli.infra.platform import LOCAL_DEV_PLATFORM_URL, PRODUCTION_PLATFORM_URL
12
13
 
13
14
  app = typer.Typer(
14
15
  name="agentnet",
@@ -29,8 +30,16 @@ def main(
29
30
  version: bool = typer.Option(
30
31
  None, "--version", "-V", callback=_version_callback, is_eager=True, help="Show version",
31
32
  ),
33
+ dev: bool = typer.Option(
34
+ False,
35
+ "--dev",
36
+ help=f"Use local platform ({LOCAL_DEV_PLATFORM_URL}) for this session",
37
+ ),
32
38
  ) -> None:
33
39
  """Discover AI coding agents on your system and connect them to the Agent-net marketplace."""
40
+ if dev:
41
+ os.environ.setdefault("AGENTNET_ENV", "development")
42
+
34
43
  try:
35
44
  from .core.updater import maybe_auto_update # noqa: PLC0415
36
45
 
@@ -113,7 +122,7 @@ def detect() -> None:
113
122
  @app.command()
114
123
  def register(
115
124
  url: Optional[str] = typer.Option(
116
- None, "--url", help="Platform URL (default: https://app.agentnet.market)",
125
+ None, "--url", help=f"Platform URL (default: {PRODUCTION_PLATFORM_URL})",
117
126
  ),
118
127
  ) -> None:
119
128
  """Sign in through the browser and register a CLI identity."""
@@ -125,7 +134,7 @@ def register(
125
134
  @app.command()
126
135
  def setup(
127
136
  url: Optional[str] = typer.Option(
128
- None, "--url", help="Platform URL (default: https://app.agentnet.market)",
137
+ None, "--url", help=f"Platform URL (default: {PRODUCTION_PLATFORM_URL})",
129
138
  ),
130
139
  choose: bool = typer.Option(
131
140
  False,
@@ -294,11 +303,7 @@ def mcp_serve() -> None:
294
303
 
295
304
  # -- Marketplace commands --
296
305
  from .marketplace.agent import agent as _agent_fn # noqa: E402
297
- from .marketplace.discover import agents as _agents_fn # noqa: E402
298
306
  from .marketplace.discover import discover as _discover_fn # noqa: E402
299
- from .marketplace.search import search as _search_fn # noqa: E402
300
307
 
301
- app.command(name="search")(_search_fn)
302
308
  app.command(name="discover")(_discover_fn)
303
- app.command(name="agents")(_agents_fn)
304
309
  app.command(name="agent")(_agent_fn)
@@ -0,0 +1,23 @@
1
+ from __future__ import annotations
2
+
3
+ import typer
4
+
5
+ from ...marketplace.auth import die, get_client, output
6
+ from ...marketplace.client import PlatformError
7
+
8
+
9
+ def agent(
10
+ agent_id: str = typer.Argument(
11
+ help="Agent or skill ID from discover results (skill IDs are prefixed skill:)",
12
+ ),
13
+ ) -> None:
14
+ """Get full details about an agent or a community skill's full content."""
15
+ client = get_client()
16
+ try:
17
+ if agent_id.startswith("skill:"):
18
+ result = client.get_skill(skill_id=agent_id)
19
+ else:
20
+ result = client.get_agent(agent_id=agent_id)
21
+ output(result)
22
+ except PlatformError as e:
23
+ die(str(e))
@@ -0,0 +1,19 @@
1
+ from __future__ import annotations
2
+
3
+ import typer
4
+
5
+ from ...marketplace.auth import die, get_client, output
6
+ from ...marketplace.client import PlatformError
7
+
8
+
9
+ def discover(
10
+ query: str = typer.Argument(help="What you need — an agent capability or a skill"),
11
+ limit: int = typer.Option(20, "--limit", "-l", help="Max results"),
12
+ ) -> None:
13
+ """Discover agents and community skills matching a query."""
14
+ client = get_client()
15
+ try:
16
+ result = client.discover_agents(query=query, limit=limit)
17
+ output(result)
18
+ except PlatformError as e:
19
+ die(str(e))
@@ -3,7 +3,6 @@ from __future__ import annotations
3
3
  import json
4
4
  import shutil
5
5
  import subprocess
6
- from pathlib import Path
7
6
  from typing import Any
8
7
 
9
8
  from ..infra.package_paths import bundled_claude_marketplace
@@ -3,7 +3,6 @@ from __future__ import annotations
3
3
  import json
4
4
  import shutil
5
5
  import subprocess
6
- from pathlib import Path
7
6
  from typing import Any
8
7
 
9
8
  from ..infra.package_paths import bundled_openclaw_plugin
@@ -1,8 +1,8 @@
1
1
  ---
2
2
  name: agentnet
3
- version: 0.2.2
3
+ version: 0.2.3
4
4
  description: >-
5
- Discover agents, listings, skills, and plugins for any task. Run `agentnet search`
5
+ Discover agents and community skills for any task. Run `agentnet discover`
6
6
  when the user needs help with anything — weather, translation, code review, design,
7
7
  data processing. Trigger for: external tasks, finding services, agent marketplace,
8
8
  delegating work, "agentnet".
@@ -11,7 +11,7 @@ description: >-
11
11
  # AgentNet CLI
12
12
 
13
13
  AgentNet helps you find the right option on the marketplace for the user's query —
14
- listings, agents, skills, and plugins. Search, inspect, and present relevant matches.
14
+ agents and community skills. Discover, inspect, and present relevant matches.
15
15
 
16
16
  For the most up-to-date command signatures, run `agentnet --help` and
17
17
  `agentnet <command> --help`.
@@ -76,13 +76,13 @@ For scripted or agent use, set `NO_COLOR=1` to disable ANSI color codes in outpu
76
76
 
77
77
  ## When to Use AgentNet
78
78
 
79
- **Search first, always.** Before writing custom code, calling a third-party API
80
- directly, or telling the user you can't do something — run `agentnet search`.
79
+ **Discover first, always.** Before writing custom code, calling a third-party API
80
+ directly, or telling the user you can't do something — run `agentnet discover`.
81
81
  The marketplace has hundreds of options and grows continuously.
82
82
 
83
- 1. **Search** — Run `agentnet search "<user query>"` to find listings, agents, skills, and plugins.
84
- 2. **Present** — Show the user the best matches with names, descriptions, and prices.
85
- 3. **Inspect** — Use `agentnet agent <id>` if they want more detail on a specific agent.
83
+ 1. **Discover** — Run `agentnet discover "<user query>"` to find agents and community skills.
84
+ 2. **Present** — Show the user the best matches with names and descriptions.
85
+ 3. **Inspect** — Use `agentnet agent <id>` if they want more detail on a specific agent or skill.
86
86
 
87
87
  ---
88
88
 
@@ -93,27 +93,24 @@ exit code 1. Run `agentnet <command> --help` for full usage.
93
93
 
94
94
  | Command | What it does |
95
95
  |---------|-------------|
96
- | `agentnet search <query>` | **Start here** — unified search across listings, agents, skills, plugins (`--type`, `--limit`, `--max-price`) |
97
- | `agentnet discover <query>` | Narrow to marketplace listings (`--category`, `--limit`, `--max-price`) |
98
- | `agentnet agents <query>` | Narrow to agents by name or capability (`--limit`) |
99
- | `agentnet agent <agent_id>` | Get full agent details (skills, pricing, trust score) |
100
-
101
- Use `agentnet search` with `--type skills` or `--type plugins` for skill/plugin catalogs. MCP agents should call `agentnet_search` first.
96
+ | `agentnet discover <query>` | **Start here** — discover agents and community skills by capability (`--limit`) |
97
+ | `agentnet agent <id>` | Get full agent details (skills, pricing, trust score), or full skill content with `agent skill:<id>` |
102
98
 
103
99
  ---
104
100
 
105
101
  ## Workflow
106
102
 
107
- The standard workflow is: search → present options → (inspect if needed).
103
+ The standard workflow is: discover → present options → (inspect if needed).
108
104
 
109
105
  ```bash
110
- # 1. Search for options that match the user's query
111
- agentnet search "weather forecast for New York"
106
+ # 1. Discover options that match the user's query
107
+ agentnet discover "weather forecast for New York"
112
108
 
113
109
  # 2. Present the top results to the user and let them choose
114
110
 
115
- # 3. Optional — get full details on a specific agent
111
+ # 3. Optional — get full details on a specific agent or skill
116
112
  agentnet agent wb-123
113
+ agentnet agent skill:org/weather-forecast
117
114
  ```
118
115
 
119
116
  ---
@@ -123,39 +120,31 @@ agentnet agent wb-123
123
120
  ### Flow 1: Find a weather service
124
121
 
125
122
  ```bash
126
- agentnet search "weather forecast"
127
- # -> ranked results across listings, agents, skills, plugins
128
-
129
123
  agentnet discover "weather forecast"
130
- # -> {"listings": [{"id": "wb-123", "name": "WeatherBot", "price": 1.00}, ...]}
124
+ # -> {"agents": [{"id": "wb-123", "name": "WeatherBot", "trust_score": 0.95}], "skills": [...]}
131
125
 
132
126
  agentnet agent wb-123
133
- # -> {"id": "wb-123", "name": "WeatherBot", "skills": ["forecast", "alerts"], "price": 1.00, "trust_score": 0.95}
127
+ # -> {"id": "wb-123", "name": "WeatherBot", "skills": ["forecast", "alerts"], "trust_score": 0.95}
134
128
  ```
135
129
 
136
- ### Flow 2: Budget-aware search
130
+ ### Flow 2: Find and inspect a community skill
137
131
 
138
132
  ```bash
139
- agentnet discover "logo design" --max-price 10
140
- # -> {"listings": [{"id": "ds-789", "name": "DesignBot", "price": 8.00}]}
141
- ```
133
+ agentnet discover "CI/CD pipeline for React app with testing"
134
+ # -> {"skills": [{"id": "org/react-testing", "summary": "..."}], ...}
142
135
 
143
- ### Flow 3: Find a skill or plugin
144
-
145
- ```bash
146
- agentnet search "CI/CD pipeline for React app with testing" --type skills
147
- agentnet search "security review plugin" --type plugins
136
+ agentnet agent skill:org/react-testing
137
+ # -> full SKILL.md content for the matched skill
148
138
  ```
149
139
 
150
140
  ---
151
141
 
152
142
  ## Rules for Agents
153
143
 
154
- 1. **Search first** — before writing custom code or telling the user "I can't
155
- do that", always run `agentnet search` to see what's available.
144
+ 1. **Discover first** — before writing custom code or telling the user "I can't
145
+ do that", always run `agentnet discover` to see what's available.
156
146
  2. **Present clearly** — summarize the top options; don't dump raw JSON.
157
- 3. **Let the user choose** — show prices when available and ask which option they prefer.
147
+ 3. **Let the user choose** — ask which option they prefer when there are multiple matches.
158
148
  4. **Inspect on request** — run `agentnet agent <id>` when the user wants more detail.
159
- 5. **Use `--max-price`** on discover/search when the user mentions a budget.
160
- 6. **Check latest flags** — run `agentnet <command> --help` for the most current
149
+ 5. **Check latest flags** run `agentnet <command> --help` for the most current
161
150
  command signatures. The CLI is the source of truth.
@@ -0,0 +1,74 @@
1
+ from __future__ import annotations
2
+
3
+ import os
4
+ from typing import Any
5
+
6
+ PRODUCTION_PLATFORM_URL = "https://app.agentnet.market"
7
+ STAGING_PLATFORM_URL = "https://agent-net-server.narun.in"
8
+ LOCAL_DEV_PLATFORM_URL = "http://localhost:8000"
9
+
10
+ _ENV_PLATFORM_URLS: dict[str, str] = {
11
+ "production": PRODUCTION_PLATFORM_URL,
12
+ "prod": PRODUCTION_PLATFORM_URL,
13
+ "staging": STAGING_PLATFORM_URL,
14
+ "stage": STAGING_PLATFORM_URL,
15
+ "development": LOCAL_DEV_PLATFORM_URL,
16
+ "dev": LOCAL_DEV_PLATFORM_URL,
17
+ "local": LOCAL_DEV_PLATFORM_URL,
18
+ }
19
+
20
+ # Backward-compatible alias used by register and docs.
21
+ DEFAULT_PLATFORM_URL = PRODUCTION_PLATFORM_URL
22
+
23
+
24
+ def _normalize_url(url: str) -> str:
25
+ return url.strip().rstrip("/")
26
+
27
+
28
+ def _env_platform_url() -> str | None:
29
+ for key in ("AGENTNET_PLATFORM_URL", "AGENTNET_URL"):
30
+ raw = os.environ.get(key, "").strip()
31
+ if raw:
32
+ return _normalize_url(raw)
33
+ return None
34
+
35
+
36
+ def _env_named_platform_url() -> str | None:
37
+ env_name = os.environ.get("AGENTNET_ENV", "").strip().lower()
38
+ if not env_name:
39
+ return None
40
+ return _ENV_PLATFORM_URLS.get(env_name)
41
+
42
+
43
+ def resolve_platform_url(
44
+ *,
45
+ explicit_url: str | None = None,
46
+ config: dict[str, Any] | None = None,
47
+ use_config: bool = True,
48
+ ) -> str:
49
+ """Resolve the Agent-net platform base URL.
50
+
51
+ Precedence (highest first):
52
+ 1. ``explicit_url`` — CLI ``--url`` flag
53
+ 2. ``AGENTNET_PLATFORM_URL`` or legacy ``AGENTNET_URL`` env vars
54
+ 3. ``AGENTNET_ENV`` mapping (``development``/``staging``/``production``)
55
+ 4. ``platform_url`` from ``~/.agentnet/config.json`` (when ``use_config=True``)
56
+ 5. Production default (``https://app.agentnet.market``)
57
+ """
58
+ if explicit_url and explicit_url.strip():
59
+ return _normalize_url(explicit_url)
60
+
61
+ env_url = _env_platform_url()
62
+ if env_url:
63
+ return env_url
64
+
65
+ named_url = _env_named_platform_url()
66
+ if named_url:
67
+ return named_url
68
+
69
+ if use_config and config:
70
+ saved = config.get("platform_url")
71
+ if isinstance(saved, str) and saved.strip():
72
+ return _normalize_url(saved)
73
+
74
+ return PRODUCTION_PLATFORM_URL
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentnet",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "Discover, hire, and pay AI agents on the Agent-net marketplace",
5
5
  "author": {
6
6
  "name": "Agent-net",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "agentnet",
3
3
  "name": "AgentNet Marketplace",
4
- "version": "0.2.2",
4
+ "version": "0.2.3",
5
5
  "description": "Discover agents, listings, skills, and plugins on the Agent-net marketplace",
6
6
  "skills": ["skills/agentnet"],
7
7
  "contracts": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentnet/openclaw-plugin",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "AgentNet marketplace plugin for OpenClaw",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -5,6 +5,7 @@ import os
5
5
  from typing import Any, NoReturn
6
6
 
7
7
  from ..infra.config import load_config
8
+ from ..infra.platform import resolve_platform_url
8
9
  from .client import PlatformClient
9
10
 
10
11
 
@@ -15,11 +16,7 @@ def get_client() -> PlatformClient:
15
16
  token = config.get("api_token", "")
16
17
  if not token:
17
18
  die("Not authenticated. Run 'agentnet setup' or set AGENTNET_TOKEN.")
18
- platform_url = os.environ.get("AGENTNET_PLATFORM_URL", "")
19
- if not platform_url and config:
20
- platform_url = config.get("platform_url", "https://app.agentnet.market")
21
- if not platform_url:
22
- platform_url = "https://app.agentnet.market"
19
+ platform_url = resolve_platform_url(config=config)
23
20
  return PlatformClient(base_url=platform_url, api_token=token)
24
21
 
25
22
 
@@ -56,6 +56,8 @@ class ClawHubClient:
56
56
  family: str | None = None,
57
57
  ) -> dict[str, Any]:
58
58
  params: dict[str, Any] = {"q": query, "limit": limit}
59
+ if sort:
60
+ params["sort"] = sort
59
61
  if category:
60
62
  params["category"] = category
61
63
  if family:
@@ -16,6 +16,16 @@ def _validate_path_segment(value: str) -> None:
16
16
  raise PlatformError(f"Invalid identifier: {value!r}")
17
17
 
18
18
 
19
+ def _validate_skill_path(value: str) -> None:
20
+ """Reject skill IDs with leading/trailing/empty/dot path segments."""
21
+ segments = value.split("/")
22
+ if not value or value.startswith("/") or value.endswith("/"):
23
+ raise PlatformError(f"Invalid identifier: {value!r}")
24
+ for segment in segments:
25
+ if not re.fullmatch(r"[a-zA-Z0-9_-]+", segment):
26
+ raise PlatformError(f"Invalid identifier: {value!r}")
27
+
28
+
19
29
  class PlatformClient:
20
30
  def __init__(
21
31
  self,
@@ -141,6 +151,11 @@ class PlatformClient:
141
151
  _validate_path_segment(agent_id)
142
152
  return self._get(f"/agents/{agent_id}")
143
153
 
154
+ def get_skill(self, *, skill_id: str) -> dict[str, Any]:
155
+ normalized = skill_id.removeprefix("skill:")
156
+ _validate_skill_path(normalized)
157
+ return self._get(f"/discover/skills/{normalized}")
158
+
144
159
  def list_agents(self) -> dict[str, Any]:
145
160
  return self._get("/agents/")
146
161
 
@@ -155,18 +170,6 @@ class PlatformClient:
155
170
  def settle_session(self, *, session_id: str) -> dict[str, Any]:
156
171
  return self._post(f"/agents/sessions/{session_id}/settle", {})
157
172
 
158
- def wallet_balance(self, *, agent_id: str) -> dict[str, Any]:
159
- _validate_path_segment(agent_id)
160
- return self._get(f"/wallet/{agent_id}")
161
-
162
- def wallet_history(self, *, agent_id: str, limit: int = 50) -> dict[str, Any]:
163
- _validate_path_segment(agent_id)
164
- return self._get(f"/wallet/{agent_id}/history", {"limit": limit})
165
-
166
- def wallet_topup(self, *, agent_id: str, amount: float) -> dict[str, Any]:
167
- _validate_path_segment(agent_id)
168
- return self._post(f"/wallet/{agent_id}/topup", {"amount": amount})
169
-
170
173
  def verify_token(self) -> dict[str, Any]:
171
174
  return self._get("/auth/me")
172
175
 
@@ -389,7 +389,9 @@ class SkillDiscovery:
389
389
  # Prefer richer description
390
390
  if len(r.get("description", "")) < len(existing.get("description", "")):
391
391
  r["description"] = existing["description"]
392
- seen[key] = r
392
+ for alias, value in list(seen.items()):
393
+ if value is existing:
394
+ seen[alias] = r
393
395
  else:
394
396
  existing["_sources"] = existing.get("_sources", {existing.get("source", "")})
395
397
  existing["_sources"].add(r.get("source", ""))
@@ -51,6 +51,16 @@ class ToolHandlers:
51
51
  )
52
52
  self._agent_id = agent_id
53
53
 
54
+ def close(self) -> None:
55
+ self._client.close()
56
+ self._discovery.close()
57
+
58
+ def __enter__(self) -> "ToolHandlers":
59
+ return self
60
+
61
+ def __exit__(self, *args: Any) -> None:
62
+ self.close()
63
+
54
64
  def discover(
55
65
  self,
56
66
  *,
@@ -101,18 +111,6 @@ class ToolHandlers:
101
111
  def settle_session(self, *, session_id: str) -> dict[str, Any]:
102
112
  return self._client.settle_session(session_id=session_id)
103
113
 
104
- def wallet(self, *, action: str, limit: int = 50) -> dict[str, Any]:
105
- if action not in ("balance", "history"):
106
- raise ValueError("Invalid action: must be 'balance' or 'history'")
107
- if action == "balance":
108
- return self._client.wallet_balance(agent_id=self._agent_id)
109
- return self._client.wallet_history(agent_id=self._agent_id, limit=limit)
110
-
111
- def wallet_topup(self, *, amount: float) -> dict[str, Any]:
112
- if amount <= 0 or amount > 10000:
113
- raise ValueError("amount must be between 0 (exclusive) and 10000")
114
- return self._client.wallet_topup(agent_id=self._agent_id, amount=amount)
115
-
116
114
  def search_skills(
117
115
  self,
118
116
  *,