Skip to content

Commit 516370a

Browse files
fix: AGENTS.md compliance -- encoding, docs, changelog
- Replace non-ASCII arrows (U+2192) and section sign (U+00A7) with ASCII - Update cli-commands.md with URL marketplace add syntax and examples - Update marketplace group description to mention URL sources - Add PR number (#691) alongside issue number (#676) in CHANGELOG Co-authored-by: Copilot <[email protected]>
1 parent fa8b7a4 commit 516370a

5 files changed

Lines changed: 24 additions & 16 deletions

File tree

CHANGELOG.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1010

1111
### Added
1212

13-
- `apm marketplace add <URL>` accepts HTTPS URLs for registering Agent Skills discovery indexes, with automatic `.well-known/agent-skills/index.json` resolution for bare origins (#676)
14-
- Agent Skills Discovery RFC v0.2.0 index parser with strict `$schema` validation, skill name rules, and digest verification (#676)
15-
- SHA-256 digest computation and integrity verification for URL-based marketplace indexes (#676)
16-
- ETag/Last-Modified conditional refresh for URL marketplace indexes with stale-while-revalidate fallback (#676)
17-
- Archive download and extraction support for `type: "archive"` skill entries with path traversal and decompression bomb safety guards (#676)
18-
- Lockfile provenance fields (`source_url`, `source_digest`) for URL-sourced marketplace dependencies (#676)
13+
- `apm marketplace add <URL>` accepts HTTPS URLs for registering Agent Skills discovery indexes, with automatic `.well-known/agent-skills/index.json` resolution for bare origins (#676, #691)
14+
- Agent Skills Discovery RFC v0.2.0 index parser with strict `$schema` validation, skill name rules, and digest verification (#676, #691)
15+
- SHA-256 digest computation and integrity verification for URL-based marketplace indexes (#676, #691)
16+
- ETag/Last-Modified conditional refresh for URL marketplace indexes with stale-while-revalidate fallback (#676, #691)
17+
- Archive download and extraction support for `type: "archive"` skill entries with path traversal and decompression bomb safety guards (#676, #691)
18+
- Lockfile provenance fields (`source_url`, `source_digest`) for URL-sourced marketplace dependencies (#676, #691)
1919
- `apm install` now automatically discovers and deploys local `.apm/` primitives (skills, instructions, agents, prompts, hooks, commands) to target directories, with local content taking priority over dependencies on collision (#626, #644)
2020

2121
### Fixed

docs/src/content/docs/reference/cli-commands.md

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -937,7 +937,7 @@ apm mcp show a5e8a7f0-d4e4-4a1d-b12f-2896a23fd4f1
937937

938938
### `apm marketplace` - Plugin marketplace management
939939

940-
Register, browse, and manage plugin marketplaces. Marketplaces are GitHub repositories containing a `marketplace.json` index of plugins.
940+
Register, browse, and manage plugin marketplaces. Marketplaces are GitHub repositories containing a `marketplace.json` index of plugins, or HTTPS URLs serving an Agent Skills Discovery index.
941941

942942
> See the [Marketplaces guide](../../guides/marketplaces/) for concepts and workflows.
943943
@@ -947,26 +947,28 @@ apm marketplace COMMAND [OPTIONS]
947947

948948
#### `apm marketplace add` - Register a marketplace
949949

950-
Register a GitHub repository as a plugin marketplace.
950+
Register a GitHub repository or HTTPS URL as a plugin marketplace.
951951

952952
```bash
953953
apm marketplace add OWNER/REPO [OPTIONS]
954954
apm marketplace add HOST/OWNER/REPO [OPTIONS]
955+
apm marketplace add URL [OPTIONS]
955956
```
956957

957958
**Arguments:**
958959
- `OWNER/REPO` - GitHub repository containing `marketplace.json`
959960
- `HOST/OWNER/REPO` - Repository on a non-github.com host (e.g., GitHub Enterprise)
961+
- `URL` - HTTPS URL to an Agent Skills Discovery index (bare origins auto-resolve to `/.well-known/agent-skills/index.json`)
960962

961963
**Options:**
962964
- `-n, --name TEXT` - Custom display name for the marketplace
963-
- `-b, --branch TEXT` - Branch to track (default: main)
964-
- `--host TEXT` - Git host FQDN (default: github.com or `GITHUB_HOST` env var)
965+
- `-b, --branch TEXT` - Branch to track (default: main; GitHub sources only)
966+
- `--host TEXT` - Git host FQDN (default: github.com or `GITHUB_HOST` env var; GitHub sources only)
965967
- `-v, --verbose` - Show detailed output
966968

967969
**Examples:**
968970
```bash
969-
# Register a marketplace
971+
# Register a GitHub marketplace
970972
apm marketplace add acme/plugin-marketplace
971973

972974
# Register with a custom name and branch
@@ -975,6 +977,12 @@ apm marketplace add acme/plugin-marketplace --name acme-plugins --branch release
975977
# Register from a GitHub Enterprise host
976978
apm marketplace add acme/plugin-marketplace --host ghes.corp.example.com
977979
apm marketplace add ghes.corp.example.com/acme/plugin-marketplace
980+
981+
# Register a URL-based marketplace (bare origin)
982+
apm marketplace add https://plugins.example.com
983+
984+
# Register with full index URL and custom name
985+
apm marketplace add https://plugins.example.com/.well-known/agent-skills/index.json --name company-skills
978986
```
979987

980988
#### `apm marketplace list` - List registered marketplaces

src/apm_cli/marketplace/client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ def _fetch_url_direct(url: str, *, etag: str = "", last_modified: str = "",
269269
if last_modified:
270270
headers["If-Modified-Since"] = last_modified
271271
resp = requests.get(url, headers=headers, timeout=30)
272-
# Guard against HTTPSHTTP redirect (S1)
272+
# Guard against HTTPS->HTTP redirect (S1)
273273
final_url = getattr(resp, "url", None)
274274
if isinstance(final_url, str) and urlparse(final_url).scheme.lower() != "https":
275275
raise MarketplaceFetchError(

tests/unit/marketplace/test_marketplace_url_client.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -833,7 +833,7 @@ class TestFetchUrlDirectRedirectEnforcement:
833833
"""_fetch_url_direct must reject responses redirected to non-HTTPS URLs."""
834834

835835
def test_redirect_to_http_raises(self, monkeypatch):
836-
"""An HTTPSHTTP redirect must be caught after the request completes."""
836+
"""An HTTPS->HTTP redirect must be caught after the request completes."""
837837
mock_resp = _mock_response(200, json_body=_AGENT_SKILLS_INDEX)
838838
mock_resp.url = "http://evil.com/index.json"
839839
monkeypatch.setattr(
@@ -844,7 +844,7 @@ def test_redirect_to_http_raises(self, monkeypatch):
844844
_fetch_url_direct("https://example.com/index.json")
845845

846846
def test_redirect_to_https_accepted(self, monkeypatch):
847-
"""HTTPSHTTPS redirect is fine."""
847+
"""HTTPS->HTTPS redirect is fine."""
848848
mock_resp = _mock_response(200, json_body=_AGENT_SKILLS_INDEX)
849849
mock_resp.url = "https://cdn.example.com/index.json"
850850
monkeypatch.setattr(

tests/unit/marketplace/test_marketplace_url_commands.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ def test_http_url_rejected(self, runner):
106106
"HTTP://example.com",
107107
])
108108
def test_mixed_case_scheme_detected_as_url(self, runner, url):
109-
"""URL detection must be case-insensitive per RFC 3986 §3.1."""
109+
"""URL detection must be case-insensitive per RFC 3986 Section 3.1."""
110110
from apm_cli.commands.marketplace import marketplace
111111

112112
result = runner.invoke(marketplace, ["add", url])
@@ -438,7 +438,7 @@ class TestAddCommandErrorMessages:
438438

439439
@patch("apm_cli.marketplace.client.fetch_marketplace")
440440
def test_schema_error_shows_invalid_index_format(self, mock_fetch, runner):
441-
"""T9: wrong $schema 'Invalid index format', not generic 'Failed to register'."""
441+
"""T9: wrong $schema -> 'Invalid index format', not generic 'Failed to register'."""
442442
from apm_cli.commands.marketplace import marketplace
443443

444444
mock_fetch.side_effect = ValueError(

0 commit comments

Comments
 (0)