@spaceflow/core 0.1.3 → 0.2.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.
- package/dist/index.js +2501 -3301
- package/dist/index.js.map +1 -1
- package/package.json +2 -13
- package/src/config/config-loader.ts +5 -6
- package/src/config/config-reader.service.ts +6 -11
- package/src/config/config-reader.ts +75 -0
- package/src/config/index.ts +4 -1
- package/src/config/load-env.ts +15 -0
- package/src/config/schema-generator.service.ts +0 -2
- package/src/config/spaceflow.config.ts +7 -20
- package/src/extension-system/define-extension.ts +25 -0
- package/src/extension-system/extension.interface.ts +0 -63
- package/src/extension-system/index.ts +5 -0
- package/src/extension-system/types.ts +201 -0
- package/src/index.ts +15 -18
- package/src/shared/claude-setup/claude-setup.service.ts +3 -8
- package/src/shared/claude-setup/index.ts +0 -1
- package/src/shared/feishu-sdk/feishu-sdk.service.ts +33 -21
- package/src/shared/feishu-sdk/fieshu-card.service.ts +9 -11
- package/src/shared/feishu-sdk/index.ts +0 -1
- package/src/shared/git-provider/git-provider.service.ts +1 -6
- package/src/shared/git-provider/index.ts +0 -1
- package/src/shared/git-sdk/git-sdk.service.ts +0 -2
- package/src/shared/git-sdk/index.ts +0 -1
- package/src/shared/llm-proxy/adapters/claude-code.adapter.spec.ts +15 -32
- package/src/shared/llm-proxy/adapters/claude-code.adapter.ts +5 -6
- package/src/shared/llm-proxy/adapters/open-code.adapter.ts +1 -3
- package/src/shared/llm-proxy/adapters/openai.adapter.spec.ts +7 -21
- package/src/shared/llm-proxy/adapters/openai.adapter.ts +1 -3
- package/src/shared/llm-proxy/index.ts +0 -1
- package/src/shared/llm-proxy/interfaces/config.interface.ts +8 -0
- package/src/shared/llm-proxy/llm-proxy.service.spec.ts +91 -68
- package/src/shared/llm-proxy/llm-proxy.service.ts +5 -8
- package/src/shared/mcp/index.ts +1 -33
- package/src/shared/output/index.ts +0 -1
- package/src/shared/output/output.service.ts +43 -13
- package/src/shared/rspack-config/rspack-config.ts +0 -6
- package/src/shared/storage/index.ts +0 -1
- package/src/shared/storage/storage.service.ts +16 -8
- package/src/shared/storage/types.ts +0 -44
- package/src/shared/verbose/index.ts +15 -0
- package/src/app.module.ts +0 -18
- package/src/config/config-reader.module.ts +0 -16
- package/src/shared/claude-setup/claude-setup.module.ts +0 -8
- package/src/shared/feishu-sdk/feishu-sdk.module.ts +0 -77
- package/src/shared/git-provider/git-provider.module.ts +0 -73
- package/src/shared/git-sdk/git-sdk.module.ts +0 -8
- package/src/shared/llm-proxy/llm-proxy.module.ts +0 -140
- package/src/shared/output/output.module.ts +0 -9
- package/src/shared/storage/storage.module.ts +0 -150
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spaceflow/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Spaceflow 核心能力库",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Lydanne",
|
|
@@ -75,25 +75,17 @@
|
|
|
75
75
|
"@anthropic-ai/claude-agent-sdk": "^0.2.7",
|
|
76
76
|
"@larksuiteoapi/node-sdk": "^1.55.0",
|
|
77
77
|
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
78
|
-
"@nestjs/common": "^11.0.1",
|
|
79
|
-
"@nestjs/config": "^4.0.2",
|
|
80
|
-
"@nestjs/core": "^11.0.1",
|
|
81
|
-
"@nestjs/event-emitter": "^3.0.1",
|
|
82
|
-
"@nestjs/platform-express": "^11.0.1",
|
|
83
|
-
"@nestjs/swagger": "^11.2.6",
|
|
84
78
|
"@opencode-ai/sdk": "^1.1.23",
|
|
85
79
|
"@release-it/conventional-changelog": "^10.0.4",
|
|
86
80
|
"@rspack/cli": "^1.7.4",
|
|
87
81
|
"@rspack/core": "^1.7.4",
|
|
88
82
|
"chalk": "^5.6.2",
|
|
89
|
-
"
|
|
90
|
-
"class-validator": "^0.14.3",
|
|
83
|
+
"dotenv": "^16.4.5",
|
|
91
84
|
"i18next": "^25.8.4",
|
|
92
85
|
"json-stringify-pretty-compact": "^4.0.0",
|
|
93
86
|
"jsonrepair": "^3.13.1",
|
|
94
87
|
"log-update": "^7.1.0",
|
|
95
88
|
"micromatch": "^4.0.8",
|
|
96
|
-
"nest-commander": "^3.20.1",
|
|
97
89
|
"openai": "^6.1.0",
|
|
98
90
|
"ora": "^9.3.0",
|
|
99
91
|
"reflect-metadata": "^0.2.2",
|
|
@@ -104,9 +96,6 @@
|
|
|
104
96
|
"zod-to-json-schema": "^3.25.1"
|
|
105
97
|
},
|
|
106
98
|
"devDependencies": {
|
|
107
|
-
"@nestjs/cli": "^11.0.0",
|
|
108
|
-
"@nestjs/schematics": "^11.0.0",
|
|
109
|
-
"@nestjs/testing": "^11.0.1",
|
|
110
99
|
"@swc/core": "1.15.3",
|
|
111
100
|
"@types/express": "^5.0.0",
|
|
112
101
|
"@types/micromatch": "^4.0.10",
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { registerAs } from "@nestjs/config";
|
|
2
1
|
import { z } from "zod";
|
|
3
2
|
import { readConfigSync } from "./spaceflow.config";
|
|
4
3
|
import { registerPluginSchema } from "./schema-generator.service";
|
|
@@ -7,7 +6,7 @@ import { registerPluginSchema } from "./schema-generator.service";
|
|
|
7
6
|
* 配置加载器选项
|
|
8
7
|
*/
|
|
9
8
|
export interface ConfigLoaderOptions<T extends z.ZodObject<z.ZodRawShape>> {
|
|
10
|
-
/** 配置 key
|
|
9
|
+
/** 配置 key(用于从 spaceflow.json 读取) */
|
|
11
10
|
configKey: string;
|
|
12
11
|
/** zod schema(应包含 .default() 设置默认值) */
|
|
13
12
|
schemaFactory: () => T;
|
|
@@ -41,7 +40,7 @@ export function createConfigLoader<T extends z.ZodObject<z.ZodRawShape>>(
|
|
|
41
40
|
const { configKey, schemaFactory, description } = options;
|
|
42
41
|
|
|
43
42
|
// 创建配置加载器
|
|
44
|
-
return
|
|
43
|
+
return (): z.infer<T> => {
|
|
45
44
|
const schema = schemaFactory();
|
|
46
45
|
// 注册 schema 用于 JSON Schema 生成
|
|
47
46
|
registerPluginSchema({
|
|
@@ -64,7 +63,7 @@ export function createConfigLoader<T extends z.ZodObject<z.ZodRawShape>>(
|
|
|
64
63
|
}
|
|
65
64
|
|
|
66
65
|
return result.data;
|
|
67
|
-
}
|
|
66
|
+
};
|
|
68
67
|
}
|
|
69
68
|
|
|
70
69
|
/**
|
|
@@ -76,7 +75,7 @@ export function createEnvConfigLoader<T extends z.ZodObject<z.ZodRawShape>>(
|
|
|
76
75
|
) {
|
|
77
76
|
const { configKey, schemaFactory, description } = options;
|
|
78
77
|
|
|
79
|
-
return
|
|
78
|
+
return (): z.infer<T> => {
|
|
80
79
|
const schema = schemaFactory();
|
|
81
80
|
// 注册 schema(如果有描述)
|
|
82
81
|
if (description) {
|
|
@@ -97,5 +96,5 @@ export function createEnvConfigLoader<T extends z.ZodObject<z.ZodRawShape>>(
|
|
|
97
96
|
}
|
|
98
97
|
|
|
99
98
|
return result.data;
|
|
100
|
-
}
|
|
99
|
+
};
|
|
101
100
|
}
|
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
import { Injectable } from "@nestjs/common";
|
|
2
|
-
import { ConfigService } from "@nestjs/config";
|
|
3
|
-
import type { SpaceflowConfig } from "./spaceflow.config";
|
|
4
|
-
|
|
5
1
|
/**
|
|
6
2
|
* 系统配置(不包含插件配置)
|
|
7
3
|
*/
|
|
@@ -57,9 +53,8 @@ export function getRegisteredPluginConfig(configKey: string): PluginConfigRegist
|
|
|
57
53
|
* 2. getOtherPluginConfig - 读取其他插件的配置(需要在 metadata 中声明依赖)
|
|
58
54
|
* 3. getSystemConfig - 读取系统配置
|
|
59
55
|
*/
|
|
60
|
-
@Injectable()
|
|
61
56
|
export class ConfigReaderService {
|
|
62
|
-
constructor(
|
|
57
|
+
constructor() {}
|
|
63
58
|
|
|
64
59
|
/**
|
|
65
60
|
* 读取插件的配置
|
|
@@ -68,8 +63,8 @@ export class ConfigReaderService {
|
|
|
68
63
|
* @returns 验证后的插件配置
|
|
69
64
|
*/
|
|
70
65
|
getPluginConfig<T>(configKey: string): T {
|
|
71
|
-
const rawConfig =
|
|
72
|
-
const userConfig = rawConfig
|
|
66
|
+
const rawConfig = (global as any).spaceflowConfig || {};
|
|
67
|
+
const userConfig = rawConfig[configKey] ?? {};
|
|
73
68
|
|
|
74
69
|
// 从注册表获取 schema 工厂函数
|
|
75
70
|
const registry = pluginRegistry.get(configKey);
|
|
@@ -124,10 +119,10 @@ export class ConfigReaderService {
|
|
|
124
119
|
* @returns 系统配置
|
|
125
120
|
*/
|
|
126
121
|
getSystemConfig(): SystemConfig {
|
|
127
|
-
const rawConfig =
|
|
122
|
+
const rawConfig = (global as any).spaceflowConfig || {};
|
|
128
123
|
return {
|
|
129
|
-
dependencies: rawConfig
|
|
130
|
-
support: rawConfig
|
|
124
|
+
dependencies: rawConfig.dependencies,
|
|
125
|
+
support: rawConfig.support,
|
|
131
126
|
};
|
|
132
127
|
}
|
|
133
128
|
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import type { ZodSchema } from "zod";
|
|
2
|
+
import { readConfigSync } from "./spaceflow.config";
|
|
3
|
+
import type { IConfigReader } from "../extension-system/types";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* 配置读取器
|
|
7
|
+
* 不依赖 NestJS,直接读取配置文件
|
|
8
|
+
*/
|
|
9
|
+
export class ConfigReader implements IConfigReader {
|
|
10
|
+
private config: Record<string, unknown>;
|
|
11
|
+
private schemas = new Map<string, ZodSchema>();
|
|
12
|
+
|
|
13
|
+
constructor(cwd?: string) {
|
|
14
|
+
this.config = readConfigSync(cwd) as Record<string, unknown>;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* 获取配置值
|
|
19
|
+
* @param key 配置路径(支持点分隔,如 "gitProvider.token")
|
|
20
|
+
*/
|
|
21
|
+
get<T>(key: string): T | undefined {
|
|
22
|
+
const parts = key.split(".");
|
|
23
|
+
let current: unknown = this.config;
|
|
24
|
+
for (const part of parts) {
|
|
25
|
+
if (current === null || current === undefined) {
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
current = (current as Record<string, unknown>)[part];
|
|
29
|
+
}
|
|
30
|
+
return current as T | undefined;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* 获取插件配置
|
|
35
|
+
* 使用已注册的 schema 验证并填充默认值
|
|
36
|
+
* @param key 插件配置 key
|
|
37
|
+
*/
|
|
38
|
+
getPluginConfig<T>(key: string): T | undefined {
|
|
39
|
+
const rawConfig = this.config[key] ?? {};
|
|
40
|
+
const schema = this.schemas.get(key);
|
|
41
|
+
if (!schema) {
|
|
42
|
+
return rawConfig as T;
|
|
43
|
+
}
|
|
44
|
+
try {
|
|
45
|
+
return schema.parse(rawConfig) as T;
|
|
46
|
+
} catch (error) {
|
|
47
|
+
console.warn(`⚠️ 配置 "${key}" 验证失败:`, error);
|
|
48
|
+
return rawConfig as T;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* 注册配置 schema
|
|
54
|
+
* @param key 配置 key
|
|
55
|
+
* @param schema Zod schema
|
|
56
|
+
*/
|
|
57
|
+
registerSchema(key: string, schema: ZodSchema): void {
|
|
58
|
+
this.schemas.set(key, schema);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* 重新加载配置
|
|
63
|
+
* @param cwd 工作目录
|
|
64
|
+
*/
|
|
65
|
+
reload(cwd?: string): void {
|
|
66
|
+
this.config = readConfigSync(cwd) as Record<string, unknown>;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* 获取原始配置对象
|
|
71
|
+
*/
|
|
72
|
+
getRawConfig(): Record<string, unknown> {
|
|
73
|
+
return this.config;
|
|
74
|
+
}
|
|
75
|
+
}
|
package/src/config/index.ts
CHANGED
|
@@ -5,10 +5,13 @@ export * from "./feishu.config";
|
|
|
5
5
|
export * from "./storage.config";
|
|
6
6
|
export * from "./spaceflow.config";
|
|
7
7
|
export * from "./config-reader.service";
|
|
8
|
-
export * from "./config-reader.module";
|
|
9
8
|
export * from "./schema-generator.service";
|
|
10
9
|
export * from "./config-loader";
|
|
11
10
|
|
|
11
|
+
// 新版配置系统(不依赖 NestJS)
|
|
12
|
+
export { ConfigReader } from "./config-reader";
|
|
13
|
+
export { loadEnvFiles } from "./load-env";
|
|
14
|
+
|
|
12
15
|
import { gitProviderConfig } from "./git-provider.config";
|
|
13
16
|
import { ciConfig } from "./ci.config";
|
|
14
17
|
import { llmConfig } from "./llm.config";
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { config } from "dotenv";
|
|
2
|
+
import { existsSync } from "fs";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 加载 .env 文件
|
|
6
|
+
* 按优先级从高到低加载,先加载的变量不会被后加载的覆盖
|
|
7
|
+
* @param paths .env 文件路径列表(按优先级从高到低排列)
|
|
8
|
+
*/
|
|
9
|
+
export function loadEnvFiles(paths: string[]): void {
|
|
10
|
+
for (const envPath of paths) {
|
|
11
|
+
if (existsSync(envPath)) {
|
|
12
|
+
config({ path: envPath, override: false });
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { Injectable } from "@nestjs/common";
|
|
2
1
|
import { z } from "zod";
|
|
3
2
|
import * as fs from "fs";
|
|
4
3
|
import * as path from "path";
|
|
@@ -34,7 +33,6 @@ export function getRegisteredSchemas(): Map<string, SchemaRegistry> {
|
|
|
34
33
|
* Schema 生成服务
|
|
35
34
|
* 用于生成 JSON Schema 文件
|
|
36
35
|
*/
|
|
37
|
-
@Injectable()
|
|
38
36
|
export class SchemaGeneratorService {
|
|
39
37
|
/**
|
|
40
38
|
* 生成完整的 spaceflow.json 的 JSON Schema
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { registerAs } from "@nestjs/config";
|
|
2
1
|
import { readFileSync, existsSync, writeFileSync } from "fs";
|
|
3
2
|
import { join } from "path";
|
|
4
3
|
import { homedir } from "os";
|
|
@@ -246,25 +245,13 @@ export function removeDependency(name: string, cwd?: string): boolean {
|
|
|
246
245
|
return true;
|
|
247
246
|
}
|
|
248
247
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
const errors = result.error.issues
|
|
257
|
-
.map((e) => ` - ${e.path.join(".")}: ${e.message}`)
|
|
258
|
-
.join("\n");
|
|
259
|
-
throw new Error(`Spaceflow 配置验证失败:\n${errors}`);
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
// 返回验证后的核心配置 + 其他插件配置
|
|
263
|
-
return {
|
|
264
|
-
...fileConfig,
|
|
265
|
-
...result.data,
|
|
266
|
-
} as SpaceflowConfig;
|
|
267
|
-
});
|
|
248
|
+
/**
|
|
249
|
+
* 获取 spaceflow 配置(兼容旧 API)
|
|
250
|
+
* @deprecated 请使用 loadSpaceflowConfig()
|
|
251
|
+
*/
|
|
252
|
+
export function spaceflowConfig(): SpaceflowConfig {
|
|
253
|
+
return loadSpaceflowConfig();
|
|
254
|
+
}
|
|
268
255
|
|
|
269
256
|
/**
|
|
270
257
|
* 加载 spaceflow.json 配置(用于 CLI 启动时)
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { ExtensionDefinition, McpServerDefinition } from "./types";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 定义扩展
|
|
5
|
+
* 这是一个类型安全的工厂函数,用于创建扩展定义
|
|
6
|
+
* @param definition 扩展定义
|
|
7
|
+
* @returns 扩展定义(原样返回,仅用于类型推断)
|
|
8
|
+
*/
|
|
9
|
+
export function defineExtension(
|
|
10
|
+
definition: ExtensionDefinition,
|
|
11
|
+
): ExtensionDefinition {
|
|
12
|
+
return definition;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* 定义 MCP 服务器
|
|
17
|
+
* 这是一个类型安全的工厂函数,用于创建 MCP 服务器定义
|
|
18
|
+
* @param definition MCP 服务器定义
|
|
19
|
+
* @returns MCP 服务器定义(原样返回,仅用于类型推断)
|
|
20
|
+
*/
|
|
21
|
+
export function defineMcpServer(
|
|
22
|
+
definition: McpServerDefinition,
|
|
23
|
+
): McpServerDefinition {
|
|
24
|
+
return definition;
|
|
25
|
+
}
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { Type, DynamicModule } from "@nestjs/common";
|
|
2
|
-
|
|
3
1
|
/** .spaceflow 目录名 */
|
|
4
2
|
export const SPACEFLOW_DIR = ".spaceflow";
|
|
5
3
|
|
|
@@ -26,67 +24,6 @@ export interface SpaceflowExtensionMetadata {
|
|
|
26
24
|
description?: string;
|
|
27
25
|
}
|
|
28
26
|
|
|
29
|
-
/**
|
|
30
|
-
* Extension 模块类型,支持静态模块或动态模块
|
|
31
|
-
*/
|
|
32
|
-
export type ExtensionModuleType = Type<any> | DynamicModule;
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Extension 接口
|
|
36
|
-
*/
|
|
37
|
-
export interface SpaceflowExtension {
|
|
38
|
-
/** 获取 Extension 元数据 */
|
|
39
|
-
getMetadata(): SpaceflowExtensionMetadata;
|
|
40
|
-
/**
|
|
41
|
-
* 获取 NestJS Module
|
|
42
|
-
* 可以返回静态 Module 类或 DynamicModule
|
|
43
|
-
* 如果需要动态配置,推荐返回 DynamicModule
|
|
44
|
-
*/
|
|
45
|
-
getModule(): ExtensionModuleType;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Extension 类静态接口
|
|
50
|
-
*/
|
|
51
|
-
export interface SpaceflowExtensionConstructor {
|
|
52
|
-
new (): SpaceflowExtension;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Extension 入口导出格式
|
|
57
|
-
*/
|
|
58
|
-
export type SpaceflowExtensionExport =
|
|
59
|
-
| SpaceflowExtensionConstructor
|
|
60
|
-
| {
|
|
61
|
-
default: SpaceflowExtensionConstructor;
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* 已加载的 Extension 信息
|
|
66
|
-
*/
|
|
67
|
-
export interface LoadedExtension {
|
|
68
|
-
/** Extension 名称 */
|
|
69
|
-
name: string;
|
|
70
|
-
/** Extension 来源(npm 包名) */
|
|
71
|
-
source: string;
|
|
72
|
-
/** NestJS 模块(静态或动态) */
|
|
73
|
-
module: ExtensionModuleType;
|
|
74
|
-
/** 包的完整导出(用于 MCP 服务发现) */
|
|
75
|
-
exports?: Record<string, unknown>;
|
|
76
|
-
/** 提供的命令列表 */
|
|
77
|
-
commands: string[];
|
|
78
|
-
/** 配置 key */
|
|
79
|
-
configKey?: string;
|
|
80
|
-
/** 依赖的其他 Extension 配置 key 列表 */
|
|
81
|
-
configDependencies?: string[];
|
|
82
|
-
/** 配置 schema 工厂函数 */
|
|
83
|
-
configSchema?: () => unknown;
|
|
84
|
-
/** Extension 版本 */
|
|
85
|
-
version?: string;
|
|
86
|
-
/** Extension 描述 */
|
|
87
|
-
description?: string;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
27
|
/**
|
|
91
28
|
* .spaceflow/package.json 中的 dependencies
|
|
92
29
|
*/
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import type { ZodSchema } from "zod";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 命令选项定义
|
|
5
|
+
*/
|
|
6
|
+
export interface OptionDefinition {
|
|
7
|
+
/** 选项标志,如 "-d, --dry-run" */
|
|
8
|
+
flags: string;
|
|
9
|
+
/** 选项描述 */
|
|
10
|
+
description: string;
|
|
11
|
+
/** 默认值 */
|
|
12
|
+
default?: unknown;
|
|
13
|
+
/** 是否为计数选项(如 -vvv 表示 verbose 级别 3) */
|
|
14
|
+
isCount?: boolean;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Spaceflow 统一上下文接口
|
|
19
|
+
* 命令和 MCP 工具共用此上下文
|
|
20
|
+
*/
|
|
21
|
+
export interface SpaceflowContext {
|
|
22
|
+
/** 配置读取器 */
|
|
23
|
+
readonly config: IConfigReader;
|
|
24
|
+
/** 输出服务 */
|
|
25
|
+
readonly output: IOutputService;
|
|
26
|
+
/** 存储服务 */
|
|
27
|
+
readonly storage: IStorageService;
|
|
28
|
+
/**
|
|
29
|
+
* 获取服务实例
|
|
30
|
+
* @param key 服务标识符(字符串 key,非 class 引用)
|
|
31
|
+
*/
|
|
32
|
+
getService<T = unknown>(key: string): T;
|
|
33
|
+
/**
|
|
34
|
+
* 检查服务是否存在
|
|
35
|
+
* @param key 服务标识符
|
|
36
|
+
*/
|
|
37
|
+
hasService(key: string): boolean;
|
|
38
|
+
/**
|
|
39
|
+
* 注册服务实例
|
|
40
|
+
* @param key 服务标识符
|
|
41
|
+
* @param service 服务实例
|
|
42
|
+
*/
|
|
43
|
+
registerService(key: string, service: unknown): void;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* 配置读取器接口
|
|
48
|
+
*/
|
|
49
|
+
export interface IConfigReader {
|
|
50
|
+
/**
|
|
51
|
+
* 获取配置值
|
|
52
|
+
* @param key 配置路径
|
|
53
|
+
*/
|
|
54
|
+
get<T>(key: string): T | undefined;
|
|
55
|
+
/**
|
|
56
|
+
* 获取插件配置
|
|
57
|
+
* @param key 插件配置 key
|
|
58
|
+
*/
|
|
59
|
+
getPluginConfig<T>(key: string): T | undefined;
|
|
60
|
+
/**
|
|
61
|
+
* 注册配置 schema
|
|
62
|
+
* @param key 配置 key
|
|
63
|
+
* @param schema Zod schema
|
|
64
|
+
*/
|
|
65
|
+
registerSchema(key: string, schema: ZodSchema): void;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* 输出服务接口
|
|
70
|
+
*/
|
|
71
|
+
export interface IOutputService {
|
|
72
|
+
/** 输出信息 */
|
|
73
|
+
info(message: string): void;
|
|
74
|
+
/** 输出成功信息 */
|
|
75
|
+
success(message: string): void;
|
|
76
|
+
/** 输出警告 */
|
|
77
|
+
warn(message: string): void;
|
|
78
|
+
/** 输出错误 */
|
|
79
|
+
error(message: string): void;
|
|
80
|
+
/** 输出调试信息 */
|
|
81
|
+
debug(message: string): void;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* 存储服务接口
|
|
86
|
+
*/
|
|
87
|
+
export interface IStorageService {
|
|
88
|
+
/** 获取存储值 */
|
|
89
|
+
get<T>(key: string): Promise<T | undefined>;
|
|
90
|
+
/** 设置存储值 */
|
|
91
|
+
set<T>(key: string, value: T, ttl?: number): Promise<void>;
|
|
92
|
+
/** 删除存储值 */
|
|
93
|
+
del(key: string): Promise<boolean>;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* 命令定义
|
|
98
|
+
*/
|
|
99
|
+
export interface CommandDefinition {
|
|
100
|
+
/** 命令名称 */
|
|
101
|
+
name: string;
|
|
102
|
+
/** 命令描述 */
|
|
103
|
+
description: string;
|
|
104
|
+
/** 命令别名 */
|
|
105
|
+
aliases?: string[];
|
|
106
|
+
/** 位置参数,如 "<script>" 或 "[file]" */
|
|
107
|
+
arguments?: string;
|
|
108
|
+
/** 参数描述 */
|
|
109
|
+
argsDescription?: Record<string, string>;
|
|
110
|
+
/** 命令选项 */
|
|
111
|
+
options?: OptionDefinition[];
|
|
112
|
+
/** 子命令 */
|
|
113
|
+
subcommands?: CommandDefinition[];
|
|
114
|
+
/**
|
|
115
|
+
* 命令执行函数
|
|
116
|
+
* @param args 位置参数
|
|
117
|
+
* @param options 选项
|
|
118
|
+
* @param ctx Spaceflow 上下文
|
|
119
|
+
*/
|
|
120
|
+
run: (args: string[], options: Record<string, unknown>, ctx: SpaceflowContext) => Promise<void>;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* 服务定义
|
|
125
|
+
* 扩展通过此接口声明其提供的服务
|
|
126
|
+
*/
|
|
127
|
+
export interface ServiceDefinition {
|
|
128
|
+
/** 服务标识符(建议格式:extName.serviceName) */
|
|
129
|
+
key: string;
|
|
130
|
+
/**
|
|
131
|
+
* 服务工厂函数
|
|
132
|
+
* @param ctx Spaceflow 上下文,可从中获取依赖
|
|
133
|
+
*/
|
|
134
|
+
factory: (ctx: SpaceflowContext) => unknown;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* MCP 工具定义
|
|
139
|
+
*/
|
|
140
|
+
export interface McpToolDefinition {
|
|
141
|
+
/** 工具名称 */
|
|
142
|
+
name: string;
|
|
143
|
+
/** 工具描述 */
|
|
144
|
+
description: string;
|
|
145
|
+
/** 输入参数 schema(Zod) */
|
|
146
|
+
inputSchema?: ZodSchema;
|
|
147
|
+
/**
|
|
148
|
+
* 工具处理函数
|
|
149
|
+
* @param input 输入参数
|
|
150
|
+
* @param ctx Spaceflow 上下文
|
|
151
|
+
*/
|
|
152
|
+
handler: (input: unknown, ctx: SpaceflowContext) => Promise<unknown>;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* MCP 服务器定义
|
|
157
|
+
*/
|
|
158
|
+
export interface McpServerDefinition {
|
|
159
|
+
/** 服务器名称 */
|
|
160
|
+
name: string;
|
|
161
|
+
/** 服务器版本 */
|
|
162
|
+
version?: string;
|
|
163
|
+
/** 服务器描述 */
|
|
164
|
+
description?: string;
|
|
165
|
+
/** 工具列表 */
|
|
166
|
+
tools: McpToolDefinition[];
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* 扩展定义
|
|
171
|
+
*/
|
|
172
|
+
export interface ExtensionDefinition {
|
|
173
|
+
/** 扩展名称(建议使用 npm 包名) */
|
|
174
|
+
name: string;
|
|
175
|
+
/** 扩展版本 */
|
|
176
|
+
version?: string;
|
|
177
|
+
/** 扩展描述 */
|
|
178
|
+
description?: string;
|
|
179
|
+
/** 配置 key(对应 spaceflow.json 中的配置路径) */
|
|
180
|
+
configKey?: string;
|
|
181
|
+
/** 配置 schema 工厂函数 */
|
|
182
|
+
configSchema?: () => ZodSchema;
|
|
183
|
+
/** 依赖的其他扩展配置 key 列表 */
|
|
184
|
+
configDependencies?: string[];
|
|
185
|
+
/** 命令列表 */
|
|
186
|
+
commands: CommandDefinition[];
|
|
187
|
+
/** MCP 服务器定义 */
|
|
188
|
+
mcp?: McpServerDefinition;
|
|
189
|
+
/** 服务定义列表 */
|
|
190
|
+
services?: ServiceDefinition[];
|
|
191
|
+
/**
|
|
192
|
+
* 扩展初始化钩子
|
|
193
|
+
* 在所有服务注册完毕后调用
|
|
194
|
+
*/
|
|
195
|
+
onInit?: (ctx: SpaceflowContext) => Promise<void>;
|
|
196
|
+
/**
|
|
197
|
+
* 扩展销毁钩子
|
|
198
|
+
* 在 CLI 退出前调用
|
|
199
|
+
*/
|
|
200
|
+
onDestroy?: (ctx: SpaceflowContext) => Promise<void>;
|
|
201
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -48,7 +48,21 @@ export * from "./shared/spaceflow-dir";
|
|
|
48
48
|
export * from "./shared/rspack-config";
|
|
49
49
|
|
|
50
50
|
// MCP - Model Context Protocol 支持
|
|
51
|
-
|
|
51
|
+
// 注意:McpServerDefinition 和 McpToolDefinition 已在 extension-system/types.ts 中定义
|
|
52
|
+
// 这里只导出装饰器和工具函数,避免重复导出
|
|
53
|
+
export {
|
|
54
|
+
MCP_SERVER_METADATA,
|
|
55
|
+
MCP_TOOL_METADATA,
|
|
56
|
+
type JsonSchema,
|
|
57
|
+
dtoToJsonSchema,
|
|
58
|
+
type McpToolMetadata,
|
|
59
|
+
McpServer,
|
|
60
|
+
McpTool,
|
|
61
|
+
isMcpServer,
|
|
62
|
+
getMcpServerMetadata,
|
|
63
|
+
getMcpTools,
|
|
64
|
+
runMcpServer,
|
|
65
|
+
} from "./shared/mcp";
|
|
52
66
|
|
|
53
67
|
// I18n - 国际化
|
|
54
68
|
export * from "./shared/i18n";
|
|
@@ -59,22 +73,5 @@ export * from "./shared/logger";
|
|
|
59
73
|
// ============ 配置相关 ============
|
|
60
74
|
export * from "./config";
|
|
61
75
|
|
|
62
|
-
// ============ NestJS 重导出 ============
|
|
63
|
-
export { Command, CommandRunner, Option, SubCommand } from "nest-commander";
|
|
64
|
-
export { Module, Injectable, Inject, Global } from "@nestjs/common";
|
|
65
|
-
export { ConfigModule, ConfigService } from "@nestjs/config";
|
|
66
|
-
|
|
67
76
|
// ============ Zod 重导出 ============
|
|
68
77
|
export { z } from "zod";
|
|
69
|
-
|
|
70
|
-
// ============ Swagger DTO 重导出 ============
|
|
71
|
-
export { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger";
|
|
72
|
-
export {
|
|
73
|
-
IsString,
|
|
74
|
-
IsNumber,
|
|
75
|
-
IsBoolean,
|
|
76
|
-
IsOptional,
|
|
77
|
-
IsArray,
|
|
78
|
-
IsEnum,
|
|
79
|
-
IsNotEmpty,
|
|
80
|
-
} from "class-validator";
|
|
@@ -1,15 +1,11 @@
|
|
|
1
|
-
import { Injectable } from "@nestjs/common";
|
|
2
|
-
import { ConfigService } from "@nestjs/config";
|
|
3
1
|
import { readFile, writeFile, mkdir, copyFile, unlink } from "fs/promises";
|
|
4
2
|
import { join } from "path";
|
|
5
3
|
import { homedir } from "os";
|
|
6
|
-
import {
|
|
7
|
-
|
|
4
|
+
import type { LlmProxyConfig } from "../llm-proxy/interfaces";
|
|
8
5
|
import { shouldLog, type VerboseLevel } from "../verbose";
|
|
9
6
|
|
|
10
|
-
@Injectable()
|
|
11
7
|
export class ClaudeSetupService {
|
|
12
|
-
constructor(protected readonly
|
|
8
|
+
constructor(protected readonly llmConfig?: LlmProxyConfig) {}
|
|
13
9
|
|
|
14
10
|
private getPaths() {
|
|
15
11
|
const claudeDir = join(homedir(), ".claude");
|
|
@@ -69,8 +65,7 @@ export class ClaudeSetupService {
|
|
|
69
65
|
async configure(verbose?: VerboseLevel): Promise<void> {
|
|
70
66
|
const { claudeDir, settingsPath, claudeJsonPath } = this.getPaths();
|
|
71
67
|
|
|
72
|
-
const
|
|
73
|
-
const claudeCode = llmConf?.claudeCode;
|
|
68
|
+
const claudeCode = this.llmConfig?.claudeCode;
|
|
74
69
|
|
|
75
70
|
if (!claudeCode) {
|
|
76
71
|
if (shouldLog(verbose, 1)) {
|