@aswless_854771076/ai_short_studio_cli 0.1.0-beta.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 (104) hide show
  1. package/README.md +56 -0
  2. package/bin/run.js +5 -0
  3. package/dist/auth/credential-store.d.ts +6 -0
  4. package/dist/auth/credential-store.js +27 -0
  5. package/dist/auth/google-oauth.d.ts +2 -0
  6. package/dist/auth/google-oauth.js +72 -0
  7. package/dist/auth/session-manager.d.ts +44 -0
  8. package/dist/auth/session-manager.js +100 -0
  9. package/dist/base-command.d.ts +11 -0
  10. package/dist/base-command.js +39 -0
  11. package/dist/client/api-client.d.ts +23 -0
  12. package/dist/client/api-client.js +64 -0
  13. package/dist/client/errors.d.ts +14 -0
  14. package/dist/client/errors.js +34 -0
  15. package/dist/command-helpers.d.ts +10 -0
  16. package/dist/command-helpers.js +24 -0
  17. package/dist/commands/auth/login.d.ts +14 -0
  18. package/dist/commands/auth/login.js +32 -0
  19. package/dist/commands/auth/logout.d.ts +11 -0
  20. package/dist/commands/auth/logout.js +12 -0
  21. package/dist/commands/auth/status.d.ts +11 -0
  22. package/dist/commands/auth/status.js +12 -0
  23. package/dist/commands/canvas/apply.d.ts +12 -0
  24. package/dist/commands/canvas/apply.js +7 -0
  25. package/dist/commands/canvas/asset/download.d.ts +16 -0
  26. package/dist/commands/canvas/asset/download.js +34 -0
  27. package/dist/commands/canvas/asset/get.d.ts +14 -0
  28. package/dist/commands/canvas/asset/get.js +12 -0
  29. package/dist/commands/canvas/asset/list.d.ts +13 -0
  30. package/dist/commands/canvas/asset/list.js +7 -0
  31. package/dist/commands/canvas/asset/select.d.ts +15 -0
  32. package/dist/commands/canvas/asset/select.js +8 -0
  33. package/dist/commands/canvas/asset/upload.d.ts +14 -0
  34. package/dist/commands/canvas/asset/upload.js +10 -0
  35. package/dist/commands/canvas/edge/connect.d.ts +13 -0
  36. package/dist/commands/canvas/edge/connect.js +9 -0
  37. package/dist/commands/canvas/edge/disconnect.d.ts +15 -0
  38. package/dist/commands/canvas/edge/disconnect.js +8 -0
  39. package/dist/commands/canvas/edge/list.d.ts +11 -0
  40. package/dist/commands/canvas/edge/list.js +10 -0
  41. package/dist/commands/canvas/get.d.ts +11 -0
  42. package/dist/commands/canvas/get.js +6 -0
  43. package/dist/commands/canvas/node/add.d.ts +18 -0
  44. package/dist/commands/canvas/node/add.js +8 -0
  45. package/dist/commands/canvas/node/delete.d.ts +15 -0
  46. package/dist/commands/canvas/node/delete.js +8 -0
  47. package/dist/commands/canvas/node/get.d.ts +14 -0
  48. package/dist/commands/canvas/node/get.js +12 -0
  49. package/dist/commands/canvas/node/list.d.ts +11 -0
  50. package/dist/commands/canvas/node/list.js +10 -0
  51. package/dist/commands/canvas/node/run.d.ts +16 -0
  52. package/dist/commands/canvas/node/run.js +11 -0
  53. package/dist/commands/canvas/node/types.d.ts +13 -0
  54. package/dist/commands/canvas/node/types.js +8 -0
  55. package/dist/commands/canvas/node/update.d.ts +15 -0
  56. package/dist/commands/canvas/node/update.js +8 -0
  57. package/dist/commands/config/get.d.ts +10 -0
  58. package/dist/commands/config/get.js +6 -0
  59. package/dist/commands/config/set.d.ts +11 -0
  60. package/dist/commands/config/set.js +7 -0
  61. package/dist/commands/project/create.d.ts +12 -0
  62. package/dist/commands/project/create.js +7 -0
  63. package/dist/commands/project/delete.d.ts +14 -0
  64. package/dist/commands/project/delete.js +8 -0
  65. package/dist/commands/project/get.d.ts +13 -0
  66. package/dist/commands/project/get.js +8 -0
  67. package/dist/commands/project/list.d.ts +14 -0
  68. package/dist/commands/project/list.js +13 -0
  69. package/dist/commands/project/update.d.ts +15 -0
  70. package/dist/commands/project/update.js +9 -0
  71. package/dist/commands/skill/install.d.ts +13 -0
  72. package/dist/commands/skill/install.js +8 -0
  73. package/dist/commands/skill/path.d.ts +10 -0
  74. package/dist/commands/skill/path.js +6 -0
  75. package/dist/commands/skill/status.d.ts +12 -0
  76. package/dist/commands/skill/status.js +7 -0
  77. package/dist/commands/skill/update.d.ts +1 -0
  78. package/dist/commands/skill/update.js +1 -0
  79. package/dist/commands/task/cancel.d.ts +14 -0
  80. package/dist/commands/task/cancel.js +8 -0
  81. package/dist/commands/task/get.d.ts +13 -0
  82. package/dist/commands/task/get.js +8 -0
  83. package/dist/commands/task/wait.d.ts +14 -0
  84. package/dist/commands/task/wait.js +9 -0
  85. package/dist/config/profiles.d.ts +15 -0
  86. package/dist/config/profiles.js +47 -0
  87. package/dist/domain/vvicat-api.d.ts +84 -0
  88. package/dist/domain/vvicat-api.js +144 -0
  89. package/dist/index.d.ts +1 -0
  90. package/dist/index.js +1 -0
  91. package/dist/output/formatter.d.ts +1 -0
  92. package/dist/output/formatter.js +3 -0
  93. package/dist/runtime.d.ts +14 -0
  94. package/dist/runtime.js +45 -0
  95. package/dist/skill/command-flags.d.ts +8 -0
  96. package/dist/skill/command-flags.js +9 -0
  97. package/dist/skill/skill-manager.d.ts +24 -0
  98. package/dist/skill/skill-manager.js +100 -0
  99. package/dist/terminal/prompt.d.ts +2 -0
  100. package/dist/terminal/prompt.js +49 -0
  101. package/package.json +55 -0
  102. package/skills/using-vvicat-cli/SKILL.md +49 -0
  103. package/skills/using-vvicat-cli/agents/openai.yaml +4 -0
  104. package/skills/using-vvicat-cli/references/commands.md +90 -0
@@ -0,0 +1,14 @@
1
+ import { BaseCommand } from '../../base-command.js';
2
+ export default class ProjectList extends BaseCommand {
3
+ static description: string;
4
+ static flags: {
5
+ page: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
6
+ 'page-size': import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
7
+ search: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
8
+ 'base-url': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
9
+ json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
+ locale: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
11
+ profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
12
+ };
13
+ run(): Promise<void>;
14
+ }
@@ -0,0 +1,13 @@
1
+ import { Flags } from '@oclif/core';
2
+ import { BaseCommand } from '../../base-command.js';
3
+ import { commandApi } from '../../command-helpers.js';
4
+ export default class ProjectList extends BaseCommand {
5
+ static description = '列出无限画布项目';
6
+ static flags = { ...BaseCommand.baseFlags, page: Flags.integer({ default: 1 }), 'page-size': Flags.integer({ default: 50 }), search: Flags.string() };
7
+ async run() {
8
+ const { flags } = await this.parse(ProjectList);
9
+ const { api } = await commandApi(flags);
10
+ const query = new URLSearchParams({ page: String(flags.page), pageSize: String(flags['page-size']), ...(flags.search ? { search: flags.search } : {}) });
11
+ this.print({ projects: await api.listProjects(query.toString()) });
12
+ }
13
+ }
@@ -0,0 +1,15 @@
1
+ import { BaseCommand } from '../../base-command.js';
2
+ export default class ProjectUpdate extends BaseCommand {
3
+ static args: {
4
+ projectId: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
5
+ };
6
+ static flags: {
7
+ name: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
8
+ description: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
9
+ 'base-url': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
10
+ json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
11
+ locale: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
12
+ profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
13
+ };
14
+ run(): Promise<void>;
15
+ }
@@ -0,0 +1,9 @@
1
+ import { Args, Flags } from '@oclif/core';
2
+ import { BaseCommand } from '../../base-command.js';
3
+ import { commandApi } from '../../command-helpers.js';
4
+ export default class ProjectUpdate extends BaseCommand {
5
+ static args = { projectId: Args.string({ required: true }) };
6
+ static flags = { ...BaseCommand.baseFlags, name: Flags.string(), description: Flags.string() };
7
+ async run() { const { args, flags } = await this.parse(ProjectUpdate); if (!flags.name && flags.description === undefined)
8
+ this.error('至少传入 --name 或 --description'); const { api } = await commandApi(flags); this.print(await api.updateProject(args.projectId, { name: flags.name, description: flags.description })); }
9
+ }
@@ -0,0 +1,13 @@
1
+ import { BaseCommand } from '../../base-command.js';
2
+ export default class SkillInstall extends BaseCommand {
3
+ static flags: {
4
+ force: import("@oclif/core/interfaces").BooleanFlag<boolean>;
5
+ target: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
6
+ directory: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
7
+ 'base-url': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
8
+ json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
9
+ locale: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
10
+ profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
+ };
12
+ run(): Promise<void>;
13
+ }
@@ -0,0 +1,8 @@
1
+ import { Flags } from '@oclif/core';
2
+ import { BaseCommand } from '../../base-command.js';
3
+ import { installSkill } from '../../skill/skill-manager.js';
4
+ import { resolveSkillTarget, skillFlags } from '../../skill/command-flags.js';
5
+ export default class SkillInstall extends BaseCommand {
6
+ static flags = { ...BaseCommand.baseFlags, ...skillFlags, force: Flags.boolean({ description: '覆盖非托管或已修改的 Skill' }) };
7
+ async run() { const { flags } = await this.parse(SkillInstall); this.print(await installSkill({ target: resolveSkillTarget(flags), force: flags.force })); }
8
+ }
@@ -0,0 +1,10 @@
1
+ import { BaseCommand } from '../../base-command.js';
2
+ export default class SkillPath extends BaseCommand {
3
+ static flags: {
4
+ 'base-url': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
5
+ json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
6
+ locale: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
7
+ profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
8
+ };
9
+ run(): Promise<void>;
10
+ }
@@ -0,0 +1,6 @@
1
+ import { BaseCommand } from '../../base-command.js';
2
+ import { bundledSkillPath } from '../../skill/skill-manager.js';
3
+ export default class SkillPath extends BaseCommand {
4
+ static flags = { ...BaseCommand.baseFlags };
5
+ async run() { await this.parse(SkillPath); this.print({ path: bundledSkillPath() }); }
6
+ }
@@ -0,0 +1,12 @@
1
+ import { BaseCommand } from '../../base-command.js';
2
+ export default class SkillStatus extends BaseCommand {
3
+ static flags: {
4
+ target: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
5
+ directory: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
6
+ 'base-url': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
7
+ json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
8
+ locale: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
9
+ profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
10
+ };
11
+ run(): Promise<void>;
12
+ }
@@ -0,0 +1,7 @@
1
+ import { BaseCommand } from '../../base-command.js';
2
+ import { skillStatus } from '../../skill/skill-manager.js';
3
+ import { resolveSkillTarget, skillFlags } from '../../skill/command-flags.js';
4
+ export default class SkillStatus extends BaseCommand {
5
+ static flags = { ...BaseCommand.baseFlags, ...skillFlags };
6
+ async run() { const { flags } = await this.parse(SkillStatus); this.print(await skillStatus(resolveSkillTarget(flags))); }
7
+ }
@@ -0,0 +1 @@
1
+ export { default } from './install.js';
@@ -0,0 +1 @@
1
+ export { default } from './install.js';
@@ -0,0 +1,14 @@
1
+ import { BaseCommand } from '../../base-command.js';
2
+ export default class TaskCancel extends BaseCommand {
3
+ static args: {
4
+ taskId: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
5
+ };
6
+ static flags: {
7
+ yes: import("@oclif/core/interfaces").BooleanFlag<boolean>;
8
+ 'base-url': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
9
+ json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
+ locale: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
11
+ profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
12
+ };
13
+ run(): Promise<void>;
14
+ }
@@ -0,0 +1,8 @@
1
+ import { Args, Flags } from '@oclif/core';
2
+ import { BaseCommand } from '../../base-command.js';
3
+ import { commandApi } from '../../command-helpers.js';
4
+ export default class TaskCancel extends BaseCommand {
5
+ static args = { taskId: Args.string({ required: true }) };
6
+ static flags = { ...BaseCommand.baseFlags, yes: Flags.boolean({ required: true }) };
7
+ async run() { const { args, flags } = await this.parse(TaskCancel); const { api } = await commandApi(flags); this.print(await api.cancelTask(args.taskId)); }
8
+ }
@@ -0,0 +1,13 @@
1
+ import { BaseCommand } from '../../base-command.js';
2
+ export default class TaskGet extends BaseCommand {
3
+ static args: {
4
+ taskId: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
5
+ };
6
+ static flags: {
7
+ 'base-url': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
8
+ json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
9
+ locale: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
10
+ profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
+ };
12
+ run(): Promise<void>;
13
+ }
@@ -0,0 +1,8 @@
1
+ import { Args } from '@oclif/core';
2
+ import { BaseCommand } from '../../base-command.js';
3
+ import { commandApi } from '../../command-helpers.js';
4
+ export default class TaskGet extends BaseCommand {
5
+ static args = { taskId: Args.string({ required: true }) };
6
+ static flags = BaseCommand.baseFlags;
7
+ async run() { const { args, flags } = await this.parse(TaskGet); const { api } = await commandApi(flags); this.print(await api.task(args.taskId)); }
8
+ }
@@ -0,0 +1,14 @@
1
+ import { BaseCommand } from '../../base-command.js';
2
+ export default class TaskWait extends BaseCommand {
3
+ static args: {
4
+ taskId: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
5
+ };
6
+ static flags: {
7
+ interval: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
8
+ 'base-url': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
9
+ json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
+ locale: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
11
+ profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
12
+ };
13
+ run(): Promise<void>;
14
+ }
@@ -0,0 +1,9 @@
1
+ import { Args, Flags } from '@oclif/core';
2
+ import { BaseCommand } from '../../base-command.js';
3
+ import { commandApi } from '../../command-helpers.js';
4
+ export default class TaskWait extends BaseCommand {
5
+ static args = { taskId: Args.string({ required: true }) };
6
+ static flags = { ...BaseCommand.baseFlags, interval: Flags.integer({ default: 1000 }) };
7
+ async run() { const { args, flags } = await this.parse(TaskWait); const { api } = await commandApi(flags); const task = await api.waitTask(args.taskId, flags.interval); this.print(task); if (task.status !== 'completed')
8
+ this.error(`任务结束:${task.status}`, { exit: 8 }); }
9
+ }
@@ -0,0 +1,15 @@
1
+ export interface CliProfile {
2
+ name: string;
3
+ baseUrl: string;
4
+ defaultProjectId?: string;
5
+ supabaseUrl?: string;
6
+ supabasePublishableKey?: string;
7
+ }
8
+ export declare class ProfileStore {
9
+ readonly path: string;
10
+ constructor(directory?: string);
11
+ current(): Promise<CliProfile | null>;
12
+ get(name: string): Promise<CliProfile | null>;
13
+ save(profile: CliProfile): Promise<void>;
14
+ private read;
15
+ }
@@ -0,0 +1,47 @@
1
+ import { homedir } from 'node:os';
2
+ import { dirname, join } from 'node:path';
3
+ import { chmod, mkdir, readFile, rename, writeFile } from 'node:fs/promises';
4
+ function defaultConfigDirectory(environment) {
5
+ if (environment.VVICAT_CONFIG_DIR)
6
+ return environment.VVICAT_CONFIG_DIR;
7
+ if (process.platform === 'win32')
8
+ return join(environment.APPDATA || homedir(), 'vvicat');
9
+ return join(environment.XDG_CONFIG_HOME || join(homedir(), '.config'), 'vvicat');
10
+ }
11
+ export class ProfileStore {
12
+ path;
13
+ constructor(directory = defaultConfigDirectory(process.env)) {
14
+ this.path = join(directory, 'config.json');
15
+ }
16
+ async current() {
17
+ const document = await this.read();
18
+ return document.profiles[document.currentProfile] ?? null;
19
+ }
20
+ async get(name) {
21
+ return (await this.read()).profiles[name] ?? null;
22
+ }
23
+ async save(profile) {
24
+ const document = await this.read();
25
+ document.currentProfile = profile.name;
26
+ document.profiles[profile.name] = { ...profile, baseUrl: profile.baseUrl.replace(/\/+$/, '') };
27
+ await mkdir(dirname(this.path), { recursive: true, mode: 0o700 });
28
+ const temporaryPath = `${this.path}.${process.pid}.tmp`;
29
+ await writeFile(temporaryPath, `${JSON.stringify(document, null, 2)}\n`, { mode: 0o600 });
30
+ await rename(temporaryPath, this.path);
31
+ await chmod(this.path, 0o600);
32
+ }
33
+ async read() {
34
+ try {
35
+ const parsed = JSON.parse(await readFile(this.path, 'utf8'));
36
+ return {
37
+ currentProfile: typeof parsed.currentProfile === 'string' ? parsed.currentProfile : 'default',
38
+ profiles: parsed.profiles && typeof parsed.profiles === 'object' ? parsed.profiles : {},
39
+ };
40
+ }
41
+ catch (error) {
42
+ if (error.code !== 'ENOENT')
43
+ throw error;
44
+ return { currentProfile: 'default', profiles: {} };
45
+ }
46
+ }
47
+ }
@@ -0,0 +1,84 @@
1
+ import type { ApiClient, ApiRequestOptions } from '../client/api-client.js';
2
+ type JsonObject = Record<string, unknown>;
3
+ type Client = Pick<ApiClient, 'request' | 'response'>;
4
+ interface CanvasNode extends JsonObject {
5
+ id: string;
6
+ kind: string;
7
+ title: string;
8
+ x: number;
9
+ y: number;
10
+ data: {
11
+ schemaVersion: 1;
12
+ config: JsonObject;
13
+ } & JsonObject;
14
+ }
15
+ interface CanvasDto extends JsonObject {
16
+ id: string;
17
+ version: number;
18
+ nodes: CanvasNode[];
19
+ edges: JsonObject[];
20
+ }
21
+ interface NodeType extends JsonObject {
22
+ kind: string;
23
+ title: string;
24
+ defaultConfig: JsonObject;
25
+ }
26
+ export declare class VvicatApi {
27
+ private readonly client;
28
+ private readonly sleep;
29
+ constructor(client: Client, sleep?: (milliseconds: number) => Promise<void>);
30
+ listProjects(query?: string): Promise<JsonObject[]>;
31
+ createProject(input: {
32
+ name: string;
33
+ description?: string | null;
34
+ }): Promise<JsonObject>;
35
+ project(projectId: string): Promise<JsonObject>;
36
+ updateProject(projectId: string, input: {
37
+ name?: string;
38
+ description?: string | null;
39
+ }): Promise<JsonObject>;
40
+ deleteProject(projectId: string): Promise<JsonObject>;
41
+ canvas(projectId: string): Promise<CanvasDto>;
42
+ listNodes(projectId: string): Promise<CanvasNode[]>;
43
+ node(projectId: string, nodeId: string): Promise<CanvasNode>;
44
+ listEdges(projectId: string): Promise<JsonObject[]>;
45
+ patchCanvas(projectId: string, input: JsonObject): Promise<JsonObject>;
46
+ nodeTypes(): Promise<{
47
+ schemaVersion: number;
48
+ nodeTypes: NodeType[];
49
+ }>;
50
+ addNode(projectId: string, input: {
51
+ kind: string;
52
+ x?: number;
53
+ y?: number;
54
+ title?: string;
55
+ config?: JsonObject;
56
+ }): Promise<JsonObject>;
57
+ updateNode(projectId: string, nodeId: string, config: JsonObject): Promise<JsonObject>;
58
+ deleteNode(projectId: string, nodeId: string): Promise<JsonObject>;
59
+ connect(projectId: string, input: {
60
+ sourceNodeId: string;
61
+ sourceHandle: string;
62
+ targetNodeId: string;
63
+ targetHandle: string;
64
+ }): Promise<JsonObject>;
65
+ disconnect(projectId: string, edgeId: string): Promise<JsonObject>;
66
+ runNode(projectId: string, nodeId: string): Promise<JsonObject>;
67
+ listAssets(projectId: string, query?: string): Promise<JsonObject>;
68
+ asset(projectId: string, assetId: string): Promise<JsonObject>;
69
+ selectAssetVersion(projectId: string, assetId: string, versionId: string): Promise<JsonObject>;
70
+ uploadAsset(projectId: string, formData: FormData): Promise<JsonObject>;
71
+ task(taskId: string): Promise<{
72
+ task: JsonObject & {
73
+ status: string;
74
+ };
75
+ }>;
76
+ cancelTask(taskId: string): Promise<JsonObject>;
77
+ waitTask(taskId: string, interval?: number): Promise<JsonObject & {
78
+ status: string;
79
+ }>;
80
+ config(): Promise<JsonObject>;
81
+ updateConfig(input: JsonObject): Promise<JsonObject>;
82
+ raw(path: string, options?: ApiRequestOptions): Promise<unknown>;
83
+ }
84
+ export {};
@@ -0,0 +1,144 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ export class VvicatApi {
3
+ client;
4
+ sleep;
5
+ constructor(client, sleep = (milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds))) {
6
+ this.client = client;
7
+ this.sleep = sleep;
8
+ }
9
+ async listProjects(query = '') {
10
+ const payload = await this.client.request(`/api/projects${query ? `?${query}` : ''}`);
11
+ return payload.projects.filter((project) => project.type === 'INFINITE_CANVAS');
12
+ }
13
+ async createProject(input) {
14
+ return this.client.request('/api/projects', { method: 'POST', body: { ...input, type: 'INFINITE_CANVAS' } });
15
+ }
16
+ project(projectId) {
17
+ return this.client.request(`/api/projects/${projectId}`);
18
+ }
19
+ updateProject(projectId, input) {
20
+ return this.client.request(`/api/projects/${projectId}`, { method: 'PATCH', body: input });
21
+ }
22
+ deleteProject(projectId) {
23
+ return this.client.request(`/api/projects/${projectId}`, { method: 'DELETE' });
24
+ }
25
+ async canvas(projectId) {
26
+ const payload = await this.client.request(`/api/projects/${projectId}/canvas`);
27
+ return payload.data.canvas;
28
+ }
29
+ async listNodes(projectId) {
30
+ return (await this.canvas(projectId)).nodes;
31
+ }
32
+ async node(projectId, nodeId) {
33
+ const node = (await this.canvas(projectId)).nodes.find((item) => item.id === nodeId);
34
+ if (!node)
35
+ throw new Error(`节点不存在:${nodeId}`);
36
+ return node;
37
+ }
38
+ async listEdges(projectId) {
39
+ return (await this.canvas(projectId)).edges;
40
+ }
41
+ patchCanvas(projectId, input) {
42
+ return this.client.request(`/api/projects/${projectId}/canvas`, { method: 'PATCH', body: input });
43
+ }
44
+ async nodeTypes() {
45
+ const payload = await this.client.request('/api/v1/canvas/node-types');
46
+ return payload.data;
47
+ }
48
+ async addNode(projectId, input) {
49
+ const canvas = await this.canvas(projectId);
50
+ const catalog = await this.nodeTypes();
51
+ const definition = catalog.nodeTypes.find((item) => item.kind === input.kind);
52
+ if (!definition)
53
+ throw new Error(`未知节点类型:${input.kind}`);
54
+ const node = {
55
+ id: randomUUID(),
56
+ kind: input.kind,
57
+ title: input.title || definition.title,
58
+ x: input.x ?? 0,
59
+ y: input.y ?? 0,
60
+ data: { schemaVersion: 1, config: { ...definition.defaultConfig, ...input.config } },
61
+ };
62
+ return this.patchCanvas(projectId, {
63
+ canvasId: canvas.id,
64
+ expectedVersion: canvas.version,
65
+ upsertNodes: [node],
66
+ });
67
+ }
68
+ async updateNode(projectId, nodeId, config) {
69
+ const canvas = await this.canvas(projectId);
70
+ const node = canvas.nodes.find((item) => item.id === nodeId);
71
+ if (!node)
72
+ throw new Error(`节点不存在:${nodeId}`);
73
+ return this.patchCanvas(projectId, {
74
+ canvasId: canvas.id,
75
+ expectedVersion: canvas.version,
76
+ upsertNodes: [{ ...node, data: { ...node.data, config: { ...node.data.config, ...config } } }],
77
+ });
78
+ }
79
+ async deleteNode(projectId, nodeId) {
80
+ const canvas = await this.canvas(projectId);
81
+ return this.patchCanvas(projectId, {
82
+ canvasId: canvas.id,
83
+ expectedVersion: canvas.version,
84
+ deleteNodeIds: [nodeId],
85
+ });
86
+ }
87
+ async connect(projectId, input) {
88
+ const canvas = await this.canvas(projectId);
89
+ return this.patchCanvas(projectId, {
90
+ canvasId: canvas.id,
91
+ expectedVersion: canvas.version,
92
+ upsertEdges: [{ id: randomUUID(), ...input }],
93
+ });
94
+ }
95
+ async disconnect(projectId, edgeId) {
96
+ const canvas = await this.canvas(projectId);
97
+ return this.patchCanvas(projectId, {
98
+ canvasId: canvas.id,
99
+ expectedVersion: canvas.version,
100
+ deleteEdgeIds: [edgeId],
101
+ });
102
+ }
103
+ runNode(projectId, nodeId) {
104
+ return this.client.request(`/api/projects/${projectId}/canvas/nodes/${nodeId}/execute`, { method: 'POST' });
105
+ }
106
+ listAssets(projectId, query = '') {
107
+ return this.client.request(`/api/projects/${projectId}/canvas/assets${query ? `?${query}` : ''}`);
108
+ }
109
+ asset(projectId, assetId) {
110
+ return this.client.request(`/api/projects/${projectId}/canvas/assets/${assetId}`);
111
+ }
112
+ selectAssetVersion(projectId, assetId, versionId) {
113
+ return this.client.request(`/api/projects/${projectId}/canvas/assets/${assetId}`, {
114
+ method: 'PATCH', body: { selectedVersionId: versionId },
115
+ });
116
+ }
117
+ uploadAsset(projectId, formData) {
118
+ formData.set('sourceProjectId', projectId);
119
+ return this.client.request('/api/asset-hub/creative-assets/upload', { method: 'POST', body: formData });
120
+ }
121
+ task(taskId) {
122
+ return this.client.request(`/api/tasks/${taskId}`);
123
+ }
124
+ cancelTask(taskId) {
125
+ return this.client.request(`/api/tasks/${taskId}`, { method: 'DELETE' });
126
+ }
127
+ async waitTask(taskId, interval = 1_000) {
128
+ while (true) {
129
+ const { task } = await this.task(taskId);
130
+ if (['completed', 'failed', 'canceled', 'dismissed'].includes(task.status))
131
+ return task;
132
+ await this.sleep(interval);
133
+ }
134
+ }
135
+ config() {
136
+ return this.client.request('/api/user/api-config?redactSecrets=1');
137
+ }
138
+ updateConfig(input) {
139
+ return this.client.request('/api/user/api-config', { method: 'PUT', body: input });
140
+ }
141
+ raw(path, options) {
142
+ return this.client.request(path, options);
143
+ }
144
+ }
@@ -0,0 +1 @@
1
+ export declare const CLI_NAME = "@vvicat/ai_short_studio_cli";
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ export const CLI_NAME = '@vvicat/ai_short_studio_cli';
@@ -0,0 +1 @@
1
+ export declare function formatJson(value: unknown): string;
@@ -0,0 +1,3 @@
1
+ export function formatJson(value) {
2
+ return JSON.stringify(value, null, 2);
3
+ }
@@ -0,0 +1,14 @@
1
+ import { ApiClient } from './client/api-client.js';
2
+ import { SessionManager } from './auth/session-manager.js';
3
+ import { type CliProfile } from './config/profiles.js';
4
+ interface RuntimeFlags {
5
+ 'base-url'?: string;
6
+ locale?: string;
7
+ profile?: string;
8
+ }
9
+ export declare function createRuntime(flags: RuntimeFlags): Promise<{
10
+ profile: CliProfile;
11
+ session: SessionManager;
12
+ client: ApiClient;
13
+ }>;
14
+ export {};
@@ -0,0 +1,45 @@
1
+ import { ApiClient } from './client/api-client.js';
2
+ import { KeyringCredentialStore } from './auth/credential-store.js';
3
+ import { SessionManager, SupabaseAuthProvider } from './auth/session-manager.js';
4
+ import { ProfileStore } from './config/profiles.js';
5
+ export async function createRuntime(flags) {
6
+ const profiles = new ProfileStore();
7
+ const selected = flags.profile ? await profiles.get(flags.profile) : await profiles.current();
8
+ const baseUrl = (flags['base-url'] || process.env.VVICAT_BASE_URL || selected?.baseUrl || '').replace(/\/+$/, '');
9
+ if (!baseUrl)
10
+ throw new Error('缺少服务地址,请传入 --base-url 或设置 VVICAT_BASE_URL');
11
+ const profile = await ensureAuthConfig({
12
+ ...selected,
13
+ name: flags.profile || selected?.name || 'default',
14
+ baseUrl,
15
+ });
16
+ await profiles.save(profile);
17
+ const session = new SessionManager({
18
+ profile: profile.name,
19
+ credentials: new KeyringCredentialStore(),
20
+ provider: new SupabaseAuthProvider(profile.supabaseUrl, profile.supabasePublishableKey),
21
+ });
22
+ return {
23
+ profile,
24
+ session,
25
+ client: new ApiClient({ baseUrl, session, locale: flags.locale }),
26
+ };
27
+ }
28
+ async function ensureAuthConfig(profile) {
29
+ if (profile.supabaseUrl && profile.supabasePublishableKey)
30
+ return profile;
31
+ const response = await fetch(`${profile.baseUrl}/api/v1/bootstrap`, {
32
+ headers: { accept: 'application/json' },
33
+ });
34
+ if (!response.ok)
35
+ throw new Error(`无法读取 CLI 引导配置:HTTP ${response.status}`);
36
+ const payload = await response.json();
37
+ if (payload.data?.auth?.provider !== 'supabase' || !payload.data.auth.url || !payload.data.auth.publishableKey) {
38
+ throw new Error('CLI 引导配置缺少 Supabase 参数');
39
+ }
40
+ return {
41
+ ...profile,
42
+ supabaseUrl: payload.data.auth.url,
43
+ supabasePublishableKey: payload.data.auth.publishableKey,
44
+ };
45
+ }
@@ -0,0 +1,8 @@
1
+ export declare const skillFlags: {
2
+ target: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
3
+ directory: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
4
+ };
5
+ export declare function resolveSkillTarget(flags: {
6
+ target: string;
7
+ directory?: string;
8
+ }): string;
@@ -0,0 +1,9 @@
1
+ import { Flags } from '@oclif/core';
2
+ import { defaultSkillTarget } from './skill-manager.js';
3
+ export const skillFlags = {
4
+ target: Flags.string({ options: ['codex', 'agents'], default: 'codex', description: 'Agent 类型' }),
5
+ directory: Flags.string({ description: '自定义安装目录' }),
6
+ };
7
+ export function resolveSkillTarget(flags) {
8
+ return flags.directory || defaultSkillTarget(flags.target);
9
+ }
@@ -0,0 +1,24 @@
1
+ export type SkillTarget = 'codex' | 'agents';
2
+ export declare function bundledSkillPath(): string;
3
+ export declare function defaultSkillTarget(target: SkillTarget): string;
4
+ export declare function skillStatus(target: string): Promise<{
5
+ target: string;
6
+ installed: boolean;
7
+ managed: boolean;
8
+ current: boolean;
9
+ packageVersion: string;
10
+ installedVersion: string | null;
11
+ modified: boolean;
12
+ }>;
13
+ export declare function installSkill(input: {
14
+ target: string;
15
+ force?: boolean;
16
+ }): Promise<{
17
+ target: string;
18
+ installed: boolean;
19
+ managed: boolean;
20
+ current: boolean;
21
+ packageVersion: string;
22
+ installedVersion: string | null;
23
+ modified: boolean;
24
+ }>;