specguard-mcp 0.1.2 → 0.1.4
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.
- package/README.md +183 -17
- package/dist/bin/specguard-mcp.js +5 -0
- package/dist/bin/specguard-mcp.js.map +1 -1
- package/dist/src/support/run-command.d.ts +42 -0
- package/dist/src/support/run-command.js +124 -8
- package/dist/src/support/run-command.js.map +1 -1
- package/dist/src/support/specguard-api.d.ts +50 -0
- package/dist/src/support/specguard-api.js +148 -8
- package/dist/src/support/specguard-api.js.map +1 -1
- package/dist/src/support/teardown.d.ts +33 -0
- package/dist/src/support/teardown.js +56 -0
- package/dist/src/support/teardown.js.map +1 -0
- package/dist/src/tools/add-repository.d.ts +55 -0
- package/dist/src/tools/add-repository.js +114 -0
- package/dist/src/tools/add-repository.js.map +1 -0
- package/dist/src/tools/args.d.ts +20 -0
- package/dist/src/tools/args.js +30 -0
- package/dist/src/tools/args.js.map +1 -1
- package/dist/src/tools/create-repository-api-key.d.ts +26 -0
- package/dist/src/tools/create-repository-api-key.js +83 -0
- package/dist/src/tools/create-repository-api-key.js.map +1 -0
- package/dist/src/tools/index.d.ts +61 -7
- package/dist/src/tools/index.js +71 -7
- package/dist/src/tools/index.js.map +1 -1
- package/dist/src/tools/list-repositories.d.ts +14 -7
- package/dist/src/tools/list-repositories.js +14 -7
- package/dist/src/tools/list-repositories.js.map +1 -1
- package/dist/src/tools/registrable-repositories.d.ts +51 -0
- package/dist/src/tools/registrable-repositories.js +92 -0
- package/dist/src/tools/registrable-repositories.js.map +1 -0
- package/dist/src/tools/remove-repository.d.ts +33 -0
- package/dist/src/tools/remove-repository.js +81 -0
- package/dist/src/tools/remove-repository.js.map +1 -0
- package/dist/src/tools/repository-overview.js +33 -8
- package/dist/src/tools/repository-overview.js.map +1 -1
- package/dist/src/tools/revoke-repository-api-key.d.ts +29 -0
- package/dist/src/tools/revoke-repository-api-key.js +85 -0
- package/dist/src/tools/revoke-repository-api-key.js.map +1 -0
- package/package.json +1 -1
|
@@ -449,9 +449,17 @@ const getRepositoryOverview = {
|
|
|
449
449
|
"branch's: pass `commit_sha` to be answered about ONE named run instead — after pushing a " +
|
|
450
450
|
"commit and waiting for CI, say — then read `run_anchor` to confirm which run you were served, " +
|
|
451
451
|
"because an unknown sha falls back to the newest rather than erroring. " +
|
|
452
|
-
"Pass `unannotated_examples: true` to list the individual tests
|
|
452
|
+
"Pass `unannotated_examples: true` to list the individual tests carrying no `@intent` — the " +
|
|
453
453
|
"examples behind the annotated ratio, which is otherwise a percentage with nothing to act on — " +
|
|
454
454
|
"and, in the same answer, which AREAS of the suite carry the most of them. " +
|
|
455
|
+
"HOW MUCH OF THE SUITE SPECGUARD CAN READ IS A DIFFERENT QUESTION FROM HOW MUCH IS ANNOTATED, " +
|
|
456
|
+
"and `latest_run.intent_readings` answers it on every response with no flag to pass. A test " +
|
|
457
|
+
"written in the ordinary `Class#method behavior` shape yields an entity, an action and a " +
|
|
458
|
+
"behavior from its own description, so SpecGuard reads it even with no annotation: " +
|
|
459
|
+
"`intent_readings.derived` counts those, `authored` counts the annotated ones, and `unreadable` " +
|
|
460
|
+
"is the ONLY figure on this endpoint that means tests SpecGuard can say nothing about. Never " +
|
|
461
|
+
"read `total_specs - annotated_specs` as that population — on a suite that has never been " +
|
|
462
|
+
"annotated it is the whole suite, and almost all of it is readable. " +
|
|
455
463
|
"TWO BLOCKS COME BACK ON EVERY RESPONSE — no parameter to pass, no flag to set — and they " +
|
|
456
464
|
"answer what everything above silently depends on: is SpecGuard still being fed? " +
|
|
457
465
|
"`delivery_health` is why the figures may be STALE: `refusing` is a comparison of stamps, not a " +
|
|
@@ -667,10 +675,22 @@ const getRepositoryOverview = {
|
|
|
667
675
|
unannotated_examples: {
|
|
668
676
|
type: "boolean",
|
|
669
677
|
description: "Open a run's UNANNOTATED examples — the individual tests behind `latest_run`'s " +
|
|
670
|
-
"`total_specs` MINUS `annotated_specs
|
|
671
|
-
"\"SpecGuard cannot see the other N tests\". Every other population this endpoint reports " +
|
|
678
|
+
"`total_specs` MINUS `annotated_specs`. Every other population this endpoint reports " +
|
|
672
679
|
"can be walked down to the examples it counts; annotation coverage was the exception, so " +
|
|
673
680
|
"`annotated_ratio` told you how far you had to go and not one test to annotate. " +
|
|
681
|
+
"UNANNOTATED IS NOT THE SAME AS UNREADABLE, and this block reports both. Every row here " +
|
|
682
|
+
"lacks an `@intent`, which is exact — and most of them SpecGuard READS anyway, from the " +
|
|
683
|
+
"test's own description. Each row carries `reading` (`\"derived\"` or `\"unreadable\"`) and " +
|
|
684
|
+
"`derived_intent` (the `entity`/`action`/`behavior` it got, or `null`), and the block " +
|
|
685
|
+
"carries `derived_count` and `unreadable_count` beside `recorded_count`. Only " +
|
|
686
|
+
"`unreadable_count` is a count of tests SpecGuard can say nothing about; treat the rest " +
|
|
687
|
+
"as annotation debt, not as blindness. THE UNREADABLE ROWS COME FIRST in the list, ahead " +
|
|
688
|
+
"of the derived ones, so the cap cannot hide them. " +
|
|
689
|
+
"A derived reading is WEAKER than an authored one and must never be presented as " +
|
|
690
|
+
"equivalent: it carries no preconditions, its behavior is prose somebody wrote for a test " +
|
|
691
|
+
"runner's output rather than a declared statement of what the test is for, and its layer " +
|
|
692
|
+
"is inferred from the directory rather than declared — which is why `derived_intent` " +
|
|
693
|
+
"carries no `layer` key at all. " +
|
|
674
694
|
"THIS ONE IS A FLAG, NOT A NAME — the only argument here that takes `true` rather than a " +
|
|
675
695
|
"value. The others open the rows behind a LINE of a ranking and so carry that line's key; " +
|
|
676
696
|
"this opens a POPULATION, which is a subtraction on the run and has no line to name. " +
|
|
@@ -681,8 +701,9 @@ const getRepositoryOverview = {
|
|
|
681
701
|
"one is additional, not instead. " +
|
|
682
702
|
"Asking populates `latest_run.unannotated_examples` — up to 100 of the unannotated " +
|
|
683
703
|
"examples OF WHATEVER YOU ASKED FOR, each with `name`, `file_path`, `line_number` and " +
|
|
684
|
-
"`spec_file_path` (
|
|
685
|
-
"per-example drill-ins above), plus that same population's own
|
|
704
|
+
"`spec_file_path`, `reading` and `derived_intent` (SIX fields: no `duration_seconds` and " +
|
|
705
|
+
"no `outcome`, unlike the per-example drill-ins above), plus that same population's own " +
|
|
706
|
+
"`recorded_count`, `derived_count` and `unreadable_count`, the " +
|
|
686
707
|
"`limit` the row list was cut at, and `spec_file`/`spec_directory` ECHOED BACK as the " +
|
|
687
708
|
"server READ them — `null` for each one you did not send. " +
|
|
688
709
|
"READ THE ECHO BEFORE YOU READ THE COUNT. `unannotated_examples.recorded_count` — the " +
|
|
@@ -700,13 +721,17 @@ const getRepositoryOverview = {
|
|
|
700
721
|
"THE DEBT IS — one run's annotation debt rolled up by code AREA, which is what you pick " +
|
|
701
722
|
"the next `spec_directory` narrowing FROM. Both come from this ONE flag: there is no " +
|
|
702
723
|
"second parameter to send and no new value. " +
|
|
703
|
-
"The map's rows carry `path`, `unannotated_count
|
|
704
|
-
"counted against
|
|
724
|
+
"The map's rows carry `path`, `unannotated_count`, the `recorded_count` that area was " +
|
|
725
|
+
"counted against, and the same three-way split as the worklist — `authored_count`, " +
|
|
726
|
+
"`derived_count` and `unreadable_count`, which sum to `recorded_count` while the last two " +
|
|
727
|
+
"sum to `unannotated_count` (the operands, never a fraction), plus `directory_count` — EVERY area " +
|
|
705
728
|
"the run touched, not every area with debt, and not `rows.size` — and its OWN `limit`, " +
|
|
706
729
|
"which is 10 and NOT the worklist's 100. Two caps under one ask, and the difference is " +
|
|
707
730
|
"the kind of list: 100 caps a WORKLIST to work through, 10 caps a RANKING to pick from. " +
|
|
708
731
|
"The orders differ for the same reason — the worklist is file-navigable, the map is " +
|
|
709
|
-
"ranked `unannotated_count` DESC with `path` as a tiebreak
|
|
732
|
+
"ranked `unreadable_count` DESC, then `unannotated_count` DESC, with `path` as a tiebreak " +
|
|
733
|
+
"only — the areas SpecGuard cannot read lead, because a ten-row ranking led by debt on an " +
|
|
734
|
+
"unannotated suite is a ranking by area SIZE and the dark corners never surface. A fully-annotated area " +
|
|
710
735
|
"is a real ROW with `unannotated_count: 0`, never an omission. Those rows sort last " +
|
|
711
736
|
"COLLECTIVELY, so on a run with more areas than the cap they are cut and never seen, " +
|
|
712
737
|
"but on a run inside the cap they ARE LISTED and listed is correct. So `rows.size` is " +
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repository-overview.js","sourceRoot":"","sources":["../../../src/tools/repository-overview.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAG5D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoaG;AACH,MAAM,qBAAqB,GAAmB;IAC5C,IAAI,EAAE,yBAAyB;IAE/B,KAAK,EAAE,mCAAmC;IAE1C,WAAW,EACT,2FAA2F;QAC3F,6FAA6F;QAC7F,yFAAyF;QACzF,+FAA+F;QAC/F,8FAA8F;QAC9F,gEAAgE;QAChE,gGAAgG;QAChG,wFAAwF;QACxF,6FAA6F;QAC7F,4BAA4B;QAC5B,gFAAgF;QAChF,4FAA4F;QAC5F,6FAA6F;QAC7F,kCAAkC;QAClC,6FAA6F;QAC7F,0FAA0F;QAC1F,wFAAwF;QACxF,yFAAyF;QACzF,4FAA4F;QAC5F,4DAA4D;QAC5D,+FAA+F;QAC/F,2FAA2F;QAC3F,gGAAgG;QAChG,wEAAwE;QACxE,
|
|
1
|
+
{"version":3,"file":"repository-overview.js","sourceRoot":"","sources":["../../../src/tools/repository-overview.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { ToolDefinition } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* `DELETE /api/v1/repositories/:repository_id/api_keys/:id` as a tool —
|
|
4
|
+
* shipped in the platform (`specguard/config/routes.rb:159`,
|
|
5
|
+
* `user_repository_api_keys_controller#destroy`, SPGD-754).
|
|
6
|
+
*
|
|
7
|
+
* == Replacement-mint-then-revoke is the rotation model
|
|
8
|
+
*
|
|
9
|
+
* The platform ships no `#regenerate`. Rotating a compromised key is therefore
|
|
10
|
+
* two calls with tools this slice lands together: mint a replacement
|
|
11
|
+
* (`create_repository_api_key`), deploy it, then revoke the old one here. That
|
|
12
|
+
* ordering is stated in the description because it is the one thing an agent
|
|
13
|
+
* must know before it revokes — revoke-first locks the repository's CI out
|
|
14
|
+
* until a human intervenes.
|
|
15
|
+
*
|
|
16
|
+
* == The id is scoped to the repository
|
|
17
|
+
*
|
|
18
|
+
* `repository.api_keys.find(params[:id])` — a key id belonging to a DIFFERENT
|
|
19
|
+
* repository is a 404, not a cross-repository delete. The bridge relies on that
|
|
20
|
+
* scoping entirely and adds no client-side check of its own, for the reason
|
|
21
|
+
* every tool here states: the server is the gate.
|
|
22
|
+
*
|
|
23
|
+
* == 204 with no body
|
|
24
|
+
*
|
|
25
|
+
* The same empty-body success `remove_repository` serves; the same reason
|
|
26
|
+
* `deleteJson` exists rather than routing a 204 through `requestJson`.
|
|
27
|
+
*/
|
|
28
|
+
declare const revokeRepositoryApiKey: ToolDefinition;
|
|
29
|
+
export default revokeRepositoryApiKey;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { deleteJson, requireUserApiConfig } from "../support/specguard-api.js";
|
|
2
|
+
import { requireString } from "./args.js";
|
|
3
|
+
/**
|
|
4
|
+
* `DELETE /api/v1/repositories/:repository_id/api_keys/:id` as a tool —
|
|
5
|
+
* shipped in the platform (`specguard/config/routes.rb:159`,
|
|
6
|
+
* `user_repository_api_keys_controller#destroy`, SPGD-754).
|
|
7
|
+
*
|
|
8
|
+
* == Replacement-mint-then-revoke is the rotation model
|
|
9
|
+
*
|
|
10
|
+
* The platform ships no `#regenerate`. Rotating a compromised key is therefore
|
|
11
|
+
* two calls with tools this slice lands together: mint a replacement
|
|
12
|
+
* (`create_repository_api_key`), deploy it, then revoke the old one here. That
|
|
13
|
+
* ordering is stated in the description because it is the one thing an agent
|
|
14
|
+
* must know before it revokes — revoke-first locks the repository's CI out
|
|
15
|
+
* until a human intervenes.
|
|
16
|
+
*
|
|
17
|
+
* == The id is scoped to the repository
|
|
18
|
+
*
|
|
19
|
+
* `repository.api_keys.find(params[:id])` — a key id belonging to a DIFFERENT
|
|
20
|
+
* repository is a 404, not a cross-repository delete. The bridge relies on that
|
|
21
|
+
* scoping entirely and adds no client-side check of its own, for the reason
|
|
22
|
+
* every tool here states: the server is the gate.
|
|
23
|
+
*
|
|
24
|
+
* == 204 with no body
|
|
25
|
+
*
|
|
26
|
+
* The same empty-body success `remove_repository` serves; the same reason
|
|
27
|
+
* `deleteJson` exists rather than routing a 204 through `requestJson`.
|
|
28
|
+
*/
|
|
29
|
+
const revokeRepositoryApiKey = {
|
|
30
|
+
name: "revoke_repository_api_key",
|
|
31
|
+
title: "Revoke repository API key",
|
|
32
|
+
description: "Revokes one CI API key on a SpecGuard repository. The key stops authenticating " +
|
|
33
|
+
"immediately; every OTHER key on the repository keeps working, so CI keeps " +
|
|
34
|
+
"ingesting if it holds a surviving key. " +
|
|
35
|
+
"The `key_id` is scoped to `repository_id`: a key id belonging to a different " +
|
|
36
|
+
"repository is refused 404, never a cross-repository delete. " +
|
|
37
|
+
"Key rotation is mint-then-revoke, in that order: the platform has no regenerate, " +
|
|
38
|
+
"so mint a replacement with `create_repository_api_key` and deploy it BEFORE " +
|
|
39
|
+
"revoking the old one — revoke first and the repository's CI is locked out until " +
|
|
40
|
+
"a human mints a new key in a browser. " +
|
|
41
|
+
"Authorization is the `keys_manage` capability — a member without it is refused " +
|
|
42
|
+
"403 in SpecGuard's own words. A 204 means the key is revoked. " +
|
|
43
|
+
"Takes `repository_id` (the numeric id `list_repositories` reports) and `key_id` " +
|
|
44
|
+
"(the id from `add_repository`'s or `create_repository_api_key`'s response). " +
|
|
45
|
+
"Needs SPECGUARD_USER_API_KEY (an sgu_… key), the same credential " +
|
|
46
|
+
"`add_repository` writes with and a DIFFERENT one from the sgk_… repository key " +
|
|
47
|
+
"`get_repository_overview` uses.",
|
|
48
|
+
inputSchema: {
|
|
49
|
+
type: "object",
|
|
50
|
+
properties: {
|
|
51
|
+
repository_id: {
|
|
52
|
+
type: "string",
|
|
53
|
+
description: "The repository the key belongs to — its numeric id, as `add_repository` " +
|
|
54
|
+
"returns and `list_repositories` reports, not the `org/repo` handle.",
|
|
55
|
+
},
|
|
56
|
+
key_id: {
|
|
57
|
+
type: "string",
|
|
58
|
+
description: "The id of the key to revoke, as served in the `api_key` block of " +
|
|
59
|
+
"`add_repository` or `create_repository_api_key` (or the repository's " +
|
|
60
|
+
"API-keys page). Scoped to `repository_id`: a foreign key id is refused 404.",
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
required: ["repository_id", "key_id"],
|
|
64
|
+
// Closed for the reason every tool here states — and on a DESTRUCTIVE path,
|
|
65
|
+
// a silently dropped misspelled argument must not be able to leave the
|
|
66
|
+
// agent believing it revoked a key the call never named.
|
|
67
|
+
additionalProperties: false,
|
|
68
|
+
},
|
|
69
|
+
async run(args, context) {
|
|
70
|
+
const repositoryId = requireString(args["repository_id"], "repository_id");
|
|
71
|
+
const keyId = requireString(args["key_id"], "key_id");
|
|
72
|
+
const api = requireUserApiConfig(context.config);
|
|
73
|
+
const body = await deleteJson(api, `/api/v1/repositories/${encodeURIComponent(repositoryId)}/api_keys/${encodeURIComponent(keyId)}`, context.fetch);
|
|
74
|
+
// 204 with no body — the tool's own words, because the deployment's whole
|
|
75
|
+
// answer was "no content".
|
|
76
|
+
return {
|
|
77
|
+
text: body === ""
|
|
78
|
+
? `Key ${keyId} revoked (204). Other keys on the repository keep authenticating.`
|
|
79
|
+
: body,
|
|
80
|
+
structured: { repository_id: repositoryId, key_id: keyId, revoked: true },
|
|
81
|
+
};
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
export default revokeRepositoryApiKey;
|
|
85
|
+
//# sourceMappingURL=revoke-repository-api-key.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"revoke-repository-api-key.js","sourceRoot":"","sources":["../../../src/tools/revoke-repository-api-key.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAC/E,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAG1C;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,sBAAsB,GAAmB;IAC7C,IAAI,EAAE,2BAA2B;IACjC,KAAK,EAAE,2BAA2B;IAClC,WAAW,EACT,iFAAiF;QACjF,4EAA4E;QAC5E,yCAAyC;QACzC,+EAA+E;QAC/E,8DAA8D;QAC9D,mFAAmF;QACnF,8EAA8E;QAC9E,kFAAkF;QAClF,wCAAwC;QACxC,iFAAiF;QACjF,gEAAgE;QAChE,kFAAkF;QAClF,8EAA8E;QAC9E,mEAAmE;QACnE,iFAAiF;QACjF,iCAAiC;IACnC,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,aAAa,EAAE;gBACb,IAAI,EAAE,QAAQ;gBACd,WAAW,EACT,0EAA0E;oBAC1E,qEAAqE;aACxE;YACD,MAAM,EAAE;gBACN,IAAI,EAAE,QAAQ;gBACd,WAAW,EACT,mEAAmE;oBACnE,uEAAuE;oBACvE,6EAA6E;aAChF;SACF;QACD,QAAQ,EAAE,CAAC,eAAe,EAAE,QAAQ,CAAC;QACrC,4EAA4E;QAC5E,uEAAuE;QACvE,yDAAyD;QACzD,oBAAoB,EAAE,KAAK;KAC5B;IAED,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO;QACrB,MAAM,YAAY,GAAG,aAAa,CAAC,IAAI,CAAC,eAAe,CAAC,EAAE,eAAe,CAAC,CAAC;QAC3E,MAAM,KAAK,GAAG,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,CAAC;QAEtD,MAAM,GAAG,GAAG,oBAAoB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAEjD,MAAM,IAAI,GAAG,MAAM,UAAU,CAC3B,GAAG,EACH,wBAAwB,kBAAkB,CAAC,YAAY,CAAC,aAAa,kBAAkB,CAAC,KAAK,CAAC,EAAE,EAChG,OAAO,CAAC,KAAK,CACd,CAAC;QAEF,0EAA0E;QAC1E,2BAA2B;QAC3B,OAAO;YACL,IAAI,EACF,IAAI,KAAK,EAAE;gBACT,CAAC,CAAC,OAAO,KAAK,mEAAmE;gBACjF,CAAC,CAAC,IAAI;YACV,UAAU,EAAE,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE;SAC1E,CAAC;IACJ,CAAC;CACF,CAAC;AAEF,eAAe,sBAAsB,CAAC"}
|