@4ort/cli 0.4.0 → 0.6.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.
Files changed (85) hide show
  1. package/README.md +286 -0
  2. package/dist/commands/kg/agent-context.d.ts +3 -0
  3. package/dist/commands/kg/agent-context.js +54 -0
  4. package/dist/commands/kg/agent-context.js.map +1 -0
  5. package/dist/commands/kg/article-context.d.ts +3 -0
  6. package/dist/commands/kg/article-context.js +51 -0
  7. package/dist/commands/kg/article-context.js.map +1 -0
  8. package/dist/commands/kg/ask.d.ts +5 -0
  9. package/dist/commands/kg/ask.js +121 -0
  10. package/dist/commands/kg/ask.js.map +1 -0
  11. package/dist/commands/kg/auth.d.ts +9 -0
  12. package/dist/commands/kg/auth.js +95 -0
  13. package/dist/commands/kg/auth.js.map +1 -0
  14. package/dist/commands/kg/entity.d.ts +4 -0
  15. package/dist/commands/kg/entity.js +33 -0
  16. package/dist/commands/kg/entity.js.map +1 -0
  17. package/dist/commands/kg/match.d.ts +5 -0
  18. package/dist/commands/kg/match.js +44 -0
  19. package/dist/commands/kg/match.js.map +1 -0
  20. package/dist/commands/kg/popularity.d.ts +3 -0
  21. package/dist/commands/kg/popularity.js +42 -0
  22. package/dist/commands/kg/popularity.js.map +1 -0
  23. package/dist/commands/kg/search.d.ts +4 -0
  24. package/dist/commands/kg/search.js +34 -0
  25. package/dist/commands/kg/search.js.map +1 -0
  26. package/dist/commands/kg/trending.d.ts +6 -0
  27. package/dist/commands/kg/trending.js +35 -0
  28. package/dist/commands/kg/trending.js.map +1 -0
  29. package/dist/commands/mcp.d.ts +5 -0
  30. package/dist/commands/mcp.js +24 -0
  31. package/dist/commands/mcp.js.map +1 -0
  32. package/dist/commands/mov.d.ts +17 -0
  33. package/dist/commands/mov.js +124 -0
  34. package/dist/commands/mov.js.map +1 -0
  35. package/dist/commands/run.d.ts +10 -0
  36. package/dist/commands/run.js +74 -0
  37. package/dist/commands/run.js.map +1 -0
  38. package/dist/commands/search.d.ts +7 -0
  39. package/dist/commands/search.js +105 -0
  40. package/dist/commands/search.js.map +1 -0
  41. package/dist/commands/vault.d.ts +7 -0
  42. package/dist/commands/vault.js +62 -0
  43. package/dist/commands/vault.js.map +1 -0
  44. package/dist/commands/web.d.ts +6 -0
  45. package/dist/commands/web.js +44 -0
  46. package/dist/commands/web.js.map +1 -0
  47. package/dist/config.d.ts +38 -0
  48. package/dist/config.js +97 -1
  49. package/dist/config.js.map +1 -1
  50. package/dist/config.mov.test.d.ts +1 -0
  51. package/dist/config.mov.test.js +23 -0
  52. package/dist/config.mov.test.js.map +1 -0
  53. package/dist/index.js +195 -37
  54. package/dist/index.js.map +1 -1
  55. package/dist/kg-client.d.ts +42 -0
  56. package/dist/kg-client.js +125 -0
  57. package/dist/kg-client.js.map +1 -0
  58. package/dist/kg-output.d.ts +33 -0
  59. package/dist/kg-output.js +132 -0
  60. package/dist/kg-output.js.map +1 -0
  61. package/dist/mcp-server.d.ts +5 -0
  62. package/dist/mcp-server.js +363 -0
  63. package/dist/mcp-server.js.map +1 -0
  64. package/dist/peertube-client.d.ts +47 -0
  65. package/dist/peertube-client.js +144 -0
  66. package/dist/peertube-client.js.map +1 -0
  67. package/dist/peertube-client.test.d.ts +1 -0
  68. package/dist/peertube-client.test.js +92 -0
  69. package/dist/peertube-client.test.js.map +1 -0
  70. package/dist/web-client.d.ts +20 -0
  71. package/dist/web-client.js +335 -0
  72. package/dist/web-client.js.map +1 -0
  73. package/package.json +21 -4
  74. package/src/api-client.ts +0 -51
  75. package/src/commands/delete.ts +0 -15
  76. package/src/commands/list.ts +0 -25
  77. package/src/commands/mail.ts +0 -79
  78. package/src/commands/provision.ts +0 -106
  79. package/src/commands/push.ts +0 -63
  80. package/src/commands/recover.ts +0 -37
  81. package/src/commands/register.ts +0 -40
  82. package/src/commands/whoami.ts +0 -20
  83. package/src/config.ts +0 -40
  84. package/src/index.ts +0 -114
  85. package/tsconfig.json +0 -8
@@ -0,0 +1,363 @@
1
+ /**
2
+ * `4ort mcp` — the 4ort MCP server. Two transports, one set of tools:
3
+ * • `4ort mcp` (stdio) — for Claude Desktop / local clients that spawn it
4
+ * • `4ort mcp serve` (HTTP) — Streamable HTTP, deploy behind a reverse proxy
5
+ * → mcp.4ort.xyz (public)
6
+ *
7
+ * Tools wrap the same logic the CLI commands use (smart-router search, the web
8
+ * reader, KG entity/match/agent-context) — they call kgRequest / webRead
9
+ * directly (NOT the CLI command wrappers, which print to stdout and exit).
10
+ */
11
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
12
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
13
+ import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
14
+ import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
15
+ import { createServer } from "node:http";
16
+ import { optionalKgConfig } from "./config.js";
17
+ import { kgRequest } from "./kg-client.js";
18
+ import { webRead } from "./web-client.js";
19
+ const VERSION = "0.5.0-dev";
20
+ const TOOLS = [
21
+ {
22
+ name: "kg_search",
23
+ description: "Smart router / front door. Given a query, returns: the canonical 4ort.xyz knowledge-graph entity it names (if any) plus that entity's official site & verified social links; a curated 'phonebook' of authoritative-source search URLs for the detected vertical (Wikipedia, TMDB, OpenAlex, SEC EDGAR, GitHub, MusicBrainz, …) that you then fetch with web_get; and ranked hits from our Common Crawl web index. Use this FIRST to decide where to look next. No auth required.",
24
+ inputSchema: {
25
+ type: "object",
26
+ properties: {
27
+ query: { type: "string", description: "The search query." },
28
+ limit_pages: { type: "integer", description: "Max web-index hits (default 15)." },
29
+ limit_sources: { type: "integer", description: "Max phonebook routes (default 12)." },
30
+ },
31
+ required: ["query"],
32
+ },
33
+ },
34
+ {
35
+ name: "web_get",
36
+ description: "Fetch a URL and return its readable text (Reader-Mode extraction — no browser, no JS). If the URL is a 4ort.xyz entity page, returns the structured entity instead of scraping. On a bot wall / 403 / paywall / PDF / binary body it returns ok:false WITH the URL so you can fall back. Use this to read phonebook routes from kg_search, web-index hits, or any arbitrary page.",
37
+ inputSchema: {
38
+ type: "object",
39
+ properties: {
40
+ url: { type: "string", description: "Absolute http(s) URL." },
41
+ max_chars: { type: "integer", description: "Cap on extracted text length (default 50000)." },
42
+ },
43
+ required: ["url"],
44
+ },
45
+ },
46
+ {
47
+ name: "kg_entity",
48
+ description: "Fetch one 4ort.xyz knowledge-graph entity by slug, UUID, or Wikidata Q-id. detail: tiny | small | medium | full (full includes facts, relationships/connections, citations). Use this to 'walk the graph' once you have an entity (e.g. from kg_search). Requires a 4ort.xyz API key on the server.",
49
+ inputSchema: {
50
+ type: "object",
51
+ properties: {
52
+ key: { type: "string", description: "Entity slug, UUID, or Q-id." },
53
+ detail: { type: "string", enum: ["tiny", "small", "medium", "full"], description: "Default: medium." },
54
+ },
55
+ required: ["key"],
56
+ },
57
+ },
58
+ {
59
+ name: "kg_match",
60
+ description: "Resolve a free-text string to its canonical 4ort.xyz knowledge-graph entity (entity linking / disambiguation). Returns ranked candidates with slug, type, and confidence. Requires a 4ort.xyz API key on the server.",
61
+ inputSchema: {
62
+ type: "object",
63
+ properties: {
64
+ text: { type: "string", description: "The string to resolve." },
65
+ limit: { type: "integer", description: "Max candidates (default 5)." },
66
+ entity_types: { type: "string", description: "Optional comma-separated entity-type filter." },
67
+ },
68
+ required: ["text"],
69
+ },
70
+ },
71
+ {
72
+ name: "kg_agent_context",
73
+ description: "Memory-bank bundle for an autonomous agent about one entity: short + long summaries, facts grouped by predicate, key connected actors, world context (country / domain rank / monthly views). Requires a 4ort.xyz API key on the server.",
74
+ inputSchema: {
75
+ type: "object",
76
+ properties: { key: { type: "string", description: "Entity slug, UUID, or Q-id." } },
77
+ required: ["key"],
78
+ },
79
+ },
80
+ {
81
+ name: "kg_article_context",
82
+ description: "Fat bundle of facts + writing hooks for an SEO writer about one entity: full entity card PLUS deduplicated citations across all facts, last-7-day Wikidata edit narrative, popularity signals, top connections, and 3-5 LLM-synthesized writing hooks ('recently controversial because X' / 'top-3 in domain Y'). Use this when you're about to draft an article. Requires a 4ort.xyz API key on the server.",
83
+ inputSchema: {
84
+ type: "object",
85
+ properties: { key: { type: "string", description: "Entity slug, UUID, or Q-id." } },
86
+ required: ["key"],
87
+ },
88
+ },
89
+ {
90
+ name: "kg_popularity",
91
+ description: "Real-world popularity score for an entity, derived from measured Wikipedia pageviews — a free CC0 alternative to Google Keyword Planner / Ahrefs / SEMrush. Returns current monthly volume, 12-month trend, 30-day daily breakdown, year-over-year change, country mix, and rank within the entity's domain. Requires a 4ort.xyz API key on the server.",
92
+ inputSchema: {
93
+ type: "object",
94
+ properties: { key: { type: "string", description: "Entity slug, UUID, or Q-id." } },
95
+ required: ["key"],
96
+ },
97
+ },
98
+ {
99
+ name: "kg_trending",
100
+ description: "What's trending RIGHT NOW on Wikipedia — live attention signal from hourly pageview deltas. Use to answer 'what's hot' / 'what are people reading about' / 'news today' type questions. Updated continuously. Requires a 4ort.xyz API key on the server.",
101
+ inputSchema: {
102
+ type: "object",
103
+ properties: {
104
+ period: { type: "string", enum: ["hour", "day", "week"], description: "Trend window. Default: day." },
105
+ country: { type: "string", description: "ISO 3166 alpha-2 (e.g. 'US', 'DE', 'JP') to filter to one country. Omit for global." },
106
+ category: { type: "string", description: "Filter to one harvest_domain (e.g. 'people', 'companies', 'software'). Omit for all." },
107
+ rank_by: { type: "string", enum: ["views", "velocity", "novelty", "weird"], description: "views=raw (default), velocity=% increase vs baseline, novelty=new-to-trending, weird=chronically-popular entities (TLDs, country pages)." },
108
+ limit: { type: "integer", description: "Max entities (1-100, default 20)." },
109
+ },
110
+ },
111
+ },
112
+ {
113
+ name: "deep_research",
114
+ description: "Kick off a DEEP, multi-step research job — an autonomous multi-agent run that searches, reads 10+ sources, and synthesizes a cited markdown briefing. ASYNC + long-running (several minutes): returns a job_id IMMEDIATELY, then poll deep_research_result until status is 'done'. Use for open-ended 'research X and write me a sourced report' tasks — NOT quick lookups (use kg_search for those). Gated: requires an authorized bearer token.",
115
+ inputSchema: {
116
+ type: "object",
117
+ properties: {
118
+ query: { type: "string", description: "The research question / brief." },
119
+ depth: { type: "string", enum: ["quick", "standard", "deep"], description: "Effort level. Default: standard." },
120
+ },
121
+ required: ["query"],
122
+ },
123
+ },
124
+ {
125
+ name: "deep_research_result",
126
+ description: "Poll a deep_research job by its job_id. Returns { status: queued | running | done | error, progress, report (clean markdown, when done), citations, sources_read }. Call repeatedly (a few seconds apart) until status is 'done' or 'error'. Gated: requires an authorized bearer token.",
127
+ inputSchema: {
128
+ type: "object",
129
+ properties: { job_id: { type: "string", description: "The job_id returned by deep_research." } },
130
+ required: ["job_id"],
131
+ },
132
+ },
133
+ // kg_qa removed 2026-05-17 — the backing /api/v1/qa endpoint was
134
+ // deprecated. Live LLM synthesis didn't belong in the API request path.
135
+ // To revive: re-enable the qa.router in app/main.py first.
136
+ ];
137
+ // Expensive/abusable tools gated at the HTTP transport (see runMcpHttp). The
138
+ // cheap read tools stay open for discovery; these burn tokens + minutes of
139
+ // compute per call, so they require a bearer token from DEEP_RESEARCH_KEYS.
140
+ const GATED_TOOLS = new Set(["deep_research", "deep_research_result"]);
141
+ function ok(data) {
142
+ return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
143
+ }
144
+ function fail(message) {
145
+ return { content: [{ type: "text", text: JSON.stringify({ error: message }) }], isError: true };
146
+ }
147
+ /** Build a fresh MCP Server with the tool handlers wired. */
148
+ function buildServer() {
149
+ const server = new Server({ name: "4ort", version: VERSION }, { capabilities: { tools: {} } });
150
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: TOOLS }));
151
+ server.setRequestHandler(CallToolRequestSchema, async (req) => {
152
+ const name = req.params.name;
153
+ const args = (req.params.arguments ?? {});
154
+ try {
155
+ switch (name) {
156
+ case "kg_search": {
157
+ const data = await kgRequest(optionalKgConfig(), "/api/v1/route", {
158
+ query: {
159
+ q: String(args.query ?? ""),
160
+ limit_pages: typeof args.limit_pages === "number" ? args.limit_pages : 15,
161
+ limit_sources: typeof args.limit_sources === "number" ? args.limit_sources : 12,
162
+ },
163
+ });
164
+ return ok(data);
165
+ }
166
+ case "web_get": {
167
+ const url = String(args.url ?? "");
168
+ if (!url)
169
+ return fail("url is required");
170
+ const r = await webRead(url, { maxChars: typeof args.max_chars === "number" ? args.max_chars : undefined });
171
+ return ok(r);
172
+ }
173
+ case "kg_entity": {
174
+ const key = String(args.key ?? "");
175
+ if (!key)
176
+ return fail("key is required");
177
+ const data = await kgRequest(optionalKgConfig(), `/api/v1/entities/${encodeURIComponent(key)}`, {
178
+ query: { detail: args.detail ?? "medium" },
179
+ });
180
+ return ok(data);
181
+ }
182
+ case "kg_match": {
183
+ const text = String(args.text ?? "");
184
+ if (!text)
185
+ return fail("text is required");
186
+ const entity_types = typeof args.entity_types === "string" && args.entity_types.trim()
187
+ ? args.entity_types.split(",").map((t) => t.trim()).filter(Boolean)
188
+ : undefined;
189
+ const data = await kgRequest(optionalKgConfig(), "/api/v1/match", {
190
+ method: "POST",
191
+ body: { text, entity_types, limit: typeof args.limit === "number" ? args.limit : 5 },
192
+ });
193
+ return ok(data);
194
+ }
195
+ case "kg_agent_context": {
196
+ const key = String(args.key ?? "");
197
+ if (!key)
198
+ return fail("key is required");
199
+ const data = await kgRequest(optionalKgConfig(), `/api/v1/entities/${encodeURIComponent(key)}/agent-context`);
200
+ return ok(data);
201
+ }
202
+ case "kg_article_context": {
203
+ const key = String(args.key ?? "");
204
+ if (!key)
205
+ return fail("key is required");
206
+ const data = await kgRequest(optionalKgConfig(), `/api/v1/entities/${encodeURIComponent(key)}/article-context`);
207
+ return ok(data);
208
+ }
209
+ case "kg_popularity": {
210
+ const key = String(args.key ?? "");
211
+ if (!key)
212
+ return fail("key is required");
213
+ const data = await kgRequest(optionalKgConfig(), `/api/v1/popularity/${encodeURIComponent(key)}`);
214
+ return ok(data);
215
+ }
216
+ case "kg_trending": {
217
+ const query = {};
218
+ if (typeof args.period === "string")
219
+ query.period = args.period;
220
+ if (typeof args.country === "string" && args.country)
221
+ query.country = args.country;
222
+ if (typeof args.category === "string" && args.category)
223
+ query.category = args.category;
224
+ if (typeof args.rank_by === "string")
225
+ query.rank_by = args.rank_by;
226
+ if (typeof args.limit === "number")
227
+ query.limit = args.limit;
228
+ const data = await kgRequest(optionalKgConfig(), "/api/v1/trending", { query });
229
+ return ok(data);
230
+ }
231
+ case "deep_research": {
232
+ const query = String(args.query ?? "");
233
+ if (!query)
234
+ return fail("query is required");
235
+ const data = await kgRequest(optionalKgConfig(), "/api/v1/research", {
236
+ method: "POST",
237
+ body: { query, depth: typeof args.depth === "string" ? args.depth : "standard" },
238
+ });
239
+ return ok(data);
240
+ }
241
+ case "deep_research_result": {
242
+ const job_id = String(args.job_id ?? "");
243
+ if (!job_id)
244
+ return fail("job_id is required");
245
+ const data = await kgRequest(optionalKgConfig(), `/api/v1/research/${encodeURIComponent(job_id)}`);
246
+ return ok(data);
247
+ }
248
+ // kg_qa case removed 2026-05-17 — see TOOLS array note above.
249
+ default:
250
+ return fail(`unknown tool: ${name}`);
251
+ }
252
+ }
253
+ catch (e) {
254
+ return fail(e?.message ?? String(e));
255
+ }
256
+ });
257
+ return server;
258
+ }
259
+ // ── stdio transport (local: Claude Desktop spawns the process) ──────────────
260
+ export async function runMcpStdio() {
261
+ const server = buildServer();
262
+ await server.connect(new StdioServerTransport());
263
+ // Stays alive on stdio until the client disconnects.
264
+ }
265
+ // ── Streamable HTTP transport (hosted: behind a reverse proxy → mcp.4ort.xyz) ─
266
+ const MAX_REQUEST_BYTES = 1_000_000;
267
+ function sendJson(res, status, body) {
268
+ res.writeHead(status, { "content-type": "application/json" });
269
+ res.end(JSON.stringify(body));
270
+ }
271
+ export async function runMcpHttp(opts) {
272
+ const httpServer = createServer(async (req, res) => {
273
+ try {
274
+ const u = new URL(req.url ?? "/", `http://${req.headers.host ?? "localhost"}`);
275
+ // health / discovery
276
+ if (req.method === "GET" && (u.pathname === "/" || u.pathname === "/health")) {
277
+ return sendJson(res, 200, {
278
+ ok: true,
279
+ service: "4ort-mcp",
280
+ version: VERSION,
281
+ transport: "streamable-http",
282
+ endpoint: "/mcp",
283
+ tools: TOOLS.map((t) => t.name),
284
+ });
285
+ }
286
+ if (u.pathname !== "/mcp") {
287
+ return sendJson(res, 404, { error: "not found — the MCP endpoint is POST /mcp" });
288
+ }
289
+ if (req.method !== "POST") {
290
+ // Stateless server: no long-lived GET/SSE stream to resume.
291
+ res.setHeader("allow", "POST");
292
+ return sendJson(res, 405, { error: "method not allowed — POST /mcp with a JSON-RPC body" });
293
+ }
294
+ // read + parse the JSON-RPC body (we manage the body so we can cap it)
295
+ const chunks = [];
296
+ let total = 0;
297
+ for await (const c of req) {
298
+ const buf = c;
299
+ total += buf.length;
300
+ if (total > MAX_REQUEST_BYTES)
301
+ return sendJson(res, 413, { error: "request too large" });
302
+ chunks.push(buf);
303
+ }
304
+ const raw = Buffer.concat(chunks).toString("utf8");
305
+ let body;
306
+ try {
307
+ body = raw ? JSON.parse(raw) : undefined;
308
+ }
309
+ catch {
310
+ return sendJson(res, 400, { error: "invalid JSON body" });
311
+ }
312
+ // Gate the expensive tools (deep_research*) at the transport — read tools
313
+ // stay open for discovery. These burn tokens + minutes of compute, so they
314
+ // require a bearer token from DEEP_RESEARCH_KEYS (comma-separated). Fail
315
+ // CLOSED: if no keys are configured, the gated tools are unusable.
316
+ const calls = Array.isArray(body) ? body : [body];
317
+ const wantsGated = calls.some((m) => m?.method === "tools/call" && GATED_TOOLS.has(m?.params?.name));
318
+ if (wantsGated) {
319
+ const allow = (process.env.DEEP_RESEARCH_KEYS ?? "")
320
+ .split(",").map((s) => s.trim()).filter(Boolean);
321
+ const token = (req.headers.authorization ?? "").replace(/^Bearer\s+/i, "").trim();
322
+ if (allow.length === 0 || !token || !allow.includes(token)) {
323
+ return sendJson(res, 401, { error: "deep_research requires an authorized bearer token" });
324
+ }
325
+ }
326
+ // Stateless: a fresh Server + transport per request. Sidesteps session
327
+ // management entirely (read tools are stateless; deep_research* only enqueue).
328
+ const server = buildServer();
329
+ const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: undefined });
330
+ res.on("close", () => {
331
+ try {
332
+ transport.close();
333
+ }
334
+ catch { /* ignore */ }
335
+ try {
336
+ server.close();
337
+ }
338
+ catch { /* ignore */ }
339
+ });
340
+ await server.connect(transport);
341
+ await transport.handleRequest(req, res, body);
342
+ }
343
+ catch (e) {
344
+ if (!res.headersSent) {
345
+ sendJson(res, 500, { error: e?.message ?? String(e) });
346
+ }
347
+ else {
348
+ try {
349
+ res.end();
350
+ }
351
+ catch { /* ignore */ }
352
+ }
353
+ }
354
+ });
355
+ await new Promise((resolve) => {
356
+ httpServer.listen(opts.port, opts.host, () => {
357
+ process.stderr.write(`4ort MCP (Streamable HTTP) listening on http://${opts.host}:${opts.port}/mcp — tools: ${TOOLS.map((t) => t.name).join(", ")}\n`);
358
+ resolve();
359
+ });
360
+ });
361
+ // Keep the process alive (the http server holds the event loop).
362
+ }
363
+ //# sourceMappingURL=mcp-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-server.js","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ import { MovConfig } from "./config.js";
2
+ export interface Channel {
3
+ id: number;
4
+ name: string;
5
+ displayName: string;
6
+ }
7
+ export interface OAuthClient {
8
+ clientId: string;
9
+ clientSecret: string;
10
+ }
11
+ export interface Tokens {
12
+ accessToken: string;
13
+ refreshToken: string;
14
+ }
15
+ export declare function privacyToEnum(name: string): number;
16
+ export declare function buildWatchUrl(server: string, shortUUID: string): string;
17
+ export declare function resolveChannelId(channels: Channel[], nameOrUndefined?: string): number;
18
+ export declare function getOAuthClient(server: string): Promise<OAuthClient>;
19
+ export declare function getToken(server: string, client: OAuthClient, username: string, password: string): Promise<Tokens>;
20
+ /** Authenticated JSON request with one transparent refresh-on-401 retry. */
21
+ export declare function ptRequest(cfg: MovConfig, path: string, opts?: {
22
+ method?: string;
23
+ body?: unknown;
24
+ }): Promise<any>;
25
+ export interface UploadOpts {
26
+ file: string;
27
+ name: string;
28
+ channelId: number;
29
+ privacy?: number;
30
+ description?: string;
31
+ nsfw?: boolean;
32
+ thumbnail?: string;
33
+ }
34
+ export declare function uploadVideo(cfg: MovConfig, o: UploadOpts): Promise<{
35
+ id: number;
36
+ uuid: string;
37
+ shortUUID: string;
38
+ }>;
39
+ export declare function listMyChannels(cfg: MovConfig): Promise<Channel[]>;
40
+ export declare function createChannel(cfg: MovConfig, name: string): Promise<number>;
41
+ export declare function listMyVideos(cfg: MovConfig): Promise<Array<{
42
+ id: number;
43
+ name: string;
44
+ shortUUID: string;
45
+ privacy: string;
46
+ }>>;
47
+ export declare function deleteVideo(cfg: MovConfig, id: number): Promise<void>;
@@ -0,0 +1,144 @@
1
+ /**
2
+ * Minimal PeerTube REST client for 4ort.mov.
3
+ *
4
+ * Auth is OAuth2 password grant:
5
+ * GET /api/v1/oauth-clients/local → { client_id, client_secret }
6
+ * POST /api/v1/users/token → { access_token, refresh_token }
7
+ * Uploads use the legacy multipart endpoint (POST /api/v1/videos/upload) — fine
8
+ * here because 4ort.mov is grey-cloud (no CF 100MB cap) + Caddy sets no body cap.
9
+ *
10
+ * Pure helpers (privacy/watch-url/channel) are split out so they're unit-tested
11
+ * without a network. Everything else talks to a real (or mock) PeerTube.
12
+ */
13
+ import fs from "node:fs";
14
+ import { basename } from "node:path";
15
+ import { saveMovConfig } from "./config.js";
16
+ const PRIVACY = { public: 1, unlisted: 2, private: 3, internal: 4 };
17
+ export function privacyToEnum(name) {
18
+ const v = PRIVACY[name];
19
+ if (!v)
20
+ throw new Error(`invalid privacy '${name}' (public|unlisted|private|internal)`);
21
+ return v;
22
+ }
23
+ export function buildWatchUrl(server, shortUUID) {
24
+ return `${server.replace(/\/$/, "")}/w/${shortUUID}`;
25
+ }
26
+ export function resolveChannelId(channels, nameOrUndefined) {
27
+ if (!channels.length)
28
+ throw new Error("account has no video channels");
29
+ if (!nameOrUndefined)
30
+ return channels[0].id;
31
+ const hit = channels.find((c) => c.name === nameOrUndefined || c.displayName === nameOrUndefined);
32
+ if (!hit)
33
+ throw new Error(`no channel named '${nameOrUndefined}' (have: ${channels.map((c) => c.name).join(", ")})`);
34
+ return hit.id;
35
+ }
36
+ function base(server) {
37
+ return server.replace(/\/$/, "");
38
+ }
39
+ async function asJson(res) {
40
+ const text = await res.text();
41
+ if (!res.ok)
42
+ throw new Error(`${res.status} ${res.statusText} — ${text.slice(0, 300)}`);
43
+ return text ? JSON.parse(text) : {};
44
+ }
45
+ export async function getOAuthClient(server) {
46
+ const j = await asJson(await fetch(`${base(server)}/api/v1/oauth-clients/local`));
47
+ return { clientId: j.client_id, clientSecret: j.client_secret };
48
+ }
49
+ export async function getToken(server, client, username, password) {
50
+ const body = new URLSearchParams({
51
+ client_id: client.clientId,
52
+ client_secret: client.clientSecret,
53
+ grant_type: "password",
54
+ username,
55
+ password,
56
+ });
57
+ const j = await asJson(await fetch(`${base(server)}/api/v1/users/token`, {
58
+ method: "POST",
59
+ headers: { "content-type": "application/x-www-form-urlencoded" },
60
+ body,
61
+ }));
62
+ return { accessToken: j.access_token, refreshToken: j.refresh_token };
63
+ }
64
+ async function refresh(cfg) {
65
+ const body = new URLSearchParams({
66
+ client_id: cfg.clientId,
67
+ client_secret: cfg.clientSecret,
68
+ grant_type: "refresh_token",
69
+ refresh_token: cfg.refreshToken,
70
+ });
71
+ const j = await asJson(await fetch(`${base(cfg.server)}/api/v1/users/token`, {
72
+ method: "POST",
73
+ headers: { "content-type": "application/x-www-form-urlencoded" },
74
+ body,
75
+ }));
76
+ const next = { ...cfg, accessToken: j.access_token, refreshToken: j.refresh_token };
77
+ saveMovConfig(next);
78
+ return next;
79
+ }
80
+ /** Authenticated JSON request with one transparent refresh-on-401 retry. */
81
+ export async function ptRequest(cfg, path, opts = {}) {
82
+ const call = (token) => fetch(`${base(cfg.server)}${path}`, {
83
+ method: opts.method ?? "GET",
84
+ headers: { authorization: `Bearer ${token}`, ...(opts.body ? { "content-type": "application/json" } : {}) },
85
+ body: opts.body ? JSON.stringify(opts.body) : undefined,
86
+ });
87
+ let res = await call(cfg.accessToken);
88
+ if (res.status === 401) {
89
+ const fresh = await refresh(cfg);
90
+ res = await call(fresh.accessToken);
91
+ }
92
+ return asJson(res);
93
+ }
94
+ const VIDEO_MIME = { ".mp4": "video/mp4", ".webm": "video/webm", ".ogv": "video/ogg" };
95
+ const IMAGE_MIME = { ".jpg": "image/jpeg", ".jpeg": "image/jpeg", ".png": "image/png" };
96
+ function mimeFor(file, table, fallback) {
97
+ const ext = file.slice(file.lastIndexOf(".")).toLowerCase();
98
+ return table[ext] ?? fallback;
99
+ }
100
+ export async function uploadVideo(cfg, o) {
101
+ const form = new FormData();
102
+ form.set("name", o.name);
103
+ form.set("channelId", String(o.channelId));
104
+ if (o.privacy)
105
+ form.set("privacy", String(o.privacy));
106
+ if (o.description)
107
+ form.set("description", o.description);
108
+ if (o.nsfw)
109
+ form.set("nsfw", "true");
110
+ const buf = await fs.promises.readFile(o.file);
111
+ form.set("videofile", new Blob([buf], { type: mimeFor(o.file, VIDEO_MIME, "video/mp4") }), basename(o.file));
112
+ if (o.thumbnail) {
113
+ const tb = await fs.promises.readFile(o.thumbnail);
114
+ form.set("thumbnailfile", new Blob([tb], { type: mimeFor(o.thumbnail, IMAGE_MIME, "image/jpeg") }), basename(o.thumbnail));
115
+ }
116
+ const send = (token) => fetch(`${base(cfg.server)}/api/v1/videos/upload`, {
117
+ method: "POST",
118
+ headers: { authorization: `Bearer ${token}` },
119
+ body: form,
120
+ });
121
+ let res = await send(cfg.accessToken);
122
+ if (res.status === 401) {
123
+ const fresh = await refresh(cfg);
124
+ res = await send(fresh.accessToken);
125
+ }
126
+ const j = await asJson(res);
127
+ return j.video;
128
+ }
129
+ export async function listMyChannels(cfg) {
130
+ const me = await ptRequest(cfg, "/api/v1/users/me");
131
+ return (me.videoChannels ?? []).map((c) => ({ id: c.id, name: c.name, displayName: c.displayName }));
132
+ }
133
+ export async function createChannel(cfg, name) {
134
+ const j = await ptRequest(cfg, "/api/v1/video-channels", { method: "POST", body: { name, displayName: name } });
135
+ return j.videoChannel.id;
136
+ }
137
+ export async function listMyVideos(cfg) {
138
+ const j = await ptRequest(cfg, "/api/v1/users/me/videos");
139
+ return (j.data ?? []).map((v) => ({ id: v.id, name: v.name, shortUUID: v.shortUUID, privacy: v.privacy?.label ?? "" }));
140
+ }
141
+ export async function deleteVideo(cfg, id) {
142
+ await ptRequest(cfg, `/api/v1/videos/${id}`, { method: "DELETE" });
143
+ }
144
+ //# sourceMappingURL=peertube-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"peertube-client.js","sourceRoot":"","sources":["../src/peertube-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};