@aswless_854771076/ai_short_studio_cli 0.1.43 → 0.1.45
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 +33 -8
- package/dist/auth/session-cache.d.ts +20 -0
- package/dist/auth/session-cache.js +76 -0
- package/dist/auth/session-manager.d.ts +5 -0
- package/dist/auth/session-manager.js +40 -13
- package/dist/command-helpers.d.ts +1 -0
- package/dist/command-helpers.js +12 -0
- package/dist/commands/canvas/apply.d.ts +2 -0
- package/dist/commands/canvas/apply.js +20 -2
- package/dist/commands/canvas/inspect.d.ts +19 -0
- package/dist/commands/canvas/inspect.js +36 -0
- package/dist/commands/canvas/node/run.d.ts +3 -1
- package/dist/commands/canvas/node/run.js +33 -7
- package/dist/commands/canvas/node/update-many.d.ts +13 -0
- package/dist/commands/canvas/node/update-many.js +48 -0
- package/dist/commands/canvas/node/update.d.ts +5 -0
- package/dist/commands/canvas/node/update.js +46 -2
- package/dist/commands/task/wait.d.ts +3 -1
- package/dist/commands/task/wait.js +19 -5
- package/dist/config/profiles.d.ts +1 -0
- package/dist/config/profiles.js +1 -1
- package/dist/domain/vvicat-api.d.ts +20 -0
- package/dist/domain/vvicat-api.js +116 -13
- package/dist/runtime.js +4 -1
- package/dist/skill/skill-manager.d.ts +13 -13
- package/dist/skill/skill-manager.js +1 -1
- package/package.json +2 -1
- package/scripts/postinstall.mjs +2 -2
- package/skills/humanizer/LICENSE +21 -0
- package/skills/humanizer/SKILL.md +412 -0
- package/skills/using-vvicat-ai-short-studio-cli/SKILL.md +21 -8
- package/skills/using-vvicat-ai-short-studio-cli/references/commands.md +17 -6
|
@@ -3,6 +3,50 @@ import { BaseCommand } from '../../../base-command.js';
|
|
|
3
3
|
import { commandApi, projectFlag, readJsonInput } from '../../../command-helpers.js';
|
|
4
4
|
export default class CanvasNodeUpdate extends BaseCommand {
|
|
5
5
|
static args = { nodeId: Args.string({ required: true }) };
|
|
6
|
-
static flags = {
|
|
7
|
-
|
|
6
|
+
static flags = {
|
|
7
|
+
...BaseCommand.baseFlags,
|
|
8
|
+
project: projectFlag,
|
|
9
|
+
config: Flags.string({ description: '配置 patch JSON 文件;无字段参数时省略可读取 stdin' }),
|
|
10
|
+
set: Flags.string({ description: '设置配置字段:key=<JSON>,可重复指定', multiple: true }),
|
|
11
|
+
unset: Flags.string({ description: '删除可选配置字段,可重复指定', multiple: true }),
|
|
12
|
+
title: Flags.string({ description: '修改节点标题' }),
|
|
13
|
+
x: Flags.integer({ description: '修改节点横坐标' }),
|
|
14
|
+
y: Flags.integer({ description: '修改节点纵坐标' }),
|
|
15
|
+
};
|
|
16
|
+
async run() {
|
|
17
|
+
const { args, flags } = await this.parse(CanvasNodeUpdate);
|
|
18
|
+
const hasFieldFlags = Boolean(flags.set?.length || flags.unset?.length || flags.title !== undefined || flags.x !== undefined || flags.y !== undefined);
|
|
19
|
+
const filePatch = flags.config || !hasFieldFlags ? await readJsonInput(flags.config) : {};
|
|
20
|
+
const set = { ...filePatch, ...parseAssignments(flags.set ?? []) };
|
|
21
|
+
const unset = flags.unset ?? [];
|
|
22
|
+
const overlap = unset.find((key) => Object.prototype.hasOwnProperty.call(set, key));
|
|
23
|
+
if (overlap)
|
|
24
|
+
throw new Error(`字段不能同时 set 和 unset:${overlap}`);
|
|
25
|
+
const { api } = await commandApi(flags);
|
|
26
|
+
this.print(await api.updateNodeFields(flags.project, {
|
|
27
|
+
nodeId: args.nodeId,
|
|
28
|
+
set,
|
|
29
|
+
unset,
|
|
30
|
+
title: flags.title,
|
|
31
|
+
x: flags.x,
|
|
32
|
+
y: flags.y,
|
|
33
|
+
}));
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function parseAssignments(assignments) {
|
|
37
|
+
return Object.fromEntries(assignments.map((assignment) => {
|
|
38
|
+
const separator = assignment.indexOf('=');
|
|
39
|
+
if (separator < 1)
|
|
40
|
+
throw new Error(`--set 必须使用 key=<JSON>:${assignment}`);
|
|
41
|
+
const key = assignment.slice(0, separator).trim();
|
|
42
|
+
const source = assignment.slice(separator + 1);
|
|
43
|
+
if (!key)
|
|
44
|
+
throw new Error('--set 字段名不能为空');
|
|
45
|
+
try {
|
|
46
|
+
return [key, JSON.parse(source)];
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
return [key, source];
|
|
50
|
+
}
|
|
51
|
+
}));
|
|
8
52
|
}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { BaseCommand } from '../../base-command.js';
|
|
2
2
|
export default class TaskWait extends BaseCommand {
|
|
3
3
|
static args: {
|
|
4
|
-
taskId: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
4
|
+
taskId: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
5
5
|
};
|
|
6
6
|
static flags: {
|
|
7
|
+
task: import("@oclif/core/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
8
|
+
concurrency: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
|
|
7
9
|
interval: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
|
|
8
10
|
'base-url': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
9
11
|
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
@@ -1,9 +1,23 @@
|
|
|
1
1
|
import { Args, Flags } from '@oclif/core';
|
|
2
2
|
import { BaseCommand } from '../../base-command.js';
|
|
3
|
-
import { commandApi } from '../../command-helpers.js';
|
|
3
|
+
import { commandApi, mapConcurrent } from '../../command-helpers.js';
|
|
4
4
|
export default class TaskWait extends BaseCommand {
|
|
5
|
-
static args = { taskId: Args.string({ required:
|
|
6
|
-
static flags = {
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
static args = { taskId: Args.string({ required: false }) };
|
|
6
|
+
static flags = {
|
|
7
|
+
...BaseCommand.baseFlags,
|
|
8
|
+
task: Flags.string({ description: '任务 ID,可重复指定以批量等待', multiple: true }),
|
|
9
|
+
concurrency: Flags.integer({ description: '批量轮询并发数', default: 4, min: 1, max: 16 }),
|
|
10
|
+
interval: Flags.integer({ default: 1000 }),
|
|
11
|
+
};
|
|
12
|
+
async run() {
|
|
13
|
+
const { args, flags } = await this.parse(TaskWait);
|
|
14
|
+
const taskIds = [...new Set([...(args.taskId ? [args.taskId] : []), ...(flags.task ?? [])])];
|
|
15
|
+
if (!taskIds.length)
|
|
16
|
+
throw new Error('请提供 taskId 或至少一个 --task');
|
|
17
|
+
const { api } = await commandApi(flags);
|
|
18
|
+
const tasks = await mapConcurrent(taskIds, flags.concurrency, async (taskId) => await api.waitTask(taskId, flags.interval));
|
|
19
|
+
this.print(tasks.length === 1 ? tasks[0] : { tasks });
|
|
20
|
+
if (tasks.some((task) => task.status !== 'completed'))
|
|
21
|
+
this.error('部分任务未成功完成', { exit: 8 });
|
|
22
|
+
}
|
|
9
23
|
}
|
|
@@ -5,6 +5,7 @@ export interface CliProfile {
|
|
|
5
5
|
supabaseUrl?: string;
|
|
6
6
|
supabasePublishableKey?: string;
|
|
7
7
|
}
|
|
8
|
+
export declare function defaultConfigDirectory(environment: NodeJS.ProcessEnv): string;
|
|
8
9
|
export declare class ProfileStore {
|
|
9
10
|
readonly path: string;
|
|
10
11
|
constructor(directory?: string);
|
package/dist/config/profiles.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { homedir } from 'node:os';
|
|
2
2
|
import { dirname, join } from 'node:path';
|
|
3
3
|
import { chmod, mkdir, readFile, rename, writeFile } from 'node:fs/promises';
|
|
4
|
-
function defaultConfigDirectory(environment) {
|
|
4
|
+
export function defaultConfigDirectory(environment) {
|
|
5
5
|
if (environment.VVICAT_CONFIG_DIR)
|
|
6
6
|
return environment.VVICAT_CONFIG_DIR;
|
|
7
7
|
if (process.platform === 'win32')
|
|
@@ -28,6 +28,23 @@ interface NodeType extends JsonObject {
|
|
|
28
28
|
defaultConfig: JsonObject;
|
|
29
29
|
configSchema: JsonObject;
|
|
30
30
|
}
|
|
31
|
+
export interface CanvasInspectOptions {
|
|
32
|
+
includes: Array<'summary' | 'nodes' | 'edges' | 'assets' | 'settings' | 'node-types'>;
|
|
33
|
+
kinds?: string[];
|
|
34
|
+
statuses?: string[];
|
|
35
|
+
search?: string;
|
|
36
|
+
operation?: string;
|
|
37
|
+
resourceType?: string;
|
|
38
|
+
producerNodeId?: string;
|
|
39
|
+
}
|
|
40
|
+
export interface NodeFieldUpdate {
|
|
41
|
+
nodeId: string;
|
|
42
|
+
set?: JsonObject;
|
|
43
|
+
unset?: string[];
|
|
44
|
+
title?: string;
|
|
45
|
+
x?: number;
|
|
46
|
+
y?: number;
|
|
47
|
+
}
|
|
31
48
|
export declare class VvicatApi {
|
|
32
49
|
private readonly client;
|
|
33
50
|
private readonly sleep;
|
|
@@ -55,6 +72,7 @@ export declare class VvicatApi {
|
|
|
55
72
|
listNodes(projectId: string): Promise<CanvasNode[]>;
|
|
56
73
|
node(projectId: string, nodeId: string): Promise<CanvasNode>;
|
|
57
74
|
listEdges(projectId: string): Promise<JsonObject[]>;
|
|
75
|
+
inspectCanvas(projectId: string, options: CanvasInspectOptions): Promise<JsonObject>;
|
|
58
76
|
continuityAnalysis(projectId: string): Promise<JsonObject>;
|
|
59
77
|
applyContinuity(projectId: string, input: {
|
|
60
78
|
expectedVersion: number;
|
|
@@ -77,6 +95,8 @@ export declare class VvicatApi {
|
|
|
77
95
|
config?: JsonObject;
|
|
78
96
|
}): Promise<JsonObject>;
|
|
79
97
|
updateNode(projectId: string, nodeId: string, config: JsonObject): Promise<JsonObject>;
|
|
98
|
+
updateNodeFields(projectId: string, update: NodeFieldUpdate): Promise<JsonObject>;
|
|
99
|
+
updateNodes(projectId: string, updates: NodeFieldUpdate[]): Promise<JsonObject>;
|
|
80
100
|
deleteNode(projectId: string, nodeId: string): Promise<JsonObject>;
|
|
81
101
|
connect(projectId: string, input: {
|
|
82
102
|
sourceNodeId: string;
|
|
@@ -49,6 +49,15 @@ function validateConfigSchema(nodeType, config, requiredValues = config ?? {}) {
|
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
|
+
function validateUnsetConfigFields(nodeType, fields) {
|
|
53
|
+
const properties = nodeType.configSchema?.properties;
|
|
54
|
+
if (!properties || typeof properties !== 'object' || Array.isArray(properties))
|
|
55
|
+
return;
|
|
56
|
+
for (const field of fields) {
|
|
57
|
+
if (!(field in properties))
|
|
58
|
+
throw new Error(`节点 ${nodeType.kind} 的 ${field} 不在实时 schema 中`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
52
61
|
export class VvicatApi {
|
|
53
62
|
client;
|
|
54
63
|
sleep;
|
|
@@ -111,6 +120,29 @@ export class VvicatApi {
|
|
|
111
120
|
async listEdges(projectId) {
|
|
112
121
|
return (await this.canvas(projectId)).edges;
|
|
113
122
|
}
|
|
123
|
+
async inspectCanvas(projectId, options) {
|
|
124
|
+
const canvas = await this.canvas(projectId);
|
|
125
|
+
const nodes = canvas.nodes.filter((node) => matchesInspectNode(node, options));
|
|
126
|
+
const nodeIds = new Set(nodes.map((node) => node.id));
|
|
127
|
+
const filtered = hasInspectFilter(options);
|
|
128
|
+
const edges = filtered
|
|
129
|
+
? canvas.edges.filter((edge) => nodeIds.has(String(edge.sourceNodeId)) || nodeIds.has(String(edge.targetNodeId)))
|
|
130
|
+
: canvas.edges;
|
|
131
|
+
const [assets, settings, nodeTypes] = await Promise.all([
|
|
132
|
+
options.includes.includes('assets') ? this.listAssets(projectId) : undefined,
|
|
133
|
+
options.includes.includes('settings') ? this.canvasSettings(projectId) : undefined,
|
|
134
|
+
options.includes.includes('node-types') ? this.nodeTypes() : undefined,
|
|
135
|
+
]);
|
|
136
|
+
return {
|
|
137
|
+
canvas: { id: canvas.id, version: canvas.version, viewport: canvas.viewport },
|
|
138
|
+
...(options.includes.includes('summary') ? { summary: canvasSummary(canvas, nodes) } : {}),
|
|
139
|
+
...(options.includes.includes('nodes') ? { nodes } : {}),
|
|
140
|
+
...(options.includes.includes('edges') ? { edges } : {}),
|
|
141
|
+
...(assets === undefined ? {} : { assets }),
|
|
142
|
+
...(settings === undefined ? {} : { settings }),
|
|
143
|
+
...(nodeTypes === undefined ? {} : { nodeTypes }),
|
|
144
|
+
};
|
|
145
|
+
}
|
|
114
146
|
async continuityAnalysis(projectId) {
|
|
115
147
|
const payload = await this.client.request(`/api/projects/${projectId}/canvas/continuity`);
|
|
116
148
|
return payload.data.analysis;
|
|
@@ -163,22 +195,48 @@ export class VvicatApi {
|
|
|
163
195
|
});
|
|
164
196
|
}
|
|
165
197
|
async updateNode(projectId, nodeId, config) {
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
if (
|
|
175
|
-
throw new Error(
|
|
176
|
-
const
|
|
177
|
-
|
|
198
|
+
return this.updateNodeFields(projectId, { nodeId, set: config });
|
|
199
|
+
}
|
|
200
|
+
async updateNodeFields(projectId, update) {
|
|
201
|
+
return this.updateNodes(projectId, [update]);
|
|
202
|
+
}
|
|
203
|
+
async updateNodes(projectId, updates) {
|
|
204
|
+
if (!updates.length)
|
|
205
|
+
throw new Error('updates 不能为空');
|
|
206
|
+
if (new Set(updates.map((update) => update.nodeId)).size !== updates.length)
|
|
207
|
+
throw new Error('同一节点不能在一个批次中重复更新');
|
|
208
|
+
const [canvas, catalog] = await Promise.all([this.canvas(projectId), this.nodeTypes()]);
|
|
209
|
+
const upsertNodes = updates.map((update) => {
|
|
210
|
+
const node = canvas.nodes.find((item) => item.id === update.nodeId);
|
|
211
|
+
if (!node)
|
|
212
|
+
throw new Error(`节点不存在:${update.nodeId}`);
|
|
213
|
+
const definitionVersionId = typeof node.data.definitionVersionId === 'string' ? node.data.definitionVersionId : null;
|
|
214
|
+
const definition = catalog.nodeTypes.find((item) => item.kind === node.kind)
|
|
215
|
+
?? (definitionVersionId ? canvas.nodeTypesByVersionId?.[definitionVersionId] : undefined);
|
|
216
|
+
if (!definition)
|
|
217
|
+
throw new Error(`未知节点类型:${node.kind}`);
|
|
218
|
+
const configPatch = update.set ?? {};
|
|
219
|
+
const unsetFields = update.unset ?? [];
|
|
220
|
+
const overlappingFields = unsetFields.filter((key) => Object.prototype.hasOwnProperty.call(configPatch, key));
|
|
221
|
+
if (overlappingFields.length)
|
|
222
|
+
throw new Error(`字段不能同时设置和移除:${overlappingFields.join(', ')}`);
|
|
223
|
+
const nextConfig = { ...node.data.config, ...configPatch };
|
|
224
|
+
for (const key of unsetFields)
|
|
225
|
+
delete nextConfig[key];
|
|
226
|
+
validateUnsetConfigFields(definition, unsetFields);
|
|
227
|
+
validateConfigSchema(definition, configPatch, nextConfig);
|
|
228
|
+
return {
|
|
229
|
+
...node,
|
|
230
|
+
...(update.title === undefined ? {} : { title: update.title }),
|
|
231
|
+
...(update.x === undefined ? {} : { x: update.x }),
|
|
232
|
+
...(update.y === undefined ? {} : { y: update.y }),
|
|
233
|
+
data: { ...node.data, config: nextConfig },
|
|
234
|
+
};
|
|
235
|
+
});
|
|
178
236
|
return this.patchCanvas(projectId, {
|
|
179
237
|
canvasId: canvas.id,
|
|
180
238
|
expectedVersion: canvas.version,
|
|
181
|
-
upsertNodes
|
|
239
|
+
upsertNodes,
|
|
182
240
|
});
|
|
183
241
|
}
|
|
184
242
|
async deleteNode(projectId, nodeId) {
|
|
@@ -247,3 +305,48 @@ export class VvicatApi {
|
|
|
247
305
|
return this.client.request(path, options);
|
|
248
306
|
}
|
|
249
307
|
}
|
|
308
|
+
function matchesInspectNode(node, options) {
|
|
309
|
+
const artifact = node.data.artifact && typeof node.data.artifact === 'object' && !Array.isArray(node.data.artifact)
|
|
310
|
+
? node.data.artifact
|
|
311
|
+
: {};
|
|
312
|
+
if (options.kinds?.length && !options.kinds.includes(node.kind))
|
|
313
|
+
return false;
|
|
314
|
+
if (options.statuses?.length && !options.statuses.includes(String(node.status ?? 'idle')))
|
|
315
|
+
return false;
|
|
316
|
+
if (options.operation && artifact.operation !== options.operation)
|
|
317
|
+
return false;
|
|
318
|
+
if (options.resourceType && artifact.resourceType !== options.resourceType)
|
|
319
|
+
return false;
|
|
320
|
+
if (options.producerNodeId && artifact.producerNodeId !== options.producerNodeId)
|
|
321
|
+
return false;
|
|
322
|
+
if (options.search) {
|
|
323
|
+
const query = options.search.toLocaleLowerCase();
|
|
324
|
+
const candidates = [node.id, node.title, artifact.name, artifact.resourceKey];
|
|
325
|
+
if (!candidates.some((value) => typeof value === 'string' && value.toLocaleLowerCase().includes(query)))
|
|
326
|
+
return false;
|
|
327
|
+
}
|
|
328
|
+
return true;
|
|
329
|
+
}
|
|
330
|
+
function hasInspectFilter(options) {
|
|
331
|
+
return Boolean(options.kinds?.length || options.statuses?.length || options.search || options.operation || options.resourceType || options.producerNodeId);
|
|
332
|
+
}
|
|
333
|
+
function canvasSummary(canvas, matchedNodes) {
|
|
334
|
+
const nodesByKind = {};
|
|
335
|
+
const nodesByStatus = {};
|
|
336
|
+
for (const node of canvas.nodes) {
|
|
337
|
+
nodesByKind[node.kind] = (nodesByKind[node.kind] ?? 0) + 1;
|
|
338
|
+
const status = String(node.status ?? 'idle');
|
|
339
|
+
nodesByStatus[status] = (nodesByStatus[status] ?? 0) + 1;
|
|
340
|
+
}
|
|
341
|
+
const nodeIds = new Set(canvas.nodes.map((node) => node.id));
|
|
342
|
+
return {
|
|
343
|
+
nodeCount: canvas.nodes.length,
|
|
344
|
+
matchedNodeCount: matchedNodes.length,
|
|
345
|
+
edgeCount: canvas.edges.length,
|
|
346
|
+
danglingEdgeIds: canvas.edges
|
|
347
|
+
.filter((edge) => !nodeIds.has(String(edge.sourceNodeId)) || !nodeIds.has(String(edge.targetNodeId)))
|
|
348
|
+
.map((edge) => edge.id),
|
|
349
|
+
nodesByKind,
|
|
350
|
+
nodesByStatus,
|
|
351
|
+
};
|
|
352
|
+
}
|
package/dist/runtime.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { ApiClient } from './client/api-client.js';
|
|
2
|
+
import { join } from 'node:path';
|
|
2
3
|
import { KeyringCredentialStore } from './auth/credential-store.js';
|
|
3
4
|
import { SessionManager, SupabaseAuthProvider } from './auth/session-manager.js';
|
|
4
|
-
import {
|
|
5
|
+
import { FileAccessTokenCache } from './auth/session-cache.js';
|
|
6
|
+
import { defaultConfigDirectory, ProfileStore } from './config/profiles.js';
|
|
5
7
|
import { fetchBootstrap } from './preflight.js';
|
|
6
8
|
export const DEFAULT_BASE_URL = 'https://ai-short-studio.vvicat.dev';
|
|
7
9
|
export async function createRuntime(flags) {
|
|
@@ -28,6 +30,7 @@ export async function createRuntime(flags) {
|
|
|
28
30
|
const session = new SessionManager({
|
|
29
31
|
profile: profile.name,
|
|
30
32
|
credentials: new KeyringCredentialStore(),
|
|
33
|
+
cache: new FileAccessTokenCache(join(defaultConfigDirectory(process.env), 'sessions')),
|
|
31
34
|
provider: new SupabaseAuthProvider(profile.supabaseUrl, profile.supabasePublishableKey),
|
|
32
35
|
});
|
|
33
36
|
return {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const BUNDLED_SKILL_NAMES: readonly ["using-vvicat-ai-short-studio-cli", "short-drama"];
|
|
1
|
+
export declare const BUNDLED_SKILL_NAMES: readonly ["using-vvicat-ai-short-studio-cli", "short-drama", "humanizer"];
|
|
2
2
|
export type BundledSkillName = typeof BUNDLED_SKILL_NAMES[number];
|
|
3
3
|
export type SkillTarget = 'codex' | 'agents';
|
|
4
4
|
export declare function bundledSkillPath(name?: BundledSkillName): string;
|
|
@@ -6,7 +6,7 @@ export declare function defaultSkillsRoot(target: SkillTarget): string;
|
|
|
6
6
|
export declare function defaultSkillTarget(target: SkillTarget): string;
|
|
7
7
|
export declare function normalizeSkillsRoot(path: string): string;
|
|
8
8
|
export declare function skillStatus(target: string): Promise<{
|
|
9
|
-
name: "using-vvicat-ai-short-studio-cli" | "short-drama";
|
|
9
|
+
name: "using-vvicat-ai-short-studio-cli" | "short-drama" | "humanizer";
|
|
10
10
|
target: string;
|
|
11
11
|
installed: boolean;
|
|
12
12
|
managed: boolean;
|
|
@@ -24,7 +24,7 @@ export declare function installSkills(input: {
|
|
|
24
24
|
current: boolean;
|
|
25
25
|
skills: ({
|
|
26
26
|
action: "unchanged";
|
|
27
|
-
name: "using-vvicat-ai-short-studio-cli" | "short-drama";
|
|
27
|
+
name: "using-vvicat-ai-short-studio-cli" | "short-drama" | "humanizer";
|
|
28
28
|
target: string;
|
|
29
29
|
installed: boolean;
|
|
30
30
|
managed: boolean;
|
|
@@ -34,7 +34,7 @@ export declare function installSkills(input: {
|
|
|
34
34
|
modified: boolean;
|
|
35
35
|
} | {
|
|
36
36
|
action: "skipped";
|
|
37
|
-
name: "using-vvicat-ai-short-studio-cli" | "short-drama";
|
|
37
|
+
name: "using-vvicat-ai-short-studio-cli" | "short-drama" | "humanizer";
|
|
38
38
|
target: string;
|
|
39
39
|
installed: boolean;
|
|
40
40
|
managed: boolean;
|
|
@@ -44,7 +44,7 @@ export declare function installSkills(input: {
|
|
|
44
44
|
modified: boolean;
|
|
45
45
|
} | {
|
|
46
46
|
action: "updated" | "installed";
|
|
47
|
-
name: "using-vvicat-ai-short-studio-cli" | "short-drama";
|
|
47
|
+
name: "using-vvicat-ai-short-studio-cli" | "short-drama" | "humanizer";
|
|
48
48
|
target: string;
|
|
49
49
|
installed: boolean;
|
|
50
50
|
managed: boolean;
|
|
@@ -59,7 +59,7 @@ export declare function autoInstallSkills(root: string): Promise<{
|
|
|
59
59
|
current: boolean;
|
|
60
60
|
skills: ({
|
|
61
61
|
action: "unchanged";
|
|
62
|
-
name: "using-vvicat-ai-short-studio-cli" | "short-drama";
|
|
62
|
+
name: "using-vvicat-ai-short-studio-cli" | "short-drama" | "humanizer";
|
|
63
63
|
target: string;
|
|
64
64
|
installed: boolean;
|
|
65
65
|
managed: boolean;
|
|
@@ -69,7 +69,7 @@ export declare function autoInstallSkills(root: string): Promise<{
|
|
|
69
69
|
modified: boolean;
|
|
70
70
|
} | {
|
|
71
71
|
action: "skipped";
|
|
72
|
-
name: "using-vvicat-ai-short-studio-cli" | "short-drama";
|
|
72
|
+
name: "using-vvicat-ai-short-studio-cli" | "short-drama" | "humanizer";
|
|
73
73
|
target: string;
|
|
74
74
|
installed: boolean;
|
|
75
75
|
managed: boolean;
|
|
@@ -79,7 +79,7 @@ export declare function autoInstallSkills(root: string): Promise<{
|
|
|
79
79
|
modified: boolean;
|
|
80
80
|
} | {
|
|
81
81
|
action: "updated" | "installed";
|
|
82
|
-
name: "using-vvicat-ai-short-studio-cli" | "short-drama";
|
|
82
|
+
name: "using-vvicat-ai-short-studio-cli" | "short-drama" | "humanizer";
|
|
83
83
|
target: string;
|
|
84
84
|
installed: boolean;
|
|
85
85
|
managed: boolean;
|
|
@@ -93,7 +93,7 @@ export declare function skillStatuses(rootInput: string): Promise<{
|
|
|
93
93
|
root: string;
|
|
94
94
|
current: boolean;
|
|
95
95
|
skills: {
|
|
96
|
-
name: "using-vvicat-ai-short-studio-cli" | "short-drama";
|
|
96
|
+
name: "using-vvicat-ai-short-studio-cli" | "short-drama" | "humanizer";
|
|
97
97
|
target: string;
|
|
98
98
|
installed: boolean;
|
|
99
99
|
managed: boolean;
|
|
@@ -107,7 +107,7 @@ export declare function installSkill(input: {
|
|
|
107
107
|
target: string;
|
|
108
108
|
force?: boolean;
|
|
109
109
|
}): Promise<{
|
|
110
|
-
name: "using-vvicat-ai-short-studio-cli" | "short-drama";
|
|
110
|
+
name: "using-vvicat-ai-short-studio-cli" | "short-drama" | "humanizer";
|
|
111
111
|
target: string;
|
|
112
112
|
installed: boolean;
|
|
113
113
|
managed: boolean;
|
|
@@ -117,7 +117,7 @@ export declare function installSkill(input: {
|
|
|
117
117
|
modified: boolean;
|
|
118
118
|
}>;
|
|
119
119
|
export declare function autoInstallSkill(target: string): Promise<{
|
|
120
|
-
name: "using-vvicat-ai-short-studio-cli" | "short-drama";
|
|
120
|
+
name: "using-vvicat-ai-short-studio-cli" | "short-drama" | "humanizer";
|
|
121
121
|
target: string;
|
|
122
122
|
installed: boolean;
|
|
123
123
|
managed: boolean;
|
|
@@ -127,7 +127,7 @@ export declare function autoInstallSkill(target: string): Promise<{
|
|
|
127
127
|
modified: boolean;
|
|
128
128
|
action: "unchanged";
|
|
129
129
|
} | {
|
|
130
|
-
name: "using-vvicat-ai-short-studio-cli" | "short-drama";
|
|
130
|
+
name: "using-vvicat-ai-short-studio-cli" | "short-drama" | "humanizer";
|
|
131
131
|
target: string;
|
|
132
132
|
installed: boolean;
|
|
133
133
|
managed: boolean;
|
|
@@ -137,7 +137,7 @@ export declare function autoInstallSkill(target: string): Promise<{
|
|
|
137
137
|
modified: boolean;
|
|
138
138
|
action: "skipped";
|
|
139
139
|
} | {
|
|
140
|
-
name: "using-vvicat-ai-short-studio-cli" | "short-drama";
|
|
140
|
+
name: "using-vvicat-ai-short-studio-cli" | "short-drama" | "humanizer";
|
|
141
141
|
target: string;
|
|
142
142
|
installed: boolean;
|
|
143
143
|
managed: boolean;
|
|
@@ -3,7 +3,7 @@ import { cp, mkdir, readFile, readdir, rename, rm, stat, writeFile } from 'node:
|
|
|
3
3
|
import { homedir } from 'node:os';
|
|
4
4
|
import { basename, dirname, join, relative } from 'node:path';
|
|
5
5
|
import { fileURLToPath } from 'node:url';
|
|
6
|
-
export const BUNDLED_SKILL_NAMES = ['using-vvicat-ai-short-studio-cli', 'short-drama'];
|
|
6
|
+
export const BUNDLED_SKILL_NAMES = ['using-vvicat-ai-short-studio-cli', 'short-drama', 'humanizer'];
|
|
7
7
|
const PACKAGE_JSON = fileURLToPath(new URL('../../package.json', import.meta.url));
|
|
8
8
|
const MANIFEST = '.vvicat-skill.json';
|
|
9
9
|
export function bundledSkillPath(name = BUNDLED_SKILL_NAMES[0]) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aswless_854771076/ai_short_studio_cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.45",
|
|
4
4
|
"description": "VVICAT 无限画布项目命令行工具",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"private": false,
|
|
@@ -37,6 +37,7 @@
|
|
|
37
37
|
"release:ci": "npm test && npm run typecheck && node scripts/publish.mjs --tag latest --verify",
|
|
38
38
|
"release": "node scripts/publish.mjs --tag latest",
|
|
39
39
|
"test": "vitest run",
|
|
40
|
+
"test:local-e2e": "npm run build && node scripts/local-e2e.mjs",
|
|
40
41
|
"typecheck": "tsc -p tsconfig.json --noEmit"
|
|
41
42
|
},
|
|
42
43
|
"dependencies": {
|
package/scripts/postinstall.mjs
CHANGED
|
@@ -11,14 +11,14 @@ export function shouldAutoInstallSkill(environment = process.env) {
|
|
|
11
11
|
export async function main(environment = process.env) {
|
|
12
12
|
if (!shouldAutoInstallSkill(environment)) return
|
|
13
13
|
try {
|
|
14
|
-
const { autoInstallSkill, autoInstallSkills, defaultSkillsRoot, installSkills } = await import('../dist/skill/skill-manager.js')
|
|
14
|
+
const { BUNDLED_SKILL_NAMES, autoInstallSkill, autoInstallSkills, defaultSkillsRoot, installSkills } = await import('../dist/skill/skill-manager.js')
|
|
15
15
|
const result = environment.VVICAT_SKILL_DIRECTORY
|
|
16
16
|
? {
|
|
17
17
|
skills: [
|
|
18
18
|
await autoInstallSkill(environment.VVICAT_SKILL_DIRECTORY),
|
|
19
19
|
...(await installSkills({
|
|
20
20
|
root: dirname(environment.VVICAT_SKILL_DIRECTORY),
|
|
21
|
-
skills:
|
|
21
|
+
skills: BUNDLED_SKILL_NAMES.slice(1),
|
|
22
22
|
})).skills,
|
|
23
23
|
],
|
|
24
24
|
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Siqi Chen
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|