@buildinternet/uploads 0.53.0 → 0.55.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -4
- package/dist/cli-catalog.js +15 -0
- package/dist/cli-help.js +1 -0
- package/dist/cli.js +10 -0
- package/dist/client.d.ts +60 -0
- package/dist/client.js +24 -0
- package/dist/commands/docs.d.ts +8 -0
- package/dist/commands/docs.js +67 -0
- package/dist/commands/feed.d.ts +2 -0
- package/dist/commands/feed.js +133 -0
- package/dist/comment-render.generated.d.ts +1 -1
- package/dist/docs.d.ts +52 -0
- package/dist/docs.js +439 -0
- package/dist/github.d.ts +12 -0
- package/dist/github.js +40 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/mcp/docs-tool.d.ts +4 -0
- package/dist/mcp/docs-tool.js +35 -0
- package/dist/mcp/output-schemas.d.ts +2 -0
- package/dist/mcp/output-schemas.js +53 -0
- package/dist/mcp/server.d.ts +1 -0
- package/dist/mcp/server.js +1 -0
- package/dist/mcp/tools.d.ts +2 -1
- package/dist/mcp/tools.js +108 -1
- package/package.json +1 -1
|
@@ -263,6 +263,20 @@ export const changelogResultSchema = objectSchema({
|
|
|
263
263
|
feed: { type: "string" },
|
|
264
264
|
entries: { type: "array", items: changelogEntrySchema },
|
|
265
265
|
}, ["url", "entries"]);
|
|
266
|
+
const docsSearchHitSchema = objectSchema({
|
|
267
|
+
title: { type: "string" },
|
|
268
|
+
url: { type: "string" },
|
|
269
|
+
page: { type: "string" },
|
|
270
|
+
snippet: { type: "string" },
|
|
271
|
+
body: { type: "string" },
|
|
272
|
+
truncated: { type: "boolean" },
|
|
273
|
+
}, ["title", "url", "page", "snippet"]);
|
|
274
|
+
export const searchDocsResultSchema = objectSchema({
|
|
275
|
+
url: { type: "string" },
|
|
276
|
+
query: { type: "string" },
|
|
277
|
+
results: { type: "array", items: docsSearchHitSchema },
|
|
278
|
+
total: { type: "number" },
|
|
279
|
+
}, ["url", "results", "total"]);
|
|
266
280
|
export const promoteToolResultSchema = objectSchema({
|
|
267
281
|
// `promotion` is optional (issue #702): a `keys`-only call (no `branch`)
|
|
268
282
|
// never runs the branch sweep, so there's nothing to report under it.
|
|
@@ -323,6 +337,39 @@ export const galleryFindResultSchema = objectSchema({
|
|
|
323
337
|
galleries: { type: "array", items: galleryResultSchema },
|
|
324
338
|
nextCursor: nullableString,
|
|
325
339
|
});
|
|
340
|
+
const feedItemSchema = objectSchema({
|
|
341
|
+
id: { type: "string" },
|
|
342
|
+
objectKey: { type: "string" },
|
|
343
|
+
filename: { type: "string" },
|
|
344
|
+
status: { type: "string" },
|
|
345
|
+
url: nullableString,
|
|
346
|
+
embedUrl: nullableString,
|
|
347
|
+
pageUrl: { type: "string" },
|
|
348
|
+
contentType: nullableString,
|
|
349
|
+
size: { type: ["number", "null"] },
|
|
350
|
+
uploaded: nullableString,
|
|
351
|
+
modified: nullableString,
|
|
352
|
+
path: nullableString,
|
|
353
|
+
state: nullableString,
|
|
354
|
+
posterUrl: { type: "string" },
|
|
355
|
+
videoDimensions: {
|
|
356
|
+
type: "object",
|
|
357
|
+
additionalProperties: true,
|
|
358
|
+
},
|
|
359
|
+
});
|
|
360
|
+
export const feedResultSchema = objectSchema({
|
|
361
|
+
id: { type: "string" },
|
|
362
|
+
url: { type: "string" },
|
|
363
|
+
workspace: { type: "string" },
|
|
364
|
+
repo: { type: "string" },
|
|
365
|
+
path: nullableString,
|
|
366
|
+
number: { type: ["number", "null"] },
|
|
367
|
+
kind: nullableString,
|
|
368
|
+
title: { type: "string" },
|
|
369
|
+
createdAt: { type: "string" },
|
|
370
|
+
updatedAt: { type: "string" },
|
|
371
|
+
items: { type: "array", items: feedItemSchema },
|
|
372
|
+
});
|
|
326
373
|
/** Hosted catalog — every tool must have an entry. */
|
|
327
374
|
export const hostedOutputSchemas = {
|
|
328
375
|
gallery_create: galleryResultSchema,
|
|
@@ -330,6 +377,8 @@ export const hostedOutputSchemas = {
|
|
|
330
377
|
gallery_add: galleryItemSchema,
|
|
331
378
|
gallery_link: galleryReferenceSchema,
|
|
332
379
|
gallery_find_by_reference: galleryFindResultSchema,
|
|
380
|
+
feed_create: feedResultSchema,
|
|
381
|
+
feed_get: feedResultSchema,
|
|
333
382
|
put: putResultSchema,
|
|
334
383
|
list: listResultSchema,
|
|
335
384
|
delete: deleteResultSchema,
|
|
@@ -345,6 +394,7 @@ export const hostedOutputSchemas = {
|
|
|
345
394
|
purge_expired: purgeExpiredResultSchema,
|
|
346
395
|
whoami: whoamiResultSchema,
|
|
347
396
|
changelog: changelogResultSchema,
|
|
397
|
+
search_docs: searchDocsResultSchema,
|
|
348
398
|
};
|
|
349
399
|
/** Shared-shape stdio tools. Hosted-only tools (`promote`, `repo_link_status`) omitted. */
|
|
350
400
|
export const stdioOutputSchemas = {
|
|
@@ -353,6 +403,8 @@ export const stdioOutputSchemas = {
|
|
|
353
403
|
gallery_add: galleryItemSchema,
|
|
354
404
|
gallery_link: galleryReferenceSchema,
|
|
355
405
|
gallery_find_by_reference: galleryFindResultSchema,
|
|
406
|
+
feed_create: feedResultSchema,
|
|
407
|
+
feed_get: feedResultSchema,
|
|
356
408
|
put: putResultSchema,
|
|
357
409
|
list: listResultSchema,
|
|
358
410
|
delete: deleteResultSchema,
|
|
@@ -379,6 +431,7 @@ export const stdioOutputSchemas = {
|
|
|
379
431
|
purge_expired: purgeExpiredResultSchema,
|
|
380
432
|
whoami: whoamiResultSchema,
|
|
381
433
|
changelog: changelogResultSchema,
|
|
434
|
+
search_docs: searchDocsResultSchema,
|
|
382
435
|
report: objectSchema({
|
|
383
436
|
ok: { type: "boolean" },
|
|
384
437
|
id: { type: "string" },
|
package/dist/mcp/server.d.ts
CHANGED
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
import { McpServer, type Implementation, type jsonSchemaValidator } from "@modelcontextprotocol/server";
|
|
21
21
|
export { appProp, canonicalMetaFromArgs, METADATA_DESCRIPTION, METADATA_PATH_CUE, MCP_EXAMPLE_PNG_BASE64, metadataArgWithCanonical, metadataProp, stateProp, optBool, optPosInt, optString, optStringArray, optStringRecord, usage, type ToolArgs, } from "./args.js";
|
|
22
22
|
export { ToolBatchError, batchFailureMessage } from "./batch-error.js";
|
|
23
|
+
export { SEARCH_DOCS_DESCRIPTION, SEARCH_DOCS_INPUT_SCHEMA, runSearchDocsTool, } from "./docs-tool.js";
|
|
23
24
|
export { mapBounded } from "../async.js";
|
|
24
25
|
export { McpServer, type jsonSchemaValidator };
|
|
25
26
|
export { commentResultSchema, deleteResultSchema, findFilesResultSchema, galleryFindResultSchema, galleryResultSchema, hostedOutputSchemas, listResultSchema, metadataFacetsResultSchema, metadataResultSchema, promoteToolResultSchema, purgeExpiredResultSchema, putResultSchema, reconcileResultSchema, repoLinkStatusResultSchema, stdioOutputSchemas, usageResultSchema, withOutputSchemas, } from "./output-schemas.js";
|
package/dist/mcp/server.js
CHANGED
|
@@ -23,6 +23,7 @@ import { errorCodeFromUnknown, recordEvent } from "../telemetry.js";
|
|
|
23
23
|
import { ToolBatchError } from "./batch-error.js";
|
|
24
24
|
export { appProp, canonicalMetaFromArgs, METADATA_DESCRIPTION, METADATA_PATH_CUE, MCP_EXAMPLE_PNG_BASE64, metadataArgWithCanonical, metadataProp, stateProp, optBool, optPosInt, optString, optStringArray, optStringRecord, usage, } from "./args.js";
|
|
25
25
|
export { ToolBatchError, batchFailureMessage } from "./batch-error.js";
|
|
26
|
+
export { SEARCH_DOCS_DESCRIPTION, SEARCH_DOCS_INPUT_SCHEMA, runSearchDocsTool, } from "./docs-tool.js";
|
|
26
27
|
export { mapBounded } from "../async.js";
|
|
27
28
|
export { McpServer };
|
|
28
29
|
export { commentResultSchema, deleteResultSchema, findFilesResultSchema, galleryFindResultSchema, galleryResultSchema, hostedOutputSchemas, listResultSchema, metadataFacetsResultSchema, metadataResultSchema, promoteToolResultSchema, purgeExpiredResultSchema, putResultSchema, reconcileResultSchema, repoLinkStatusResultSchema, stdioOutputSchemas, usageResultSchema, withOutputSchemas, } from "./output-schemas.js";
|
package/dist/mcp/tools.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* MCP tool set mirroring the CLI commands (put, attach, list, delete,
|
|
3
|
-
* usage, reconcile, purge_expired, comment, whoami, doctor, changelog
|
|
3
|
+
* usage, reconcile, purge_expired, comment, whoami, doctor, changelog,
|
|
4
|
+
* search_docs). Config is
|
|
4
5
|
* resolved fresh per tool call so a
|
|
5
6
|
* per-call `workspace` argument behaves like the CLI's --workspace flag, and
|
|
6
7
|
* a missing token surfaces as a tool error rather than a startup failure.
|
package/dist/mcp/tools.js
CHANGED
|
@@ -4,7 +4,7 @@ import { resolveFrameId } from "../frame.js";
|
|
|
4
4
|
import { resolveConfig, resolvePutDefaults, } from "../config.js";
|
|
5
5
|
import { resolvePutPrefix } from "../destinations.js";
|
|
6
6
|
import { fetchUploadSource, resolveUploadFilename } from "../fetch-upload-source.js";
|
|
7
|
-
import { ghKeyPrefix, ghPrivateKeyPrefix } from "../github.js";
|
|
7
|
+
import { ghKeyPrefix, ghPrivateKeyPrefix, parseGithubIssueRef } from "../github.js";
|
|
8
8
|
import { safeCaptureFacts } from "../capture-facts.js";
|
|
9
9
|
import { deriveRepoSlugFromGit } from "../keys.js";
|
|
10
10
|
import { validateMetaMap } from "../metadata.js";
|
|
@@ -15,6 +15,7 @@ import { batchFailureMessage, mcpDestroyPublic, mcpNoAuth, mcpOAuthAny, mcpOAuth
|
|
|
15
15
|
import { attachmentFromText, buildReportPayload, parseReportType, REPORT_TYPES, submitReport, validateReportMessage, } from "../report.js";
|
|
16
16
|
import { resolveApiUrl } from "../config.js";
|
|
17
17
|
import { DEFAULT_CHANGELOG_LIMIT, MAX_CHANGELOG_LIMIT, fetchChangelog } from "../changelog.js";
|
|
18
|
+
import { SEARCH_DOCS_DESCRIPTION, SEARCH_DOCS_INPUT_SCHEMA, runSearchDocsTool, } from "./docs-tool.js";
|
|
18
19
|
function mcpOptimizeOptions(args, defaults) {
|
|
19
20
|
const quality = optPosInt(args, "optimizeQuality");
|
|
20
21
|
if (quality !== undefined && quality > 100)
|
|
@@ -74,6 +75,12 @@ function galleryId(args) {
|
|
|
74
75
|
usage("galleryId is required");
|
|
75
76
|
return id;
|
|
76
77
|
}
|
|
78
|
+
function feedId(args) {
|
|
79
|
+
const id = optString(args, "feedId");
|
|
80
|
+
if (!id)
|
|
81
|
+
usage("feedId is required");
|
|
82
|
+
return id;
|
|
83
|
+
}
|
|
77
84
|
function galleryReference(args) {
|
|
78
85
|
const provider = optString(args, "provider");
|
|
79
86
|
const coordinate = optString(args, "coordinate");
|
|
@@ -85,6 +92,33 @@ function galleryReference(args) {
|
|
|
85
92
|
usage("provider must be github");
|
|
86
93
|
return { provider, coordinate };
|
|
87
94
|
}
|
|
95
|
+
function feedCreateOptions(args) {
|
|
96
|
+
const github = optString(args, "github");
|
|
97
|
+
const repo = optString(args, "repo");
|
|
98
|
+
const path = optString(args, "path");
|
|
99
|
+
const pr = optPosInt(args, "pr");
|
|
100
|
+
const issue = optPosInt(args, "issue");
|
|
101
|
+
if (pr != null && issue != null)
|
|
102
|
+
usage("pr and issue are mutually exclusive");
|
|
103
|
+
if (github && (pr != null || issue != null))
|
|
104
|
+
usage("github cannot be combined with pr or issue");
|
|
105
|
+
if (github) {
|
|
106
|
+
const ref = parseGithubIssueRef(github);
|
|
107
|
+
if (!ref)
|
|
108
|
+
usage("github must be owner/repo#number or a GitHub issue/PR URL");
|
|
109
|
+
if (repo && repo.trim().toLowerCase() !== ref.repo)
|
|
110
|
+
usage("repo does not match github");
|
|
111
|
+
return { repo: ref.repo, path, number: ref.number, kind: ref.kind };
|
|
112
|
+
}
|
|
113
|
+
if (!repo)
|
|
114
|
+
usage("repo is required");
|
|
115
|
+
return {
|
|
116
|
+
repo,
|
|
117
|
+
path,
|
|
118
|
+
...(pr != null ? { number: pr, kind: "pull" } : {}),
|
|
119
|
+
...(issue != null ? { number: issue, kind: "issue" } : {}),
|
|
120
|
+
};
|
|
121
|
+
}
|
|
88
122
|
const workspaceProp = {
|
|
89
123
|
type: "string",
|
|
90
124
|
description: "Override the workspace for this call (like the CLI's --workspace flag).",
|
|
@@ -288,6 +322,66 @@ export function createUploadsMcpTools(opts) {
|
|
|
288
322
|
});
|
|
289
323
|
},
|
|
290
324
|
},
|
|
325
|
+
{
|
|
326
|
+
name: "feed_create",
|
|
327
|
+
title: "Create change feed",
|
|
328
|
+
annotations: mcpWritePublic,
|
|
329
|
+
securitySchemes: mcpOAuthWrite,
|
|
330
|
+
description: "Create a public newest-first screenshot feed (same product as CLI `uploads feed create`). Pass `repo` alone for the whole GitHub repo. Pass `pr` plus `repo` — or `github` as owner/repo#123 / a GitHub PR URL — to scope that same feed to one pull request. `issue` does the same for an issue. Optional `path` filters by page-path metadata. Creating the same scope again returns the existing URL. This is a live query, not a curated gallery. Anyone who knows the URL can view it.",
|
|
331
|
+
inputSchema: {
|
|
332
|
+
type: "object",
|
|
333
|
+
properties: {
|
|
334
|
+
repo: {
|
|
335
|
+
type: "string",
|
|
336
|
+
description: "GitHub owner/repo, for example acme/app. Required unless github is set.",
|
|
337
|
+
},
|
|
338
|
+
pr: {
|
|
339
|
+
type: "integer",
|
|
340
|
+
minimum: 1,
|
|
341
|
+
description: "Scope the feed to this pull request. Same product as a repo feed — one extra filter. Mutually exclusive with issue and github.",
|
|
342
|
+
},
|
|
343
|
+
issue: {
|
|
344
|
+
type: "integer",
|
|
345
|
+
minimum: 1,
|
|
346
|
+
description: "Scope the feed to this issue. Mutually exclusive with pr and github.",
|
|
347
|
+
},
|
|
348
|
+
github: {
|
|
349
|
+
type: "string",
|
|
350
|
+
description: "Scope via owner/repo#number or a GitHub issue/PR URL. Supplies repo when omitted. Mutually exclusive with pr and issue.",
|
|
351
|
+
},
|
|
352
|
+
path: {
|
|
353
|
+
type: "string",
|
|
354
|
+
description: "Optional exact page-path metadata filter, for example /settings.",
|
|
355
|
+
},
|
|
356
|
+
workspace: workspaceProp,
|
|
357
|
+
},
|
|
358
|
+
additionalProperties: false,
|
|
359
|
+
},
|
|
360
|
+
async handler(args) {
|
|
361
|
+
const { client } = await clientFor(args);
|
|
362
|
+
return client.createFeed(feedCreateOptions(args));
|
|
363
|
+
},
|
|
364
|
+
},
|
|
365
|
+
{
|
|
366
|
+
name: "feed_get",
|
|
367
|
+
title: "Get change feed",
|
|
368
|
+
annotations: mcpRead,
|
|
369
|
+
securitySchemes: mcpOAuthRead,
|
|
370
|
+
description: "Get a workspace-owned change feed by ID, including its current newest-first screenshots and the canonical public /c/<id> URL. Each item includes pageUrl (`/c/<id>/<item>`) for the pager. The feed may be repo-wide or scoped to one pull request / issue (see `number` and `kind` on the result). Anyone with the URL can view the media.",
|
|
371
|
+
inputSchema: {
|
|
372
|
+
type: "object",
|
|
373
|
+
properties: {
|
|
374
|
+
feedId: { type: "string", description: "Opaque feed ID." },
|
|
375
|
+
workspace: workspaceProp,
|
|
376
|
+
},
|
|
377
|
+
required: ["feedId"],
|
|
378
|
+
additionalProperties: false,
|
|
379
|
+
},
|
|
380
|
+
async handler(args) {
|
|
381
|
+
const { client } = await clientFor(args);
|
|
382
|
+
return client.getFeed(feedId(args));
|
|
383
|
+
},
|
|
384
|
+
},
|
|
291
385
|
{
|
|
292
386
|
name: "put",
|
|
293
387
|
title: "Upload file",
|
|
@@ -1553,6 +1647,19 @@ export function createUploadsMcpTools(opts) {
|
|
|
1553
1647
|
return { ...target, ...result };
|
|
1554
1648
|
},
|
|
1555
1649
|
},
|
|
1650
|
+
{
|
|
1651
|
+
name: "search_docs",
|
|
1652
|
+
title: "Search uploads.sh docs",
|
|
1653
|
+
annotations: {
|
|
1654
|
+
readOnlyHint: true,
|
|
1655
|
+
destructiveHint: false,
|
|
1656
|
+
openWorldHint: true,
|
|
1657
|
+
},
|
|
1658
|
+
securitySchemes: mcpNoAuth,
|
|
1659
|
+
description: SEARCH_DOCS_DESCRIPTION,
|
|
1660
|
+
inputSchema: SEARCH_DOCS_INPUT_SCHEMA,
|
|
1661
|
+
handler: runSearchDocsTool,
|
|
1662
|
+
},
|
|
1556
1663
|
{
|
|
1557
1664
|
name: "changelog",
|
|
1558
1665
|
title: "Product changelog",
|