@pome-sh/cli 0.23.16 → 0.23.17
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/dist/build-info.json +3 -3
- package/dist/{checks-J6HGCRC5.js → checks-O2XGFPLY.js} +1 -1
- package/dist/{chunk-EKQS3K3I.js → chunk-G4LBVXYN.js} +1 -1
- package/dist/{chunk-YG5PKZPV.js → chunk-KNZJW3YT.js} +2 -2
- package/dist/{chunk-TV5S6WQV.js → chunk-OW7VVW6X.js} +56 -1
- package/dist/{chunk-CQZRDFIZ.js → chunk-PTM7SZYG.js} +11 -11
- package/dist/{chunk-EKNESUTV.js → chunk-V3ZHRNQU.js} +2 -2
- package/dist/{chunk-I5WCSROP.js → chunk-YWELMGPG.js} +2 -2
- package/dist/{runDemo-CWO4WVN2.js → runDemo-OCBR5HL7.js} +5 -5
- package/dist/{runTrialGroup-YFQTWHFN.js → runTrialGroup-RQRUZPTT.js} +4 -4
- package/dist/{server-DR56XIGP.js → server-KOR7UHEP.js} +1 -1
- package/dist/src/cli/main.js +13 -13
- package/dist/{src-3BV32GLS.js → src-2MGTP2RK.js} +1 -1
- package/dist/{src-DUPU2IJB.js → src-6OG5GIZN.js} +151 -43
- package/dist/{src-ITPKDJJN.js → src-E6TRTNLF.js} +1 -1
- package/dist/{src-W6P253DD.js → src-R5TKYCCV.js} +1 -1
- package/dist/{src-RZFD2GWN.js → src-ZC7YOHIQ.js} +1 -1
- package/dist/twinHarness-CTWDE7YN.js +5 -0
- package/dist/{twinStart-2HTNIP6N.js → twinStart-UMKMZBHC.js} +3 -3
- package/package.json +1 -1
- package/dist/twinHarness-QBFIKVDR.js +0 -5
package/dist/build-info.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"package": "pome-sh",
|
|
3
|
-
"version": "0.23.
|
|
4
|
-
"git_sha": "
|
|
5
|
-
"build_time": "2026-08-
|
|
3
|
+
"version": "0.23.17",
|
|
4
|
+
"git_sha": "74385b2e1bddb7bac97b42153ce73391d732b7e9",
|
|
5
|
+
"build_time": "2026-08-12T11:51:44.980Z"
|
|
6
6
|
}
|
|
@@ -183,7 +183,7 @@ async function checkTwinReachable(_configDir) {
|
|
|
183
183
|
});
|
|
184
184
|
let harness;
|
|
185
185
|
try {
|
|
186
|
-
const { bootTwin } = await import('./twinHarness-
|
|
186
|
+
const { bootTwin } = await import('./twinHarness-CTWDE7YN.js');
|
|
187
187
|
harness = await bootTwin({
|
|
188
188
|
twin: "github",
|
|
189
189
|
seedState: void 0,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { readManifest, normalizeManifestTwins } from './chunk-ABM3CMQB.js';
|
|
2
|
-
import { createHostedClient, perTwinReturnedByCloud, parseTaskFile, runAgentCommand, writeRunArtifactsCore, toTwinHttpEvent, redactJsonl, uploadRunBlobs, scoreFromFinalizeResponse, scoreStatus, evaluationCounts } from './chunk-
|
|
2
|
+
import { createHostedClient, perTwinReturnedByCloud, parseTaskFile, runAgentCommand, writeRunArtifactsCore, toTwinHttpEvent, redactJsonl, uploadRunBlobs, scoreFromFinalizeResponse, scoreStatus, evaluationCounts } from './chunk-V3ZHRNQU.js';
|
|
3
3
|
import { MOUNTED_TWINS, HostedAuthError, HostedDiscardRefusedError, HostedQuotaError, HostedOrchError, HostedTrialError, agentResponseSchema } from './chunk-X66JOOO7.js';
|
|
4
4
|
import { redactSecrets, redactEvent } from './chunk-SG6ZTIMT.js';
|
|
5
5
|
import { existsSync } from 'node:fs';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { TWIN_NAMES, isTwinName, TWIN_REGISTRY } from './chunk-
|
|
2
|
-
import { createFileBackedRecorderStore, createRecorderStore } from './chunk-
|
|
1
|
+
import { TWIN_NAMES, isTwinName, TWIN_REGISTRY } from './chunk-PTM7SZYG.js';
|
|
2
|
+
import { createFileBackedRecorderStore, createRecorderStore } from './chunk-OW7VVW6X.js';
|
|
3
3
|
|
|
4
4
|
// src/recorder/recorder.ts
|
|
5
5
|
function createRecorder(options = {}) {
|
|
@@ -98,7 +98,8 @@ var mcpFixtureSubstrateSchema = z.enum([
|
|
|
98
98
|
"oss-source",
|
|
99
99
|
"not-captured",
|
|
100
100
|
"twin-code-transcription",
|
|
101
|
-
"twin-authored-from-vendor-docs"
|
|
101
|
+
"twin-authored-from-vendor-docs",
|
|
102
|
+
"upstream-capture-projection"
|
|
102
103
|
]);
|
|
103
104
|
var UPSTREAM_SUBSTRATES = /* @__PURE__ */ new Set([
|
|
104
105
|
"live-wire-unauth",
|
|
@@ -110,6 +111,7 @@ var TWIN_OWNED_SUBSTRATES = /* @__PURE__ */ new Set([
|
|
|
110
111
|
"twin-authored-from-vendor-docs"
|
|
111
112
|
]);
|
|
112
113
|
var OSS_SUBSTRATES = /* @__PURE__ */ new Set(["oss-source"]);
|
|
114
|
+
var PROJECTION_SUBSTRATES = /* @__PURE__ */ new Set(["upstream-capture-projection"]);
|
|
113
115
|
var sha256Hex = z.string().regex(/^[0-9a-f]{64}$/, "must be a lowercase hex sha256");
|
|
114
116
|
var mcpToolFixtureMetaSchema = z.strictObject({
|
|
115
117
|
twin: z.string().min(1),
|
|
@@ -153,9 +155,62 @@ var mcpToolFixtureMetaSchema = z.strictObject({
|
|
|
153
155
|
contentOrigin: z.string().min(1),
|
|
154
156
|
comparedToUpstream: z.string().min(1)
|
|
155
157
|
}).optional(),
|
|
158
|
+
/**
|
|
159
|
+
* Mandatory on `upstream-capture-projection`, rejected everywhere else: WHICH
|
|
160
|
+
* capture these rows came from, and every row that is not that capture's.
|
|
161
|
+
*
|
|
162
|
+
* The sha is the load-bearing field. `rawFileSha256` above proves this file
|
|
163
|
+
* has not been hand-edited since it was derived; it says nothing about what
|
|
164
|
+
* it was derived FROM, and "these are GitHub's bytes" is the whole claim a
|
|
165
|
+
* projection makes. With the source digest on the file, a reader — or the
|
|
166
|
+
* `--check` producer — can prove the claim instead of taking the substrate
|
|
167
|
+
* word for it. Without it, re-pointing the projection at a stale or
|
|
168
|
+
* hand-edited golden would re-hash clean.
|
|
169
|
+
*
|
|
170
|
+
* `dropped` and `carried` are records rather than lists so a name cannot be
|
|
171
|
+
* added without a reason, the same rule `verification_opt_out` and the
|
|
172
|
+
* MCP-lane registry are built on: the value IS the justification.
|
|
173
|
+
*/
|
|
174
|
+
projection: z.strictObject({
|
|
175
|
+
/** Repo-relative path of the upstream golden the rows were copied from. */
|
|
176
|
+
sourceFixture: z.string().min(1),
|
|
177
|
+
/** That golden's own `rawFileSha256`. Re-checked by the producer on every run. */
|
|
178
|
+
sourceRawFileSha256: sha256Hex,
|
|
179
|
+
sourceCaptureDate: z.string().regex(/^\d{4}-\d{2}-\d{2}$/, "must be an ISO date (YYYY-MM-DD)"),
|
|
180
|
+
sourceSubstrate: mcpFixtureSubstrateSchema,
|
|
181
|
+
/** The commit an `oss-source` golden was built from, when it pins one. */
|
|
182
|
+
sourceCommit: z.string().min(1).optional(),
|
|
183
|
+
/** The script that wrote this file, and the command that re-derives it. */
|
|
184
|
+
producer: z.string().min(1),
|
|
185
|
+
/** Tools the capture carries that this twin does not serve — name → reason. */
|
|
186
|
+
dropped: z.record(z.string(), z.string().min(1)),
|
|
187
|
+
/** Rows that are NOT the capture's — name → reason. Empty on a pure subtraction. */
|
|
188
|
+
carried: z.record(z.string(), z.string().min(1))
|
|
189
|
+
}).optional(),
|
|
156
190
|
notes: z.array(z.string()).optional(),
|
|
157
191
|
files: z.strictObject({ raw: z.string().min(1), canonical: z.string().min(1) })
|
|
158
192
|
}).superRefine((meta, ctx) => {
|
|
193
|
+
if (PROJECTION_SUBSTRATES.has(meta.substrate) && !meta.projection) {
|
|
194
|
+
ctx.addIssue({
|
|
195
|
+
code: "custom",
|
|
196
|
+
path: ["projection"],
|
|
197
|
+
message: `substrate '${meta.substrate}' claims these rows are an upstream capture's, so the fixture must name that capture, carry its digest, and list every row that is NOT its. A projection that does not say what it projected from is a substrate word doing the work of evidence.`
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
if (meta.projection && !PROJECTION_SUBSTRATES.has(meta.substrate)) {
|
|
201
|
+
ctx.addIssue({
|
|
202
|
+
code: "custom",
|
|
203
|
+
path: ["projection"],
|
|
204
|
+
message: `substrate '${meta.substrate}' does not project an upstream capture, so \`projection\` is a claim nothing here made.`
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
if (PROJECTION_SUBSTRATES.has(meta.substrate) && !meta.configuration) {
|
|
208
|
+
ctx.addIssue({
|
|
209
|
+
code: "custom",
|
|
210
|
+
path: ["configuration"],
|
|
211
|
+
message: `substrate '${meta.substrate}' inherits its rows from a capture, so it inherits that capture's configuration question too \u2014 GitHub serves 44 tools at /mcp/ and 85 at /mcp/x/all, and a projection that does not say which it descends from is as unarguable as a capture that does not.`
|
|
212
|
+
});
|
|
213
|
+
}
|
|
159
214
|
if (UPSTREAM_SUBSTRATES.has(meta.substrate) && !meta.configuration) {
|
|
160
215
|
ctx.addIssue({
|
|
161
216
|
code: "custom",
|
|
@@ -39,7 +39,7 @@ var TWIN_REGISTRY = {
|
|
|
39
39
|
defaultSeedState,
|
|
40
40
|
GitHubDomain,
|
|
41
41
|
openGitHubCloneDatabase
|
|
42
|
-
} = await import('./src-
|
|
42
|
+
} = await import('./src-6OG5GIZN.js');
|
|
43
43
|
const db = openGitHubCloneDatabase();
|
|
44
44
|
const domain = new GitHubDomain(db);
|
|
45
45
|
domain.seed(seedState === void 0 ? defaultSeedState() : seedState);
|
|
@@ -59,9 +59,9 @@ var TWIN_REGISTRY = {
|
|
|
59
59
|
envName: "SLACK",
|
|
60
60
|
defaultPort: 3333,
|
|
61
61
|
version: package_default2.version,
|
|
62
|
-
defaultSeed: async () => (await import('./src-
|
|
62
|
+
defaultSeed: async () => (await import('./src-R5TKYCCV.js')).defaultSeedState(),
|
|
63
63
|
async boot({ seedState, runId, recorder }) {
|
|
64
|
-
const { createSlackTwinApp, openSlackTwinDatabase, SlackDomain } = await import('./src-
|
|
64
|
+
const { createSlackTwinApp, openSlackTwinDatabase, SlackDomain } = await import('./src-R5TKYCCV.js');
|
|
65
65
|
const db = openSlackTwinDatabase(":memory:");
|
|
66
66
|
const domain = new SlackDomain(db);
|
|
67
67
|
domain.applySeed(seedState);
|
|
@@ -84,10 +84,10 @@ var TWIN_REGISTRY = {
|
|
|
84
84
|
envName: "STRIPE",
|
|
85
85
|
defaultPort: 3333,
|
|
86
86
|
version: package_default3.version,
|
|
87
|
-
defaultSeed: async () => (await import('./src-
|
|
87
|
+
defaultSeed: async () => (await import('./src-E6TRTNLF.js')).defaultSeed(),
|
|
88
88
|
async boot({ seedState, runId, recorder, twinBaseUrl }) {
|
|
89
|
-
const stripeTwin = await import('./src-
|
|
90
|
-
const { createApp } = await import('./server-
|
|
89
|
+
const stripeTwin = await import('./src-E6TRTNLF.js');
|
|
90
|
+
const { createApp } = await import('./server-KOR7UHEP.js');
|
|
91
91
|
const {
|
|
92
92
|
applySeed: applyStripeSeed,
|
|
93
93
|
createTwinStripeApp,
|
|
@@ -128,9 +128,9 @@ var TWIN_REGISTRY = {
|
|
|
128
128
|
portEnvName: "GMAIL_TWIN_PORT",
|
|
129
129
|
tokenEnvName: "POME_GMAIL_TOKEN",
|
|
130
130
|
version: package_default4.version,
|
|
131
|
-
defaultSeed: async () => (await import('./src-
|
|
131
|
+
defaultSeed: async () => (await import('./src-2MGTP2RK.js')).defaultSeedState(),
|
|
132
132
|
async boot({ seedState, runId, recorder }) {
|
|
133
|
-
const { createGmailTwinApp, GmailDomain, openGmailTwinDatabase, parseSeed } = await import('./src-
|
|
133
|
+
const { createGmailTwinApp, GmailDomain, openGmailTwinDatabase, parseSeed } = await import('./src-2MGTP2RK.js');
|
|
134
134
|
const db = openGmailTwinDatabase(":memory:");
|
|
135
135
|
const seed = parseSeed(seedState);
|
|
136
136
|
const domain = new GmailDomain(db);
|
|
@@ -149,7 +149,7 @@ var TWIN_REGISTRY = {
|
|
|
149
149
|
portEnvName: "LINEAR_TWIN_PORT",
|
|
150
150
|
tokenEnvName: "POME_LINEAR_TOKEN",
|
|
151
151
|
version: package_default5.version,
|
|
152
|
-
defaultSeed: async () => (await import('./src-
|
|
152
|
+
defaultSeed: async () => (await import('./src-ZC7YOHIQ.js')).defaultSeedState(),
|
|
153
153
|
async boot({ seedState, runId, recorder }) {
|
|
154
154
|
const {
|
|
155
155
|
createLinearTwinApp,
|
|
@@ -157,7 +157,7 @@ var TWIN_REGISTRY = {
|
|
|
157
157
|
LinearDomain,
|
|
158
158
|
openLinearTwinDatabase,
|
|
159
159
|
parseSeed
|
|
160
|
-
} = await import('./src-
|
|
160
|
+
} = await import('./src-ZC7YOHIQ.js');
|
|
161
161
|
const db = openLinearTwinDatabase(":memory:");
|
|
162
162
|
const seed = parseSeed(seedState);
|
|
163
163
|
const domain = new LinearDomain(db);
|
|
@@ -173,7 +173,7 @@ var TWIN_REGISTRY = {
|
|
|
173
173
|
}
|
|
174
174
|
};
|
|
175
175
|
async function createGitHubSmokeApp() {
|
|
176
|
-
const { createGitHubCloneApp } = await import('./src-
|
|
176
|
+
const { createGitHubCloneApp } = await import('./src-6OG5GIZN.js');
|
|
177
177
|
return createGitHubCloneApp();
|
|
178
178
|
}
|
|
179
179
|
function defaultPortFor(twin, env = process.env) {
|
|
@@ -2,8 +2,8 @@ import { criterionSchema, finalizeResponseSchema, HostedDiscardRefusedError, Hos
|
|
|
2
2
|
import { seedSchema, parseSeed, defaultSeedState as defaultSeedState$2 } from './chunk-KIUIKAVU.js';
|
|
3
3
|
import { gmailSeedSchema, defaultSeedState } from './chunk-NJ246QPJ.js';
|
|
4
4
|
import { linearSeedSchema, defaultSeedState as defaultSeedState$1 } from './chunk-ZKID2HS3.js';
|
|
5
|
-
import { isTwinName, TWIN_REGISTRY } from './chunk-
|
|
6
|
-
import { toTwinHttpEventRow } from './chunk-
|
|
5
|
+
import { isTwinName, TWIN_REGISTRY } from './chunk-PTM7SZYG.js';
|
|
6
|
+
import { toTwinHttpEventRow } from './chunk-OW7VVW6X.js';
|
|
7
7
|
import { redactEvent, redactSecrets } from './chunk-SG6ZTIMT.js';
|
|
8
8
|
import { mkdir, appendFile, writeFile, readFile } from 'node:fs/promises';
|
|
9
9
|
import { existsSync } from 'node:fs';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { getAvailablePort } from './chunk-XDU6TD4O.js';
|
|
2
2
|
import { buildEgressAllowlist, readBlockedEgress } from './chunk-CBFKZZBR.js';
|
|
3
|
-
import { parseTaskFile, seedStateForTwin, runAgentCommand, writeRunArtifactsCore } from './chunk-
|
|
4
|
-
import { createRecorder, bootTwin } from './chunk-
|
|
3
|
+
import { parseTaskFile, seedStateForTwin, runAgentCommand, writeRunArtifactsCore } from './chunk-V3ZHRNQU.js';
|
|
4
|
+
import { createRecorder, bootTwin } from './chunk-KNZJW3YT.js';
|
|
5
5
|
import { eventSchema } from './chunk-VBATFCWR.js';
|
|
6
6
|
import { redactSecrets, redactEvent } from './chunk-SG6ZTIMT.js';
|
|
7
7
|
import { serve } from '@hono/node-server';
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import { newGroupId, reassuranceBox, twinReadyLine, trialsHeaderLine, trialLine, summaryLines, evaluatingLine, criterionPhrase } from './chunk-RGZBC7NF.js';
|
|
2
2
|
import { DemoCapacityError, capacityLabel, parseCapacityMarker, capacityKindFrom } from './chunk-ZX4WNSZ5.js';
|
|
3
|
-
import { runTask, demoTaskPath, DEMO_TASK_NAME, DEMO_REPO } from './chunk-
|
|
3
|
+
import { runTask, demoTaskPath, DEMO_TASK_NAME, DEMO_REPO } from './chunk-YWELMGPG.js';
|
|
4
4
|
import { getAvailablePort } from './chunk-XDU6TD4O.js';
|
|
5
5
|
import './chunk-CBFKZZBR.js';
|
|
6
|
-
import { createHostedClient, parseTaskFile, uploadRunBlobs, scoreFromFinalizeResponse, scoreStatus, outcomeOf } from './chunk-
|
|
6
|
+
import { createHostedClient, parseTaskFile, uploadRunBlobs, scoreFromFinalizeResponse, scoreStatus, outcomeOf } from './chunk-V3ZHRNQU.js';
|
|
7
7
|
import './chunk-NW7HGA2K.js';
|
|
8
8
|
import { HostedQuotaError, HostedOrchError } from './chunk-X66JOOO7.js';
|
|
9
9
|
import './chunk-KIUIKAVU.js';
|
|
10
10
|
import './chunk-NJ246QPJ.js';
|
|
11
11
|
import './chunk-ZKID2HS3.js';
|
|
12
|
-
import { bootTwin } from './chunk-
|
|
13
|
-
import './chunk-
|
|
14
|
-
import './chunk-
|
|
12
|
+
import { bootTwin } from './chunk-KNZJW3YT.js';
|
|
13
|
+
import './chunk-PTM7SZYG.js';
|
|
14
|
+
import './chunk-OW7VVW6X.js';
|
|
15
15
|
import './chunk-VBATFCWR.js';
|
|
16
16
|
import './chunk-SG6ZTIMT.js';
|
|
17
17
|
import { readFile } from 'node:fs/promises';
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { newGroupId, criterionPhrase } from './chunk-RGZBC7NF.js';
|
|
2
|
-
import { runTaskHosted, resolveRunAgentIdentity } from './chunk-
|
|
2
|
+
import { runTaskHosted, resolveRunAgentIdentity } from './chunk-G4LBVXYN.js';
|
|
3
3
|
import './chunk-ABM3CMQB.js';
|
|
4
|
-
import { createHostedClient, parseTaskFile, outcomeOf } from './chunk-
|
|
4
|
+
import { createHostedClient, parseTaskFile, outcomeOf } from './chunk-V3ZHRNQU.js';
|
|
5
5
|
import './chunk-NW7HGA2K.js';
|
|
6
6
|
import { HostedQuotaError, HostedTrialError } from './chunk-X66JOOO7.js';
|
|
7
7
|
import './chunk-KIUIKAVU.js';
|
|
8
8
|
import './chunk-NJ246QPJ.js';
|
|
9
9
|
import './chunk-ZKID2HS3.js';
|
|
10
|
-
import './chunk-
|
|
11
|
-
import './chunk-
|
|
10
|
+
import './chunk-PTM7SZYG.js';
|
|
11
|
+
import './chunk-OW7VVW6X.js';
|
|
12
12
|
import './chunk-VBATFCWR.js';
|
|
13
13
|
import './chunk-SG6ZTIMT.js';
|
|
14
14
|
import { randomUUID } from 'node:crypto';
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { FAILURE_INJECTION_OVERRIDE_KEY, POME_RECORDER_EVENTS_PATH, PROVIDER_SHAPED_TEAM_ID, TwinBootError, TwinError, UnknownToolError, bearerAuth, createAdminGate, createApp, createFailureInjectionStore, createFileBackedRecorderStore, createRecorderHandle, createRecorderStore, created, ensureTwinAuthSecret, failureInjectionMiddleware, failureInjectionRuleSchema, formTokenResolver, isLoopbackHost, mintProviderToken, ok, queryTokenResolver, recordedRequestHeaders, requireAdminAuth, resolveAuthSecret, resolveRecorderStore, serve, setClientIp, setRecordedTool, toTwinHttpEventRow, twinBuildInfo, verifyProviderToken } from './chunk-
|
|
1
|
+
export { FAILURE_INJECTION_OVERRIDE_KEY, POME_RECORDER_EVENTS_PATH, PROVIDER_SHAPED_TEAM_ID, TwinBootError, TwinError, UnknownToolError, bearerAuth, createAdminGate, createApp, createFailureInjectionStore, createFileBackedRecorderStore, createRecorderHandle, createRecorderStore, created, ensureTwinAuthSecret, failureInjectionMiddleware, failureInjectionRuleSchema, formTokenResolver, isLoopbackHost, mintProviderToken, ok, queryTokenResolver, recordedRequestHeaders, requireAdminAuth, resolveAuthSecret, resolveRecorderStore, serve, setClientIp, setRecordedTool, toTwinHttpEventRow, twinBuildInfo, verifyProviderToken } from './chunk-OW7VVW6X.js';
|
|
2
2
|
import './chunk-VBATFCWR.js';
|
|
3
3
|
export { redactEvent, redactSecrets } from './chunk-SG6ZTIMT.js';
|
package/dist/src/cli/main.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { DEFAULT_CONTROL_PLANE_URL, DEFAULT_DASHBOARD_URL, clearLocalCredentials, friendlyHostedError, runSessionCreate, runSessionList, runSessionStop, resolveCredentials, runTaskHosted, discoverRunSet, VERDICT_ARTIFACT_VERSION, persistCredentialsAfterLogin, DEFAULT_DOCS_SITE_ORIGIN, resolveSeams, resolveCachedAgentId, readLinkCache, postAgentResolver, writeLinkCache, ensurePomeGitignored } from '../../chunk-
|
|
2
|
+
import { DEFAULT_CONTROL_PLANE_URL, DEFAULT_DASHBOARD_URL, clearLocalCredentials, friendlyHostedError, runSessionCreate, runSessionList, runSessionStop, resolveCredentials, runTaskHosted, discoverRunSet, VERDICT_ARTIFACT_VERSION, persistCredentialsAfterLogin, DEFAULT_DOCS_SITE_ORIGIN, resolveSeams, resolveCachedAgentId, readLinkCache, postAgentResolver, writeLinkCache, ensurePomeGitignored } from '../../chunk-G4LBVXYN.js';
|
|
3
3
|
import { readManifest, writeManifest, MANIFEST_JSON, readRequiredManifest, normalizeManifestTwins } from '../../chunk-ABM3CMQB.js';
|
|
4
|
-
import { assetPath, runTask, resolvePackageRoot, DEMO_TASK_NAME, demoTaskPath } from '../../chunk-
|
|
4
|
+
import { assetPath, runTask, resolvePackageRoot, DEMO_TASK_NAME, demoTaskPath } from '../../chunk-YWELMGPG.js';
|
|
5
5
|
import '../../chunk-XDU6TD4O.js';
|
|
6
6
|
import '../../chunk-CBFKZZBR.js';
|
|
7
|
-
import { parseTaskFile, scoreStatus, runScoreLine, readLatestRun, readMetaSummary, outcomeOf, readConfigTwins, scoreCountsSummary, markerFor, criterionMarkerLabel, twinSkipSuffix, readCodeCriteria, createHostedClient, toTwinHttpEvent, redactJsonl, scoreFromFinalizeResponse, parseGitHubSeedState, uploadRunBlobs, isPreSatisfied } from '../../chunk-
|
|
7
|
+
import { parseTaskFile, scoreStatus, runScoreLine, readLatestRun, readMetaSummary, outcomeOf, readConfigTwins, scoreCountsSummary, markerFor, criterionMarkerLabel, twinSkipSuffix, readCodeCriteria, createHostedClient, toTwinHttpEvent, redactJsonl, scoreFromFinalizeResponse, parseGitHubSeedState, uploadRunBlobs, isPreSatisfied } from '../../chunk-V3ZHRNQU.js';
|
|
8
8
|
import '../../chunk-NW7HGA2K.js';
|
|
9
9
|
import { MOUNTED_TWINS, deriveAgentSlug, exitCodeFor, HostedUsageError, HostedOrchError, HostedAuthError, HostedQuotaError } from '../../chunk-X66JOOO7.js';
|
|
10
10
|
import { TAPE_ASSERTABLE_TOOLS } from '../../chunk-FKZZWWYC.js';
|
|
@@ -15,9 +15,9 @@ import '../../chunk-NJ246QPJ.js';
|
|
|
15
15
|
import { LINEAR_CHECKS } from '../../chunk-XBT6ZLBG.js';
|
|
16
16
|
import '../../chunk-ZKID2HS3.js';
|
|
17
17
|
import { oneOf, defineCheck, repoRef, VACUITY_SENTINEL_NUMBER, childStatePath, VACUITY_SENTINEL, statePath, templateSlots, renderCheck, checksDigest, checkPattern, checkNearMissPattern } from '../../chunk-JWJYNAWI.js';
|
|
18
|
-
import '../../chunk-
|
|
19
|
-
import { TWIN_NAME_LIST, isTwinName, createGitHubSmokeApp } from '../../chunk-
|
|
20
|
-
import '../../chunk-
|
|
18
|
+
import '../../chunk-KNZJW3YT.js';
|
|
19
|
+
import { TWIN_NAME_LIST, isTwinName, createGitHubSmokeApp } from '../../chunk-PTM7SZYG.js';
|
|
20
|
+
import '../../chunk-OW7VVW6X.js';
|
|
21
21
|
import { isLegacyEventRow, eventSchema } from '../../chunk-VBATFCWR.js';
|
|
22
22
|
import { redactEvent, redactSecrets } from '../../chunk-SG6ZTIMT.js';
|
|
23
23
|
import { Command } from 'commander';
|
|
@@ -850,7 +850,7 @@ async function throwForStatus(res) {
|
|
|
850
850
|
|
|
851
851
|
// src/task/seed-verifier.ts
|
|
852
852
|
async function verifySeedWithTwin(seed) {
|
|
853
|
-
const { GitHubDomain, openGitHubCloneDatabase } = await import('../../src-
|
|
853
|
+
const { GitHubDomain, openGitHubCloneDatabase } = await import('../../src-6OG5GIZN.js');
|
|
854
854
|
const db = openGitHubCloneDatabase(":memory:");
|
|
855
855
|
try {
|
|
856
856
|
new GitHubDomain(db).seed(seed);
|
|
@@ -4541,7 +4541,7 @@ var DEFAULT_AGENT_COMMAND = `node ${DEFAULT_AGENT_FILE}`;
|
|
|
4541
4541
|
var MANIFEST_SCHEMA_URL = "https://pome.sh/schemas/v1/pome.json";
|
|
4542
4542
|
var MAX_UNREADABLE_PATHS_SHOWN = 5;
|
|
4543
4543
|
function readPackageVersion() {
|
|
4544
|
-
if ("0.23.
|
|
4544
|
+
if ("0.23.17".length > 0) return "0.23.17";
|
|
4545
4545
|
try {
|
|
4546
4546
|
const here = dirname(fileURLToPath(import.meta.url));
|
|
4547
4547
|
const candidates = [
|
|
@@ -4996,7 +4996,7 @@ function createProgram() {
|
|
|
4996
4996
|
return;
|
|
4997
4997
|
}
|
|
4998
4998
|
{
|
|
4999
|
-
const { runDoctorChecks } = await import('../../checks-
|
|
4999
|
+
const { runDoctorChecks } = await import('../../checks-O2XGFPLY.js');
|
|
5000
5000
|
const { renderDoctorReport } = await import('../../render-ZQQ4UMNO.js');
|
|
5001
5001
|
const doctorReport = await runDoctorChecks({ mode: useLocal ? "full" : "hosted" });
|
|
5002
5002
|
if (!doctorReport.ok) {
|
|
@@ -5034,7 +5034,7 @@ function createProgram() {
|
|
|
5034
5034
|
taskForRuns.config.runs
|
|
5035
5035
|
);
|
|
5036
5036
|
if (k > 1) {
|
|
5037
|
-
const { runTrialGroup } = await import('../../runTrialGroup-
|
|
5037
|
+
const { runTrialGroup } = await import('../../runTrialGroup-RQRUZPTT.js');
|
|
5038
5038
|
const fileForRerun = relative(process.cwd(), file);
|
|
5039
5039
|
const rerunCommand = defaultTask ? options.trials !== void 0 ? `pome run -n ${k}` : "pome run" : `pome run ${fileForRerun && !fileForRerun.startsWith("..") ? fileForRerun : file} -n ${k}`;
|
|
5040
5040
|
const groupResult = await runTrialGroup({
|
|
@@ -5128,7 +5128,7 @@ function createProgram() {
|
|
|
5128
5128
|
process.exitCode = 5;
|
|
5129
5129
|
return;
|
|
5130
5130
|
}
|
|
5131
|
-
const { runDemo } = await import('../../runDemo-
|
|
5131
|
+
const { runDemo } = await import('../../runDemo-OCBR5HL7.js');
|
|
5132
5132
|
const result = await runDemo({
|
|
5133
5133
|
apiBase: opts.apiUrl.replace(/\/$/, ""),
|
|
5134
5134
|
dashboardBase: process.env.POME_DASHBOARD_URL ?? DEFAULT_DASHBOARD_URL,
|
|
@@ -5146,7 +5146,7 @@ function createProgram() {
|
|
|
5146
5146
|
program.command("doctor").description(
|
|
5147
5147
|
"Check the agent\u2194twin wiring: pome.json (or pome.yaml) present + valid, the local twin boots + serves, requests routed to the twin (not a hardcoded production host), egress floor active. On failure prints one named cause (file:line where knowable) + one concrete fix and exits non-zero."
|
|
5148
5148
|
).action(async () => {
|
|
5149
|
-
const { runDoctorChecks } = await import('../../checks-
|
|
5149
|
+
const { runDoctorChecks } = await import('../../checks-O2XGFPLY.js');
|
|
5150
5150
|
const { renderDoctorReport } = await import('../../render-ZQQ4UMNO.js');
|
|
5151
5151
|
const report = await runDoctorChecks();
|
|
5152
5152
|
for (const line of renderDoctorReport(report, { passNote: true })) console.error(line);
|
|
@@ -5322,7 +5322,7 @@ function createProgram() {
|
|
|
5322
5322
|
).description(
|
|
5323
5323
|
"Start a standalone twin as a long-lived foreground server (Ctrl-C to stop)"
|
|
5324
5324
|
).action(async (name, options) => {
|
|
5325
|
-
const { runTwinStartCommand } = await import('../../twinStart-
|
|
5325
|
+
const { runTwinStartCommand } = await import('../../twinStart-UMKMZBHC.js');
|
|
5326
5326
|
await runTwinStartCommand(name, options);
|
|
5327
5327
|
});
|
|
5328
5328
|
twin.command("reset").argument("[name]", "Twin name (default: github)", "github").description("Reset standalone twin state").action(async (name) => {
|
|
@@ -3,7 +3,7 @@ import { gmailErrorEnvelope, gmailSeedSchema, parseSeed, defaultSeedState, notFo
|
|
|
3
3
|
export { DEFAULT_GMAIL_AGENT_EMAIL, GmailError, SEARCH_MAILBOX_MESSAGE_BUDGET, agentPathInboxMailbox, defaultSeedState, gmailErrorEnvelope, gmailSeedSchema, loadSeedFromEnv, parseSearchQuery, parseSeed, validateSearchQuery } from './chunk-NJ246QPJ.js';
|
|
4
4
|
import './chunk-JWJYNAWI.js';
|
|
5
5
|
import { routeInputDeclarer, integerInput, booleanInput, repeatedInput, mountDeclaredRoute, UndeclaredInputError, MalformedBodyError } from './chunk-2Q3P45LK.js';
|
|
6
|
-
import { loadMcpToolFixture, deriveMcpToolTable, defineTwin, openTwinDatabase, createApp } from './chunk-
|
|
6
|
+
import { loadMcpToolFixture, deriveMcpToolTable, defineTwin, openTwinDatabase, createApp } from './chunk-OW7VVW6X.js';
|
|
7
7
|
import './chunk-VBATFCWR.js';
|
|
8
8
|
import './chunk-SG6ZTIMT.js';
|
|
9
9
|
import { createHash, createHmac, timingSafeEqual, randomBytes } from 'node:crypto';
|
|
@@ -2,7 +2,7 @@ import './chunk-FKZZWWYC.js';
|
|
|
2
2
|
import { defaultSeedState, parseSeed } from './chunk-KIUIKAVU.js';
|
|
3
3
|
export { defaultSeedState, parseSeed, seedSchema } from './chunk-KIUIKAVU.js';
|
|
4
4
|
import { routeInputDeclarer, integerInput, mountDeclaredRoute, UndeclaredInputError, MalformedBodyError } from './chunk-2Q3P45LK.js';
|
|
5
|
-
import { loadMcpToolFixture, defineTwin, twinBuildInfo, deriveMcpToolTable, UnknownToolError, openTwinDatabase, createApp } from './chunk-
|
|
5
|
+
import { loadMcpToolFixture, defineTwin, twinBuildInfo, deriveMcpToolTable, UnknownToolError, openTwinDatabase, createApp } from './chunk-OW7VVW6X.js';
|
|
6
6
|
import './chunk-VBATFCWR.js';
|
|
7
7
|
import './chunk-SG6ZTIMT.js';
|
|
8
8
|
import { z, ZodError } from 'zod';
|
|
@@ -570,71 +570,126 @@ var GITHUB_ROUTES = {
|
|
|
570
570
|
// ../packages/twin-github/dist/fixtures/mcp-tools-list.meta.json
|
|
571
571
|
var mcp_tools_list_meta_default = {
|
|
572
572
|
twin: "github",
|
|
573
|
-
substrate: "
|
|
574
|
-
endpoint: "
|
|
573
|
+
substrate: "upstream-capture-projection",
|
|
574
|
+
endpoint: "https://api.githubcopilot.com/mcp/",
|
|
575
575
|
method: "tools/list",
|
|
576
|
-
protocol: "JSON-RPC 2.0 over
|
|
576
|
+
protocol: "JSON-RPC 2.0 over stdio (the public server, built from source)",
|
|
577
577
|
protocolVersion: "2025-06-18",
|
|
578
|
-
captureDate: "2026-08-
|
|
579
|
-
rawFileSha256: "
|
|
578
|
+
captureDate: "2026-08-12",
|
|
579
|
+
rawFileSha256: "a0e583e3ef51011cf2ba1c784a0e89fa8cbdabb5b38562402283f4894bfd63e9",
|
|
580
580
|
liveToolCount: 36,
|
|
581
581
|
liveToolOrder: [
|
|
582
|
-
"
|
|
582
|
+
"add_issue_comment",
|
|
583
|
+
"add_reply_to_pull_request_comment",
|
|
584
|
+
"create_branch",
|
|
585
|
+
"create_or_update_file",
|
|
586
|
+
"create_pull_request",
|
|
583
587
|
"create_repository",
|
|
588
|
+
"delete_file",
|
|
584
589
|
"fork_repository",
|
|
585
|
-
"
|
|
586
|
-
"search_users",
|
|
590
|
+
"get_commit",
|
|
587
591
|
"get_file_contents",
|
|
588
|
-
"
|
|
589
|
-
"
|
|
590
|
-
"
|
|
591
|
-
"
|
|
592
|
+
"get_latest_release",
|
|
593
|
+
"get_me",
|
|
594
|
+
"get_release_by_tag",
|
|
595
|
+
"get_tag",
|
|
592
596
|
"issue_read",
|
|
593
597
|
"issue_write",
|
|
594
|
-
"
|
|
598
|
+
"list_branches",
|
|
599
|
+
"list_commits",
|
|
595
600
|
"list_issues",
|
|
596
|
-
"
|
|
597
|
-
"
|
|
601
|
+
"list_pull_requests",
|
|
602
|
+
"list_releases",
|
|
598
603
|
"list_repository_collaborators",
|
|
604
|
+
"list_tags",
|
|
605
|
+
"merge_pull_request",
|
|
599
606
|
"pull_request_read",
|
|
600
607
|
"pull_request_review_write",
|
|
601
|
-
"
|
|
602
|
-
"
|
|
603
|
-
"merge_pull_request",
|
|
604
|
-
"update_pull_request_branch",
|
|
605
|
-
"create_pull_request",
|
|
606
|
-
"list_branches",
|
|
607
|
-
"delete_file",
|
|
608
|
-
"get_commit",
|
|
609
|
-
"update_pull_request",
|
|
610
|
-
"add_reply_to_pull_request_comment",
|
|
611
|
-
"list_tags",
|
|
612
|
-
"list_releases",
|
|
613
|
-
"get_latest_release",
|
|
614
|
-
"get_me",
|
|
608
|
+
"push_files",
|
|
609
|
+
"search_code",
|
|
615
610
|
"search_commits",
|
|
616
|
-
"
|
|
617
|
-
"
|
|
611
|
+
"search_issues",
|
|
612
|
+
"search_repositories",
|
|
613
|
+
"search_users",
|
|
614
|
+
"update_pull_request",
|
|
615
|
+
"update_pull_request_branch",
|
|
616
|
+
"create_issue",
|
|
617
|
+
"create_pull_request_review"
|
|
618
618
|
],
|
|
619
|
-
transcription: {
|
|
620
|
-
readFrom: "derived from packages/twin-github/src/tools.ts by scripts/regenerate-mcp-tool-fixture.ts. The 2026-08-06 revision of this file was read off twin-github's own tools/list (booted on defaultSeedState(), driven through Hono's app.request) immediately before the table became fixture-driven (F-1325); the tool NAMES moved for the first time on 2026-08-09, under F-1376.",
|
|
621
|
-
contentOrigin: "packages/twin-github/src/tools.ts declares one zod schema per tool and no names; each inputSchema here is z.toJSONSchema() of that schema, frozen verbatim including the $schema key it emits. Descriptions are this twin's own.",
|
|
622
|
-
comparedToUpstream: "never, in the sense this field means: nothing has driven api.githubcopilot.com/mcp/ and compared answers. The tool NAMES were compared, once, as two committed documents \u2014 pome-cloud's MCP lane (F-1327) against F-1326's upstream golden (fixtures/mcp-tools-list/github.canonical.json, 44 tools for the `default` toolset examples/support-triage points at) \u2014 and F-1376 acted on the result. Behaviour, argument schemas and descriptions remain uncompared."
|
|
623
|
-
},
|
|
624
619
|
notes: [
|
|
625
|
-
"
|
|
626
|
-
"
|
|
627
|
-
|
|
620
|
+
"These rows are GitHub's, not this twin's. Until F-1468 the fixture was a transcription of src/tools.ts (substrate twin-code-transcription): the descriptions were ours and every inputSchema was z.toJSONSchema() of the twin's own validator, which pome-cloud's MCP lane priced at 577 findings across 34 tools against twin-slack's 0. Almost none of them was a decision anybody made \u2014 68 were annotations z.toJSONSchema cannot emit, 181 were our descriptions, 78 were zod's minLength, 37 were integer where GitHub says number, and 34 were the additionalProperties:false that z.object() ADVERTISES while accepting the unknown key at runtime.",
|
|
621
|
+
"The 36 are the captured default surface's 44, minus 10 this twin does not model, plus 2 it serves that the capture cannot carry. Every dropped and carried name gives its reason in `projection`, and both lists are enforced by the producer: a dropped name the capture does not carry fails, and a carried name the capture DOES carry fails because the feature-flag ruling that justified it has expired. The two carried are create_issue and create_pull_request_review \u2014 real GitHub tools registered into Default:true toolsets behind the client-settable X-MCP-Features flags issues_granular and pull_requests_granular, so the golden's flags-off capture cannot see them. Both carry a registered entry in pome-cloud's known-divergences/github.mcp.yaml; reasoning per tool in docs/github-mcp-twin-only-tools.md and docs/github-mcp-unmodelled-tools.md.",
|
|
622
|
+
'What this file does NOT say is what the twin ACCEPTS. These are GitHub\'s advertised schemas; the twin\'s zod validators are what actually admit or refuse an examinee\'s call, and the two can disagree \u2014 GitHub advertises `perPage` where the validator also takes `per_page`, and advertises state ["OPEN","CLOSED"] where the validator still takes lowercase. src/tool-schema-conformance.ts is the report on that gap. Reading this fixture as a statement about behaviour is the mistake it exists to make visible.',
|
|
623
|
+
"Dropping a tool from this listing does NOT drop the twin's REST route for the same operation. Fourteen of the thirty-four names retired by F-1376 (milestones, commit statuses, check runs, issue-comment edit/delete) were GitHub REST operations that were never MCP tools upstream, and they remain reachable exactly the way an examinee could always have reached them at GitHub: over HTTP."
|
|
628
624
|
],
|
|
629
|
-
canonicalFileSha256: "
|
|
625
|
+
canonicalFileSha256: "ccd957048004c010791e19999d1aff507791171dec4882d5a3e171e22482f13b",
|
|
630
626
|
files: {
|
|
631
627
|
raw: "mcp-tools-list.raw.json",
|
|
632
628
|
canonical: "mcp-tools-list.canonical.json"
|
|
629
|
+
},
|
|
630
|
+
configuration: {
|
|
631
|
+
toolsets: "default",
|
|
632
|
+
whyThisToolset: [
|
|
633
|
+
"examples/support-triage declares mcp_servers[name=github].url = https://api.githubcopilot.com/mcp/ (agents/support-triage-v1.yaml and -v2.yaml, byte-identical on that line).",
|
|
634
|
+
"docs/remote-server.md at the pinned commit maps that exact URL to the `default` toolset. `all` is a DIFFERENT URL: https://api.githubcopilot.com/mcp/x/all.",
|
|
635
|
+
"Measured at the pinned commit: --toolsets=default returns 44 tools, --toolsets=all returns 85. Reading the union would invent 41 tools no examinee of ours can call."
|
|
636
|
+
],
|
|
637
|
+
readOnly: false,
|
|
638
|
+
lockdown: false,
|
|
639
|
+
insiders: false,
|
|
640
|
+
featureFlags: [],
|
|
641
|
+
scopeFiltering: "none \u2014 docs/scope-filtering.md filters tools by a classic PAT's OAuth scopes; with no readable scopes the server logs `continuing without scope filtering` and serves the unfiltered toolset, which is what an examinee with full scopes gets",
|
|
642
|
+
serverArgs: [
|
|
643
|
+
"stdio",
|
|
644
|
+
"--toolsets=default"
|
|
645
|
+
],
|
|
646
|
+
serverEnv: {
|
|
647
|
+
GITHUB_PERSONAL_ACCESS_TOKEN: "f1326-unauthenticated-capture"
|
|
648
|
+
},
|
|
649
|
+
serverEnvNote: "the token is deliberately not a credential; it only gets the server past its startup check. Verified: a valid-shaped ghp_ placeholder and this string produce a byte-identical tools/list.",
|
|
650
|
+
completeness: "subset-of-remote",
|
|
651
|
+
knownRemoteOnlyToolsNotInCapture: [
|
|
652
|
+
"create_pull_request_with_copilot"
|
|
653
|
+
],
|
|
654
|
+
knownRemoteOnlyToolsEvidence: "README.md 'Additional Tools in Remote GitHub MCP Server' at the pinned commit lists create_pull_request_with_copilot under the Copilot toolset, which is Default:true, so the remote `default` surface is this capture plus that one tool. The other two remote-only groups (copilot_spaces, github_support_docs_search) are non-default toolsets and are correctly absent. A consumer of this golden must treat a github tool in that list as not-compared rather than as a gap.",
|
|
655
|
+
unguardedDirection: "The asymmetry is on the record deliberately: there is no field, and no mechanism, for the OPPOSITE error \u2014 a tool in this capture that the remote deployment does not serve. `subset-of-remote` is an assumption about the remote's `default` composition matching the local one, sourced from the vendor's docs rather than from the remote itself, and only a credentialed read could confirm it. If the two ever diverge in that direction this golden over-reports and nothing here catches it. Whoever gains a credential for this endpoint should check that first."
|
|
656
|
+
},
|
|
657
|
+
projection: {
|
|
658
|
+
sourceFixture: "fixtures/mcp-tools-list/github.raw.json",
|
|
659
|
+
sourceRawFileSha256: "cf2b5e5d515bf37eda6e06c9d9d29955f6350ce3adf477911bca445133cc909d",
|
|
660
|
+
sourceCaptureDate: "2026-08-12",
|
|
661
|
+
sourceSubstrate: "oss-source",
|
|
662
|
+
sourceCommit: "c2bc7dc068245fda0d9779cfde1e84b0f338e4fb",
|
|
663
|
+
producer: "packages/twin-github/scripts/adopt-upstream-mcp-fixture.ts \u2014 re-derive and diff with `npm run gate:mcp-fixture -w @pome-sh/twin-github`",
|
|
664
|
+
dropped: {
|
|
665
|
+
add_comment_to_pending_review: "out of modeled scope: the twin has no pending-review workflow. `pull_request_review_write` creates a review in one call, so there is no pending review for a comment to attach to.",
|
|
666
|
+
assign_copilot_to_issue: "out of modeled scope: nothing in this twin models the Copilot coding agent \u2014 no assignment, no agent session, no resulting branch or pull request.",
|
|
667
|
+
request_copilot_review: "out of modeled scope: same absence as `assign_copilot_to_issue`. A review this twin cannot produce is not a review an examinee can be graded on requesting.",
|
|
668
|
+
get_teams: "out of modeled scope: the twin models no organization teams. Its access-control layer is per-repository (src/access-control.ts), with no team membership behind it.",
|
|
669
|
+
get_team_members: "out of modeled scope: same absence as `get_teams`. There is no team for this to enumerate.",
|
|
670
|
+
list_issue_types: "out of modeled scope: organization-level issue types are not modeled. The twin's issues carry labels and state, and no type.",
|
|
671
|
+
list_issue_fields: "out of modeled scope: Projects-v2 issue fields are not modeled. The twin has no project board.",
|
|
672
|
+
sub_issue_write: "out of modeled scope: the twin models no sub-issue hierarchy \u2014 issues have no parent and no children, so there is no edge for this tool to write.",
|
|
673
|
+
get_label: "COVERAGE GAP, not a scope decision, and it is filed here so it stops being invisible rather than because it is acceptable. The twin DOES model labels \u2014 it serves list-repository-labels, create-repository-label and list-issue-labels (src/routes.ts) \u2014 and simply has no single-label read. Closing it is a route plus a tool, not a new capability. Tracked in docs/github-mcp-unmodelled-tools.md.",
|
|
674
|
+
search_pull_requests: "COVERAGE GAP, not a scope decision, on the same terms as `get_label`. The twin serves five search tools and GitHub's sixth is `/search/issues` scoped to `is:pr`, which this twin answers unscoped as `search_issues`. An examinee that searches for pull requests gets issues here. Tracked in docs/github-mcp-unmodelled-tools.md."
|
|
675
|
+
},
|
|
676
|
+
carried: {
|
|
677
|
+
create_issue: "GitHub registers this into the `issues` toolset (Default:true) gated on the `issues_granular` feature flag, which is in `AllowedFeatureFlags` \u2014 so a client sending `X-MCP-Features: issues_granular` IS served it. The golden is captured with no flags set, deliberately, because that is the default surface. Registered as GITHUB-MCP-001.",
|
|
678
|
+
create_pull_request_review: "Same fact, different flag: `pull_requests_granular`, likewise in `AllowedFeatureFlags`. Registered as GITHUB-MCP-002."
|
|
679
|
+
}
|
|
633
680
|
}
|
|
634
681
|
};
|
|
635
682
|
|
|
636
683
|
// ../packages/twin-github/dist/fixtures/mcp-tools-list.raw.json
|
|
637
|
-
var mcp_tools_list_raw_default = { jsonrpc: "2.0", id: 1, result: { tools: [{ name: "search_repositories", description: "Search local repositories by name or description.", inputSchema: { $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { query: { type: "string" }, q: { type: "string" }, page: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 }, per_page: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 }, perPage: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 } }, additionalProperties: false } }, { name: "create_repository", description: "Create a repository with an initial README and main branch.", inputSchema: { $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { name: { type: "string", minLength: 1 }, owner: { type: "string", minLength: 1 }, description: { type: "string" }, private: { type: "boolean" } }, required: ["name"], additionalProperties: false } }, { name: "fork_repository", description: "Fork a repository into the current user or an organization.", inputSchema: { $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { owner: { type: "string", minLength: 1 }, repo: { type: "string", minLength: 1 }, organization: { type: "string", minLength: 1 } }, required: ["owner", "repo"], additionalProperties: false } }, { name: "search_code", description: "Search files in the local GitHub twin.", inputSchema: { $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { query: { type: "string" }, q: { type: "string" }, owner: { type: "string" }, repo: { type: "string" }, page: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 }, per_page: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 }, perPage: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 } }, additionalProperties: false } }, { name: "search_users", description: "Search seeded users and organizations.", inputSchema: { $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { query: { type: "string" }, q: { type: "string" }, page: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 }, per_page: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 }, perPage: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 } }, additionalProperties: false } }, { name: "get_file_contents", description: "Read a file or directory from a repository branch.", inputSchema: { $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { owner: { type: "string", minLength: 1 }, repo: { type: "string", minLength: 1 }, path: { type: "string" }, ref: { type: "string" } }, required: ["owner", "repo"], additionalProperties: false } }, { name: "list_commits", description: "List commits for a repository.", inputSchema: { $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { owner: { type: "string", minLength: 1 }, repo: { type: "string", minLength: 1 }, sha: { type: "string" }, page: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 }, per_page: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 }, perPage: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 } }, required: ["owner", "repo"], additionalProperties: false } }, { name: "create_or_update_file", description: "Create or update one file and advance the branch head atomically.", inputSchema: { $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { owner: { type: "string", minLength: 1 }, repo: { type: "string", minLength: 1 }, path: { type: "string", minLength: 1 }, message: { type: "string", minLength: 1 }, content: { type: "string" }, branch: { type: "string" }, sha: { type: "string" }, encoding: { type: "string", enum: ["utf-8", "base64"] } }, required: ["owner", "repo", "path", "message", "content"], additionalProperties: false } }, { name: "create_branch", description: "Create a branch from an existing branch or SHA.", inputSchema: { $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { owner: { type: "string", minLength: 1 }, repo: { type: "string", minLength: 1 }, branch: { type: "string", minLength: 1 }, from_branch: { type: "string" }, sha: { type: "string" } }, required: ["owner", "repo", "branch"], additionalProperties: false } }, { name: "push_files", description: "Push multiple files in a single commit.", inputSchema: { $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { owner: { type: "string", minLength: 1 }, repo: { type: "string", minLength: 1 }, branch: { type: "string" }, message: { type: "string", minLength: 1 }, files: { minItems: 1, type: "array", items: { type: "object", properties: { path: { type: "string", minLength: 1 }, content: { type: "string" }, encoding: { type: "string", enum: ["utf-8", "base64"] } }, required: ["path", "content"], additionalProperties: false } } }, required: ["owner", "repo", "message", "files"], additionalProperties: false } }, { name: "issue_read", description: "Read an issue. Methods: get, get_comments, get_labels.", inputSchema: { $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { method: { type: "string", enum: ["get", "get_comments", "get_sub_issues", "get_parent", "get_labels"] }, owner: { type: "string", minLength: 1 }, repo: { type: "string", minLength: 1 }, issue_number: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 }, page: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 }, perPage: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 } }, required: ["method", "owner", "repo", "issue_number"], additionalProperties: false } }, { name: "issue_write", description: "Create or update an issue. Methods: create, update.", inputSchema: { $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { method: { type: "string", enum: ["create", "update"] }, owner: { type: "string", minLength: 1 }, repo: { type: "string", minLength: 1 }, issue_number: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 }, title: { type: "string" }, body: { type: "string" }, state: { type: "string", enum: ["open", "closed"] }, labels: { type: "array", items: { type: "string" } }, assignees: { type: "array", items: { type: "string" } } }, required: ["method", "owner", "repo"], additionalProperties: false } }, { name: "search_issues", description: "Search all local issues.", inputSchema: { $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { query: { type: "string" }, q: { type: "string" }, state: { type: "string", enum: ["open", "closed", "all"] }, page: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 }, per_page: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 }, perPage: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 } }, additionalProperties: false } }, { name: "list_issues", description: "List repository issues with common filters.", inputSchema: { $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { owner: { type: "string", minLength: 1 }, repo: { type: "string", minLength: 1 }, state: { type: "string", enum: ["open", "closed", "all"] }, labels: { type: "string" }, assignee: { type: "string" }, page: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 }, per_page: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 }, perPage: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 } }, required: ["owner", "repo"], additionalProperties: false } }, { name: "add_issue_comment", description: "Add an issue comment.", inputSchema: { $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { owner: { type: "string", minLength: 1 }, repo: { type: "string", minLength: 1 }, issue_number: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 }, issueNumber: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 }, body: { type: "string", minLength: 1 } }, required: ["owner", "repo", "body"], additionalProperties: false } }, { name: "create_issue", description: "Create an issue.", inputSchema: { $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { owner: { type: "string", minLength: 1 }, repo: { type: "string", minLength: 1 }, title: { type: "string", minLength: 1 }, body: { type: "string" }, labels: { type: "array", items: { type: "string" } }, assignees: { type: "array", items: { type: "string" } } }, required: ["owner", "repo", "title"], additionalProperties: false } }, { name: "list_repository_collaborators", description: "List repository collaborators.", inputSchema: { $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { owner: { type: "string", minLength: 1 }, repo: { type: "string", minLength: 1 }, affiliation: { type: "string", enum: ["outside", "direct", "all"] }, page: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 }, perPage: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 } }, required: ["owner", "repo"], additionalProperties: false } }, { name: "pull_request_read", description: "Read a pull request. Methods: get, get_diff, get_status, get_files, get_commits, get_reviews, get_comments, get_review_comments, get_check_runs.", inputSchema: { $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { method: { type: "string", enum: ["get", "get_diff", "get_status", "get_files", "get_commits", "get_review_comments", "get_reviews", "get_comments", "get_check_runs"] }, owner: { type: "string", minLength: 1 }, repo: { type: "string", minLength: 1 }, pullNumber: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 }, page: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 }, perPage: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 } }, required: ["method", "owner", "repo", "pullNumber"], additionalProperties: false } }, { name: "pull_request_review_write", description: "Create a pull request review. Methods: create.", inputSchema: { $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { method: { type: "string", enum: ["create", "submit_pending", "delete_pending", "resolve_thread", "unresolve_thread"] }, owner: { type: "string", minLength: 1 }, repo: { type: "string", minLength: 1 }, pullNumber: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 }, event: { type: "string", enum: ["APPROVE", "REQUEST_CHANGES", "COMMENT"] }, body: { type: "string" } }, required: ["method", "owner", "repo", "pullNumber"], additionalProperties: false } }, { name: "create_pull_request_review", description: "Create a pull request review.", inputSchema: { $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { owner: { type: "string", minLength: 1 }, repo: { type: "string", minLength: 1 }, pull_number: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 }, pullNumber: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 }, event: { type: "string", enum: ["APPROVE", "REQUEST_CHANGES", "COMMENT"] }, body: { type: "string" } }, required: ["owner", "repo", "event"], additionalProperties: false } }, { name: "list_pull_requests", description: "List repository pull requests.", inputSchema: { $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { owner: { type: "string", minLength: 1 }, repo: { type: "string", minLength: 1 }, state: { type: "string", enum: ["open", "closed", "all"] }, page: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 }, per_page: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 }, perPage: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 } }, required: ["owner", "repo"], additionalProperties: false } }, { name: "merge_pull_request", description: "Merge a pull request using simplified local merge semantics.", inputSchema: { $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { owner: { type: "string", minLength: 1 }, repo: { type: "string", minLength: 1 }, pull_number: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 }, pullNumber: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 }, commit_title: { type: "string" }, commit_message: { type: "string" } }, required: ["owner", "repo"], additionalProperties: false } }, { name: "update_pull_request_branch", description: "Update a PR branch from its base branch.", inputSchema: { $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { owner: { type: "string", minLength: 1 }, repo: { type: "string", minLength: 1 }, pull_number: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 }, pullNumber: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 }, expected_head_sha: { type: "string" } }, required: ["owner", "repo"], additionalProperties: false } }, { name: "create_pull_request", description: "Create a pull request from a head branch to a base branch.", inputSchema: { $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { owner: { type: "string", minLength: 1 }, repo: { type: "string", minLength: 1 }, title: { type: "string", minLength: 1 }, body: { type: "string" }, head: { type: "string", minLength: 1 }, base: { type: "string" } }, required: ["owner", "repo", "title", "head"], additionalProperties: false } }, { name: "list_branches", description: "List branches for a repository.", inputSchema: { $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { owner: { type: "string", minLength: 1 }, repo: { type: "string", minLength: 1 }, page: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 }, per_page: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 }, perPage: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 } }, required: ["owner", "repo"], additionalProperties: false } }, { name: "delete_file", description: "Delete one file and advance the branch head atomically.", inputSchema: { $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { owner: { type: "string", minLength: 1 }, repo: { type: "string", minLength: 1 }, path: { type: "string", minLength: 1 }, message: { type: "string", minLength: 1 }, sha: { type: "string", minLength: 1 }, branch: { type: "string" } }, required: ["owner", "repo", "path", "message", "sha"], additionalProperties: false } }, { name: "get_commit", description: "Get one commit with its file changes and stats.", inputSchema: { $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { owner: { type: "string", minLength: 1 }, repo: { type: "string", minLength: 1 }, ref: { type: "string", minLength: 1 } }, required: ["owner", "repo", "ref"], additionalProperties: false } }, { name: "update_pull_request", description: "Update a pull request title, body, state, or base branch.", inputSchema: { $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { owner: { type: "string", minLength: 1 }, repo: { type: "string", minLength: 1 }, pull_number: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 }, pullNumber: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 }, title: { type: "string" }, body: { type: "string" }, state: { type: "string", enum: ["open", "closed"] }, base: { type: "string" } }, required: ["owner", "repo"], additionalProperties: false } }, { name: "add_reply_to_pull_request_comment", description: "Reply to an existing pull request review comment.", inputSchema: { $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { owner: { type: "string", minLength: 1 }, repo: { type: "string", minLength: 1 }, pull_number: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 }, pullNumber: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 }, comment_id: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 }, commentId: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 }, body: { type: "string", minLength: 1 } }, required: ["owner", "repo", "body"], additionalProperties: false } }, { name: "list_tags", description: "List tags for a repository, most recent first.", inputSchema: { $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { owner: { type: "string", minLength: 1 }, repo: { type: "string", minLength: 1 }, page: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 }, per_page: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 }, perPage: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 } }, required: ["owner", "repo"], additionalProperties: false } }, { name: "list_releases", description: "List releases for a repository, most recent first.", inputSchema: { $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { owner: { type: "string", minLength: 1 }, repo: { type: "string", minLength: 1 }, page: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 }, per_page: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 }, perPage: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 } }, required: ["owner", "repo"], additionalProperties: false } }, { name: "get_latest_release", description: "Get the latest published (non-draft, non-prerelease) release.", inputSchema: { $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { owner: { type: "string", minLength: 1 }, repo: { type: "string", minLength: 1 } }, required: ["owner", "repo"], additionalProperties: false } }, { name: "get_me", description: "Get the authenticated user.", inputSchema: { $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: {}, additionalProperties: false } }, { name: "search_commits", description: "Search commits on repository default branches by message or author.", inputSchema: { $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { query: { type: "string" }, q: { type: "string" }, owner: { type: "string" }, repo: { type: "string" }, page: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 }, per_page: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 }, perPage: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 } }, additionalProperties: false } }, { name: "get_release_by_tag", description: "Get a release by its tag name.", inputSchema: { $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { owner: { type: "string", minLength: 1 }, repo: { type: "string", minLength: 1 }, tag: { type: "string", minLength: 1 } }, required: ["owner", "repo", "tag"], additionalProperties: false } }, { name: "get_tag", description: "Get a tag by name, including the commit it points at.", inputSchema: { $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { owner: { type: "string", minLength: 1 }, repo: { type: "string", minLength: 1 }, tag: { type: "string", minLength: 1 } }, required: ["owner", "repo", "tag"], additionalProperties: false } }] } };
|
|
684
|
+
var mcp_tools_list_raw_default = { jsonrpc: "2.0", id: 1, result: { tools: [{ annotations: { idempotentHint: false, readOnlyHint: false, title: "Add comment to issue or pull request" }, description: "Add a comment and/or reaction to a specific issue or issue comment in a GitHub repository. Use this tool with pull requests as well (in this case pass pull request number as issue_number), but only if user is not asking specifically to add or react to review comments. At least one of body or reaction is required.", inputSchema: { type: "object", properties: { body: { type: "string", description: "Comment content. Required unless reaction is provided." }, comment_id: { type: "number", description: "The numeric ID of the issue or pull request comment to react to. Use this for reactions to comments; omit it to react to the issue or pull request itself. Cannot be combined with body.", minimum: 1 }, issue_number: { type: "number", description: "Issue or pull request number to comment on or react to." }, owner: { type: "string", description: "Repository owner", "x-mcp-header": "owner" }, reaction: { type: "string", description: "Emoji reaction to add. Required unless body is provided.", enum: ["+1", "-1", "laugh", "confused", "heart", "hooray", "rocket", "eyes"] }, repo: { type: "string", description: "Repository name", "x-mcp-header": "repo" } }, required: ["owner", "repo", "issue_number"] }, name: "add_issue_comment" }, { annotations: { idempotentHint: false, readOnlyHint: false, title: "Add reply to pull request comment" }, description: "Add a reply and/or reaction to an existing pull request comment. This can create a new comment linked as a reply to the specified comment, add an emoji reaction to the specified comment, or do both. At least one of body or reaction is required.", inputSchema: { type: "object", properties: { body: { type: "string", description: "The text of the reply. Required unless reaction is provided." }, commentId: { type: "number", description: "The numeric ID of the pull request review comment to reply or react to. Use the number from a #discussion_r... anchor, not the GraphQL thread node ID (PRRT_...).", minimum: 1 }, owner: { type: "string", description: "Repository owner", "x-mcp-header": "owner" }, pullNumber: { type: "number", description: "Pull request number. Required when body is provided." }, reaction: { type: "string", description: "Emoji reaction to add. Required unless body is provided.", enum: ["+1", "-1", "laugh", "confused", "heart", "hooray", "rocket", "eyes"] }, repo: { type: "string", description: "Repository name", "x-mcp-header": "repo" } }, required: ["owner", "repo", "commentId"] }, name: "add_reply_to_pull_request_comment" }, { annotations: { idempotentHint: false, readOnlyHint: false, title: "Create branch" }, description: "Create a new branch in a GitHub repository", inputSchema: { type: "object", properties: { branch: { type: "string", description: "Name for new branch" }, from_branch: { type: "string", description: "Source branch (defaults to repo default)" }, owner: { type: "string", description: "Repository owner", "x-mcp-header": "owner" }, repo: { type: "string", description: "Repository name", "x-mcp-header": "repo" } }, required: ["owner", "repo", "branch"] }, name: "create_branch" }, { annotations: { idempotentHint: false, readOnlyHint: false, title: "Create or update file" }, description: "Create or update a single file in a GitHub repository. \nIf updating, you should provide the SHA of the file you want to update. Use this tool to create or update a file in a GitHub repository remotely; do not use it for local file operations.\n\nIn order to obtain the SHA of original file version before updating, use the following git command:\ngit rev-parse <branch>:<path to file>\n\nSHA MUST be provided for existing file updates.\n", inputSchema: { type: "object", properties: { branch: { type: "string", description: "Branch to create/update the file in" }, content: { type: "string", description: "Content of the file, exactly as it should appear once written. Do not base64-encode it; this server does that before calling the REST API." }, message: { type: "string", description: "Commit message" }, owner: { type: "string", description: "Repository owner (username or organization)", "x-mcp-header": "owner" }, path: { type: "string", description: "Path where to create/update the file" }, repo: { type: "string", description: "Repository name", "x-mcp-header": "repo" }, sha: { type: "string", description: "The blob SHA of the file being replaced. Required if the file already exists." } }, required: ["owner", "repo", "path", "content", "message", "branch"] }, name: "create_or_update_file" }, { annotations: { idempotentHint: false, readOnlyHint: false, title: "Open new pull request" }, description: "Create a new pull request in a GitHub repository.", inputSchema: { type: "object", properties: { base: { type: "string", description: "Branch to merge into" }, body: { type: "string", description: "PR description" }, draft: { type: "boolean", description: "Create as draft PR" }, head: { type: "string", description: "Branch containing changes" }, maintainer_can_modify: { type: "boolean", description: "Allow maintainer edits" }, owner: { type: "string", description: "Repository owner", "x-mcp-header": "owner" }, repo: { type: "string", description: "Repository name", "x-mcp-header": "repo" }, reviewers: { type: "array", items: { type: "string" }, description: "GitHub usernames or ORG/team-slug team reviewers to request reviews from" }, title: { type: "string", description: "PR title" } }, required: ["owner", "repo", "title", "head", "base"] }, name: "create_pull_request" }, { annotations: { idempotentHint: false, readOnlyHint: false, title: "Create repository" }, description: "Create a new GitHub repository in your account or specified organization", inputSchema: { type: "object", properties: { autoInit: { type: "boolean", description: "Initialize with README" }, description: { type: "string", description: "Repository description" }, name: { type: "string", description: "Repository name" }, organization: { type: "string", description: "Organization to create the repository in (omit to create in your personal account)" }, private: { type: "boolean", description: "Whether the repository should be private. Defaults to true (private) when omitted.", default: true } }, required: ["name"] }, name: "create_repository" }, { annotations: { destructiveHint: true, idempotentHint: false, readOnlyHint: false, title: "Delete file" }, description: "Delete a file from a GitHub repository", inputSchema: { type: "object", properties: { branch: { type: "string", description: "Branch to delete the file from" }, message: { type: "string", description: "Commit message" }, owner: { type: "string", description: "Repository owner (username or organization)", "x-mcp-header": "owner" }, path: { type: "string", description: "Path to the file to delete" }, repo: { type: "string", description: "Repository name", "x-mcp-header": "repo" } }, required: ["owner", "repo", "path", "message", "branch"] }, name: "delete_file" }, { annotations: { idempotentHint: false, readOnlyHint: false, title: "Fork repository" }, description: "Fork a GitHub repository to your account or specified organization", inputSchema: { type: "object", properties: { organization: { type: "string", description: "Organization to fork to" }, owner: { type: "string", description: "Repository owner", "x-mcp-header": "owner" }, repo: { type: "string", description: "Repository name", "x-mcp-header": "repo" } }, required: ["owner", "repo"] }, name: "fork_repository" }, { annotations: { idempotentHint: false, readOnlyHint: true, title: "Get commit details" }, description: "Get details for a commit from a GitHub repository", inputSchema: { type: "object", properties: { detail: { type: "string", description: 'Level of detail to include for changed files. "none" omits stats and files entirely. "stats" (default) includes per-file metadata: filename, status, and lines-of-code counts (additions, deletions, changes), with no patch content. "full_patch" additionally includes the unified diff content for each file and can be very large.', default: "stats", enum: ["none", "stats", "full_patch"] }, owner: { type: "string", description: "Repository owner", "x-mcp-header": "owner" }, page: { type: "number", description: "Page number for pagination (min 1)", minimum: 1 }, perPage: { type: "number", description: "Results per page for pagination (min 1, max 100)", minimum: 1, maximum: 100 }, repo: { type: "string", description: "Repository name", "x-mcp-header": "repo" }, sha: { type: "string", description: "Commit SHA, branch name, or tag name" } }, required: ["owner", "repo", "sha"] }, name: "get_commit" }, { annotations: { idempotentHint: false, readOnlyHint: true, title: "Get file or directory contents" }, description: "Get the contents of a file or directory from a GitHub repository", inputSchema: { type: "object", properties: { fields: { type: "array", items: { type: "string", enum: ["type", "name", "path", "size", "sha", "url", "git_url", "html_url", "download_url"] }, description: "Subset of fields to return for each entry when the path is a directory. If omitted, all fields are returned. Ignored when the path is a single file. Use this to reduce response size when listing directories and you only need specific fields, e.g. just 'name' and 'type'." }, owner: { type: "string", description: "Repository owner (username or organization)", "x-mcp-header": "owner" }, path: { type: "string", description: "Path to file/directory", default: "/" }, ref: { type: "string", description: "Accepts optional git refs such as `refs/tags/{tag}`, `refs/heads/{branch}` or `refs/pull/{pr_number}/head`" }, repo: { type: "string", description: "Repository name", "x-mcp-header": "repo" }, sha: { type: "string", description: "Accepts optional commit SHA. If specified, it will be used instead of ref" } }, required: ["owner", "repo"] }, name: "get_file_contents" }, { annotations: { idempotentHint: false, readOnlyHint: true, title: "Get latest release" }, description: "Get the latest release in a GitHub repository", inputSchema: { type: "object", properties: { owner: { type: "string", description: "Repository owner", "x-mcp-header": "owner" }, repo: { type: "string", description: "Repository name", "x-mcp-header": "repo" } }, required: ["owner", "repo"] }, name: "get_latest_release" }, { annotations: { idempotentHint: false, readOnlyHint: true, title: "Get my user profile" }, description: "Get details of the authenticated GitHub user. Use this when a request is about the user's own profile for GitHub. Or when information is missing to build other tool calls.", inputSchema: { type: "object", properties: {} }, name: "get_me" }, { annotations: { idempotentHint: false, readOnlyHint: true, title: "Get a release by tag name" }, description: "Get a specific release by its tag name in a GitHub repository", inputSchema: { type: "object", properties: { owner: { type: "string", description: "Repository owner", "x-mcp-header": "owner" }, repo: { type: "string", description: "Repository name", "x-mcp-header": "repo" }, tag: { type: "string", description: "Tag name (e.g., 'v1.0.0')" } }, required: ["owner", "repo", "tag"] }, name: "get_release_by_tag" }, { annotations: { idempotentHint: false, readOnlyHint: true, title: "Get tag details" }, description: "Get details about a specific git tag in a GitHub repository", inputSchema: { type: "object", properties: { owner: { type: "string", description: "Repository owner", "x-mcp-header": "owner" }, repo: { type: "string", description: "Repository name", "x-mcp-header": "repo" }, tag: { type: "string", description: "Tag name" } }, required: ["owner", "repo", "tag"] }, name: "get_tag" }, { annotations: { idempotentHint: false, readOnlyHint: true, title: "Get issue details" }, description: "Get information about a specific issue in a GitHub repository.", inputSchema: { type: "object", properties: { issue_number: { type: "number", description: "The number of the issue" }, method: { type: "string", description: "The read operation to perform on a single issue.\nOptions are:\n1. get - Get issue details. Also returns best-effort hierarchy flags (`has_parent`, `has_children`); `parent` and `sub_issues_summary` are optional relationship summaries, and `closed_by_pull_requests` summarizes the pull requests configured to close the issue as `total_count` plus up to 5 `references`.\n2. get_comments - Get issue comments.\n3. get_sub_issues - Get sub-issues (children) of the issue.\n4. get_parent - Get the parent issue, if this issue is a sub-issue of another.\n5. get_labels - Get labels assigned to the issue.\n", enum: ["get", "get_comments", "get_sub_issues", "get_parent", "get_labels"] }, owner: { type: "string", description: "The owner of the repository", "x-mcp-header": "owner" }, page: { type: "number", description: "Page number for pagination (min 1)", minimum: 1 }, perPage: { type: "number", description: "Results per page for pagination (min 1, max 100)", minimum: 1, maximum: 100 }, repo: { type: "string", description: "The name of the repository", "x-mcp-header": "repo" } }, required: ["method", "owner", "repo", "issue_number"] }, name: "issue_read" }, { annotations: { idempotentHint: false, readOnlyHint: false, title: "Create or update issue/pull request" }, description: "Create a new or update an existing issue in a GitHub repository.", inputSchema: { type: "object", properties: { assignees: { type: "array", items: { type: "string" }, description: "Usernames to assign to this issue" }, body: { type: "string", description: "Issue body content" }, duplicate_of: { type: "number", description: "Issue number that this issue is a duplicate of. Required when state_reason is 'duplicate'." }, issue_fields: { type: "array", items: { type: "object", properties: { delete: { type: "boolean", description: "Set to true to clear this field's current value on the issue. Cannot be combined with 'value' or 'field_option_name'.", enum: [true] }, field_name: { type: "string", description: "Issue field name (case-insensitive). Must match a field returned by list_issue_fields for this repository or its organization." }, field_option_name: { type: "string", description: "Option name for single-select fields. Validated against the field's options before the API call. Cannot be combined with 'value' or 'delete'." }, value: { type: ["string", "number", "boolean"], description: "Value to set. Use for text, number, and date fields (date as YYYY-MM-DD). For single-select fields, prefer 'field_option_name' so the option is validated before the API call. Cannot be combined with 'field_option_name' or 'delete'." } }, required: ["field_name"], additionalProperties: false }, description: "Issue field values to set or clear. Each item requires 'field_name' and exactly one of 'value', 'field_option_name', or 'delete: true'." }, issue_number: { type: "number", description: "Issue number to update" }, labels: { type: "array", items: { type: "string" }, description: "Labels to apply to this issue" }, method: { type: "string", description: "Write operation to perform on a single issue.\nOptions are:\n- 'create' - creates a new issue.\n- 'update' - updates an existing issue.\n", enum: ["create", "update"] }, milestone: { type: "number", description: "Milestone number" }, owner: { type: "string", description: "Repository owner", "x-mcp-header": "owner" }, repo: { type: "string", description: "Repository name", "x-mcp-header": "repo" }, state: { type: "string", description: "New state", enum: ["open", "closed"] }, state_reason: { type: "string", description: "Reason for the state change. Ignored unless state is changed.", enum: ["completed", "not_planned", "duplicate"] }, title: { type: "string", description: "Issue title" }, type: { description: "Type of this issue. For updates, pass null to remove the current type. Only use if issue types are enabled for this repository. Use list_issue_types to get valid type values for this repository or its owner organization. If the repository doesn't support issue types, omit this parameter.", anyOf: [{ type: "string", minLength: 1 }, { type: "null" }] } }, required: ["method", "owner", "repo"] }, name: "issue_write" }, { annotations: { idempotentHint: false, readOnlyHint: true, title: "List branches" }, description: "List branches in a GitHub repository", inputSchema: { type: "object", properties: { owner: { type: "string", description: "Repository owner", "x-mcp-header": "owner" }, page: { type: "number", description: "Page number for pagination (min 1)", minimum: 1 }, perPage: { type: "number", description: "Results per page for pagination (min 1, max 100)", minimum: 1, maximum: 100 }, repo: { type: "string", description: "Repository name", "x-mcp-header": "repo" } }, required: ["owner", "repo"] }, name: "list_branches" }, { annotations: { idempotentHint: false, readOnlyHint: true, title: "List commits" }, description: "Get list of commits of a branch in a GitHub repository. Returns at least 30 results per page by default, but can return more if specified using the perPage parameter (up to 100).", inputSchema: { type: "object", properties: { author: { type: "string", description: "Author username or email address to filter commits by" }, fields: { type: "array", items: { type: "string", enum: ["sha", "html_url", "commit", "author", "committer"] }, description: "Subset of fields to return for each commit. If omitted, all fields are returned. Use this to reduce response size when you only need specific fields, e.g. just 'sha' and 'html_url'." }, owner: { type: "string", description: "Repository owner", "x-mcp-header": "owner" }, page: { type: "number", description: "Page number for pagination (min 1)", minimum: 1 }, path: { type: "string", description: "Only commits containing this file path will be returned" }, perPage: { type: "number", description: "Results per page for pagination (min 1, max 100)", minimum: 1, maximum: 100 }, repo: { type: "string", description: "Repository name", "x-mcp-header": "repo" }, sha: { type: "string", description: "Commit SHA, branch or tag name to list commits of. If not provided, uses the default branch of the repository. If a commit SHA is provided, will list commits up to that SHA." }, since: { type: "string", description: "Only commits after this date will be returned (ISO 8601 format: YYYY-MM-DDTHH:MM:SSZ or YYYY-MM-DD)" }, until: { type: "string", description: "Only commits before this date will be returned (ISO 8601 format: YYYY-MM-DDTHH:MM:SSZ or YYYY-MM-DD)" } }, required: ["owner", "repo"] }, name: "list_commits" }, { annotations: { idempotentHint: false, readOnlyHint: true, title: "List issues" }, description: "List issues in a GitHub repository. For pagination, use the 'endCursor' from the previous response's 'pageInfo' in the 'after' parameter.", inputSchema: { type: "object", properties: { after: { type: "string", description: "Cursor for pagination. Use the cursor from the previous response." }, direction: { type: "string", description: "Order direction. If provided, the 'orderBy' also needs to be provided.", enum: ["ASC", "DESC"] }, field_filters: { type: "array", items: { type: "object", properties: { field_name: { type: "string", description: 'Name of the custom field (e.g. "Priority"). Case-insensitive.' }, value: { type: "string", description: 'Value to filter on. For single-select fields, the option name (e.g. "P1"). For dates, YYYY-MM-DD. For numbers, the numeric value as a string. For text, the text value.' } }, required: ["field_name", "value"] }, description: "Filter by custom issue field values. Each entry takes a field_name and a value; the server looks up the field and coerces the value to its type (single-select option name, text, number, or YYYY-MM-DD date)." }, fields: { type: "array", items: { type: "string", enum: ["number", "title", "body", "state", "user", "labels", "comments", "created_at", "updated_at", "field_values"] }, description: "Subset of fields to return for each issue. If omitted, all fields are returned. Use this to reduce response size when you only need specific fields; omitting 'body' and 'field_values' in particular drops the largest per-result data." }, labels: { type: "array", items: { type: "string" }, description: "Filter by labels" }, orderBy: { type: "string", description: "Order issues by field. If provided, the 'direction' also needs to be provided.", enum: ["CREATED_AT", "UPDATED_AT", "COMMENTS"] }, owner: { type: "string", description: "Repository owner", "x-mcp-header": "owner" }, perPage: { type: "number", description: "Results per page for pagination (min 1, max 100)", minimum: 1, maximum: 100 }, repo: { type: "string", description: "Repository name", "x-mcp-header": "repo" }, since: { type: "string", description: "Filter by date (ISO 8601 timestamp)" }, state: { type: "string", description: "Filter by state, by default both open and closed issues are returned when not provided", enum: ["OPEN", "CLOSED"] } }, required: ["owner", "repo"] }, name: "list_issues" }, { annotations: { idempotentHint: false, readOnlyHint: true, title: "List pull requests" }, description: "List pull requests in a GitHub repository. If the user specifies an author, then DO NOT use this tool and use the search_pull_requests tool instead.", inputSchema: { type: "object", properties: { base: { type: "string", description: "Filter by base branch" }, direction: { type: "string", description: "Sort direction", enum: ["asc", "desc"] }, fields: { type: "array", items: { type: "string", enum: ["number", "title", "body", "state", "draft", "merged", "mergeable_state", "html_url", "user", "labels", "assignees", "requested_reviewers", "merged_by", "head", "base", "additions", "deletions", "changed_files", "commits", "comments", "created_at", "updated_at", "closed_at", "merged_at", "milestone"] }, description: "Subset of fields to return for each pull request. If omitted, all fields are returned. Use this to reduce response size when you only need specific fields; omitting 'body' in particular drops the largest per-result data." }, head: { type: "string", description: "Filter by head user/org and branch" }, owner: { type: "string", description: "Repository owner", "x-mcp-header": "owner" }, page: { type: "number", description: "Page number for pagination (min 1)", minimum: 1 }, perPage: { type: "number", description: "Results per page for pagination (min 1, max 100)", minimum: 1, maximum: 100 }, repo: { type: "string", description: "Repository name", "x-mcp-header": "repo" }, sort: { type: "string", description: "Sort by", enum: ["created", "updated", "popularity", "long-running"] }, state: { type: "string", description: "Filter by state", enum: ["open", "closed", "all"] } }, required: ["owner", "repo"] }, name: "list_pull_requests" }, { annotations: { idempotentHint: false, readOnlyHint: true, title: "List releases" }, description: "List releases in a GitHub repository", inputSchema: { type: "object", properties: { fields: { type: "array", items: { type: "string", enum: ["id", "tag_name", "name", "body", "html_url", "published_at", "prerelease", "draft", "author"] }, description: "Subset of fields to return for each release. If omitted, all fields are returned. Use this to reduce response size when you only need specific fields; omitting 'body' in particular drops the largest per-release data." }, owner: { type: "string", description: "Repository owner", "x-mcp-header": "owner" }, page: { type: "number", description: "Page number for pagination (min 1)", minimum: 1 }, perPage: { type: "number", description: "Results per page for pagination (min 1, max 100)", minimum: 1, maximum: 100 }, repo: { type: "string", description: "Repository name", "x-mcp-header": "repo" } }, required: ["owner", "repo"] }, name: "list_releases" }, { annotations: { idempotentHint: false, readOnlyHint: true, title: "List repository collaborators" }, description: "List collaborators of a GitHub repository. Results are paginated; the response includes `nextPage`, `prevPage`, `firstPage`, and `lastPage` fields. To get the next page, use the `nextPage` value as the `page` parameter.", inputSchema: { type: "object", properties: { affiliation: { type: "string", description: "Filter by affiliation. Can be one of: 'outside' (outside collaborators), 'direct' (all with permissions regardless of org membership), 'all' (all collaborators). Default: 'all'", enum: ["outside", "direct", "all"] }, owner: { type: "string", description: "Repository owner", "x-mcp-header": "owner" }, page: { type: "number", description: "Page number for pagination (default 1, min 1)", minimum: 1 }, perPage: { type: "number", description: "Results per page for pagination (default 30, min 1, max 100)", minimum: 1, maximum: 100 }, repo: { type: "string", description: "Repository name", "x-mcp-header": "repo" } }, required: ["owner", "repo"] }, name: "list_repository_collaborators" }, { annotations: { idempotentHint: false, readOnlyHint: true, title: "List tags" }, description: "List git tags in a GitHub repository", inputSchema: { type: "object", properties: { owner: { type: "string", description: "Repository owner", "x-mcp-header": "owner" }, page: { type: "number", description: "Page number for pagination (min 1)", minimum: 1 }, perPage: { type: "number", description: "Results per page for pagination (min 1, max 100)", minimum: 1, maximum: 100 }, repo: { type: "string", description: "Repository name", "x-mcp-header": "repo" } }, required: ["owner", "repo"] }, name: "list_tags" }, { annotations: { idempotentHint: false, readOnlyHint: false, title: "Merge pull request" }, description: "Merge a pull request in a GitHub repository.", inputSchema: { type: "object", properties: { commit_message: { type: "string", description: "Extra detail for merge commit" }, commit_title: { type: "string", description: "Title for merge commit" }, merge_method: { type: "string", description: "Merge method", enum: ["merge", "squash", "rebase"] }, owner: { type: "string", description: "Repository owner", "x-mcp-header": "owner" }, pullNumber: { type: "number", description: "Pull request number" }, repo: { type: "string", description: "Repository name", "x-mcp-header": "repo" } }, required: ["owner", "repo", "pullNumber"] }, name: "merge_pull_request" }, { annotations: { idempotentHint: false, readOnlyHint: true, title: "Get details for a single pull request" }, description: "Get information on a specific pull request in GitHub repository.", inputSchema: { type: "object", properties: { after: { type: "string", description: "Cursor for pagination, used only by the get_review_comments method. Pass the endCursor from the previous page's PageInfo to fetch the next page." }, method: { type: "string", description: "Action to specify what pull request data needs to be retrieved from GitHub. \nPossible options: \n 1. get - Get details of a specific pull request.\n 2. get_diff - Get the diff of a pull request.\n 3. get_status - Get combined commit status of a head commit in a pull request.\n 4. get_files - Get the list of files changed in a pull request. Use with pagination parameters to control the number of results returned.\n 5. get_commits - Get the list of commits on a pull request. Use with pagination parameters to control the number of results returned.\n 6. get_review_comments - Get review threads on a pull request. Each thread contains logically grouped review comments made on the same code location during pull request reviews. Returns threads with metadata (isResolved, isOutdated, isCollapsed) and their associated comments. Use cursor-based pagination (perPage, after) to control results.\n 7. get_reviews - Get the reviews on a pull request. When asked for review comments, use get_review_comments method. Use with pagination parameters to control the number of results returned.\n 8. get_comments - Get comments on a pull request. Use this if user doesn't specifically want review comments. Use with pagination parameters to control the number of results returned.\n 9. get_check_runs - Get check runs for the head commit of a pull request. Check runs are the individual CI/CD jobs and checks that run on the PR.\n", enum: ["get", "get_diff", "get_status", "get_files", "get_commits", "get_review_comments", "get_reviews", "get_comments", "get_check_runs"] }, owner: { type: "string", description: "Repository owner", "x-mcp-header": "owner" }, page: { type: "number", description: "Page number for pagination (min 1)", minimum: 1 }, perPage: { type: "number", description: "Results per page for pagination (min 1, max 100)", minimum: 1, maximum: 100 }, pullNumber: { type: "number", description: "Pull request number" }, repo: { type: "string", description: "Repository name", "x-mcp-header": "repo" } }, required: ["method", "owner", "repo", "pullNumber"] }, name: "pull_request_read" }, { annotations: { idempotentHint: false, readOnlyHint: false, title: "Write operations (create, submit, delete) on pull request reviews" }, description: `Create and/or submit, delete review of a pull request.
|
|
685
|
+
|
|
686
|
+
Available methods:
|
|
687
|
+
- create: Create a new review of a pull request. If "event" parameter is provided, the review is submitted. If "event" is omitted, a pending review is created.
|
|
688
|
+
- submit_pending: Submit an existing pending review of a pull request. This requires that a pending review exists for the current user on the specified pull request. The "body" and "event" parameters are used when submitting the review.
|
|
689
|
+
- delete_pending: Delete an existing pending review of a pull request. This requires that a pending review exists for the current user on the specified pull request.
|
|
690
|
+
- resolve_thread: Resolve a review thread. Requires only "threadId" parameter with the thread's node ID (e.g., PRRT_kwDOxxx). The owner, repo, and pullNumber parameters are not used for this method. Resolving an already-resolved thread is a no-op.
|
|
691
|
+
- unresolve_thread: Unresolve a previously resolved review thread. Requires only "threadId" parameter. The owner, repo, and pullNumber parameters are not used for this method. Unresolving an already-unresolved thread is a no-op.
|
|
692
|
+
`, inputSchema: { type: "object", properties: { body: { type: "string", description: "Review comment text" }, commitID: { type: "string", description: "SHA of commit to review" }, event: { type: "string", description: "Review action to perform.", enum: ["APPROVE", "REQUEST_CHANGES", "COMMENT"] }, method: { type: "string", description: "The write operation to perform on pull request review.", enum: ["create", "submit_pending", "delete_pending", "resolve_thread", "unresolve_thread"] }, owner: { type: "string", description: "Repository owner", "x-mcp-header": "owner" }, pullNumber: { type: "number", description: "Pull request number" }, repo: { type: "string", description: "Repository name", "x-mcp-header": "repo" }, threadId: { type: "string", description: "The node ID of the review thread (e.g., PRRT_kwDOxxx). Required for resolve_thread and unresolve_thread methods. Get thread IDs from pull_request_read with method get_review_comments." } }, required: ["method", "owner", "repo", "pullNumber"] }, name: "pull_request_review_write" }, { annotations: { idempotentHint: false, readOnlyHint: false, title: "Push files to repository" }, description: "Push multiple files to a GitHub repository in a single commit", inputSchema: { type: "object", properties: { branch: { type: "string", description: "Branch to push to" }, files: { type: "array", items: { type: "object", properties: { content: { type: "string", description: "file content" }, path: { type: "string", description: "path to the file" } }, required: ["path", "content"], additionalProperties: false }, description: "Array of file objects to push, each object with path (string) and content (string)" }, message: { type: "string", description: "Commit message" }, owner: { type: "string", description: "Repository owner", "x-mcp-header": "owner" }, repo: { type: "string", description: "Repository name", "x-mcp-header": "repo" } }, required: ["owner", "repo", "branch", "files", "message"] }, name: "push_files" }, { annotations: { idempotentHint: false, readOnlyHint: true, title: "Search code" }, description: "Fast and precise code search across ALL GitHub repositories using GitHub's native search engine. Best for finding exact symbols, functions, classes, or specific code patterns.", inputSchema: { type: "object", properties: { fields: { type: "array", items: { type: "string", enum: ["name", "path", "sha", "repository", "text_matches"] }, description: "Subset of fields to return for each code search result. If omitted, all fields are returned. Use this to reduce response size when you only need specific fields; omitting 'repository' and 'text_matches' in particular drops the largest per-result data." }, order: { type: "string", description: "Sort order for results", enum: ["asc", "desc"] }, page: { type: "number", description: "Page number for pagination (min 1)", minimum: 1 }, perPage: { type: "number", description: "Results per page for pagination (min 1, max 100)", minimum: 1, maximum: 100 }, query: { type: "string", description: 'Search query (GitHub code search REST). Implicit AND between terms; supports `OR`, `NOT`, and `"quoted phrase"` for exact match. Qualifiers: `repo:owner/repo`, `org:`, `user:`, `language:`, `path:dir` (prefix match), `filename:exact.ext`, `extension:`, `in:file`, `in:path`, `size:`, `is:archived`, `is:fork`. Max 256 chars. Examples: `WithContext language:go org:github`; `"package main" repo:o/r`; `func extension:go path:cmd repo:o/r`; `NOT TODO language:go repo:o/r`.' }, sort: { type: "string", description: "Sort field ('indexed' only)" } }, required: ["query"] }, name: "search_code" }, { annotations: { idempotentHint: false, readOnlyHint: true, title: "Search commits" }, description: "Search for commits across GitHub repositories using GitHub's commit search syntax. Useful for finding specific changes, authors, or messages across one or many repositories. Searches the default branch only.", inputSchema: { type: "object", properties: { order: { type: "string", description: "Sort order", enum: ["asc", "desc"] }, page: { type: "number", description: "Page number for pagination (min 1)", minimum: 1 }, perPage: { type: "number", description: "Results per page for pagination (min 1, max 100)", minimum: 1, maximum: 100 }, query: { type: "string", description: 'Commit search query (GitHub commit search REST). Searches commit messages on the default branch only. Scope the search with `repo:owner/repo`, `org:`, or `user:` (queries without a scope qualifier match across all of GitHub and are usually not what you want). Other qualifiers: `author:`, `committer:`, `author-name:`, `committer-name:`, `author-email:`, `committer-email:`, `author-date:`, `committer-date:` (supports `>`, `<`, `>=`, `<=`, and `YYYY-MM-DD..YYYY-MM-DD` ranges), `merge:true|false`, `hash:`, `tree:`, `parent:`, `is:public`. Examples: `repo:owner/repo fix panic`; `org:github author:defunkt committer-date:>=2024-01-01`; `"refactor cache" repo:o/r`; `hash:abc1234 repo:o/r`.' }, sort: { type: "string", description: "Sort by author or committer date (defaults to best match)", enum: ["author-date", "committer-date"] } }, required: ["query"] }, name: "search_commits" }, { annotations: { idempotentHint: false, readOnlyHint: true, title: "Search issues" }, description: 'Search issues using natural-language semantic matching. Best for conceptual or paraphrased queries (e.g. "login fails after password reset"). Already scoped to is:issue.', inputSchema: { type: "object", properties: { fields: { type: "array", items: { type: "string", enum: ["number", "title", "body", "state", "state_reason", "draft", "locked", "html_url", "user", "author_association", "labels", "assignee", "assignees", "milestone", "comments", "reactions", "created_at", "updated_at", "closed_at", "closed_by", "type", "repository_url", "pull_request", "field_values"] }, description: "Subset of fields to return for each issue result. If omitted, all fields are returned. Use this to reduce response size when you only need specific fields; omitting 'body', 'reactions', and 'labels' in particular drops the largest per-result data." }, order: { type: "string", description: "Sort order", enum: ["asc", "desc"] }, owner: { type: "string", description: "Optional repository owner. If provided with repo, only issues for this repository are listed.", "x-mcp-header": "owner" }, page: { type: "number", description: "Page number for pagination (min 1)", minimum: 1 }, perPage: { type: "number", description: "Results per page for pagination (min 1, max 100)", minimum: 1, maximum: 100 }, query: { type: "string", description: "The search query, as natural language. When the user gives alternative wordings, include them as plain words rather than joining them with OR." }, repo: { type: "string", description: "Optional repository name. If provided with owner, only issues for this repository are listed.", "x-mcp-header": "repo" }, sort: { type: "string", description: "Sort field by number of matches of categories, defaults to best match", enum: ["comments", "reactions", "reactions-+1", "reactions--1", "reactions-smile", "reactions-thinking_face", "reactions-heart", "reactions-tada", "interactions", "created", "updated"] } }, required: ["query"] }, name: "search_issues" }, { annotations: { idempotentHint: false, readOnlyHint: true, title: "Search repositories" }, description: "Find GitHub repositories by name, description, readme, topics, or other metadata. Perfect for discovering projects, finding examples, or locating specific repositories across GitHub.", inputSchema: { type: "object", properties: { minimal_output: { type: "boolean", description: "Return minimal repository information (default: true). When false, returns full GitHub API repository objects.", default: true }, order: { type: "string", description: "Sort order", enum: ["asc", "desc"] }, page: { type: "number", description: "Page number for pagination (min 1)", minimum: 1 }, perPage: { type: "number", description: "Results per page for pagination (min 1, max 100)", minimum: 1, maximum: 100 }, query: { type: "string", description: "Repository search query. Examples: 'machine learning in:name stars:>1000 language:python', 'topic:react', 'user:facebook'. Supports advanced search syntax for precise filtering." }, sort: { type: "string", description: "Sort repositories by field, defaults to best match", enum: ["stars", "forks", "help-wanted-issues", "updated"] } }, required: ["query"] }, name: "search_repositories" }, { annotations: { idempotentHint: false, readOnlyHint: true, title: "Search users" }, description: "Find GitHub users by username, real name, or other profile information. Useful for locating developers, contributors, or team members.", inputSchema: { type: "object", properties: { order: { type: "string", description: "Sort order", enum: ["asc", "desc"] }, page: { type: "number", description: "Page number for pagination (min 1)", minimum: 1 }, perPage: { type: "number", description: "Results per page for pagination (min 1, max 100)", minimum: 1, maximum: 100 }, query: { type: "string", description: "User search query. Examples: 'john smith', 'location:seattle', 'followers:>100'. Search is automatically scoped to type:user." }, sort: { type: "string", description: "Sort users by number of followers or repositories, or when the person joined GitHub.", enum: ["followers", "repositories", "joined"] } }, required: ["query"] }, name: "search_users" }, { annotations: { idempotentHint: false, readOnlyHint: false, title: "Edit pull request" }, description: "Update an existing pull request in a GitHub repository.", inputSchema: { type: "object", properties: { base: { type: "string", description: "New base branch name" }, body: { type: "string", description: "New description" }, draft: { type: "boolean", description: "Mark pull request as draft (true) or ready for review (false)" }, maintainer_can_modify: { type: "boolean", description: "Allow maintainer edits" }, owner: { type: "string", description: "Repository owner", "x-mcp-header": "owner" }, pullNumber: { type: "number", description: "Pull request number to update" }, repo: { type: "string", description: "Repository name", "x-mcp-header": "repo" }, reviewers: { type: "array", items: { type: "string" }, description: "GitHub usernames or ORG/team-slug team reviewers to request reviews from" }, state: { type: "string", description: "New state", enum: ["open", "closed"] }, title: { type: "string", description: "New title" } }, required: ["owner", "repo", "pullNumber"] }, name: "update_pull_request" }, { annotations: { idempotentHint: false, readOnlyHint: false, title: "Update pull request branch" }, description: "Update the branch of a pull request with the latest changes from the base branch.", inputSchema: { type: "object", properties: { expectedHeadSha: { type: "string", description: "The expected SHA of the pull request's HEAD ref" }, owner: { type: "string", description: "Repository owner", "x-mcp-header": "owner" }, pullNumber: { type: "number", description: "Pull request number" }, repo: { type: "string", description: "Repository name", "x-mcp-header": "repo" } }, required: ["owner", "repo", "pullNumber"] }, name: "update_pull_request_branch" }, { name: "create_issue", description: "Create an issue.", inputSchema: { $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { owner: { type: "string", minLength: 1 }, repo: { type: "string", minLength: 1 }, title: { type: "string", minLength: 1 }, body: { type: "string" }, labels: { type: "array", items: { type: "string" } }, assignees: { type: "array", items: { type: "string" } } }, required: ["owner", "repo", "title"], additionalProperties: false } }, { name: "create_pull_request_review", description: "Create a pull request review.", inputSchema: { $schema: "https://json-schema.org/draft/2020-12/schema", type: "object", properties: { owner: { type: "string", minLength: 1 }, repo: { type: "string", minLength: 1 }, pull_number: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 }, pullNumber: { type: "integer", exclusiveMinimum: 0, maximum: 9007199254740991 }, event: { type: "string", enum: ["APPROVE", "REQUEST_CHANGES", "COMMENT"] }, body: { type: "string" } }, required: ["owner", "repo", "event"], additionalProperties: false } }] } };
|
|
638
693
|
|
|
639
694
|
// ../packages/twin-github/dist/src/errors.js
|
|
640
695
|
var TwinError = class extends Error {
|
|
@@ -4841,5 +4896,58 @@ function createGitHubCloneApp(options = {}) {
|
|
|
4841
4896
|
seed: options.db ? void 0 : options.seed ?? defaultSeedState()
|
|
4842
4897
|
});
|
|
4843
4898
|
}
|
|
4899
|
+
function toolSchemaConformance() {
|
|
4900
|
+
const problems = [];
|
|
4901
|
+
const declared = new Set(githubToolFixture.toolNames);
|
|
4902
|
+
const schemas = new Map(toolArgumentSchemas.map((tool) => [tool.name, tool.schema]));
|
|
4903
|
+
for (const name of schemas.keys()) {
|
|
4904
|
+
if (!declared.has(name))
|
|
4905
|
+
problems.push(`'${name}' is validated here and absent from the fixture`);
|
|
4906
|
+
}
|
|
4907
|
+
for (const tool of githubToolFixture.tools) {
|
|
4908
|
+
const schema = schemas.get(tool.name);
|
|
4909
|
+
if (!schema) {
|
|
4910
|
+
problems.push(`'${tool.name}' is declared in the fixture and validated by nothing`);
|
|
4911
|
+
continue;
|
|
4912
|
+
}
|
|
4913
|
+
const upstream = tool.inputSchema;
|
|
4914
|
+
const projected = z.toJSONSchema(schema, { target: "draft-7", io: "input" });
|
|
4915
|
+
const upstreamKeys = new Set(Object.keys(upstream.properties ?? {}));
|
|
4916
|
+
const ourKeys = new Set(Object.keys(projected.properties ?? {}));
|
|
4917
|
+
for (const key of ourKeys) {
|
|
4918
|
+
if (!upstreamKeys.has(key)) {
|
|
4919
|
+
problems.push(`'${tool.name}' validates '${key}', which GitHub's inputSchema does not declare`);
|
|
4920
|
+
}
|
|
4921
|
+
}
|
|
4922
|
+
for (const key of upstreamKeys) {
|
|
4923
|
+
if (!ourKeys.has(key)) {
|
|
4924
|
+
problems.push(`'${tool.name}' does not model GitHub's parameter '${key}'`);
|
|
4925
|
+
}
|
|
4926
|
+
}
|
|
4927
|
+
const upstreamRequired = [...upstream.required ?? []].sort().join(",");
|
|
4928
|
+
const ourRequired = [...projected.required ?? []].sort().join(",");
|
|
4929
|
+
if (upstreamRequired !== ourRequired) {
|
|
4930
|
+
problems.push(`'${tool.name}' requires [${ourRequired}] and GitHub requires [${upstreamRequired}]`);
|
|
4931
|
+
}
|
|
4932
|
+
if (upstream.additionalProperties === void 0 && !schema.safeParse(unknownKeyProbe(upstream)).success) {
|
|
4933
|
+
const withoutUnknown = schema.safeParse(knownKeyProbe(upstream));
|
|
4934
|
+
if (withoutUnknown.success) {
|
|
4935
|
+
problems.push(`'${tool.name}' rejects unknown arguments, and GitHub's inputSchema declares no additionalProperties \u2014 a live parameter would be hard-rejected here and accepted there`);
|
|
4936
|
+
}
|
|
4937
|
+
}
|
|
4938
|
+
}
|
|
4939
|
+
return problems;
|
|
4940
|
+
}
|
|
4941
|
+
function knownKeyProbe(upstream) {
|
|
4942
|
+
const probe = {};
|
|
4943
|
+
for (const key of upstream.required ?? []) {
|
|
4944
|
+
const spec = (upstream.properties ?? {})[key];
|
|
4945
|
+
probe[key] = spec?.type === "number" || spec?.type === "integer" ? 1 : spec?.type === "boolean" ? true : "probe";
|
|
4946
|
+
}
|
|
4947
|
+
return probe;
|
|
4948
|
+
}
|
|
4949
|
+
function unknownKeyProbe(upstream) {
|
|
4950
|
+
return { ...knownKeyProbe(upstream), __pome_unknown_argument__: "probe" };
|
|
4951
|
+
}
|
|
4844
4952
|
|
|
4845
|
-
export { GitHubDomain, createGitHubCloneApp, executeTool, githubToolFixture, githubToolInputSchema, githubTwinDefinition, openGitHubCloneDatabase, resetDatabase, toolArgumentSchemas };
|
|
4953
|
+
export { GitHubDomain, createGitHubCloneApp, executeTool, githubToolFixture, githubToolInputSchema, githubTwinDefinition, openGitHubCloneDatabase, resetDatabase, toolArgumentSchemas, toolSchemaConformance };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { routeInputDeclarer, bracketedQuery, integerInput, booleanInput, mountDeclaredRoute, UndeclaredInputError } from './chunk-2Q3P45LK.js';
|
|
2
|
-
import { failureInjectionRuleSchema, loadMcpToolFixture, openTwinDatabase, createFailureInjectionStore, defineTwin, twinBuildInfo, deriveMcpToolTable, failureInjectionMiddleware, createApp, FAILURE_INJECTION_OVERRIDE_KEY, recordedRequestHeaders, UnknownToolError } from './chunk-
|
|
2
|
+
import { failureInjectionRuleSchema, loadMcpToolFixture, openTwinDatabase, createFailureInjectionStore, defineTwin, twinBuildInfo, deriveMcpToolTable, failureInjectionMiddleware, createApp, FAILURE_INJECTION_OVERRIDE_KEY, recordedRequestHeaders, UnknownToolError } from './chunk-OW7VVW6X.js';
|
|
3
3
|
import './chunk-VBATFCWR.js';
|
|
4
4
|
import './chunk-SG6ZTIMT.js';
|
|
5
5
|
import { z, ZodError } from 'zod';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { SLACK_CHECKS } from './chunk-IDNSKKEC.js';
|
|
2
2
|
import './chunk-JWJYNAWI.js';
|
|
3
3
|
import { routeInputDeclarer, booleanInput, integerInput, mountDeclaredRoute, UndeclaredInputError } from './chunk-2Q3P45LK.js';
|
|
4
|
-
import { loadMcpToolFixture, defineTwin, queryTokenResolver, formTokenResolver, deriveMcpToolTable, UnknownToolError, openTwinDatabase, createApp } from './chunk-
|
|
4
|
+
import { loadMcpToolFixture, defineTwin, queryTokenResolver, formTokenResolver, deriveMcpToolTable, UnknownToolError, openTwinDatabase, createApp } from './chunk-OW7VVW6X.js';
|
|
5
5
|
import './chunk-VBATFCWR.js';
|
|
6
6
|
import './chunk-SG6ZTIMT.js';
|
|
7
7
|
import { z, ZodError } from 'zod';
|
|
@@ -3,7 +3,7 @@ import { MCP_PAGE_MAX, defaultSeedState, linearSeedSchema, notFound, badUserInpu
|
|
|
3
3
|
export { DEFAULT_LINEAR_CLOCK, DEFAULT_LINEAR_EMAIL, DEFAULT_LINEAR_PORT, DEFAULT_LINEAR_SID, DEFAULT_LINEAR_TOKEN, LINEAR_PROVIDER_TOKEN_PREFIX, LinearTwinError, STATE_EXPORT_CAP, assertWebhookUrl, defaultSeedState, linearErrorEnvelope, linearSeedSchema, loadSeedFromEnv, parseSeed, unauthorizedEnvelope, unsupportedEnvelope, webhookUrlError } from './chunk-ZKID2HS3.js';
|
|
4
4
|
import './chunk-JWJYNAWI.js';
|
|
5
5
|
import { routeInputDeclarer, mountDeclaredRoute, UndeclaredInputError } from './chunk-2Q3P45LK.js';
|
|
6
|
-
import { loadMcpToolFixture, deriveMcpToolTable, openTwinDatabase, defineTwin, createApp } from './chunk-
|
|
6
|
+
import { loadMcpToolFixture, deriveMcpToolTable, openTwinDatabase, defineTwin, createApp } from './chunk-OW7VVW6X.js';
|
|
7
7
|
import './chunk-VBATFCWR.js';
|
|
8
8
|
import './chunk-SG6ZTIMT.js';
|
|
9
9
|
import { createHmac, timingSafeEqual, createHash, randomBytes } from 'node:crypto';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { bootTwin } from './chunk-
|
|
2
|
-
import { isTwinName, TWIN_NAMES, defaultPortFor, TWIN_REGISTRY } from './chunk-
|
|
3
|
-
import './chunk-
|
|
1
|
+
import { bootTwin } from './chunk-KNZJW3YT.js';
|
|
2
|
+
import { isTwinName, TWIN_NAMES, defaultPortFor, TWIN_REGISTRY } from './chunk-PTM7SZYG.js';
|
|
3
|
+
import './chunk-OW7VVW6X.js';
|
|
4
4
|
import './chunk-VBATFCWR.js';
|
|
5
5
|
import './chunk-SG6ZTIMT.js';
|
|
6
6
|
import { randomBytes } from 'node:crypto';
|
package/package.json
CHANGED