zerocut-cli 0.3.1 → 0.3.3
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/commands/skill.js +4 -0
- package/package.json +1 -1
- package/src/commands/config.ts +50 -51
- package/src/commands/skill.ts +12 -2
- package/src/services/commandLoader.ts +3 -1
package/dist/commands/skill.js
CHANGED
|
@@ -16,6 +16,10 @@ function printSkill(relativePath) {
|
|
|
16
16
|
if (!content.endsWith("\n")) {
|
|
17
17
|
process.stdout.write("\n");
|
|
18
18
|
}
|
|
19
|
+
const outputPath = node_path_1.default.resolve(process.cwd(), "zerocut-cli/SKILL.md");
|
|
20
|
+
node_fs_1.default.mkdirSync(node_path_1.default.dirname(outputPath), { recursive: true });
|
|
21
|
+
node_fs_1.default.writeFileSync(outputPath, content, "utf8");
|
|
22
|
+
process.stderr.write(`Saved skill markdown to ${outputPath}\n`);
|
|
19
23
|
}
|
|
20
24
|
function register(program) {
|
|
21
25
|
const parent = program.command("skill").description("Print built-in skill markdown");
|
package/package.json
CHANGED
package/src/commands/config.ts
CHANGED
|
@@ -14,6 +14,30 @@ async function ask(question: string, defaults?: string): Promise<string> {
|
|
|
14
14
|
return trimmed.length > 0 ? trimmed : (defaults ?? "");
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
+
async function exchangeOttAndSave(ott: string, region: "cn" | "us"): Promise<void> {
|
|
18
|
+
const base = region === "cn" ? "https://api2.zerocut.cn" : "https://api2.zerocut.art";
|
|
19
|
+
const resp = await fetch(`${base}/api/open/ott/exchange`, {
|
|
20
|
+
method: "POST",
|
|
21
|
+
headers: { "content-type": "application/json" },
|
|
22
|
+
body: JSON.stringify({ ott }),
|
|
23
|
+
});
|
|
24
|
+
if (!resp.ok) {
|
|
25
|
+
process.stderr.write(`OTT exchange failed: HTTP ${resp.status}\n`);
|
|
26
|
+
process.exitCode = 1;
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const json = (await resp.json()) as { data?: { apiKey?: string } };
|
|
30
|
+
const apiKey = json?.data?.apiKey;
|
|
31
|
+
if (typeof apiKey !== "string" || apiKey.length === 0) {
|
|
32
|
+
process.stderr.write("OTT exchange failed: missing data.apiKey in response\n");
|
|
33
|
+
process.exitCode = 1;
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
setConfigValueSync("apiKey", apiKey);
|
|
37
|
+
setConfigValueSync("region", region);
|
|
38
|
+
process.stdout.write("apiKey set via OTT\n");
|
|
39
|
+
}
|
|
40
|
+
|
|
17
41
|
export function register(program: Command): void {
|
|
18
42
|
const parent = program
|
|
19
43
|
.command("config")
|
|
@@ -21,36 +45,36 @@ export function register(program: Command): void {
|
|
|
21
45
|
.option("--ott <token>", "One-Time Token (OTT) for fetching API key")
|
|
22
46
|
.option("--region <region>", "Region for OTT exchange: cn|us")
|
|
23
47
|
.action(async function (this: Command, opts: { ott?: string; region?: string }) {
|
|
24
|
-
const
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
if (
|
|
28
|
-
|
|
48
|
+
const cfg = readConfigSync() as { region?: unknown };
|
|
49
|
+
const regionInput = typeof opts.region === "string" ? opts.region.trim().toLowerCase() : "";
|
|
50
|
+
let region: "cn" | "us";
|
|
51
|
+
if (regionInput === "cn" || regionInput === "us") {
|
|
52
|
+
region = regionInput;
|
|
53
|
+
} else if (regionInput.length > 0) {
|
|
54
|
+
process.stderr.write("Invalid --region. Allowed: cn|us\n");
|
|
29
55
|
process.exitCode = 1;
|
|
30
56
|
return;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
});
|
|
39
|
-
if (!resp.ok) {
|
|
40
|
-
process.stderr.write(`OTT exchange failed: HTTP ${resp.status}\n`);
|
|
57
|
+
} else {
|
|
58
|
+
const defaultRegion = cfg.region === "cn" || cfg.region === "us" ? cfg.region : "us";
|
|
59
|
+
const regionAnswer = (await ask("Choose region (cn/us)", defaultRegion))
|
|
60
|
+
.trim()
|
|
61
|
+
.toLowerCase();
|
|
62
|
+
if (regionAnswer !== "cn" && regionAnswer !== "us") {
|
|
63
|
+
process.stderr.write("Invalid region. Allowed: cn|us\n");
|
|
41
64
|
process.exitCode = 1;
|
|
42
65
|
return;
|
|
43
66
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
67
|
+
region = regionAnswer;
|
|
68
|
+
}
|
|
69
|
+
const ott = typeof opts.ott === "string" ? opts.ott.trim() : "";
|
|
70
|
+
const ottValue = ott.length > 0 ? ott : (await ask("Enter One-Time Token (OTT)")).trim();
|
|
71
|
+
if (!ottValue) {
|
|
72
|
+
process.stderr.write("OTT is required\n");
|
|
73
|
+
process.exitCode = 1;
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
try {
|
|
77
|
+
await exchangeOttAndSave(ottValue, region);
|
|
54
78
|
} catch (err) {
|
|
55
79
|
process.stderr.write(`OTT exchange failed: ${(err as Error).message}\n`);
|
|
56
80
|
process.exitCode = 1;
|
|
@@ -82,32 +106,7 @@ export function register(program: Command): void {
|
|
|
82
106
|
return;
|
|
83
107
|
}
|
|
84
108
|
try {
|
|
85
|
-
|
|
86
|
-
const resp = await fetch(`${base}/api/open/ott/exchange`, {
|
|
87
|
-
method: "POST",
|
|
88
|
-
headers: {
|
|
89
|
-
"content-type": "application/json",
|
|
90
|
-
},
|
|
91
|
-
body: JSON.stringify({ ott }),
|
|
92
|
-
});
|
|
93
|
-
if (!resp.ok) {
|
|
94
|
-
process.stderr.write(`OTT exchange failed: HTTP ${resp.status}\n`);
|
|
95
|
-
process.exitCode = 1;
|
|
96
|
-
return;
|
|
97
|
-
}
|
|
98
|
-
const json = (await resp.json()) as {
|
|
99
|
-
data?: { apiKey?: string };
|
|
100
|
-
[k: string]: unknown;
|
|
101
|
-
};
|
|
102
|
-
const apiKey = json?.data?.apiKey;
|
|
103
|
-
if (typeof apiKey !== "string" || apiKey.length === 0) {
|
|
104
|
-
process.stderr.write("OTT exchange failed: missing data.apiKey in response\n");
|
|
105
|
-
process.exitCode = 1;
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
108
|
-
setConfigValueSync("apiKey", apiKey);
|
|
109
|
-
setConfigValueSync("region", region);
|
|
110
|
-
process.stdout.write("apiKey set via OTT\n");
|
|
109
|
+
await exchangeOttAndSave(ott, region);
|
|
111
110
|
} catch (err) {
|
|
112
111
|
process.stderr.write(`OTT exchange failed: ${(err as Error).message}\n`);
|
|
113
112
|
process.exitCode = 1;
|
package/src/commands/skill.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Command } from "commander";
|
|
2
2
|
import fs from "node:fs";
|
|
3
|
+
import os from "node:os";
|
|
3
4
|
import path from "node:path";
|
|
4
5
|
|
|
5
6
|
export const name = "skill";
|
|
@@ -15,7 +16,10 @@ function printSkill(relativePath: string): void {
|
|
|
15
16
|
}
|
|
16
17
|
|
|
17
18
|
export function register(program: Command): void {
|
|
18
|
-
const parent = program
|
|
19
|
+
const parent = program
|
|
20
|
+
.command("skill")
|
|
21
|
+
.description("Print built-in skill markdown")
|
|
22
|
+
.option("--claude", "Append Claude skill save hint");
|
|
19
23
|
|
|
20
24
|
parent
|
|
21
25
|
.command("one-click-video")
|
|
@@ -31,7 +35,13 @@ export function register(program: Command): void {
|
|
|
31
35
|
printSkill("../skill/edit-video/SKILL.md");
|
|
32
36
|
});
|
|
33
37
|
|
|
34
|
-
parent.action(() => {
|
|
38
|
+
parent.action((opts: { claude?: boolean }) => {
|
|
35
39
|
printSkill("../skill/SKILL.md");
|
|
40
|
+
if (opts.claude) {
|
|
41
|
+
const savePath = path.join(os.homedir(), ".claude", "skills", "zerocut", "SKILL.md");
|
|
42
|
+
process.stdout.write(
|
|
43
|
+
`\n⚠️ Please save the markdown above to ${savePath} to create the skill.\n`
|
|
44
|
+
);
|
|
45
|
+
}
|
|
36
46
|
});
|
|
37
47
|
}
|
|
@@ -10,6 +10,7 @@ import { register as registerPandoc } from "../commands/pandoc";
|
|
|
10
10
|
import { register as registerSkill } from "../commands/skill";
|
|
11
11
|
import fs from "node:fs";
|
|
12
12
|
import path from "node:path";
|
|
13
|
+
import { pathToFileURL } from "node:url";
|
|
13
14
|
|
|
14
15
|
export function loadBuiltInCommands(program: Command): void {
|
|
15
16
|
registerHelp(program);
|
|
@@ -31,7 +32,8 @@ export async function loadExternalCommandsAsync(program: Command, dir?: string):
|
|
|
31
32
|
for (const f of files) {
|
|
32
33
|
const full = path.join(d, f);
|
|
33
34
|
try {
|
|
34
|
-
const
|
|
35
|
+
const moduleSpecifier = pathToFileURL(full).href;
|
|
36
|
+
const mod = (await import(moduleSpecifier)) as {
|
|
35
37
|
register?: (p: Command) => void;
|
|
36
38
|
default?: (p: Command) => void;
|
|
37
39
|
};
|