@remixmate/cli 0.9.71 → 0.9.72
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/handlers/gen-post.d.ts +4 -3
- package/dist/handlers/gen-post.js +21 -17
- package/dist/manifest.json +11 -12
- package/package.json +1 -1
- package/skills/gen-post/SKILL.md +23 -13
- package/skills/gen-post/skill.json +9 -10
|
@@ -13,9 +13,10 @@
|
|
|
13
13
|
* call (one LLM run, billed separately), issued concurrently.
|
|
14
14
|
* - --render-id links the result to a studio take so it shows up in the web
|
|
15
15
|
* panel; without it the backend generates without persisting anything.
|
|
16
|
-
* - --instruction
|
|
17
|
-
*
|
|
18
|
-
* since the draft belongs to one platform.
|
|
16
|
+
* - --instruction is the user's "how should it read" request. With a draft
|
|
17
|
+
* (--title / --description / --tag) it rewrites that caption — single platform
|
|
18
|
+
* only, since the draft belongs to one platform. Without a draft it is an extra
|
|
19
|
+
* requirement applied to a fresh generation on every requested platform.
|
|
19
20
|
*/
|
|
20
21
|
import type { HandlerContext, HandlerInput } from './index.js';
|
|
21
22
|
export declare function genPost(input: HandlerInput, ctxIn: HandlerContext): Promise<void>;
|
|
@@ -13,9 +13,10 @@
|
|
|
13
13
|
* call (one LLM run, billed separately), issued concurrently.
|
|
14
14
|
* - --render-id links the result to a studio take so it shows up in the web
|
|
15
15
|
* panel; without it the backend generates without persisting anything.
|
|
16
|
-
* - --instruction
|
|
17
|
-
*
|
|
18
|
-
* since the draft belongs to one platform.
|
|
16
|
+
* - --instruction is the user's "how should it read" request. With a draft
|
|
17
|
+
* (--title / --description / --tag) it rewrites that caption — single platform
|
|
18
|
+
* only, since the draft belongs to one platform. Without a draft it is an extra
|
|
19
|
+
* requirement applied to a fresh generation on every requested platform.
|
|
19
20
|
*/
|
|
20
21
|
import { EXIT, mmPost, resolveHttpContext, SkillError } from '../http.js';
|
|
21
22
|
import { emitProgress } from '../progress.js';
|
|
@@ -49,7 +50,9 @@ function resolvePlatforms(value) {
|
|
|
49
50
|
const out = [];
|
|
50
51
|
for (const item of raw) {
|
|
51
52
|
const key = item.toLowerCase();
|
|
52
|
-
|
|
53
|
+
// 「全部」: the web param card writes option labels into the message, and the agent
|
|
54
|
+
// may forward the label verbatim.
|
|
55
|
+
const codes = key === 'all' || item === '全部' ? [...DEFAULT_PLATFORMS] : [PLATFORM_ALIASES[item] ?? PLATFORM_ALIASES[key] ?? key];
|
|
53
56
|
for (const code of codes)
|
|
54
57
|
if (!out.includes(code))
|
|
55
58
|
out.push(code);
|
|
@@ -114,18 +117,19 @@ export async function genPost(input, ctxIn) {
|
|
|
114
117
|
tags: normalizeTags(input.tag),
|
|
115
118
|
};
|
|
116
119
|
const hasDraft = !!(current.title || current.description || current.tags.length);
|
|
117
|
-
if (instruction) {
|
|
118
|
-
|
|
119
|
-
throw new SkillError('❌ --instruction rewrites one platform\'s caption; pass exactly one --platform');
|
|
120
|
-
}
|
|
121
|
-
if (!hasDraft) {
|
|
122
|
-
throw new SkillError('❌ --instruction needs the caption to rewrite: pass --title / --description / --tag');
|
|
123
|
-
}
|
|
124
|
-
if (instruction.length > 500) {
|
|
125
|
-
throw new SkillError('❌ --instruction must be at most 500 characters');
|
|
126
|
-
}
|
|
120
|
+
if (instruction && instruction.length > 500) {
|
|
121
|
+
throw new SkillError('❌ --instruction must be at most 500 characters');
|
|
127
122
|
}
|
|
128
|
-
|
|
123
|
+
// With a draft, --instruction rewrites that one platform's caption. Without one it is
|
|
124
|
+
// an extra requirement for a fresh generation, which needs the video's context.
|
|
125
|
+
const rewriting = !!instruction && hasDraft;
|
|
126
|
+
if (hasDraft && !instruction) {
|
|
127
|
+
throw new SkillError('❌ --title / --description / --tag are the draft to rewrite; pass --instruction with them');
|
|
128
|
+
}
|
|
129
|
+
if (rewriting && platforms.length !== 1) {
|
|
130
|
+
throw new SkillError('❌ rewriting a caption (--instruction with --title / --description / --tag) needs exactly one --platform');
|
|
131
|
+
}
|
|
132
|
+
if (!rewriting && !topic && !hook) {
|
|
129
133
|
throw new SkillError('❌ Please provide --topic (what the video is about); --hook is optional extra context');
|
|
130
134
|
}
|
|
131
135
|
const durationSec = toNumber(input.duration, 'duration');
|
|
@@ -156,10 +160,10 @@ export async function genPost(input, ctxIn) {
|
|
|
156
160
|
const promptOverride = optString(input.prompt);
|
|
157
161
|
if (promptOverride)
|
|
158
162
|
base.promptOverride = promptOverride;
|
|
159
|
-
if (instruction)
|
|
163
|
+
if (instruction)
|
|
160
164
|
base.instruction = instruction;
|
|
165
|
+
if (rewriting)
|
|
161
166
|
base.current = current;
|
|
162
|
-
}
|
|
163
167
|
const ctx = await resolveHttpContext(ctxIn.skillName, {
|
|
164
168
|
apiBaseUrl: input.api_base_url,
|
|
165
169
|
privateToken: input.priv_token,
|
package/dist/manifest.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
|
-
"version": "0.9.
|
|
4
|
-
"generatedAt": "2026-10-
|
|
3
|
+
"version": "0.9.72",
|
|
4
|
+
"generatedAt": "2026-10-08T04:30:08.225Z",
|
|
5
5
|
"skills": [
|
|
6
6
|
{
|
|
7
7
|
"id": "doc-parse",
|
|
@@ -417,7 +417,7 @@
|
|
|
417
417
|
"tier": "tool",
|
|
418
418
|
"category": "consuming",
|
|
419
419
|
"title": "Social Post Copy",
|
|
420
|
-
"summary": "Write the text of a social post for a finished video — title, description and hashtags — per platform (text only; it does not upload or publish the video): Douyin (抖音), Xiaohongshu (小红书) and TikTok. Same prompts as the web studio's publish panel, including the platform's length limits and ad-law / community-guideline compliance rules, and the user's saved prompt overrides. Generates all three platforms by default; pass `platform` to pick.
|
|
420
|
+
"summary": "Write the text of a social post for a finished video — title, description and hashtags — per platform (text only; it does not upload or publish the video): Douyin (抖音), Xiaohongshu (小红书) and TikTok. Same prompts as the web studio's publish panel, including the platform's length limits and ad-law / community-guideline compliance rules, and the user's saved prompt overrides. Generates all three platforms by default; pass `platform` to pick. Fill the video context yourself from the conversation — topic, hook, source URL, duration, aspect ratio — rather than asking the user; it only writes from what it is given. `instruction` carries the user's own request: alone it shapes a fresh generation, and with the current title/description/tags (from an earlier run in the conversation) it rewrites that caption instead. Each platform is one LLM call and costs credits.",
|
|
421
421
|
"triggers": [
|
|
422
422
|
"Publish copy / caption / title + description + hashtags for a video",
|
|
423
423
|
"发布文案、视频标题、话题标签、抖音文案、小红书笔记文案、TikTok caption",
|
|
@@ -438,7 +438,7 @@
|
|
|
438
438
|
"properties": {
|
|
439
439
|
"topic": {
|
|
440
440
|
"type": "string",
|
|
441
|
-
"description": "What the video is about — the main input for the copy (
|
|
441
|
+
"description": "What the video is about — the main input for the copy. Take it from the conversation (video title, script, source page). Required unless rewriting an existing caption."
|
|
442
442
|
},
|
|
443
443
|
"platform": {
|
|
444
444
|
"type": "array",
|
|
@@ -469,7 +469,7 @@
|
|
|
469
469
|
},
|
|
470
470
|
"instruction": {
|
|
471
471
|
"type": "string",
|
|
472
|
-
"description": "
|
|
472
|
+
"description": "The user's request for how the copy should read, e.g. 'shorter title, drop the emoji'. Alone: applied as an extra requirement to a fresh generation. With the current title / description / tag: rewrites that caption (exactly one platform). Max 500 characters."
|
|
473
473
|
},
|
|
474
474
|
"title": {
|
|
475
475
|
"type": "string",
|
|
@@ -507,22 +507,21 @@
|
|
|
507
507
|
},
|
|
508
508
|
"ui": {
|
|
509
509
|
"primary": [
|
|
510
|
-
"topic",
|
|
511
510
|
"platform",
|
|
512
|
-
"
|
|
511
|
+
"instruction"
|
|
513
512
|
],
|
|
514
|
-
"advanced": [
|
|
513
|
+
"advanced": [],
|
|
514
|
+
"hidden": [
|
|
515
|
+
"topic",
|
|
516
|
+
"hook",
|
|
515
517
|
"source_url",
|
|
516
518
|
"duration",
|
|
517
519
|
"aspect_ratio",
|
|
518
520
|
"language",
|
|
519
|
-
"instruction",
|
|
520
521
|
"title",
|
|
521
522
|
"description",
|
|
522
523
|
"tag",
|
|
523
|
-
"prompt"
|
|
524
|
-
],
|
|
525
|
-
"hidden": [
|
|
524
|
+
"prompt",
|
|
526
525
|
"render_id",
|
|
527
526
|
"video_project_id",
|
|
528
527
|
"json_output"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remixmate/cli",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.72",
|
|
4
4
|
"description": "AI media generation skills for Claude Code / Codex — 12 skills covering image, video, voice, digital human, web screenshot, web recording, script, template registry, rendering, Jianying export, and video deconstruction.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
package/skills/gen-post/SKILL.md
CHANGED
|
@@ -27,11 +27,18 @@ prompt overrides from the web panel apply here too.
|
|
|
27
27
|
|
|
28
28
|
Default is all three. Each platform is one LLM call, run concurrently, charged separately.
|
|
29
29
|
|
|
30
|
-
##
|
|
30
|
+
## Where the inputs come from
|
|
31
|
+
|
|
32
|
+
**You fill the video context; the user only says how they want it to read.** Take
|
|
33
|
+
`--topic` / `--hook` / `--source-url` / `--duration` / `--aspect-ratio` from the conversation —
|
|
34
|
+
the video's title, the script, the page it was made from, the render result. Don't ask the
|
|
35
|
+
user for them. The copy is written only from what you pass — anything missing is treated as
|
|
36
|
+
"not provided", never invented — so pass everything you know.
|
|
37
|
+
|
|
38
|
+
The user's own words ("标题去掉 emoji", "语气轻松一点", "只要小红书") go to `--instruction`
|
|
39
|
+
(and `--platform` when they name platforms). If they gave no request, just generate.
|
|
31
40
|
|
|
32
|
-
|
|
33
|
-
never invented. So pass what you know about the video: `--topic` is the main input, and
|
|
34
|
-
`--hook` / `--source-url` / `--duration` / `--aspect-ratio` sharpen it.
|
|
41
|
+
## Generate
|
|
35
42
|
|
|
36
43
|
```bash
|
|
37
44
|
remixmate gen-post \
|
|
@@ -45,15 +52,18 @@ remixmate gen-post \
|
|
|
45
52
|
remixmate gen-post --topic "<topic>" --platform xhs --json-output
|
|
46
53
|
```
|
|
47
54
|
|
|
48
|
-
|
|
49
|
-
|
|
55
|
+
```bash
|
|
56
|
+
# The user's request shapes a fresh generation on every platform
|
|
57
|
+
remixmate gen-post --topic "<topic>" --instruction "语气轻松一点,标题不要 emoji"
|
|
58
|
+
```
|
|
50
59
|
|
|
51
60
|
## Rewrite
|
|
52
61
|
|
|
53
|
-
|
|
54
|
-
pass
|
|
55
|
-
|
|
56
|
-
|
|
62
|
+
When a caption was already generated earlier in the conversation and the user asks to change
|
|
63
|
+
it, pass that caption back as the draft: `--instruction` plus `--title` / `--description` /
|
|
64
|
+
`--tag` rewrites it instead of starting over. One platform per call. Fields the instruction
|
|
65
|
+
doesn't mention are kept. Compliance rules still win either way: asking for superlatives,
|
|
66
|
+
guarantees or off-platform links gets a compliant rewording, not a literal one.
|
|
57
67
|
|
|
58
68
|
```bash
|
|
59
69
|
remixmate gen-post --platform douyin \
|
|
@@ -66,14 +76,14 @@ remixmate gen-post --platform douyin \
|
|
|
66
76
|
|
|
67
77
|
| Flag | Description | Default |
|
|
68
78
|
|------|-------------|---------|
|
|
69
|
-
| `--topic` | What the video is about (required unless
|
|
79
|
+
| `--topic` | What the video is about (required unless rewriting) | — |
|
|
70
80
|
| `--platform` | `douyin` / `xiaohongshu` / `tiktok` / `all`; repeatable or comma-separated | `all` |
|
|
71
81
|
| `--hook` | Opening hook line | none |
|
|
72
82
|
| `--source-url` | Project/source URL, context only | none |
|
|
73
83
|
| `--duration` | Seconds | none |
|
|
74
84
|
| `--aspect-ratio` | e.g. `9:16` | `9:16` |
|
|
75
85
|
| `--language` | Output language | per platform (see table) |
|
|
76
|
-
| `--instruction` |
|
|
86
|
+
| `--instruction` | The user's request, ≤ 500 chars; rewrites when a draft is given | none |
|
|
77
87
|
| `--title` / `--description` / `--tag` | Current caption to rewrite | none |
|
|
78
88
|
| `--prompt` | Replace the platform prompt for this run; placeholders `{{topic}}` `{{hook}}` `{{sourceUrl}}` `{{durationSec}}` `{{aspectRatio}}` `{{language}}` | saved/default prompt |
|
|
79
89
|
| `--render-id` / `--video-project-id` | Save the result to a studio take (shows in the web publish panel) | not saved |
|
|
@@ -101,4 +111,4 @@ Each platform charges credits. Relay the footer when it appears:
|
|
|
101
111
|
- **Token missing / 401**: set `PRIV_TOKEN` or run `remixmate login`.
|
|
102
112
|
- **`不支持的平台`**: the platform code is not one the backend knows.
|
|
103
113
|
- **`模型响应超时` / timeout**: retry; generating fewer platforms at once also helps.
|
|
104
|
-
-
|
|
114
|
+
- **Rewrite errors**: a draft (`--title` / `--description` / `--tag`) needs `--instruction` and exactly one `--platform`.
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"tier": "tool",
|
|
5
5
|
"category": "consuming",
|
|
6
6
|
"title": "Social Post Copy",
|
|
7
|
-
"description": "Write the text of a social post for a finished video — title, description and hashtags — per platform (text only; it does not upload or publish the video): Douyin (抖音), Xiaohongshu (小红书) and TikTok. Same prompts as the web studio's publish panel, including the platform's length limits and ad-law / community-guideline compliance rules, and the user's saved prompt overrides. Generates all three platforms by default; pass `platform` to pick.
|
|
7
|
+
"description": "Write the text of a social post for a finished video — title, description and hashtags — per platform (text only; it does not upload or publish the video): Douyin (抖音), Xiaohongshu (小红书) and TikTok. Same prompts as the web studio's publish panel, including the platform's length limits and ad-law / community-guideline compliance rules, and the user's saved prompt overrides. Generates all three platforms by default; pass `platform` to pick. Fill the video context yourself from the conversation — topic, hook, source URL, duration, aspect ratio — rather than asking the user; it only writes from what it is given. `instruction` carries the user's own request: alone it shapes a fresh generation, and with the current title/description/tags (from an earlier run in the conversation) it rewrites that caption instead. Each platform is one LLM call and costs credits.",
|
|
8
8
|
"auth": "required",
|
|
9
9
|
"envVars": [
|
|
10
10
|
"PRIV_TOKEN",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"properties": {
|
|
21
21
|
"topic": {
|
|
22
22
|
"type": "string",
|
|
23
|
-
"description": "What the video is about — the main input for the copy (
|
|
23
|
+
"description": "What the video is about — the main input for the copy. Take it from the conversation (video title, script, source page). Required unless rewriting an existing caption."
|
|
24
24
|
},
|
|
25
25
|
"platform": {
|
|
26
26
|
"type": "array",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
},
|
|
52
52
|
"instruction": {
|
|
53
53
|
"type": "string",
|
|
54
|
-
"description": "
|
|
54
|
+
"description": "The user's request for how the copy should read, e.g. 'shorter title, drop the emoji'. Alone: applied as an extra requirement to a fresh generation. With the current title / description / tag: rewrites that caption (exactly one platform). Max 500 characters."
|
|
55
55
|
},
|
|
56
56
|
"title": {
|
|
57
57
|
"type": "string",
|
|
@@ -89,22 +89,21 @@
|
|
|
89
89
|
},
|
|
90
90
|
"ui": {
|
|
91
91
|
"primary": [
|
|
92
|
-
"topic",
|
|
93
92
|
"platform",
|
|
94
|
-
"
|
|
93
|
+
"instruction"
|
|
95
94
|
],
|
|
96
|
-
"advanced": [
|
|
95
|
+
"advanced": [],
|
|
96
|
+
"hidden": [
|
|
97
|
+
"topic",
|
|
98
|
+
"hook",
|
|
97
99
|
"source_url",
|
|
98
100
|
"duration",
|
|
99
101
|
"aspect_ratio",
|
|
100
102
|
"language",
|
|
101
|
-
"instruction",
|
|
102
103
|
"title",
|
|
103
104
|
"description",
|
|
104
105
|
"tag",
|
|
105
|
-
"prompt"
|
|
106
|
-
],
|
|
107
|
-
"hidden": [
|
|
106
|
+
"prompt",
|
|
108
107
|
"render_id",
|
|
109
108
|
"video_project_id",
|
|
110
109
|
"json_output"
|