github-agent 2.4.15__py3-none-any.whl → 2.5.0__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.
- github_agent/api/api_client_dependabot.py +2 -0
- github_agent/api/api_client_orgs.py +4 -4
- github_agent/api/api_client_pages.py +2 -2
- github_agent/api/api_client_pulls.py +2 -0
- github_agent/auth.py +0 -10
- github_agent/mcp_server.py +14 -1
- github_agent/ontology/certification.json +3 -3
- github_agent/ontology/github.ttl +8 -5
- github_agent/ontology/shapes/connector.shacl.ttl +2 -2
- github_agent/skills/github-agent-development/SKILL.md +1 -2
- {github_agent-2.4.15.dist-info → github_agent-2.5.0.dist-info}/METADATA +2 -6
- {github_agent-2.4.15.dist-info → github_agent-2.5.0.dist-info}/RECORD +19 -18
- tests/test_cq_paths.py +1 -1
- tests/test_destructive_declaration.py +86 -0
- tests/test_ontology_parent_link.py +5 -0
- {github_agent-2.4.15.dist-info → github_agent-2.5.0.dist-info}/WHEEL +0 -0
- {github_agent-2.4.15.dist-info → github_agent-2.5.0.dist-info}/entry_points.txt +0 -0
- {github_agent-2.4.15.dist-info → github_agent-2.5.0.dist-info}/licenses/LICENSE +0 -0
- {github_agent-2.4.15.dist-info → github_agent-2.5.0.dist-info}/top_level.txt +0 -0
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
from typing import Any
|
|
3
3
|
|
|
4
4
|
from scion_sdk.exceptions import require_auth
|
|
5
|
+
from scion_sdk.mcp.destructive import destructive_operation
|
|
5
6
|
|
|
6
7
|
from github_agent.api.api_client_base import BaseApiClient
|
|
7
8
|
from github_agent.github_response_models import Response
|
|
@@ -59,6 +60,7 @@ class Api(BaseApiClient):
|
|
|
59
60
|
response.raise_for_status()
|
|
60
61
|
return Response(response=response, data=response.json())
|
|
61
62
|
|
|
63
|
+
@destructive_operation
|
|
62
64
|
@require_auth
|
|
63
65
|
def update_dependabot_alert(
|
|
64
66
|
self,
|
|
@@ -111,8 +111,8 @@ class Api(BaseApiClient):
|
|
|
111
111
|
"""Schedule an organization for deletion. IRREVERSIBLE.
|
|
112
112
|
|
|
113
113
|
GitHub responds 202 Accepted and deletes the organization, all of its
|
|
114
|
-
repositories, and all of its data asynchronously. The
|
|
115
|
-
|
|
114
|
+
repositories, and all of its data asynchronously. The SDK asks
|
|
115
|
+
the caller to confirm this action.
|
|
116
116
|
|
|
117
117
|
DELETE /orgs/{org}
|
|
118
118
|
https://docs.github.com/en/rest/orgs/orgs#delete-an-organization
|
|
@@ -240,8 +240,8 @@ class Api(BaseApiClient):
|
|
|
240
240
|
def remove_organization_member(self, org: str, username: str) -> Response:
|
|
241
241
|
"""Remove a user from an organization (repositories access included).
|
|
242
242
|
|
|
243
|
-
Destructive: the
|
|
244
|
-
|
|
243
|
+
Destructive: the SDK asks the caller to confirm this
|
|
244
|
+
action. GitHub responds 204.
|
|
245
245
|
|
|
246
246
|
DELETE /orgs/{org}/members/{username}
|
|
247
247
|
https://docs.github.com/en/rest/orgs/members#remove-an-organization-member
|
|
@@ -150,8 +150,8 @@ class Api(BaseApiClient):
|
|
|
150
150
|
def delete_pages(self, owner: str, repo: str) -> Response:
|
|
151
151
|
"""Disable GitHub Pages for a repository and delete the site.
|
|
152
152
|
|
|
153
|
-
Destructive: the
|
|
154
|
-
|
|
153
|
+
Destructive: the SDK asks the caller to confirm this
|
|
154
|
+
action. GitHub responds 204.
|
|
155
155
|
|
|
156
156
|
DELETE /repos/{owner}/{repo}/pages
|
|
157
157
|
https://docs.github.com/en/rest/pages/pages#delete-a-apiname-pages-site
|
|
@@ -5,6 +5,7 @@ from scion_sdk.exceptions import (
|
|
|
5
5
|
ParameterError,
|
|
6
6
|
require_auth,
|
|
7
7
|
)
|
|
8
|
+
from scion_sdk.mcp.destructive import destructive_operation
|
|
8
9
|
|
|
9
10
|
from github_agent.api.api_client_base import BaseApiClient
|
|
10
11
|
from github_agent.github_input_models import (
|
|
@@ -107,6 +108,7 @@ class Api(BaseApiClient):
|
|
|
107
108
|
response.raise_for_status()
|
|
108
109
|
return Response(response=response, data=response.json())
|
|
109
110
|
|
|
111
|
+
@destructive_operation
|
|
110
112
|
@require_auth
|
|
111
113
|
def merge_pull_request(
|
|
112
114
|
self,
|
github_agent/auth.py
CHANGED
|
@@ -21,16 +21,6 @@ from github_agent.api_client import Api
|
|
|
21
21
|
logger = get_logger(__name__)
|
|
22
22
|
|
|
23
23
|
|
|
24
|
-
def allow_destructive_default() -> bool:
|
|
25
|
-
"""Fleet-wide default for the destructive-action gate.
|
|
26
|
-
|
|
27
|
-
Destructive MCP actions (e.g. organization delete, member removal) are
|
|
28
|
-
blocked unless the caller passes allow_destructive=true or the
|
|
29
|
-
GITHUB_ALLOW_DESTRUCTIVE environment variable is set truthy.
|
|
30
|
-
"""
|
|
31
|
-
return setting("GITHUB_ALLOW_DESTRUCTIVE", False)
|
|
32
|
-
|
|
33
|
-
|
|
34
24
|
def _exchange_delegated_token(settings: DelegationSettings) -> str:
|
|
35
25
|
"""Exchange the caller's verified MCP token for a downstream GitHub token."""
|
|
36
26
|
logger.info(
|
github_agent/mcp_server.py
CHANGED
|
@@ -29,6 +29,7 @@ from scion_sdk.config import load_config
|
|
|
29
29
|
from scion_sdk.connector_identity import connector_version
|
|
30
30
|
from scion_sdk.mcp.concurrency import run_blocking
|
|
31
31
|
from scion_sdk.mcp.content import ConnectorContent
|
|
32
|
+
from scion_sdk.mcp.destructive import guard_destructive
|
|
32
33
|
from scion_sdk.mcp.server import create_mcp_server
|
|
33
34
|
from scion_sdk.mcp.tool_surface import register_tool_surface
|
|
34
35
|
|
|
@@ -218,7 +219,7 @@ def register_auto_merge_tools(mcp: FastMCP):
|
|
|
218
219
|
"""Register the GraphQL-only pull request auto-merge tools."""
|
|
219
220
|
|
|
220
221
|
@mcp.tool(
|
|
221
|
-
tags={"pulls"}, annotations={"readOnlyHint": False, "destructiveHint":
|
|
222
|
+
tags={"pulls"}, annotations={"readOnlyHint": False, "destructiveHint": True}
|
|
222
223
|
)
|
|
223
224
|
async def github_pulls_enable_auto_merge(
|
|
224
225
|
owner: str = Field(description="Repository owner."),
|
|
@@ -228,9 +229,21 @@ def register_auto_merge_tools(mcp: FastMCP):
|
|
|
228
229
|
default="MERGE", description="MERGE, SQUASH or REBASE."
|
|
229
230
|
),
|
|
230
231
|
client=Depends(get_client),
|
|
232
|
+
confirm: bool = Field(
|
|
233
|
+
default=False,
|
|
234
|
+
description="Confirm this destructive call when the client cannot be asked.",
|
|
235
|
+
),
|
|
231
236
|
ctx: Context | None = Field(default=None, description="MCP context"),
|
|
232
237
|
) -> Any:
|
|
233
238
|
"""Turn on auto-merge for a pull request: it merges once required checks pass."""
|
|
239
|
+
refused = await guard_destructive(
|
|
240
|
+
ctx,
|
|
241
|
+
"enable_auto_merge",
|
|
242
|
+
{"owner": owner, "repo": repo, "number": number},
|
|
243
|
+
confirm=confirm,
|
|
244
|
+
)
|
|
245
|
+
if refused is not None:
|
|
246
|
+
return refused
|
|
234
247
|
try:
|
|
235
248
|
gql_client = await run_blocking(get_graphql_client)
|
|
236
249
|
except Exception as e:
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
"api_version": "graphos.io/v1",
|
|
3
3
|
"artifacts": {
|
|
4
4
|
"github_agent/ontology/fixtures/records.json": "12f5b54b0ae98770f279f99e136788d063340042a9d6ff4bac0c22a886d2dc7b",
|
|
5
|
-
"github_agent/ontology/github.ttl": "
|
|
5
|
+
"github_agent/ontology/github.ttl": "70c68c0ae5cc8b056bd6f21af44eb3cbdf6d3bf213e0764e5c3341ea536fbd20",
|
|
6
6
|
"github_agent/ontology/mappings/source.yaml": "5142f75b88634aeac6850fe6de5b176958d63073daab2c573cf9c03daa46021c",
|
|
7
7
|
"github_agent/ontology/migrations/manifest.json": "adf16022502dd031dd303a52abae7a0677ece1135e1e05c21dba24c9ae51935c",
|
|
8
|
-
"github_agent/ontology/shapes/connector.shacl.ttl": "
|
|
8
|
+
"github_agent/ontology/shapes/connector.shacl.ttl": "0972b7e3b5f56fb0452f070800cd1f7ee790f6cf183f308f1cf69e5a0db716e0"
|
|
9
9
|
},
|
|
10
10
|
"checks": {
|
|
11
11
|
"declared_tool_schema": "passed",
|
|
@@ -29,5 +29,5 @@
|
|
|
29
29
|
"signer": "UNSIGNED-PREVIEW",
|
|
30
30
|
"signing_public_key": "",
|
|
31
31
|
"status": "source-validated",
|
|
32
|
-
"validated_at": "2026-11-
|
|
32
|
+
"validated_at": "2026-11-12T19:19:41Z"
|
|
33
33
|
}
|
github_agent/ontology/github.ttl
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
|
|
3
3
|
@prefix dc: <http://purl.org/dc/terms/> .
|
|
4
4
|
@prefix : <http://knuckles.team/kg#> .
|
|
5
|
+
@prefix core: <https://knuckles-team.github.io/ontology/core#> .
|
|
5
6
|
@prefix owl: <http://www.w3.org/2002/07/owl#> .
|
|
6
7
|
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
|
7
8
|
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
|
|
@@ -15,24 +16,26 @@
|
|
|
15
16
|
# Shared concepts owned by the epistemic-graph ontology and referenced here, never redeclared:
|
|
16
17
|
# Repository, PullRequest, Release, Branch, Commit, PipelineRun. Only the GitHub-specific subclasses and properties are declared in this pack.
|
|
17
18
|
|
|
18
|
-
:Organization a owl:Class
|
|
19
|
+
:Organization a owl:Class ;
|
|
20
|
+
rdfs:subClassOf core:Organization .
|
|
19
21
|
|
|
20
22
|
|
|
21
23
|
:Issue a owl:Class ;
|
|
22
|
-
rdfs:subClassOf :WorkItem ;
|
|
24
|
+
rdfs:subClassOf core:WorkItem ;
|
|
23
25
|
rdfs:label "Issue" ;
|
|
24
26
|
rdfs:comment "A tracked work item, bug, or discussion in a repository (github_get_issues)." .
|
|
25
27
|
|
|
26
|
-
:Workflow a owl:Class
|
|
28
|
+
:Workflow a owl:Class ;
|
|
29
|
+
rdfs:subClassOf core:Workflow .
|
|
27
30
|
|
|
28
31
|
|
|
29
32
|
:WorkflowRun a owl:Class ;
|
|
30
|
-
rdfs:subClassOf :PipelineRun ;
|
|
33
|
+
rdfs:subClassOf core:PipelineRun ;
|
|
31
34
|
rdfs:label "Workflow Run" ;
|
|
32
35
|
rdfs:comment "A single execution of a GitHub Actions workflow for a ref/commit (github_get_workflow_runs)." .
|
|
33
36
|
|
|
34
37
|
:CheckRun a owl:Class ;
|
|
35
|
-
rdfs:subClassOf :PipelineRun ;
|
|
38
|
+
rdfs:subClassOf core:PipelineRun ;
|
|
36
39
|
rdfs:label "Check Run" ;
|
|
37
40
|
rdfs:comment """A single job/check within a PipelineRun (github_get_workflow_run_jobs workflow-run job or
|
|
38
41
|
GitHub Checks-API check run). Shares its class name with the twin gitlab-api producer.""" .
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
@prefix : <
|
|
2
|
-
@prefix shape: <
|
|
1
|
+
@prefix : <https://knuckles-team.github.io/ontology/core#> .
|
|
2
|
+
@prefix shape: <https://knuckles-team.github.io/ontology/connector/github-shapes#> .
|
|
3
3
|
@prefix sh: <http://www.w3.org/ns/shacl#> .
|
|
4
4
|
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
|
|
5
5
|
|
|
@@ -65,8 +65,7 @@ with local copies or bypass a failing check.
|
|
|
65
65
|
- Credentials come from `GITHUB_TOKEN`; the endpoint is derived from `GITHUB_URL`
|
|
66
66
|
(`api.github.com`, or a GitHub Enterprise `/api/v3` host whose GraphQL endpoint
|
|
67
67
|
is `/api/graphql`). Mock all GitHub calls; never use a real token in a gate.
|
|
68
|
-
- Destructive operations
|
|
69
|
-
by default and test both states.
|
|
68
|
+
- Destructive operations are declared once with the SDK `destructive_operation` decorator; the SDK asks the caller to confirm (`confirm=true`), and `SCION_ALLOW_DESTRUCTIVE` is the one operator setting. Never add a connector-local knob.
|
|
70
69
|
- Prefer one aliased `github_graphql` query over many REST calls for cross-repo
|
|
71
70
|
reads; keep REST and GraphQL parity when adding a tool domain.
|
|
72
71
|
- Packaged skills under `github_agent/skills/` have their own helper tests
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: github-agent
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.5.0
|
|
4
4
|
Summary: GitHub Agent for MCP
|
|
5
5
|
Author-email: Repository Maintainers <maintainers@knuckles.team>
|
|
6
6
|
License: MIT
|
|
@@ -13,7 +13,7 @@ Requires-Python: >=3.12
|
|
|
13
13
|
Description-Content-Type: text/markdown
|
|
14
14
|
License-File: LICENSE
|
|
15
15
|
Requires-Dist: requests>=2.34.2
|
|
16
|
-
Requires-Dist: scion-sdk[graphql,mcp]
|
|
16
|
+
Requires-Dist: scion-sdk[graphql,mcp]<0.11,>=0.10.2
|
|
17
17
|
Provides-Extra: mcp
|
|
18
18
|
Provides-Extra: all
|
|
19
19
|
Provides-Extra: test
|
|
@@ -247,7 +247,6 @@ When query strings or parameters are supplied, an LLM-free **Knowledge Graph res
|
|
|
247
247
|
"COMMITTOOL": "True",
|
|
248
248
|
"CONTENTTOOL": "True",
|
|
249
249
|
"DEPENDABOTTOOL": "True",
|
|
250
|
-
"GITHUB_ALLOW_DESTRUCTIVE": "False",
|
|
251
250
|
"GITHUB_HTTP_CONNECT_TIMEOUT": "10",
|
|
252
251
|
"GITHUB_HTTP_READ_TIMEOUT": "30",
|
|
253
252
|
"GITHUB_TOKEN": "your_github_token_here",
|
|
@@ -298,7 +297,6 @@ own runtime secret boundary.
|
|
|
298
297
|
"COMMITTOOL": "True",
|
|
299
298
|
"CONTENTTOOL": "True",
|
|
300
299
|
"DEPENDABOTTOOL": "True",
|
|
301
|
-
"GITHUB_ALLOW_DESTRUCTIVE": "False",
|
|
302
300
|
"GITHUB_HTTP_CONNECT_TIMEOUT": "10",
|
|
303
301
|
"GITHUB_HTTP_READ_TIMEOUT": "30",
|
|
304
302
|
"GITHUB_TOKEN": "your_github_token_here",
|
|
@@ -348,7 +346,6 @@ docker run -i --rm \
|
|
|
348
346
|
-e COMMITTOOL=True \
|
|
349
347
|
-e CONTENTTOOL=True \
|
|
350
348
|
-e DEPENDABOTTOOL=True \
|
|
351
|
-
-e GITHUB_ALLOW_DESTRUCTIVE=False \
|
|
352
349
|
-e GITHUB_HTTP_CONNECT_TIMEOUT=10 \
|
|
353
350
|
-e GITHUB_HTTP_READ_TIMEOUT=30 \
|
|
354
351
|
-e GITHUB_TOKEN=your_github_token_here \
|
|
@@ -412,7 +409,6 @@ the detailed transport contract.
|
|
|
412
409
|
| `TLS_PROFILE` | `private-ca` | AgentConfig named transport profile |
|
|
413
410
|
| `TLS_PROFILE_REF` | `secret://transport/provider` | Direct runtime profile reference |
|
|
414
411
|
| `TLS_PROFILES_REF` | `secret://transport/catalog` | Named runtime profile catalog |
|
|
415
|
-
| `GITHUB_ALLOW_DESTRUCTIVE` | `False` | Allow destructive (delete/force) operations |
|
|
416
412
|
| `GITHUB_HTTP_CONNECT_TIMEOUT` | `10` | HTTP client timeouts (seconds) |
|
|
417
413
|
| `GITHUB_HTTP_READ_TIMEOUT` | `30` | |
|
|
418
414
|
| `DEBUG` | `False` | |
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
github_agent/__init__.py,sha256=C7pWvMKXqVTxI5_jZAr1KWEYADZurn5is0VOx5l5CbM,474
|
|
2
2
|
github_agent/__main__.py,sha256=O4Xg__fMvKfUsA6m61pLV56jlYY6EORiLhgDLlp0vJ8,92
|
|
3
3
|
github_agent/api_client.py,sha256=O69YfkXBKyVd59EC8szaMlw3_ZxwEEvsLSvhWlfYnvk,1581
|
|
4
|
-
github_agent/auth.py,sha256=
|
|
4
|
+
github_agent/auth.py,sha256=pB3jUeP7qvLdzzpYeZZ8o7FTS3GMsBpuaIIzWx1daLs,4239
|
|
5
5
|
github_agent/connector_contracts.py,sha256=2plbwsw6d4mMuxRx-kksD4EamYDgf03HOqBFd8ixCAQ,41936
|
|
6
6
|
github_agent/connector_sources.py,sha256=00mzXqC9KPSi15QIIE20UkmgS0QLd7wnYAatdWAjRoQ,6329
|
|
7
7
|
github_agent/github_gql.py,sha256=23_sJnv037WE2CvG93bXFHob8oiw1VShnevLi78BiTU,4282
|
|
@@ -10,18 +10,18 @@ github_agent/github_input_models.py,sha256=yqqPGHb206th736MZvbnxq9F1JRsBUBODNeNV
|
|
|
10
10
|
github_agent/github_response_models.py,sha256=mllSt0frBgzklUtfuHywJ2Ald3m99So948Xikt3H2Tc,8859
|
|
11
11
|
github_agent/kg_ingest.py,sha256=aXVYbK8RDlE39wBJxgxc73OoqEdgNJLGUCFCl5hbNd8,17958
|
|
12
12
|
github_agent/mcp_config.json,sha256=2OOXrwO1sDLyHQqpZwhvDHizPIe3by6YmK4KFE333gI,23
|
|
13
|
-
github_agent/mcp_server.py,sha256=
|
|
13
|
+
github_agent/mcp_server.py,sha256=LmtrpwEWZJGILrgmkeQs0_-Y8RtrDPplhc4MWtqNGN8,15784
|
|
14
14
|
github_agent/api/__init__.py,sha256=ntaEPqk-dsAV3HyyDLc2hYpc9nTTyG5CKI-SVDDjc24,27
|
|
15
15
|
github_agent/api/api_client_base.py,sha256=UdVOUPPRnfVo8IeZxpHXn7VbrHm-4vsXTKk3ZAv8wgQ,7445
|
|
16
16
|
github_agent/api/api_client_branches.py,sha256=Lj3eCwNxuyR564YV4Lh00Zm4xjsJDfN20q463ON5qDg,3930
|
|
17
17
|
github_agent/api/api_client_comments.py,sha256=lfUveMt5m3-ZPrIY2UV-j3huEm1nThllz1uPp2QxVnw,13192
|
|
18
18
|
github_agent/api/api_client_commits.py,sha256=1p8XOPnlGAtNvhG3JqoediHnCANK-z0B066AY0NiahY,1471
|
|
19
19
|
github_agent/api/api_client_contents.py,sha256=3dwNkGzl_Nk5PlGKsdlmw2lKf9HQUOOxChZfpnRgD-Q,3916
|
|
20
|
-
github_agent/api/api_client_dependabot.py,sha256=
|
|
20
|
+
github_agent/api/api_client_dependabot.py,sha256=0JE2xe3bJjAx5gJYkGCad1-ak3o6eKP0De86qEFlHu4,3608
|
|
21
21
|
github_agent/api/api_client_issues.py,sha256=yOmzu1bFd2s_FOdQpuq5J4ob6h-a33R4JjtqQ4AWrsk,2952
|
|
22
|
-
github_agent/api/api_client_orgs.py,sha256=
|
|
23
|
-
github_agent/api/api_client_pages.py,sha256=
|
|
24
|
-
github_agent/api/api_client_pulls.py,sha256=
|
|
22
|
+
github_agent/api/api_client_orgs.py,sha256=OVJ3qWwgXt6YBbfjAAdSS3xqiWhhvFhsbiVmZcdB8BY,11040
|
|
23
|
+
github_agent/api/api_client_pages.py,sha256=9-4yM4dbsqxn9VUD6k2Jezzn4AfVxhNnUMnAStaL5L0,8790
|
|
24
|
+
github_agent/api/api_client_pulls.py,sha256=8q2s2Ir-Ci_y4PwPSsFonxipH9llpOK-HkFyd42mzrU,5888
|
|
25
25
|
github_agent/api/api_client_releases.py,sha256=q3XrePe9KW3_tyjzpagnGIU4KOJB4wo3Ek-g4yxsGCY,3661
|
|
26
26
|
github_agent/api/api_client_repos.py,sha256=zBpuc4WeslH7Pw0PKeh9XpveE4eGmoSXsUniED8hCHE,8420
|
|
27
27
|
github_agent/api/api_client_search.py,sha256=-lOrVHjSncZ4us2tr4Keo3ygUdOABJxCWikpbsmTwJo,2222
|
|
@@ -29,12 +29,12 @@ github_agent/api/api_client_workflows.py,sha256=_ukxS6rnezp33Zk6bmAyNv4RIjwZvkUf
|
|
|
29
29
|
github_agent/connectors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
30
30
|
github_agent/mcp/__init__.py,sha256=9aOfl64J5oMSnaUZVwnpo3XO7GykLM2D11_4Kt761go,31
|
|
31
31
|
github_agent/ontology/__init__.py,sha256=dy7lE5jChNOHXMHm7ZfGfT8bH8ZhCZMSuGgu3G-Q3mM,532
|
|
32
|
-
github_agent/ontology/certification.json,sha256=
|
|
33
|
-
github_agent/ontology/github.ttl,sha256=
|
|
32
|
+
github_agent/ontology/certification.json,sha256=JRrxEABdVSLxZW8Kj7hWdwpoUX386qAF0H_4r6dCUss,1313
|
|
33
|
+
github_agent/ontology/github.ttl,sha256=cMaMCuXMiwVr1vIa9E6zy99tO_IT4HZOXDNB6lNvvSA,8362
|
|
34
34
|
github_agent/ontology/fixtures/records.json,sha256=EvW1Swrph3DyefmeE2eI0GM0AEKp1v9LrAwiqIbS3Hs,543
|
|
35
35
|
github_agent/ontology/mappings/source.yaml,sha256=UUL3W4hjSurGhQ_m3lsXaVjWMHPaqyxXPPnAPapGAhw,529
|
|
36
36
|
github_agent/ontology/migrations/manifest.json,sha256=rfFgIlAt0DHdMDpSq656Bnfs4RNeHgXCHbokya5Rk1w,118
|
|
37
|
-
github_agent/ontology/shapes/connector.shacl.ttl,sha256=
|
|
37
|
+
github_agent/ontology/shapes/connector.shacl.ttl,sha256=CXK347X1b7BFLwcIAM0ffueQ9s8YPzCPHPaeWg23FuA,3284
|
|
38
38
|
github_agent/prompts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
39
39
|
github_agent/prompts/github-mcp-operator.json,sha256=HZVcyK-7TdWT7XKnjmJL2V1XsNhha9PHtJMVj0wT_uo,12687
|
|
40
40
|
github_agent/prompts/github-mcp-release-manager.json,sha256=Vi4NwiDjI4O_VLntSXzSFidcu_eL4fsI0a41pv6QlvA,6990
|
|
@@ -42,7 +42,7 @@ github_agent/prompts/github-mcp-repository-administrator.json,sha256=rkPXgrh3UN5
|
|
|
42
42
|
github_agent/prompts/github-mcp-triage-lead.json,sha256=-PZ_ycFLeQRN5hPEBmkqr6WJQQhPmOECUUrzRKXkGF8,4581
|
|
43
43
|
github_agent/skills/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
44
44
|
github_agent/skills/github-actions-ci-review/SKILL.md,sha256=v_g7ilOldIotyzvizEbgiQqUszNBqcP4BSdtUxxroy4,1998
|
|
45
|
-
github_agent/skills/github-agent-development/SKILL.md,sha256=
|
|
45
|
+
github_agent/skills/github-agent-development/SKILL.md,sha256=5Rd_v1QmXbMo_DC2nQXB2BGQgOUQoEhogyFWvKROuK0,4047
|
|
46
46
|
github_agent/skills/github-agent-operations/SKILL.md,sha256=sPwGdgGfXZLFsCttOaEaJ7zTzttgNeFItgmB6gcFdPE,2739
|
|
47
47
|
github_agent/skills/github-backlog-planner/SKILL.md,sha256=xzP7Iyvm9huKF4-XR1JjwIuIjYpJoHfi5PNvW5BqzMU,2631
|
|
48
48
|
github_agent/skills/github-backlog-planner/references/addressed-heuristics.md,sha256=GoW7Adzm43p7pKlh6U_g2mHtNHrrgdM60EY917384gQ,3413
|
|
@@ -68,13 +68,14 @@ github_agent/skills/github-triage-resolver/SKILL.md,sha256=o8EIk-rrDSmeTBn2gl_Qd
|
|
|
68
68
|
github_agent/skills/github-triage-resolver/references/resolution-rules.md,sha256=lGPvfLCSHpNIeh2rKWcH2k_2lla3ovgBxzwvtMmyQ-0,4133
|
|
69
69
|
github_agent/skills/github-triage-resolver/scripts/classify_safe.py,sha256=peh1R5oksZfTwlzWEvKuBLmMBdNwHucwAJYWYA9fVDU,9548
|
|
70
70
|
github_agent/skills/github-triage-resolver/scripts/gh_write.py,sha256=ZA9xXbjzM-jq1dSFzcZVd1_fKyGeU4mZSAfmX4LeqxY,4129
|
|
71
|
-
github_agent-2.
|
|
71
|
+
github_agent-2.5.0.dist-info/licenses/LICENSE,sha256=5ALbh4fIALWVsUhO7q1nFT1bQb-CL9sWKf7p3GgLEG8,1070
|
|
72
72
|
tests/conftest.py,sha256=wbbxNvJTHj5_Ma2ewxkI0--A_CM9KtlMzI_rWN-F82Q,3533
|
|
73
73
|
tests/test_api_client_endpoints.py,sha256=ykF9UMx3hIbf_dCpecl9uE57FJ-VQH5yw51dUQ1WlVc,6572
|
|
74
74
|
tests/test_api_validation.py,sha256=eXAKGdqzGyoKFoN4-RmZzCwKBtyK43pVEFliwzQDH2Q,3291
|
|
75
75
|
tests/test_auth_client_edge_cases.py,sha256=OZjqgLoOQPxDVwqQZMxPG7VIfS6szKUMgABNpvLgKuQ,6440
|
|
76
|
-
tests/test_cq_paths.py,sha256=
|
|
76
|
+
tests/test_cq_paths.py,sha256=yMFO2dayYrBGXPdhqdQfvDlxr7DgboTCSqA9vvhNIK0,1489
|
|
77
77
|
tests/test_default_content_surfaces.py,sha256=UmgtO78MWki9qmTzZtnNxy47SNVmsjZjz_8dQKQQe58,2455
|
|
78
|
+
tests/test_destructive_declaration.py,sha256=yBDf2HJ9rvVk9skrBR9hTmWVcJNTfjlSsBeEqauPsI0,2751
|
|
78
79
|
tests/test_fleet_name.py,sha256=L1SuM4w05dbQvyj-eBiw01lKfvI-p2o1oj6dpQxsPIY,1409
|
|
79
80
|
tests/test_github_agent_api_brute_force_coverage.py,sha256=5jWW6oVU7cmXL2sS3OZ-3gbYGhyjlYPIWqH2rsdF2fw,7347
|
|
80
81
|
tests/test_github_agent_brute_force_coverage.py,sha256=n5RJyxWfOeZEMXRRx_c48pF9ntN_ai67qyzUKtzoiKQ,4849
|
|
@@ -84,7 +85,7 @@ tests/test_ingest_sources.py,sha256=SQFPhf0qqgX_R5sn2NP_5qVzT3x2rqQIATbvHBM7IFs,
|
|
|
84
85
|
tests/test_init_dynamics.py,sha256=qX7QPHvM9T7-1fE9clZWHZz2NHG9PddsEu4WmO7dwm8,1840
|
|
85
86
|
tests/test_kg_ingest.py,sha256=98VEL2pog_8xl_lQa8qGwcPmeszt0BAxJp5AjlcvVUk,9466
|
|
86
87
|
tests/test_model_fields.py,sha256=NboFxPOtLN-uevE9TLbS4Al-55RbF63PFFTa318gJ40,3374
|
|
87
|
-
tests/test_ontology_parent_link.py,sha256=
|
|
88
|
+
tests/test_ontology_parent_link.py,sha256=jE_arQxO9yG0q9B6Hqiwu6K7hCmIx6FWXhysd6KFFDc,4344
|
|
88
89
|
tests/test_pages.py,sha256=ow_qLRo4IytkSGdQxjxJGoZOnTY0s8MebHFZn_ggElg,10815
|
|
89
90
|
tests/test_skill_backlog_build_plan.py,sha256=DdvwgZKQnQ-d_SxErxKoTpjOROuCijr4q7CVAqB82BI,4569
|
|
90
91
|
tests/test_skill_ci_failure_sweep_summarize_runs.py,sha256=lFHXWuIzGHCzHQpBBqF4VSHIfzO6cKVgstZHdXqE7U0,3933
|
|
@@ -94,8 +95,8 @@ tests/test_skill_org_remediation_classify_fix_risk.py,sha256=CK43UuLA9ZomajH7EMO
|
|
|
94
95
|
tests/test_skill_pr_review_sweep_summarize_prs.py,sha256=NrNaucQvM7K-k1WBcOBKtTGjxJbW16VgTHbC7dSsjm4,3821
|
|
95
96
|
tests/test_skill_triage_resolver_classify_safe.py,sha256=CNXXf98xa6UYk1xoQyDM6ZSbW_G_WLNMb-oNYUFErcI,9535
|
|
96
97
|
tests/test_startup.py,sha256=Ix_g69k0tsZbY0-Vkeh8ADWojUdbYwTwwmnM4_hVuCc,1245
|
|
97
|
-
github_agent-2.
|
|
98
|
-
github_agent-2.
|
|
99
|
-
github_agent-2.
|
|
100
|
-
github_agent-2.
|
|
101
|
-
github_agent-2.
|
|
98
|
+
github_agent-2.5.0.dist-info/METADATA,sha256=qqjXxLS6Qcmbn4zUWMfAZbl5EXCXyu4HqmU0puBS0gs,31632
|
|
99
|
+
github_agent-2.5.0.dist-info/WHEEL,sha256=mOdXR9C3wMVov7cSY8PY-XCzo3SmmWCHvGQr5csJoao,91
|
|
100
|
+
github_agent-2.5.0.dist-info/entry_points.txt,sha256=Xs66xjLEy6t408ysVybR_GA4blcThForMZfxAMw4oAw,125
|
|
101
|
+
github_agent-2.5.0.dist-info/top_level.txt,sha256=rF1I0e3JiEUPistmGCg9UI1zYzTjg-bzVJ61YgbPrjU,42
|
|
102
|
+
github_agent-2.5.0.dist-info/RECORD,,
|
tests/test_cq_paths.py
CHANGED
|
@@ -35,7 +35,7 @@ def test_state_is_declared_on_the_issue_type() -> None:
|
|
|
35
35
|
|
|
36
36
|
|
|
37
37
|
def test_check_run_extends_pipeline_run() -> None:
|
|
38
|
-
assert "rdfs:subClassOf :PipelineRun" in _block("CheckRun")
|
|
38
|
+
assert "rdfs:subClassOf core:PipelineRun" in _block("CheckRun")
|
|
39
39
|
|
|
40
40
|
|
|
41
41
|
def test_no_mapping_has_a_null_ontology_class() -> None:
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"""CONN-GITHUB-AGENT-CONNECTOR-CONTENT-R008: destructive operations use the SDK's one declaration and guard."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import asyncio
|
|
6
|
+
import importlib
|
|
7
|
+
from unittest.mock import patch
|
|
8
|
+
|
|
9
|
+
import pytest
|
|
10
|
+
import requests
|
|
11
|
+
from fastmcp import Client, FastMCP
|
|
12
|
+
|
|
13
|
+
pytestmark = pytest.mark.spec("CONN-GITHUB-AGENT-CONNECTOR-CONTENT-R008")
|
|
14
|
+
|
|
15
|
+
DECLARED = {
|
|
16
|
+
"github_merge_pull_request",
|
|
17
|
+
"github_update_dependabot_alert",
|
|
18
|
+
"github_pulls_enable_auto_merge",
|
|
19
|
+
}
|
|
20
|
+
CLASSIFIED = {"github_delete_repository", "github_delete_branch"}
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _server() -> FastMCP:
|
|
24
|
+
module = importlib.import_module("github_agent.mcp_server")
|
|
25
|
+
with patch(
|
|
26
|
+
"sys.argv", ["github-mcp", "--transport", "stdio", "--auth-type", "none"]
|
|
27
|
+
):
|
|
28
|
+
result = module.get_mcp_instance()
|
|
29
|
+
if isinstance(result, FastMCP):
|
|
30
|
+
return result
|
|
31
|
+
return next(value for value in result if isinstance(value, FastMCP))
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def test_declared_and_classified_operations_are_destructive_tools_that_ask_first(
|
|
35
|
+
monkeypatch,
|
|
36
|
+
):
|
|
37
|
+
monkeypatch.delenv("SCION_ALLOW_DESTRUCTIVE", raising=False)
|
|
38
|
+
|
|
39
|
+
async def _run():
|
|
40
|
+
async with Client(_server()) as client:
|
|
41
|
+
tools = {t.name: t for t in await client.list_tools()}
|
|
42
|
+
for name in DECLARED | CLASSIFIED:
|
|
43
|
+
assert tools[name].annotations.destructive_hint is True, name
|
|
44
|
+
assert "confirm" in tools[name].input_schema["properties"], name
|
|
45
|
+
for name, tool in tools.items():
|
|
46
|
+
assert "allow_destructive" not in tool.input_schema["properties"], name
|
|
47
|
+
|
|
48
|
+
asyncio.run(_run())
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
@pytest.mark.parametrize(
|
|
52
|
+
"name,arguments",
|
|
53
|
+
[
|
|
54
|
+
(
|
|
55
|
+
"github_merge_pull_request",
|
|
56
|
+
{"owner": "o", "repo": "r", "number": 1},
|
|
57
|
+
),
|
|
58
|
+
(
|
|
59
|
+
"github_delete_branch",
|
|
60
|
+
{"owner": "o", "repo": "r", "branch": "b"},
|
|
61
|
+
),
|
|
62
|
+
],
|
|
63
|
+
)
|
|
64
|
+
def test_unconfirmed_call_sends_no_request(name, arguments, monkeypatch):
|
|
65
|
+
monkeypatch.delenv("SCION_ALLOW_DESTRUCTIVE", raising=False)
|
|
66
|
+
monkeypatch.setenv("GITHUB_TOKEN", "test-token")
|
|
67
|
+
sent: list[str] = []
|
|
68
|
+
|
|
69
|
+
def record(self, method, url, **kwargs):
|
|
70
|
+
sent.append(f"{method} {url}")
|
|
71
|
+
raise AssertionError("no request may be made without confirmation")
|
|
72
|
+
|
|
73
|
+
monkeypatch.setattr(requests.Session, "request", record)
|
|
74
|
+
|
|
75
|
+
async def _run():
|
|
76
|
+
async with Client(_server()) as client:
|
|
77
|
+
refused = await client.call_tool(name, arguments, raise_on_error=False)
|
|
78
|
+
assert refused.structured_content["cancelled"] is True
|
|
79
|
+
|
|
80
|
+
asyncio.run(_run())
|
|
81
|
+
assert sent == []
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def test_no_connector_local_knob_remains():
|
|
85
|
+
auth = importlib.import_module("github_agent.auth")
|
|
86
|
+
assert not hasattr(auth, "allow_destructive_default")
|
|
@@ -30,6 +30,11 @@ PARENT_CLASSES = frozenset(
|
|
|
30
30
|
"http://knuckles.team/kg#Workflow",
|
|
31
31
|
)
|
|
32
32
|
)
|
|
33
|
+
# The core ontology is addressed under its one HTTPS base; a pack class rolls up to a core class by that IRI.
|
|
34
|
+
CORE_BASE = "https://knuckles-team.github.io/ontology/core#"
|
|
35
|
+
PARENT_CLASSES = PARENT_CLASSES | frozenset(
|
|
36
|
+
CORE_BASE + iri.rsplit("#", 1)[1] for iri in PARENT_CLASSES
|
|
37
|
+
)
|
|
33
38
|
# Classes for which the parent ontology has no fitting class yet. Each is a candidate for a new
|
|
34
39
|
# parent class (see the orphan mapping report); a class leaves this set when it gains a parent.
|
|
35
40
|
PENDING_NEW_PARENT: frozenset[str] = frozenset()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|