@nyuchi/mzizi-mcp 0.9.0 → 0.10.0
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/LICENSE +202 -0
- package/README.md +115 -85
- package/dist/access.d.ts +69 -0
- package/dist/access.d.ts.map +1 -0
- package/dist/access.js +72 -0
- package/dist/access.js.map +1 -0
- package/dist/auth/authkit-handler.d.ts +4 -3
- package/dist/auth/authkit-handler.d.ts.map +1 -1
- package/dist/auth/authkit-handler.js +52 -6
- package/dist/auth/authkit-handler.js.map +1 -1
- package/dist/auth/front.d.ts +17 -0
- package/dist/auth/front.d.ts.map +1 -0
- package/dist/auth/front.js +25 -0
- package/dist/auth/front.js.map +1 -0
- package/dist/auth/mcp-api-handler.d.ts +20 -7
- package/dist/auth/mcp-api-handler.d.ts.map +1 -1
- package/dist/auth/mcp-api-handler.js +43 -29
- package/dist/auth/mcp-api-handler.js.map +1 -1
- package/dist/desk-context.d.ts +33 -0
- package/dist/desk-context.d.ts.map +1 -0
- package/dist/desk-context.js +49 -0
- package/dist/desk-context.js.map +1 -0
- package/dist/docs-federation.d.ts +68 -0
- package/dist/docs-federation.d.ts.map +1 -0
- package/dist/docs-federation.js +282 -0
- package/dist/docs-federation.js.map +1 -0
- package/dist/env.d.ts +7 -8
- package/dist/env.d.ts.map +1 -1
- package/dist/env.js +5 -5
- package/dist/fundi-a2a.d.ts +1 -1
- package/dist/fundi-a2a.js +2 -2
- package/dist/fundi-a2a.js.map +1 -1
- package/dist/fundi-client.d.ts +24 -4
- package/dist/fundi-client.d.ts.map +1 -1
- package/dist/fundi-client.js +91 -4
- package/dist/fundi-client.js.map +1 -1
- package/dist/generated/registry-pin.d.ts +5 -0
- package/dist/generated/registry-pin.d.ts.map +1 -0
- package/dist/generated/registry-pin.js +3 -0
- package/dist/generated/registry-pin.js.map +1 -0
- package/dist/generated/registry.d.ts +23 -0
- package/dist/generated/registry.d.ts.map +1 -0
- package/dist/generated/registry.js +1204 -0
- package/dist/generated/registry.js.map +1 -0
- package/dist/generated/skills.d.ts +18 -0
- package/dist/generated/skills.d.ts.map +1 -0
- package/dist/generated/skills.js +67 -0
- package/dist/generated/skills.js.map +1 -0
- package/dist/http.d.ts +18 -9
- package/dist/http.d.ts.map +1 -1
- package/dist/http.js +16 -13
- package/dist/http.js.map +1 -1
- package/dist/issue-desk.d.ts +152 -0
- package/dist/issue-desk.d.ts.map +1 -0
- package/dist/issue-desk.js +392 -0
- package/dist/issue-desk.js.map +1 -0
- package/dist/issue-log.d.ts +80 -0
- package/dist/issue-log.d.ts.map +1 -0
- package/dist/issue-log.js +146 -0
- package/dist/issue-log.js.map +1 -0
- package/dist/issue-report.d.ts +138 -0
- package/dist/issue-report.d.ts.map +1 -0
- package/dist/issue-report.js +112 -0
- package/dist/issue-report.js.map +1 -0
- package/dist/rate-limit.d.ts +41 -0
- package/dist/rate-limit.d.ts.map +1 -0
- package/dist/rate-limit.js +58 -0
- package/dist/rate-limit.js.map +1 -0
- package/dist/registry.d.ts +126 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +280 -0
- package/dist/registry.js.map +1 -0
- package/dist/server.d.ts +96 -22
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +76 -32
- package/dist/server.js.map +1 -1
- package/dist/stdio.d.ts +6 -13
- package/dist/stdio.d.ts.map +1 -1
- package/dist/stdio.js +6 -29
- package/dist/stdio.js.map +1 -1
- package/dist/tools.d.ts +45 -6
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +313 -82
- package/dist/tools.js.map +1 -1
- package/dist/worker.d.ts +26 -14
- package/dist/worker.d.ts.map +1 -1
- package/dist/worker.js +42 -14
- package/dist/worker.js.map +1 -1
- package/package.json +24 -19
- package/dist/api-client.d.ts +0 -101
- package/dist/api-client.d.ts.map +0 -1
- package/dist/api-client.js +0 -200
- package/dist/api-client.js.map +0 -1
- package/dist/defaults.d.ts +0 -29
- package/dist/defaults.d.ts.map +0 -1
- package/dist/defaults.js +0 -29
- package/dist/defaults.js.map +0 -1
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The issue desk's report shape and the pure functions that turn a report into
|
|
3
|
+
* a GitHub issue.
|
|
4
|
+
*
|
|
5
|
+
* Split out of `issue-desk.ts` for one concrete reason: that module imports
|
|
6
|
+
* `cloudflare:workers` for the `DurableObject` base class, which only resolves
|
|
7
|
+
* inside workerd. Everything here is ordinary TypeScript, so it runs — and is
|
|
8
|
+
* tested — under plain Node. The rendering is where this feature can be
|
|
9
|
+
* silently wrong (a body claiming a reproduction that never ran will be
|
|
10
|
+
* believed by whoever reads the issue), so it is the part that most needs to be
|
|
11
|
+
* reachable by a test that does not need a runtime.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Stages, in order. A report only ever moves forward, and `failed` is terminal
|
|
15
|
+
* for the attempt rather than for the report — `retry` re-enters at the stage
|
|
16
|
+
* that failed instead of starting again, so a fundi outage does not cost the
|
|
17
|
+
* reproduction that already succeeded.
|
|
18
|
+
*
|
|
19
|
+
* The last stage is `logged`, not `filed`, and the rename is the change itself
|
|
20
|
+
* rather than a tidy-up. This desk no longer files anything: it hands the
|
|
21
|
+
* drafted report to fundi, which owns the GitHub credential, the issue log and
|
|
22
|
+
* the lifecycle write-back. Calling the terminal stage `filed` would claim a
|
|
23
|
+
* GitHub issue that, at that instant, does not exist yet — the same class of
|
|
24
|
+
* overclaim as a body asserting a reproduction that never ran.
|
|
25
|
+
*/
|
|
26
|
+
export type Stage = "opened" | "reproducing" | "drafted" | "logged" | "failed";
|
|
27
|
+
export type ReportKind = "feedback" | "observability" | "chaos";
|
|
28
|
+
export type Severity = "low" | "medium" | "high" | "critical";
|
|
29
|
+
export interface OpenInput {
|
|
30
|
+
kind: ReportKind;
|
|
31
|
+
message: string;
|
|
32
|
+
component?: string;
|
|
33
|
+
severity?: Severity;
|
|
34
|
+
/** fundi skill to run for the reproduction, when one applies. */
|
|
35
|
+
skill?: string;
|
|
36
|
+
}
|
|
37
|
+
export interface Report {
|
|
38
|
+
id: string;
|
|
39
|
+
createdAt: string;
|
|
40
|
+
updatedAt: string;
|
|
41
|
+
kind: ReportKind;
|
|
42
|
+
component: string | null;
|
|
43
|
+
severity: Severity | null;
|
|
44
|
+
message: string;
|
|
45
|
+
stage: Stage;
|
|
46
|
+
/** fundi's answer to the reproduce stage, verbatim. */
|
|
47
|
+
repro: unknown | null;
|
|
48
|
+
/** The drafted issue body — present from `drafted` onward. */
|
|
49
|
+
draft: string | null;
|
|
50
|
+
/**
|
|
51
|
+
* `fundi_issues.id` once the report has been logged.
|
|
52
|
+
*
|
|
53
|
+
* The handle everything downstream hangs off: fundi files the GitHub issue
|
|
54
|
+
* from this row, writes the lifecycle back onto it, and the console at
|
|
55
|
+
* app.mzizi.dev lists it. A report that has one is recorded somewhere a
|
|
56
|
+
* maintainer can see, which is the thing the old GitHub-token path could
|
|
57
|
+
* never honestly claim.
|
|
58
|
+
*/
|
|
59
|
+
fundiIssueId: number | null;
|
|
60
|
+
/** fundi's status for that row: open, triaged, in_progress, closed, … */
|
|
61
|
+
issueStatus: string | null;
|
|
62
|
+
/**
|
|
63
|
+
* The GitHub issue, once fundi has filed it.
|
|
64
|
+
*
|
|
65
|
+
* Null at the moment a report is logged and filled in on a later read — fundi
|
|
66
|
+
* files on a cron pass, so the URL arrives minutes after the report does.
|
|
67
|
+
*/
|
|
68
|
+
issueUrl: string | null;
|
|
69
|
+
error: string | null;
|
|
70
|
+
}
|
|
71
|
+
export interface Actor {
|
|
72
|
+
userId: string;
|
|
73
|
+
email?: string;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Everything the desk needs from the request that is not part of the report.
|
|
77
|
+
*
|
|
78
|
+
* A Durable Object has no request context of its own: it cannot see `ctx.props`,
|
|
79
|
+
* so it cannot name the reporter or authenticate to fundi on its own behalf.
|
|
80
|
+
* Both have to be handed in by the Worker, and this is the object that carries
|
|
81
|
+
* them.
|
|
82
|
+
*
|
|
83
|
+
* This type exists because they were NOT handed in. `mcp-api-handler.ts` passed
|
|
84
|
+
* the DO stub straight to the tool layer through `as unknown as
|
|
85
|
+
* IssueDeskContext`, and that double assertion silenced a real arity mismatch:
|
|
86
|
+
* the interface declares `open(input)` while the class implements
|
|
87
|
+
* `open(input, actor)`. Every report therefore reached `renderIssueBody` with
|
|
88
|
+
* `actor === undefined` and threw on `actor.email`. Grouping the two into a
|
|
89
|
+
* named parameter makes the omission a type error rather than a runtime one.
|
|
90
|
+
*/
|
|
91
|
+
export interface DeskCaller {
|
|
92
|
+
actor: Actor;
|
|
93
|
+
/**
|
|
94
|
+
* The signed-in user's WorkOS access token, forwarded to fundi as
|
|
95
|
+
* `X-Fundi-User-Token`.
|
|
96
|
+
*
|
|
97
|
+
* A string rather than the thunk `fundi-client.ts` uses, because the desk
|
|
98
|
+
* resolves it once per request and calls fundi immediately — there is no
|
|
99
|
+
* long-lived session here for it to go stale across. Optional because a token
|
|
100
|
+
* that cannot be resolved must not stop a report being filed: reproduction is
|
|
101
|
+
* the non-fatal stage, and losing it costs evidence, not the report.
|
|
102
|
+
*/
|
|
103
|
+
userToken?: string;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* fundi names its skills; they are never inferred from instruction text
|
|
107
|
+
* (`fundi-a2a.ts` §2). This maps the report KIND — which the caller does
|
|
108
|
+
* choose from a closed set — onto one, and takes an explicit `skill` override
|
|
109
|
+
* when the caller knows better.
|
|
110
|
+
*
|
|
111
|
+
* `feedback` maps to NOTHING, and that is the point. It used to fall through to
|
|
112
|
+
* `a11y-audit`, so every free-text report was submitted as an accessibility
|
|
113
|
+
* audit — including one about stale organisational text in the registry, which
|
|
114
|
+
* has no visual surface for an audit to look at. Two costs, not one: the repro
|
|
115
|
+
* field filled with an irrelevant result, and `a11y-audit` is entitlement-gated
|
|
116
|
+
* behind a paid fundi_tester subscription, so most reporters got a 403 recorded
|
|
117
|
+
* against a report that was otherwise fine.
|
|
118
|
+
*
|
|
119
|
+
* A caller who knows a skill applies can still name one explicitly. Returning
|
|
120
|
+
* null means "do not reproduce", which the desk treats as a normal outcome
|
|
121
|
+
* rather than a failure.
|
|
122
|
+
*/
|
|
123
|
+
export declare function defaultSkill(kind: ReportKind): string | null;
|
|
124
|
+
export declare function reproInstruction(input: OpenInput): string;
|
|
125
|
+
export declare function issueTitle(report: Report): string;
|
|
126
|
+
/**
|
|
127
|
+
* The issue body.
|
|
128
|
+
*
|
|
129
|
+
* Three things a hand-written report usually lacks and this one always has:
|
|
130
|
+
* what the reproduction attempt actually returned (including "it did not run"),
|
|
131
|
+
* the reporter's recent history so a maintainer can see a pattern, and the
|
|
132
|
+
* report id so a follow-up can be tied to it.
|
|
133
|
+
*/
|
|
134
|
+
export declare function renderIssueBody(report: Report, history: Report[], actor: {
|
|
135
|
+
userId: string;
|
|
136
|
+
email?: string;
|
|
137
|
+
}): string;
|
|
138
|
+
//# sourceMappingURL=issue-report.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"issue-report.d.ts","sourceRoot":"","sources":["../src/issue-report.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,KAAK,GAAG,QAAQ,GAAG,aAAa,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAA;AAE9E,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,eAAe,GAAG,OAAO,CAAA;AAC/D,MAAM,MAAM,QAAQ,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAA;AAE7D,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,UAAU,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,QAAQ,CAAA;IACnB,iEAAiE;IACjE,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAA;IACV,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,UAAU,CAAA;IAChB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAA;IACzB,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,KAAK,CAAA;IACZ,uDAAuD;IACvD,KAAK,EAAE,OAAO,GAAG,IAAI,CAAA;IACrB,8DAA8D;IAC9D,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB;;;;;;;;OAQG;IACH,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,yEAAyE;IACzE,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B;;;;;OAKG;IACH,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CACrB;AAED,MAAM,WAAW,KAAK;IACpB,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,KAAK,CAAA;IACZ;;;;;;;;;OASG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,GAAG,IAAI,CAU5D;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAGzD;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAKjD;AAUD;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EAAE,EACjB,KAAK,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GACxC,MAAM,CAqER"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The issue desk's report shape and the pure functions that turn a report into
|
|
3
|
+
* a GitHub issue.
|
|
4
|
+
*
|
|
5
|
+
* Split out of `issue-desk.ts` for one concrete reason: that module imports
|
|
6
|
+
* `cloudflare:workers` for the `DurableObject` base class, which only resolves
|
|
7
|
+
* inside workerd. Everything here is ordinary TypeScript, so it runs — and is
|
|
8
|
+
* tested — under plain Node. The rendering is where this feature can be
|
|
9
|
+
* silently wrong (a body claiming a reproduction that never ran will be
|
|
10
|
+
* believed by whoever reads the issue), so it is the part that most needs to be
|
|
11
|
+
* reachable by a test that does not need a runtime.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* fundi names its skills; they are never inferred from instruction text
|
|
15
|
+
* (`fundi-a2a.ts` §2). This maps the report KIND — which the caller does
|
|
16
|
+
* choose from a closed set — onto one, and takes an explicit `skill` override
|
|
17
|
+
* when the caller knows better.
|
|
18
|
+
*
|
|
19
|
+
* `feedback` maps to NOTHING, and that is the point. It used to fall through to
|
|
20
|
+
* `a11y-audit`, so every free-text report was submitted as an accessibility
|
|
21
|
+
* audit — including one about stale organisational text in the registry, which
|
|
22
|
+
* has no visual surface for an audit to look at. Two costs, not one: the repro
|
|
23
|
+
* field filled with an irrelevant result, and `a11y-audit` is entitlement-gated
|
|
24
|
+
* behind a paid fundi_tester subscription, so most reporters got a 403 recorded
|
|
25
|
+
* against a report that was otherwise fine.
|
|
26
|
+
*
|
|
27
|
+
* A caller who knows a skill applies can still name one explicitly. Returning
|
|
28
|
+
* null means "do not reproduce", which the desk treats as a normal outcome
|
|
29
|
+
* rather than a failure.
|
|
30
|
+
*/
|
|
31
|
+
export function defaultSkill(kind) {
|
|
32
|
+
switch (kind) {
|
|
33
|
+
case "chaos":
|
|
34
|
+
return "chaos-run";
|
|
35
|
+
case "observability":
|
|
36
|
+
return "security-scan";
|
|
37
|
+
case "feedback":
|
|
38
|
+
default:
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
export function reproInstruction(input) {
|
|
43
|
+
const where = input.component ? `component \`${input.component}\`` : "the Mzizi registry";
|
|
44
|
+
return `Reproduce a reported problem in ${where}. Reported symptom: ${input.message}`;
|
|
45
|
+
}
|
|
46
|
+
export function issueTitle(report) {
|
|
47
|
+
const scope = report.component ? `${report.component}: ` : "";
|
|
48
|
+
const firstLine = report.message.split("\n")[0].trim();
|
|
49
|
+
const body = firstLine.length > 80 ? `${firstLine.slice(0, 77)}…` : firstLine;
|
|
50
|
+
return `${scope}${body}`;
|
|
51
|
+
}
|
|
52
|
+
/* `labelsFor` used to live here, building `reported-via-mcp` / kind / severity
|
|
53
|
+
labels for the desk's own `POST /repos/…/issues` call. That call is gone, and
|
|
54
|
+
so is the label vocabulary: fundi labels what it files, from the row, as
|
|
55
|
+
`fundi:severity/…`, `fundi:type/…` and `fundi:source/mcp-issue-desk` — the
|
|
56
|
+
same canonical `fundi:<dim>/<value>` form its webhook parses back off an
|
|
57
|
+
issue. Two label vocabularies on one tracker is how a webhook filter starts
|
|
58
|
+
silently missing issues. */
|
|
59
|
+
/**
|
|
60
|
+
* The issue body.
|
|
61
|
+
*
|
|
62
|
+
* Three things a hand-written report usually lacks and this one always has:
|
|
63
|
+
* what the reproduction attempt actually returned (including "it did not run"),
|
|
64
|
+
* the reporter's recent history so a maintainer can see a pattern, and the
|
|
65
|
+
* report id so a follow-up can be tied to it.
|
|
66
|
+
*/
|
|
67
|
+
export function renderIssueBody(report, history, actor) {
|
|
68
|
+
const lines = [];
|
|
69
|
+
lines.push(report.message.trim(), "");
|
|
70
|
+
lines.push("## Report", "");
|
|
71
|
+
lines.push(`| | |`, `| --- | --- |`);
|
|
72
|
+
lines.push(`| kind | \`${report.kind}\` |`);
|
|
73
|
+
if (report.component)
|
|
74
|
+
lines.push(`| component | \`${report.component}\` |`);
|
|
75
|
+
if (report.severity)
|
|
76
|
+
lines.push(`| severity | \`${report.severity}\` |`);
|
|
77
|
+
lines.push(`| reported by | ${actor.email ?? actor.userId} |`);
|
|
78
|
+
lines.push(`| report id | \`${report.id}\` |`);
|
|
79
|
+
lines.push("");
|
|
80
|
+
lines.push("## Reproduction", "");
|
|
81
|
+
const repro = report.repro;
|
|
82
|
+
if (!repro || repro.attempted === false) {
|
|
83
|
+
lines.push(`No reproduction was attempted — ${repro?.reason ?? "the reproduction stage did not run"}.`);
|
|
84
|
+
}
|
|
85
|
+
else if (repro.error) {
|
|
86
|
+
lines.push(`The reproduction call failed: \`${repro.error}\``);
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
lines.push(`Delegated to fundi as skill \`${repro.skill}\`; fundi answered HTTP \`${repro.status}\`.`, "", "<details><summary>fundi's response, verbatim</summary>", "", "```json", JSON.stringify(repro.response, null, 2).slice(0, 4000), "```", "", "</details>", "", "> fundi currently records a submitted task and parks it — its executors are not", "> built yet, so an `accepted-not-executed` status above means the report has NOT", "> been independently reproduced. Read the symptom, not the status.");
|
|
90
|
+
}
|
|
91
|
+
lines.push("");
|
|
92
|
+
const previous = history.filter((h) => h.id !== report.id);
|
|
93
|
+
if (previous.length > 0) {
|
|
94
|
+
lines.push("## Earlier reports from the same person", "");
|
|
95
|
+
for (const h of previous.slice(0, 5)) {
|
|
96
|
+
const url = h.issueUrl ? ` — ${h.issueUrl}` : "";
|
|
97
|
+
const scope = h.component ? `\`${h.component}\`: ` : "";
|
|
98
|
+
lines.push(`- ${h.createdAt.slice(0, 10)} · ${scope}${h.message.split("\n")[0].slice(0, 100)}${url}`);
|
|
99
|
+
}
|
|
100
|
+
lines.push("", "> Included because a repeated complaint from one reporter is often one bug, and", "> three separate issues is how it stops looking like one.", "");
|
|
101
|
+
}
|
|
102
|
+
lines.push("---", "");
|
|
103
|
+
// Present tense about the logging, future about the filing — because this
|
|
104
|
+
// string is rendered at the DRAFT stage, before the report has been logged at
|
|
105
|
+
// all, and it is handed straight back to the caller as `report.draft`. Saying
|
|
106
|
+
// "which filed this issue" would assert a GitHub issue that does not exist
|
|
107
|
+
// yet and may not for another five minutes, which is the same overclaim the
|
|
108
|
+
// `logged` stage name exists to avoid.
|
|
109
|
+
lines.push("_Reported through the Mzizi MCP issue desk (`mzizi_report_issue`) and logged to fundi, which files the GitHub issue and tracks it from there._");
|
|
110
|
+
return lines.join("\n");
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=issue-report.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"issue-report.js","sourceRoot":"","sources":["../src/issue-report.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Abuse protection for the free tier: a per-IP limit on anonymous requests.
|
|
3
|
+
*
|
|
4
|
+
* Enforced by the Workers rate-limit binding (`[[ratelimits]]` in
|
|
5
|
+
* wrangler.toml, `ANON_RATE_LIMIT`), not by code here. The binding needs no
|
|
6
|
+
* resource created on the Cloudflare side: `namespace_id` is a number chosen
|
|
7
|
+
* in the config, and `wrangler deploy` applies it. Its counters are kept per
|
|
8
|
+
* Cloudflare location and are eventually consistent, which is what abuse
|
|
9
|
+
* protection needs; it is not a metering system and is not used as one.
|
|
10
|
+
*
|
|
11
|
+
* Signed-in requests are not limited here. They carry an identity, and the
|
|
12
|
+
* OAuth provider has already spent a KV read validating the token.
|
|
13
|
+
*
|
|
14
|
+
* Where the binding is absent (the stdio bin never gets here; an older local
|
|
15
|
+
* runtime might) the request is let through. Failing closed would take the
|
|
16
|
+
* free tier down with a missing binding, and the limit is a guard, not a gate.
|
|
17
|
+
*/
|
|
18
|
+
/** The binding's shape (`RateLimit` in @cloudflare/workers-types). */
|
|
19
|
+
export type RateLimiter = {
|
|
20
|
+
limit(options: {
|
|
21
|
+
key: string;
|
|
22
|
+
}): Promise<{
|
|
23
|
+
success: boolean;
|
|
24
|
+
}>;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* The key for one client: the connecting IP Cloudflare reports.
|
|
28
|
+
*
|
|
29
|
+
* `CF-Connecting-IP` is set by Cloudflare's edge and cannot be forged from
|
|
30
|
+
* outside it. Off the edge (`wrangler dev`) it may be missing, and every such
|
|
31
|
+
* request shares one bucket, which is correct for a single local client.
|
|
32
|
+
*/
|
|
33
|
+
export declare function clientKey(request: Request): string;
|
|
34
|
+
/**
|
|
35
|
+
* `null` when the request may proceed, or the 429 to send.
|
|
36
|
+
*
|
|
37
|
+
* The body is a JSON-RPC error so an MCP client can show it, and it names the
|
|
38
|
+
* way past the limit: signing in.
|
|
39
|
+
*/
|
|
40
|
+
export declare function limitAnonymous(limiter: RateLimiter | undefined, request: Request): Promise<Response | null>;
|
|
41
|
+
//# sourceMappingURL=rate-limit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rate-limit.d.ts","sourceRoot":"","sources":["../src/rate-limit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,sEAAsE;AACtE,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,CAAC,OAAO,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CAChE,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAElD;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,WAAW,GAAG,SAAS,EAChC,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAuB1B"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Abuse protection for the free tier: a per-IP limit on anonymous requests.
|
|
3
|
+
*
|
|
4
|
+
* Enforced by the Workers rate-limit binding (`[[ratelimits]]` in
|
|
5
|
+
* wrangler.toml, `ANON_RATE_LIMIT`), not by code here. The binding needs no
|
|
6
|
+
* resource created on the Cloudflare side: `namespace_id` is a number chosen
|
|
7
|
+
* in the config, and `wrangler deploy` applies it. Its counters are kept per
|
|
8
|
+
* Cloudflare location and are eventually consistent, which is what abuse
|
|
9
|
+
* protection needs; it is not a metering system and is not used as one.
|
|
10
|
+
*
|
|
11
|
+
* Signed-in requests are not limited here. They carry an identity, and the
|
|
12
|
+
* OAuth provider has already spent a KV read validating the token.
|
|
13
|
+
*
|
|
14
|
+
* Where the binding is absent (the stdio bin never gets here; an older local
|
|
15
|
+
* runtime might) the request is let through. Failing closed would take the
|
|
16
|
+
* free tier down with a missing binding, and the limit is a guard, not a gate.
|
|
17
|
+
*/
|
|
18
|
+
import { ANONYMOUS_RATE_LIMIT, SIGN_IN_MCP_URL } from "./access.js";
|
|
19
|
+
/**
|
|
20
|
+
* The key for one client: the connecting IP Cloudflare reports.
|
|
21
|
+
*
|
|
22
|
+
* `CF-Connecting-IP` is set by Cloudflare's edge and cannot be forged from
|
|
23
|
+
* outside it. Off the edge (`wrangler dev`) it may be missing, and every such
|
|
24
|
+
* request shares one bucket, which is correct for a single local client.
|
|
25
|
+
*/
|
|
26
|
+
export function clientKey(request) {
|
|
27
|
+
return request.headers.get("CF-Connecting-IP") ?? "unknown";
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* `null` when the request may proceed, or the 429 to send.
|
|
31
|
+
*
|
|
32
|
+
* The body is a JSON-RPC error so an MCP client can show it, and it names the
|
|
33
|
+
* way past the limit: signing in.
|
|
34
|
+
*/
|
|
35
|
+
export async function limitAnonymous(limiter, request) {
|
|
36
|
+
if (!limiter)
|
|
37
|
+
return null;
|
|
38
|
+
const { success } = await limiter.limit({ key: clientKey(request) });
|
|
39
|
+
if (success)
|
|
40
|
+
return null;
|
|
41
|
+
const { limit, periodSeconds } = ANONYMOUS_RATE_LIMIT;
|
|
42
|
+
return new Response(JSON.stringify({
|
|
43
|
+
jsonrpc: "2.0",
|
|
44
|
+
id: null,
|
|
45
|
+
error: {
|
|
46
|
+
code: -32000,
|
|
47
|
+
message: `Rate limit: anonymous requests are limited to ${limit} per ${periodSeconds} seconds per IP address. Wait and retry, or sign in (free) at ${SIGN_IN_MCP_URL} for no limit.`,
|
|
48
|
+
},
|
|
49
|
+
}), {
|
|
50
|
+
status: 429,
|
|
51
|
+
headers: {
|
|
52
|
+
"Content-Type": "application/json",
|
|
53
|
+
"Retry-After": String(periodSeconds),
|
|
54
|
+
"Access-Control-Allow-Origin": "*",
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=rate-limit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rate-limit.js","sourceRoot":"","sources":["../src/rate-limit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAOpE;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CAAC,OAAgB;IACxC,OAAO,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,IAAI,SAAS,CAAC;AAC9D,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,OAAgC,EAChC,OAAgB;IAEhB,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAC1B,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACrE,IAAI,OAAO;QAAE,OAAO,IAAI,CAAC;IACzB,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,GAAG,oBAAoB,CAAC;IACtD,OAAO,IAAI,QAAQ,CACjB,IAAI,CAAC,SAAS,CAAC;QACb,OAAO,EAAE,KAAK;QACd,EAAE,EAAE,IAAI;QACR,KAAK,EAAE;YACL,IAAI,EAAE,CAAC,KAAK;YACZ,OAAO,EAAE,iDAAiD,KAAK,QAAQ,aAAa,iEAAiE,eAAe,gBAAgB;SACrL;KACF,CAAC,EACF;QACE,MAAM,EAAE,GAAG;QACX,OAAO,EAAE;YACP,cAAc,EAAE,kBAAkB;YAClC,aAAa,EAAE,MAAM,CAAC,aAAa,CAAC;YACpC,6BAA6B,EAAE,GAAG;SACnC;KACF,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The registry this MCP serves — read from files bundled into the build.
|
|
3
|
+
*
|
|
4
|
+
* `src/generated/registry.ts` is produced at build time by
|
|
5
|
+
* `scripts/generate-registry.mjs` from mzizi-dev/mzizi-registry at the commit
|
|
6
|
+
* pinned in `registry.pin.json`. It holds the exact payloads the registry's own
|
|
7
|
+
* API route handlers produce for that commit, so a tool answering from here and
|
|
8
|
+
* a consumer reading `api.mzizi.dev/v1` at the same commit get the same bytes.
|
|
9
|
+
*
|
|
10
|
+
* There is no network call and no database anywhere below. That is the owner's
|
|
11
|
+
* ruling — nothing but the console touches the database — and it also removes a
|
|
12
|
+
* class of failure: a tool can no longer be "down" because an upstream is.
|
|
13
|
+
*
|
|
14
|
+
* Failure policy is unchanged from the HTTP client this replaced: every method
|
|
15
|
+
* returns a discriminated result, so a tool turns "no such component" into a
|
|
16
|
+
* sentence the caller can act on rather than an exception.
|
|
17
|
+
*/
|
|
18
|
+
export type Ok<T> = {
|
|
19
|
+
ok: true;
|
|
20
|
+
data: T;
|
|
21
|
+
};
|
|
22
|
+
export type Miss = {
|
|
23
|
+
ok: false;
|
|
24
|
+
reason: "not_found" | "invalid";
|
|
25
|
+
message: string;
|
|
26
|
+
};
|
|
27
|
+
export type Result<T> = Ok<T> | Miss;
|
|
28
|
+
/** The shape of the generated module, and of a test fixture. Values are JSON strings. */
|
|
29
|
+
export type RawRegistry = {
|
|
30
|
+
REGISTRY_PIN: {
|
|
31
|
+
readonly repository: string;
|
|
32
|
+
readonly ref: string;
|
|
33
|
+
};
|
|
34
|
+
SECTIONS: Readonly<Record<string, string>>;
|
|
35
|
+
COMPONENTS: Readonly<Record<string, string>>;
|
|
36
|
+
COMPONENT_DOCS: Readonly<Record<string, string>>;
|
|
37
|
+
NODES: Readonly<Record<string, string>>;
|
|
38
|
+
AI_INSTRUCTIONS: Readonly<Record<string, string>>;
|
|
39
|
+
};
|
|
40
|
+
export type IndexRow = {
|
|
41
|
+
name: string;
|
|
42
|
+
type?: string;
|
|
43
|
+
title?: string;
|
|
44
|
+
description?: string;
|
|
45
|
+
categories?: string[];
|
|
46
|
+
dependencies?: string[];
|
|
47
|
+
registryDependencies?: string[];
|
|
48
|
+
node?: number;
|
|
49
|
+
nodeLabel?: string;
|
|
50
|
+
owner?: string;
|
|
51
|
+
collection?: string;
|
|
52
|
+
};
|
|
53
|
+
type IndexPayload = {
|
|
54
|
+
items: IndexRow[];
|
|
55
|
+
[k: string]: unknown;
|
|
56
|
+
};
|
|
57
|
+
export type ListQuery = {
|
|
58
|
+
node?: number;
|
|
59
|
+
owner?: string;
|
|
60
|
+
collection?: string;
|
|
61
|
+
type?: string;
|
|
62
|
+
limit?: number;
|
|
63
|
+
offset?: number;
|
|
64
|
+
};
|
|
65
|
+
export type SearchHit = {
|
|
66
|
+
kind: "component" | "convention" | "ai-instruction" | "release";
|
|
67
|
+
name: string;
|
|
68
|
+
title?: string;
|
|
69
|
+
description?: string;
|
|
70
|
+
};
|
|
71
|
+
export type Registry = ReturnType<typeof createRegistry>;
|
|
72
|
+
export declare function createRegistry(raw: RawRegistry): {
|
|
73
|
+
pin: {
|
|
74
|
+
readonly repository: string;
|
|
75
|
+
readonly ref: string;
|
|
76
|
+
};
|
|
77
|
+
resolveName: (name: string) => string | undefined;
|
|
78
|
+
/** The index, filtered and paged exactly as `GET /v1/ui` does it. */
|
|
79
|
+
listComponents(q?: ListQuery): Ok<IndexPayload & {
|
|
80
|
+
meta: Record<string, unknown>;
|
|
81
|
+
}>;
|
|
82
|
+
/** One component, shadcn-shaped, with its source inline. */
|
|
83
|
+
getComponent(name: string): Result<unknown>;
|
|
84
|
+
/** Use cases, variants, sizes, a11y notes — from the item's `meta` in registry.json. */
|
|
85
|
+
getComponentDocs(name: string): Result<unknown>;
|
|
86
|
+
/**
|
|
87
|
+
* Version history, derived from the changelog and the rename map.
|
|
88
|
+
*
|
|
89
|
+
* `GET /v1/ui/{name}/versions` reads the database's `component_versions` view,
|
|
90
|
+
* which this server must not touch. The committed changelog records which
|
|
91
|
+
* release added, modified, deprecated or removed each component, and the
|
|
92
|
+
* rename map records every earlier name — together that is the history the
|
|
93
|
+
* files hold. The row shape therefore differs from the database view's; it
|
|
94
|
+
* is documented in the README.
|
|
95
|
+
*/
|
|
96
|
+
getComponentVersions(name: string): Result<unknown>;
|
|
97
|
+
/**
|
|
98
|
+
* Word search over components, conventions, AI instruction sets and releases.
|
|
99
|
+
*
|
|
100
|
+
* Documentation pages are NOT here — they live on docs.mzizi.dev, which this
|
|
101
|
+
* server federates as the `docs_*` tools.
|
|
102
|
+
*/
|
|
103
|
+
search(query: string, limit?: number): Ok<{
|
|
104
|
+
data: SearchHit[];
|
|
105
|
+
meta: Record<string, unknown>;
|
|
106
|
+
}>;
|
|
107
|
+
getArchitecture(): Ok<unknown>;
|
|
108
|
+
/** One node or rung. `n` is uncapped — a missing number is a gap, not an error. */
|
|
109
|
+
getNode(n: number): Result<unknown>;
|
|
110
|
+
getBrand(): Ok<Record<string, unknown>>;
|
|
111
|
+
getUbuntuPillars(): Ok<unknown>;
|
|
112
|
+
getUbuntuPrinciples(): Ok<unknown>;
|
|
113
|
+
listAiInstructions(): Ok<unknown>;
|
|
114
|
+
/** By name, or by target audience (mcp-server, claude-system-prompt, …), as the API resolves it. */
|
|
115
|
+
getAiInstructions(name: string): Result<unknown>;
|
|
116
|
+
/** The mzizi conventions — the list omits bodies; pass a name for one in full. */
|
|
117
|
+
listConventions(): Ok<unknown>;
|
|
118
|
+
getConvention(name: string): Result<unknown>;
|
|
119
|
+
};
|
|
120
|
+
/**
|
|
121
|
+
* The registry bundled into this build. Imported lazily so a module that only
|
|
122
|
+
* needs the types (or a test with a fixture) does not load 4 MB of strings.
|
|
123
|
+
*/
|
|
124
|
+
export declare function bundledRegistry(): Promise<Registry>;
|
|
125
|
+
export {};
|
|
126
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"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"}
|