@buildinternet/uploads 0.11.0 → 0.11.1
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 +2 -2
- package/dist/async.d.ts +5 -0
- package/dist/async.js +21 -0
- package/dist/cli-catalog.js +1 -1
- package/dist/commands/install.js +5 -0
- package/dist/commands.d.ts +91 -1
- package/dist/commands.js +350 -139
- package/dist/mcp/batch-error.d.ts +16 -0
- package/dist/mcp/batch-error.js +24 -0
- package/dist/mcp/server.d.ts +1 -0
- package/dist/mcp/server.js +16 -0
- package/dist/mcp/tools.d.ts +1 -1
- package/dist/mcp/tools.js +170 -94
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -128,7 +128,7 @@ Config layers (first match wins): CLI flags → env vars → `--env-file` → `~
|
|
|
128
128
|
|
|
129
129
|
## MCP server
|
|
130
130
|
|
|
131
|
-
`uploads mcp` serves the Model Context Protocol over stdio (newline-delimited JSON-RPC, no extra dependencies). Tools include file operations plus public gallery workflows: `gallery_create`, `gallery_get`, `gallery_add`, `gallery_link`, and `gallery_find_by_reference`. Gallery tools return API-provided canonical URLs and never need GitHub credentials. The remaining stdio tools are `put`, `attach`, `list`, `delete`, `set_metadata`, `find_files`, `usage`, `reconcile`, `purge_expired`, `comment`, `health`, and `doctor` — with the same config resolution and defaults, plus a per-call `workspace` argument. `put` and `attach` accept a `metadata` param (same `gh.*` auto-injection as the CLI's `attach`); `set_metadata
|
|
131
|
+
`uploads mcp` serves the Model Context Protocol over stdio (newline-delimited JSON-RPC, no extra dependencies). Tools include file operations plus public gallery workflows: `gallery_create`, `gallery_get`, `gallery_add`, `gallery_link`, and `gallery_find_by_reference`. Gallery tools return API-provided canonical URLs and never need GitHub credentials. The remaining stdio tools are `put`, `attach`, `list`, `delete`, `get_metadata`, `set_metadata`, `find_files`, `usage`, `reconcile`, `purge_expired`, `comment`, `health`, and `doctor` — with the same config resolution and defaults, plus a per-call `workspace` argument. `put` and `attach` accept a `metadata` param (same `gh.*` auto-injection as the CLI's `attach`); `get_metadata`, `set_metadata`, and `find_files` mirror `uploads meta get` / `meta set` / `find`. Interactive/credential commands (`setup`, `login`, `admin`, `config`) are not exposed. A token isn't required to start the server; auth errors surface per tool call (`health` needs no auth).
|
|
132
132
|
|
|
133
133
|
```json
|
|
134
134
|
{ "command": "uploads", "args": ["--env-file", "/path/to/.env", "mcp"] }
|
|
@@ -136,7 +136,7 @@ Config layers (first match wins): CLI flags → env vars → `--env-file` → `~
|
|
|
136
136
|
|
|
137
137
|
Or with `UPLOADS_TOKEN`/`UPLOADS_WORKSPACE` in the environment or user config. Claude Code: `claude mcp add uploads -- uploads --env-file /path/to/.env mcp`.
|
|
138
138
|
|
|
139
|
-
For HTTP clients there's also a hosted variant at `https://agents.uploads.sh/mcp` — the workspace is inferred from the bearer token, so only the URL and token are needed (`https://agents.uploads.sh/<workspace>/mcp` and the `mcp.uploads.sh` hostname also work). Tools: file operations plus `gallery_create`, `gallery_get`, `gallery_add`, `gallery_link`, and `gallery_find_by_reference`; all use the same bearer-token workspace scopes and gallery URLs come from the API — see `apps/mcp` in the repo. The hosted `put` also accepts a `metadata` param. `uploads install` registers the skills + hosted MCP (short progress; `--verbose` for underlying output). Its `put` takes no content type: the stored type is sniffed server-side from the bytes and checked against the workspace allowlist, and writes are rate limited per workspace.
|
|
139
|
+
For HTTP clients there's also a hosted variant at `https://agents.uploads.sh/mcp` — the workspace is inferred from the bearer token, so only the URL and token are needed (`https://agents.uploads.sh/<workspace>/mcp` and the `mcp.uploads.sh` hostname also work). Tools: file operations (including `get_metadata` / `set_metadata` / `find_files`) plus `gallery_create`, `gallery_get`, `gallery_add`, `gallery_link`, and `gallery_find_by_reference`; all use the same bearer-token workspace scopes and gallery URLs come from the API — see `apps/mcp` in the repo. The hosted `put` also accepts a `metadata` param. `uploads install` registers the skills + hosted MCP (short progress; `--verbose` for underlying output). Its `put` takes no content type: the stored type is sniffed server-side from the bytes and checked against the workspace allowlist, and writes are rate limited per workspace.
|
|
140
140
|
|
|
141
141
|
## Programmatic use
|
|
142
142
|
|
package/dist/async.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Run `fn` over `values` with bounded concurrency, preserving input order
|
|
3
|
+
* in the returned array. Used by multi-file attach (and similar fan-outs).
|
|
4
|
+
*/
|
|
5
|
+
export declare function mapBounded<T, R>(values: readonly T[], concurrency: number, fn: (value: T, index: number) => Promise<R>): Promise<R[]>;
|
package/dist/async.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Run `fn` over `values` with bounded concurrency, preserving input order
|
|
3
|
+
* in the returned array. Used by multi-file attach (and similar fan-outs).
|
|
4
|
+
*/
|
|
5
|
+
export async function mapBounded(values, concurrency, fn) {
|
|
6
|
+
if (values.length === 0)
|
|
7
|
+
return [];
|
|
8
|
+
const limit = Math.max(1, Math.min(concurrency, values.length));
|
|
9
|
+
const result = Array.from({ length: values.length });
|
|
10
|
+
let next = 0;
|
|
11
|
+
async function worker() {
|
|
12
|
+
for (;;) {
|
|
13
|
+
const index = next++;
|
|
14
|
+
if (index >= values.length)
|
|
15
|
+
return;
|
|
16
|
+
result[index] = await fn(values[index], index);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
await Promise.all(Array.from({ length: limit }, worker));
|
|
20
|
+
return result;
|
|
21
|
+
}
|
package/dist/cli-catalog.js
CHANGED
package/dist/commands/install.js
CHANGED
|
@@ -189,6 +189,7 @@ export async function runInstall(args, opts, help = false) {
|
|
|
189
189
|
.filter(([step]) => step.startsWith("skill:"))
|
|
190
190
|
.map(([, r]) => r);
|
|
191
191
|
const skillsOk = skillResults.length > 0 && skillResults.every((r) => r.ok);
|
|
192
|
+
const skillsFailed = skillResults.some((r) => !r.ok);
|
|
192
193
|
if (!failed && !dryRun) {
|
|
193
194
|
const stepLabels = [
|
|
194
195
|
...new Set(Object.keys(results).map((k) => (k.startsWith("skill:") ? "skills" : k))),
|
|
@@ -201,5 +202,9 @@ export async function runInstall(args, opts, help = false) {
|
|
|
201
202
|
: "Fix the MCP step above, then re-run `uploads install mcp`.";
|
|
202
203
|
process.stdout.write(`\nSkills are installed. ${next}\n`);
|
|
203
204
|
}
|
|
205
|
+
else if (failed && !dryRun && skillsFailed) {
|
|
206
|
+
// Mixed or total skill failure used to print only per-step lines (#191).
|
|
207
|
+
process.stdout.write("\nSkill install incomplete. Fix the errors above, then re-run `uploads install skill`.\n");
|
|
208
|
+
}
|
|
204
209
|
return failed ? 1 : 0;
|
|
205
210
|
}
|
package/dist/commands.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type UploadsClient } from "./client.js";
|
|
1
|
+
import { type PutResult, type UploadsClient } from "./client.js";
|
|
2
2
|
import { type CommandFlags } from "./cli-args.js";
|
|
3
3
|
import { type ResolvedConfig } from "./config.js";
|
|
4
4
|
import { type GhTarget } from "./github.js";
|
|
@@ -6,6 +6,10 @@ import { type CommandRunner } from "./github-gh.js";
|
|
|
6
6
|
import { type OptimizeImageOptions, type OptimizeImageResult } from "./optimize.js";
|
|
7
7
|
import { type FrameResult } from "./frame.js";
|
|
8
8
|
import type { PutDefaults } from "./config-file.js";
|
|
9
|
+
/** Parallel fan-out for multi-file put/attach (matches files-sdk bulk default). */
|
|
10
|
+
export declare const UPLOAD_BATCH_CONCURRENCY = 8;
|
|
11
|
+
/** @deprecated Use UPLOAD_BATCH_CONCURRENCY. */
|
|
12
|
+
export declare const ATTACH_CONCURRENCY = 8;
|
|
9
13
|
export { formatUsageHuman } from "./format-usage.js";
|
|
10
14
|
export interface CliContext {
|
|
11
15
|
config: ResolvedConfig;
|
|
@@ -42,6 +46,92 @@ export declare function syncAttachmentsComment(client: UploadsClient, target: Gh
|
|
|
42
46
|
action: "created" | "updated" | "skipped";
|
|
43
47
|
count: number;
|
|
44
48
|
}>;
|
|
49
|
+
export type AttachUploadItem = PutResult & {
|
|
50
|
+
file: string;
|
|
51
|
+
markdown: string;
|
|
52
|
+
optimize: {
|
|
53
|
+
optimized: boolean;
|
|
54
|
+
skippedReason?: OptimizeImageResult["skippedReason"];
|
|
55
|
+
originalBytes: number;
|
|
56
|
+
outputBytes: number;
|
|
57
|
+
filename: string;
|
|
58
|
+
};
|
|
59
|
+
frame?: PreparedUpload["frame"];
|
|
60
|
+
};
|
|
61
|
+
export type AttachFailure = {
|
|
62
|
+
file: string;
|
|
63
|
+
error: {
|
|
64
|
+
message: string;
|
|
65
|
+
code?: string;
|
|
66
|
+
status?: number;
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* Prepare + put each path as a PR/issue attachment with bounded concurrency.
|
|
71
|
+
* Per-file errors collect in `failures` (does not throw). `firstError` is the
|
|
72
|
+
* original cause of the first failure — for rethrowing single-file CLI paths.
|
|
73
|
+
*/
|
|
74
|
+
export declare function uploadAttachments(opts: {
|
|
75
|
+
client: UploadsClient;
|
|
76
|
+
target: GhTarget;
|
|
77
|
+
files: readonly string[];
|
|
78
|
+
contentType?: string;
|
|
79
|
+
optimize: OptimizeImageOptions;
|
|
80
|
+
frame: {
|
|
81
|
+
frameId?: string;
|
|
82
|
+
frameUrl?: string;
|
|
83
|
+
frameFit?: "cover" | "contain";
|
|
84
|
+
};
|
|
85
|
+
metadata?: Record<string, string>;
|
|
86
|
+
/** Provenance `client` field (default uploads-cli). */
|
|
87
|
+
provenanceClient?: string;
|
|
88
|
+
concurrency?: number;
|
|
89
|
+
}): Promise<{
|
|
90
|
+
uploads: AttachUploadItem[];
|
|
91
|
+
failures: AttachFailure[];
|
|
92
|
+
firstError?: unknown;
|
|
93
|
+
}>;
|
|
94
|
+
export type PutUploadItem = PutResult & {
|
|
95
|
+
file: string;
|
|
96
|
+
markdown: string;
|
|
97
|
+
optimize: AttachUploadItem["optimize"];
|
|
98
|
+
frame?: PreparedUpload["frame"];
|
|
99
|
+
};
|
|
100
|
+
/**
|
|
101
|
+
* Prepare + put each path with put-style key resolution and bounded concurrency.
|
|
102
|
+
* Same partial-failure shape as uploadAttachments.
|
|
103
|
+
*/
|
|
104
|
+
export declare function uploadPuts(opts: {
|
|
105
|
+
client: UploadsClient;
|
|
106
|
+
files: readonly string[];
|
|
107
|
+
/** Single-file --name leaf override. */
|
|
108
|
+
nameOverride?: string;
|
|
109
|
+
/** Single-file --key. */
|
|
110
|
+
explicitKey?: string;
|
|
111
|
+
ghTarget?: GhTarget;
|
|
112
|
+
prefix?: string;
|
|
113
|
+
repo?: string;
|
|
114
|
+
ref?: string;
|
|
115
|
+
deriveRepoFromGit?: boolean;
|
|
116
|
+
contentType?: string;
|
|
117
|
+
dryRun?: boolean;
|
|
118
|
+
optimize: OptimizeImageOptions;
|
|
119
|
+
frame: {
|
|
120
|
+
frameId?: string;
|
|
121
|
+
frameUrl?: string;
|
|
122
|
+
frameFit?: "cover" | "contain";
|
|
123
|
+
};
|
|
124
|
+
metadata?: Record<string, string>;
|
|
125
|
+
provenanceClient?: string;
|
|
126
|
+
/** When set, used as alt for every file; else each file's basename. */
|
|
127
|
+
alt?: string;
|
|
128
|
+
width?: number;
|
|
129
|
+
concurrency?: number;
|
|
130
|
+
}): Promise<{
|
|
131
|
+
uploads: PutUploadItem[];
|
|
132
|
+
failures: AttachFailure[];
|
|
133
|
+
firstError?: unknown;
|
|
134
|
+
}>;
|
|
45
135
|
export declare function runAttach(ctx: CliContext, args: string[], help?: boolean, run?: CommandRunner): Promise<number>;
|
|
46
136
|
export declare function runPut(ctx: CliContext, args: string[], help?: boolean, run?: CommandRunner): Promise<number>;
|
|
47
137
|
export declare function runGallery(ctx: CliContext, args: string[], help?: boolean): Promise<number>;
|