@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.
Files changed (50) hide show
  1. package/dist/index.js +2501 -3301
  2. package/dist/index.js.map +1 -1
  3. package/package.json +2 -13
  4. package/src/config/config-loader.ts +5 -6
  5. package/src/config/config-reader.service.ts +6 -11
  6. package/src/config/config-reader.ts +75 -0
  7. package/src/config/index.ts +4 -1
  8. package/src/config/load-env.ts +15 -0
  9. package/src/config/schema-generator.service.ts +0 -2
  10. package/src/config/spaceflow.config.ts +7 -20
  11. package/src/extension-system/define-extension.ts +25 -0
  12. package/src/extension-system/extension.interface.ts +0 -63
  13. package/src/extension-system/index.ts +5 -0
  14. package/src/extension-system/types.ts +201 -0
  15. package/src/index.ts +15 -18
  16. package/src/shared/claude-setup/claude-setup.service.ts +3 -8
  17. package/src/shared/claude-setup/index.ts +0 -1
  18. package/src/shared/feishu-sdk/feishu-sdk.service.ts +33 -21
  19. package/src/shared/feishu-sdk/fieshu-card.service.ts +9 -11
  20. package/src/shared/feishu-sdk/index.ts +0 -1
  21. package/src/shared/git-provider/git-provider.service.ts +1 -6
  22. package/src/shared/git-provider/index.ts +0 -1
  23. package/src/shared/git-sdk/git-sdk.service.ts +0 -2
  24. package/src/shared/git-sdk/index.ts +0 -1
  25. package/src/shared/llm-proxy/adapters/claude-code.adapter.spec.ts +15 -32
  26. package/src/shared/llm-proxy/adapters/claude-code.adapter.ts +5 -6
  27. package/src/shared/llm-proxy/adapters/open-code.adapter.ts +1 -3
  28. package/src/shared/llm-proxy/adapters/openai.adapter.spec.ts +7 -21
  29. package/src/shared/llm-proxy/adapters/openai.adapter.ts +1 -3
  30. package/src/shared/llm-proxy/index.ts +0 -1
  31. package/src/shared/llm-proxy/interfaces/config.interface.ts +8 -0
  32. package/src/shared/llm-proxy/llm-proxy.service.spec.ts +91 -68
  33. package/src/shared/llm-proxy/llm-proxy.service.ts +5 -8
  34. package/src/shared/mcp/index.ts +1 -33
  35. package/src/shared/output/index.ts +0 -1
  36. package/src/shared/output/output.service.ts +43 -13
  37. package/src/shared/rspack-config/rspack-config.ts +0 -6
  38. package/src/shared/storage/index.ts +0 -1
  39. package/src/shared/storage/storage.service.ts +16 -8
  40. package/src/shared/storage/types.ts +0 -44
  41. package/src/shared/verbose/index.ts +15 -0
  42. package/src/app.module.ts +0 -18
  43. package/src/config/config-reader.module.ts +0 -16
  44. package/src/shared/claude-setup/claude-setup.module.ts +0 -8
  45. package/src/shared/feishu-sdk/feishu-sdk.module.ts +0 -77
  46. package/src/shared/git-provider/git-provider.module.ts +0 -73
  47. package/src/shared/git-sdk/git-sdk.module.ts +0 -8
  48. package/src/shared/llm-proxy/llm-proxy.module.ts +0 -140
  49. package/src/shared/output/output.module.ts +0 -9
  50. 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.1.3",
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
- "class-transformer": "^0.5.1",
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(用于 registerAs 和从 spaceflow.json 读取) */
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 registerAs(configKey, (): z.infer<T> => {
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 registerAs(configKey, (): z.infer<T> => {
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(protected readonly configService: ConfigService) {}
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 = this.configService.get<Record<string, unknown>>("spaceflow");
72
- const userConfig = rawConfig?.[configKey] ?? {};
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 = this.configService.get<SpaceflowConfig>("spaceflow");
122
+ const rawConfig = (global as any).spaceflowConfig || {};
128
123
  return {
129
- dependencies: rawConfig?.dependencies,
130
- support: rawConfig?.support,
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
+ }
@@ -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
- export const spaceflowConfig = registerAs("spaceflow", (): SpaceflowConfig => {
250
- const fileConfig = readConfigSync();
251
-
252
- // 使用 zod 验证核心配置
253
- const result = SpaceflowCoreConfigSchema.safeParse(fileConfig);
254
-
255
- if (!result.success) {
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
  */
@@ -1 +1,6 @@
1
+ // 旧版接口(保留兼容,后续移除)
1
2
  export * from "./extension.interface";
3
+
4
+ // 新版接口
5
+ export * from "./types";
6
+ export * from "./define-extension";
@@ -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
- export * from "./shared/mcp";
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 { LlmConfig } from "../../config";
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 configService: ConfigService) {}
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 llmConf = this.configService.get<LlmConfig>("llm");
73
- const claudeCode = llmConf?.claudeCode;
68
+ const claudeCode = this.llmConfig?.claudeCode;
74
69
 
75
70
  if (!claudeCode) {
76
71
  if (shouldLog(verbose, 1)) {
@@ -1,2 +1 @@
1
1
  export * from "./claude-setup.service";
2
- export * from "./claude-setup.module";