html2pptx-local-mcp 1.1.22 → 1.1.24

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 (51) hide show
  1. package/app/docs/content.js +116 -2
  2. package/cli/dist/commands/config-show.d.ts +1 -0
  3. package/cli/dist/commands/config-show.js +16 -0
  4. package/cli/dist/commands/convert.d.ts +10 -0
  5. package/cli/dist/commands/convert.js +311 -0
  6. package/cli/dist/commands/edit.d.ts +33 -0
  7. package/cli/dist/commands/edit.js +818 -0
  8. package/cli/dist/commands/init.d.ts +1 -0
  9. package/cli/dist/commands/init.js +35 -0
  10. package/cli/dist/commands/logout.d.ts +1 -0
  11. package/cli/dist/commands/logout.js +19 -0
  12. package/cli/dist/commands/publish.d.ts +10 -0
  13. package/cli/dist/commands/publish.js +17 -0
  14. package/cli/dist/commands/status.d.ts +5 -0
  15. package/cli/dist/commands/status.js +71 -0
  16. package/cli/dist/commands/templates.d.ts +13 -0
  17. package/cli/dist/commands/templates.js +85 -0
  18. package/cli/dist/commands/whoami.d.ts +5 -0
  19. package/cli/dist/commands/whoami.js +51 -0
  20. package/cli/dist/config.d.ts +7 -0
  21. package/cli/dist/config.js +24 -0
  22. package/cli/dist/dist/commands/config-show.d.ts +1 -0
  23. package/cli/dist/dist/commands/config-show.js +16 -0
  24. package/cli/dist/dist/commands/convert.d.ts +10 -0
  25. package/cli/dist/dist/commands/convert.js +311 -0
  26. package/cli/dist/dist/commands/edit.d.ts +34 -0
  27. package/cli/dist/dist/commands/edit.js +801 -0
  28. package/cli/dist/dist/commands/init.d.ts +1 -0
  29. package/cli/dist/dist/commands/init.js +35 -0
  30. package/cli/dist/dist/commands/logout.d.ts +1 -0
  31. package/cli/dist/dist/commands/logout.js +19 -0
  32. package/cli/dist/dist/commands/publish.d.ts +10 -0
  33. package/cli/dist/dist/commands/publish.js +17 -0
  34. package/cli/dist/dist/commands/status.d.ts +5 -0
  35. package/cli/dist/dist/commands/status.js +71 -0
  36. package/cli/dist/dist/commands/templates.d.ts +13 -0
  37. package/cli/dist/dist/commands/templates.js +85 -0
  38. package/cli/dist/dist/commands/whoami.d.ts +5 -0
  39. package/cli/dist/dist/commands/whoami.js +51 -0
  40. package/cli/dist/dist/config.d.ts +7 -0
  41. package/cli/dist/dist/config.js +24 -0
  42. package/cli/dist/dist/index.d.ts +2 -0
  43. package/cli/dist/dist/index.js +93 -0
  44. package/cli/dist/dist/update-check.d.ts +1 -0
  45. package/cli/dist/dist/update-check.js +30 -0
  46. package/cli/dist/index.d.ts +2 -0
  47. package/cli/dist/index.js +93 -0
  48. package/cli/dist/update-check.d.ts +1 -0
  49. package/cli/dist/update-check.js +30 -0
  50. package/package.json +1 -1
  51. package/scripts/install-mcp.mjs +5 -1
@@ -0,0 +1 @@
1
+ export declare function initCommand(): Promise<void>;
@@ -0,0 +1,35 @@
1
+ import * as p from "@clack/prompts";
2
+ import pc from "picocolors";
3
+ import { loadConfig, saveConfig, getConfigPath } from "../config.js";
4
+ export async function initCommand() {
5
+ p.intro(pc.bgCyan(pc.black(" html2pptx ")));
6
+ const config = await loadConfig();
7
+ const hasExisting = !!config.apiKey;
8
+ if (hasExisting) {
9
+ p.log.info(`Existing API key found: ${pc.dim(config.apiKey.slice(0, 12) + "...")}`);
10
+ }
11
+ p.log.info(`Get your API key at: ${pc.cyan(pc.underline("https://html2pptx.app/dashboard/en?tab=api-keys"))}`);
12
+ const result = await p.group({
13
+ apiKey: () => p.text({
14
+ message: "Enter your API key",
15
+ placeholder: "sk_live_...",
16
+ initialValue: config.apiKey ?? "",
17
+ validate(value) {
18
+ if (!value)
19
+ return "API key is required";
20
+ if (!value.startsWith("sk_live_"))
21
+ return 'API key should start with "sk_live_"';
22
+ },
23
+ }),
24
+ }, {
25
+ onCancel() {
26
+ p.cancel("Setup cancelled.");
27
+ process.exit(0);
28
+ },
29
+ });
30
+ await saveConfig({
31
+ apiKey: result.apiKey,
32
+ });
33
+ p.log.success(`Config saved to ${pc.dim(getConfigPath())}`);
34
+ p.outro("You're all set! Run " + pc.cyan("html2pptx convert") + " to start.");
35
+ }
@@ -0,0 +1 @@
1
+ export declare function logoutCommand(): Promise<void>;
@@ -0,0 +1,19 @@
1
+ import { unlink } from "node:fs/promises";
2
+ import * as p from "@clack/prompts";
3
+ import pc from "picocolors";
4
+ import { loadConfig, getConfigPath } from "../config.js";
5
+ export async function logoutCommand() {
6
+ const config = await loadConfig();
7
+ if (!config.apiKey) {
8
+ p.log.warn("No API key found. You're already logged out.");
9
+ return;
10
+ }
11
+ try {
12
+ await unlink(getConfigPath());
13
+ p.log.success(`API key removed. Config deleted at ${pc.dim(getConfigPath())}`);
14
+ }
15
+ catch {
16
+ p.log.error("Failed to remove config file.");
17
+ process.exit(1);
18
+ }
19
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * `html2pptx templates publish` is intentionally disabled.
3
+ *
4
+ * Marketplace template draft creation is HTML-only and remote-MCP-only:
5
+ * html2pptx_validate_template_html -> html2pptx_publish_template.
6
+ */
7
+ export interface PublishOptions {
8
+ json?: boolean;
9
+ }
10
+ export declare function publishCommand(_input: string | undefined, options?: PublishOptions): Promise<void>;
@@ -0,0 +1,17 @@
1
+ import pc from "picocolors";
2
+ const REMOTE_MCP_MESSAGE = "テンプレートdraft作成はHTMLのみ、remote MCPのみ対応しています。\n\n" +
3
+ "CLI / Web UI / REST API からは公開用draftを作成できません。Claude Code / Codex などの remote MCP から " +
4
+ "`html2pptx_validate_template_html` を実行し、すべてのエラーを修正してから " +
5
+ "`html2pptx_publish_template` を呼び出してください。";
6
+ export async function publishCommand(_input, options = {}) {
7
+ bail(REMOTE_MCP_MESSAGE, options);
8
+ }
9
+ function bail(msg, options) {
10
+ if (options.json) {
11
+ console.log(JSON.stringify({ ok: false, error: msg }));
12
+ }
13
+ else {
14
+ console.error(pc.red(msg));
15
+ }
16
+ process.exit(1);
17
+ }
@@ -0,0 +1,5 @@
1
+ interface StatusOptions {
2
+ baseUrl?: string;
3
+ }
4
+ export declare function statusCommand(options?: StatusOptions): Promise<void>;
5
+ export {};
@@ -0,0 +1,71 @@
1
+ import * as p from "@clack/prompts";
2
+ import pc from "picocolors";
3
+ import { loadConfig } from "../config.js";
4
+ export async function statusCommand(options = {}) {
5
+ const config = await loadConfig();
6
+ const apiKey = config.apiKey;
7
+ const baseUrl = options.baseUrl ?? config.baseUrl ?? "https://html2pptx.app";
8
+ if (!apiKey) {
9
+ p.log.error("No API key found. Run " + pc.cyan("html2pptx login") + " first.");
10
+ process.exit(1);
11
+ }
12
+ const spinner = p.spinner();
13
+ spinner.start("Fetching usage...");
14
+ try {
15
+ const res = await fetch(`${baseUrl}/api/v1/export/usage`, {
16
+ headers: { Authorization: `Bearer ${apiKey}` },
17
+ });
18
+ if (res.status === 401) {
19
+ spinner.stop("Failed");
20
+ p.log.error("Invalid API key. Run " +
21
+ pc.cyan("html2pptx login") +
22
+ " to update your key.");
23
+ process.exit(1);
24
+ }
25
+ if (res.status === 403) {
26
+ spinner.stop("Failed");
27
+ p.log.error("Access denied. Your API key may be expired or revoked. Visit " +
28
+ pc.cyan("https://html2pptx.app/dashboard") +
29
+ " to check.");
30
+ process.exit(1);
31
+ }
32
+ if (!res.ok) {
33
+ const text = await res.text();
34
+ throw new Error(`API error ${res.status}: ${text}`);
35
+ }
36
+ const data = (await res.json());
37
+ spinner.stop("Usage retrieved");
38
+ const used = data.usage?.dailyUsed ?? 0;
39
+ const limit = data.limits?.dailyRequestLimit ?? 0;
40
+ const usageBar = renderBar(used, limit);
41
+ p.log.info(pc.bold("Plan: ") + (data.plan?.name ?? "Unknown"));
42
+ p.log.info(pc.bold("Daily Usage: ") +
43
+ `${used} / ${limit} exports ${usageBar}`);
44
+ if (data.usage?.dailyRemaining !== undefined) {
45
+ p.log.info(pc.bold("Remaining: ") + pc.green(String(data.usage.dailyRemaining)));
46
+ }
47
+ if (data.usage?.dayResetsAt) {
48
+ const resetDate = new Date(data.usage.dayResetsAt);
49
+ p.log.info(pc.bold("Resets: ") + resetDate.toLocaleDateString());
50
+ }
51
+ if (data.limits?.requestsPerMinute) {
52
+ p.log.info(pc.bold("Rate Limit: ") + `${data.limits.requestsPerMinute} req/min`);
53
+ }
54
+ if (data.limits?.maxSlidesPerJob) {
55
+ p.log.info(pc.bold("Max Slides: ") + `${data.limits.maxSlidesPerJob} per job`);
56
+ }
57
+ }
58
+ catch (e) {
59
+ spinner.stop("Failed");
60
+ p.log.error(e.message);
61
+ process.exit(1);
62
+ }
63
+ }
64
+ function renderBar(used, limit) {
65
+ const width = 20;
66
+ const ratio = limit > 0 ? Math.min(used / limit, 1) : 0;
67
+ const filled = Math.round(ratio * width);
68
+ const empty = width - filled;
69
+ const color = ratio > 0.9 ? pc.red : ratio > 0.7 ? pc.yellow : pc.green;
70
+ return color("\u2588".repeat(filled)) + pc.dim("\u2591".repeat(empty));
71
+ }
@@ -0,0 +1,13 @@
1
+ interface TemplatesOptions {
2
+ json?: boolean;
3
+ baseUrl?: string;
4
+ }
5
+ interface TemplateGetOptions {
6
+ prompt?: boolean;
7
+ html?: boolean;
8
+ json?: boolean;
9
+ baseUrl?: string;
10
+ }
11
+ export declare function templatesListCommand(options?: TemplatesOptions): Promise<void>;
12
+ export declare function templatesGetCommand(id?: string, options?: TemplateGetOptions): Promise<void>;
13
+ export {};
@@ -0,0 +1,85 @@
1
+ import * as p from "@clack/prompts";
2
+ import pc from "picocolors";
3
+ import { loadConfig } from "../config.js";
4
+ export async function templatesListCommand(options = {}) {
5
+ const config = await loadConfig();
6
+ const baseUrl = options.baseUrl ?? config.baseUrl ?? "https://html2pptx.app";
7
+ const spinner = options.json ? null : p.spinner();
8
+ spinner?.start("Fetching templates...");
9
+ try {
10
+ const res = await fetch(`${baseUrl}/api/templates`);
11
+ if (!res.ok)
12
+ throw new Error(`API error ${res.status}`);
13
+ const data = (await res.json());
14
+ if (options.json) {
15
+ console.log(JSON.stringify(data.templates, null, 2));
16
+ return;
17
+ }
18
+ spinner?.stop(`${data.templates.length} templates found`);
19
+ for (const t of data.templates) {
20
+ p.log.info(`${pc.bold(t.title)} ${pc.dim(`(${t.id})`)}` +
21
+ `\n ${pc.dim(t.category)} | ${t.slides} slides` +
22
+ `\n ${pc.dim(t.description)}`);
23
+ }
24
+ }
25
+ catch (e) {
26
+ spinner?.stop("Failed");
27
+ p.log.error(e.message);
28
+ process.exit(1);
29
+ }
30
+ }
31
+ export async function templatesGetCommand(id, options = {}) {
32
+ const config = await loadConfig();
33
+ const baseUrl = options.baseUrl ?? config.baseUrl ?? "https://html2pptx.app";
34
+ if (!id) {
35
+ p.log.error("Template ID is required. Run " + pc.cyan("html2pptx templates list") + " to see available IDs.");
36
+ process.exit(1);
37
+ }
38
+ const include = [];
39
+ if (options.prompt)
40
+ include.push("prompt");
41
+ if (options.html)
42
+ include.push("html");
43
+ const includeParam = include.length ? `&include=${include.join(",")}` : "";
44
+ const spinner = options.json ? null : p.spinner();
45
+ spinner?.start("Fetching template...");
46
+ try {
47
+ const res = await fetch(`${baseUrl}/api/templates?id=${encodeURIComponent(id)}${includeParam}`);
48
+ if (!res.ok) {
49
+ if (res.status === 404)
50
+ throw new Error(`Template "${id}" not found.`);
51
+ throw new Error(`API error ${res.status}`);
52
+ }
53
+ const data = (await res.json());
54
+ if (options.json) {
55
+ console.log(JSON.stringify(data, null, 2));
56
+ return;
57
+ }
58
+ spinner?.stop("Found");
59
+ p.log.info(pc.bold("Title: ") + data.title);
60
+ p.log.info(pc.bold("ID: ") + data.id);
61
+ p.log.info(pc.bold("Category: ") + data.category);
62
+ p.log.info(pc.bold("Slides: ") + String(data.slides));
63
+ if (data.downloadUrl) {
64
+ p.log.info(pc.bold("PPTX: ") + pc.cyan(data.downloadUrl));
65
+ }
66
+ if (data.htmlUrl) {
67
+ p.log.info(pc.bold("HTML: ") + pc.cyan(data.htmlUrl));
68
+ }
69
+ if (data.prompt) {
70
+ p.log.info("");
71
+ p.log.info(pc.bold("Prompt:"));
72
+ console.log(data.prompt);
73
+ }
74
+ if (data.html) {
75
+ p.log.info("");
76
+ p.log.info(pc.bold("HTML Source:"));
77
+ console.log(data.html);
78
+ }
79
+ }
80
+ catch (e) {
81
+ spinner?.stop("Failed");
82
+ p.log.error(e.message);
83
+ process.exit(1);
84
+ }
85
+ }
@@ -0,0 +1,5 @@
1
+ interface WhoamiOptions {
2
+ baseUrl?: string;
3
+ }
4
+ export declare function whoamiCommand(options?: WhoamiOptions): Promise<void>;
5
+ export {};
@@ -0,0 +1,51 @@
1
+ import * as p from "@clack/prompts";
2
+ import pc from "picocolors";
3
+ import { loadConfig, getConfigPath } from "../config.js";
4
+ export async function whoamiCommand(options = {}) {
5
+ const config = await loadConfig();
6
+ const apiKey = config.apiKey;
7
+ const baseUrl = options.baseUrl ?? config.baseUrl ?? "https://html2pptx.app";
8
+ if (!apiKey) {
9
+ p.log.error("Not logged in.");
10
+ p.log.info("Run " + pc.cyan("html2pptx login") + " to configure your API key.");
11
+ process.exit(1);
12
+ }
13
+ p.log.info(pc.bold("Config: ") + pc.dim(getConfigPath()));
14
+ p.log.info(pc.bold("API Key: ") + pc.dim(apiKey.slice(0, 12) + "..." + apiKey.slice(-4)));
15
+ const spinner = p.spinner();
16
+ spinner.start("Verifying API key...");
17
+ try {
18
+ const res = await fetch(`${baseUrl}/api/v1/export/usage`, {
19
+ headers: { Authorization: `Bearer ${apiKey}` },
20
+ });
21
+ if (res.status === 401) {
22
+ spinner.stop(pc.red("Invalid"));
23
+ p.log.error("API key is invalid. Run " +
24
+ pc.cyan("html2pptx login") +
25
+ " to update.");
26
+ process.exit(1);
27
+ }
28
+ if (!res.ok) {
29
+ spinner.stop(pc.yellow("Unknown"));
30
+ p.log.warn(`Could not verify (HTTP ${res.status})`);
31
+ return;
32
+ }
33
+ const data = (await res.json());
34
+ spinner.stop(pc.green("Authenticated"));
35
+ if (data.plan?.name) {
36
+ p.log.info(pc.bold("Plan: ") + data.plan.name);
37
+ }
38
+ if (data.usage?.dailyUsed !== undefined && data.limits?.dailyRequestLimit !== undefined) {
39
+ p.log.info(pc.bold("Usage: ") +
40
+ `${data.usage.dailyUsed} / ${data.limits.dailyRequestLimit} exports today`);
41
+ }
42
+ if (data.usage?.dailyRemaining !== undefined) {
43
+ p.log.info(pc.bold("Remaining: ") + pc.green(String(data.usage.dailyRemaining)));
44
+ }
45
+ }
46
+ catch (e) {
47
+ spinner.stop("Failed");
48
+ p.log.error(e.message);
49
+ process.exit(1);
50
+ }
51
+ }
@@ -0,0 +1,7 @@
1
+ export interface Config {
2
+ apiKey?: string;
3
+ baseUrl?: string;
4
+ }
5
+ export declare function loadConfig(): Promise<Config>;
6
+ export declare function saveConfig(config: Config): Promise<void>;
7
+ export declare function getConfigPath(): string;
@@ -0,0 +1,24 @@
1
+ import { readFile, writeFile, mkdir } from "node:fs/promises";
2
+ import { homedir } from "node:os";
3
+ import { join } from "node:path";
4
+ const CONFIG_DIR = join(homedir(), ".html2pptx");
5
+ const CONFIG_FILE = join(CONFIG_DIR, "config.json");
6
+ export async function loadConfig() {
7
+ try {
8
+ const raw = await readFile(CONFIG_FILE, "utf-8");
9
+ return JSON.parse(raw);
10
+ }
11
+ catch {
12
+ return {};
13
+ }
14
+ }
15
+ export async function saveConfig(config) {
16
+ await mkdir(CONFIG_DIR, { recursive: true });
17
+ await writeFile(CONFIG_FILE, JSON.stringify(config, null, 2) + "\n", {
18
+ encoding: "utf-8",
19
+ mode: 0o600,
20
+ });
21
+ }
22
+ export function getConfigPath() {
23
+ return CONFIG_FILE;
24
+ }
@@ -0,0 +1 @@
1
+ export declare function configShowCommand(): Promise<void>;
@@ -0,0 +1,16 @@
1
+ import * as p from "@clack/prompts";
2
+ import pc from "picocolors";
3
+ import { loadConfig, getConfigPath } from "../config.js";
4
+ export async function configShowCommand() {
5
+ const config = await loadConfig();
6
+ const configPath = getConfigPath();
7
+ p.log.info(pc.bold("Config file: ") + pc.dim(configPath));
8
+ if (!config.apiKey) {
9
+ p.log.warn("No configuration found. Run " + pc.cyan("html2pptx login") + " to set up.");
10
+ return;
11
+ }
12
+ p.log.info(pc.bold("API Key: ") +
13
+ pc.dim(config.apiKey.slice(0, 12) + "..." + config.apiKey.slice(-4)));
14
+ p.log.info(pc.bold("API Base URL: ") +
15
+ (config.baseUrl ?? "https://html2pptx.app") + pc.dim(" (default)"));
16
+ }
@@ -0,0 +1,10 @@
1
+ interface ConvertOptions {
2
+ output?: string;
3
+ size?: string;
4
+ css?: string;
5
+ json?: boolean;
6
+ open?: boolean;
7
+ baseUrl?: string;
8
+ }
9
+ export declare function convertCommand(input?: string, options?: ConvertOptions): Promise<void>;
10
+ export {};