@spaceflow/core 0.8.0 → 0.9.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 (86) hide show
  1. package/dist/index.js +5589 -970
  2. package/dist/index.js.map +1 -1
  3. package/package.json +9 -3
  4. package/src/cli-runtime/di/config.ts +157 -0
  5. package/src/cli-runtime/di/container.ts +120 -0
  6. package/src/cli-runtime/di/index.ts +3 -0
  7. package/src/cli-runtime/di/services.ts +53 -0
  8. package/src/cli-runtime/extension-loader.ts +74 -0
  9. package/src/{shared → cli-runtime}/i18n/index.ts +7 -1
  10. package/src/cli-runtime/i18n/init.ts +117 -0
  11. package/src/cli-runtime/index.ts +131 -0
  12. package/src/cli-runtime/internal-extensions.ts +33 -0
  13. package/src/commands/build/build.service.ts +323 -0
  14. package/src/commands/build/index.ts +49 -0
  15. package/src/commands/clear/clear.service.ts +159 -0
  16. package/src/commands/clear/index.ts +35 -0
  17. package/src/commands/commit/commit.config.ts +168 -0
  18. package/src/commands/commit/commit.service.ts +950 -0
  19. package/src/commands/commit/index.ts +58 -0
  20. package/src/commands/create/create.service.ts +318 -0
  21. package/src/commands/create/index.ts +42 -0
  22. package/src/commands/dev/index.ts +30 -0
  23. package/src/commands/install/index.ts +65 -0
  24. package/src/commands/install/install.service.ts +1539 -0
  25. package/src/commands/list/index.ts +33 -0
  26. package/src/commands/list/list.service.ts +127 -0
  27. package/src/commands/mcp/index.ts +37 -0
  28. package/src/commands/mcp/mcp.service.ts +246 -0
  29. package/src/commands/runx/index.ts +47 -0
  30. package/src/commands/runx/runx.service.ts +142 -0
  31. package/src/commands/runx/runx.utils.ts +83 -0
  32. package/src/commands/schema/index.ts +30 -0
  33. package/src/commands/setup/index.ts +34 -0
  34. package/src/commands/setup/setup.service.ts +234 -0
  35. package/src/commands/uninstall/index.ts +42 -0
  36. package/src/commands/uninstall/uninstall.service.ts +166 -0
  37. package/src/commands/update/index.ts +42 -0
  38. package/src/commands/update/update.service.ts +373 -0
  39. package/src/config/index.ts +1 -30
  40. package/src/config/spaceflow.config.ts +226 -278
  41. package/src/index.ts +11 -1
  42. package/src/locales/en/build.json +22 -0
  43. package/src/locales/en/clear.json +16 -0
  44. package/src/locales/en/commit.json +45 -0
  45. package/src/locales/en/create.json +27 -0
  46. package/src/locales/en/dev.json +5 -0
  47. package/src/locales/en/install.json +71 -0
  48. package/src/locales/en/list.json +8 -0
  49. package/src/locales/en/mcp.json +19 -0
  50. package/src/locales/en/runx.json +13 -0
  51. package/src/locales/en/schema.json +4 -0
  52. package/src/locales/en/setup.json +14 -0
  53. package/src/locales/en/uninstall.json +18 -0
  54. package/src/locales/en/update.json +28 -0
  55. package/src/locales/zh-cn/build.json +22 -0
  56. package/src/locales/zh-cn/clear.json +16 -0
  57. package/src/locales/zh-cn/commit.json +45 -0
  58. package/src/locales/zh-cn/create.json +27 -0
  59. package/src/locales/zh-cn/dev.json +5 -0
  60. package/src/locales/zh-cn/install.json +71 -0
  61. package/src/locales/zh-cn/list.json +8 -0
  62. package/src/locales/zh-cn/mcp.json +19 -0
  63. package/src/locales/zh-cn/runx.json +13 -0
  64. package/src/locales/zh-cn/schema.json +4 -0
  65. package/src/locales/zh-cn/setup.json +14 -0
  66. package/src/locales/zh-cn/uninstall.json +18 -0
  67. package/src/locales/zh-cn/update.json +28 -0
  68. package/src/shared/editor-config/index.ts +2 -21
  69. package/src/shared/llm-proxy/adapters/openai.adapter.ts +3 -1
  70. package/src/shared/package-manager/index.ts +5 -76
  71. package/src/shared/source-utils/index.ts +12 -130
  72. package/src/shared/spaceflow-dir/index.ts +13 -135
  73. package/src/shared/verbose/index.ts +10 -87
  74. package/dist/524.js +0 -9
  75. package/src/config/ci.config.ts +0 -29
  76. package/src/config/config-loader.ts +0 -100
  77. package/src/config/config-reader.service.ts +0 -128
  78. package/src/config/config-reader.ts +0 -75
  79. package/src/config/feishu.config.ts +0 -35
  80. package/src/config/git-provider.config.ts +0 -29
  81. package/src/config/llm.config.ts +0 -110
  82. package/src/config/load-env.ts +0 -15
  83. package/src/config/storage.config.ts +0 -33
  84. /package/src/{shared → cli-runtime}/i18n/i18n.spec.ts +0 -0
  85. /package/src/{shared → cli-runtime}/i18n/i18n.ts +0 -0
  86. /package/src/{shared → cli-runtime}/i18n/locale-detect.ts +0 -0
@@ -1,128 +0,0 @@
1
- /**
2
- * 系统配置(不包含插件配置)
3
- */
4
- export interface SystemConfig {
5
- /** 已安装的技能包注册表 */
6
- dependencies?: Record<string, string>;
7
- /** 支持的编辑器列表 */
8
- support?: string[];
9
- }
10
-
11
- /**
12
- * 插件配置注册信息
13
- */
14
- export interface PluginConfigRegistry {
15
- /** 插件名称 */
16
- name: string;
17
- /** 配置 key */
18
- configKey?: string;
19
- /** 依赖的其他插件配置 */
20
- configDependencies?: string[];
21
- /** 配置 schema 工厂函数 */
22
- configSchema?: () => unknown;
23
- }
24
-
25
- /** 全局插件配置注册表(使用 global 确保跨模块共享) */
26
- const PLUGIN_REGISTRY_KEY = Symbol.for("spaceflow.pluginRegistry");
27
- const globalAny = global as any;
28
- if (!globalAny[PLUGIN_REGISTRY_KEY]) {
29
- globalAny[PLUGIN_REGISTRY_KEY] = new Map<string, PluginConfigRegistry>();
30
- }
31
- const pluginRegistry: Map<string, PluginConfigRegistry> = globalAny[PLUGIN_REGISTRY_KEY];
32
-
33
- /**
34
- * 注册插件配置(由插件加载器调用)
35
- */
36
- export function registerPluginConfig(registry: PluginConfigRegistry): void {
37
- if (registry.configKey) {
38
- pluginRegistry.set(registry.configKey, registry);
39
- }
40
- }
41
-
42
- /**
43
- * 获取已注册的插件配置
44
- */
45
- export function getRegisteredPluginConfig(configKey: string): PluginConfigRegistry | undefined {
46
- return pluginRegistry.get(configKey);
47
- }
48
-
49
- /**
50
- * 配置读取服务
51
- * 提供三种配置读取方式:
52
- * 1. getPluginConfig - 读取指定插件的配置
53
- * 2. getOtherPluginConfig - 读取其他插件的配置(需要在 metadata 中声明依赖)
54
- * 3. getSystemConfig - 读取系统配置
55
- */
56
- export class ConfigReaderService {
57
- constructor() {}
58
-
59
- /**
60
- * 读取插件的配置
61
- * 使用 schema 验证并合并默认值
62
- * @param configKey 插件的配置 key
63
- * @returns 验证后的插件配置
64
- */
65
- getPluginConfig<T>(configKey: string): T {
66
- const rawConfig = (global as any).spaceflowConfig || {};
67
- const userConfig = rawConfig[configKey] ?? {};
68
-
69
- // 从注册表获取 schema 工厂函数
70
- const registry = pluginRegistry.get(configKey);
71
- const schemaFactory = registry?.configSchema;
72
-
73
- if (!schemaFactory || typeof schemaFactory !== "function") {
74
- return userConfig as T;
75
- }
76
-
77
- // 调用工厂函数获取 schema
78
- const schema = schemaFactory();
79
- if (!schema || typeof (schema as any).parse !== "function") {
80
- return userConfig as T;
81
- }
82
-
83
- // 使用 schema.parse() 验证并填充默认值
84
- try {
85
- return (schema as any).parse(userConfig) as T;
86
- } catch (error) {
87
- console.warn(`⚠️ 配置 "${configKey}" 验证失败:`, error);
88
- return userConfig as T;
89
- }
90
- }
91
-
92
- /**
93
- * 读取其他插件的配置
94
- * 必须在插件的 metadata.configDependencies 中声明依赖
95
- * @param fromConfigKey 当前插件的配置 key
96
- * @param targetConfigKey 目标插件的配置 key
97
- * @returns 合并后的插件配置
98
- */
99
- getOtherPluginConfig<T>(fromConfigKey: string, targetConfigKey: string): T {
100
- const fromRegistry = pluginRegistry.get(fromConfigKey);
101
- if (!fromRegistry) {
102
- throw new Error(`插件 "${fromConfigKey}" 未注册`);
103
- }
104
-
105
- // 检查是否已声明依赖
106
- const dependencies = fromRegistry.configDependencies ?? [];
107
- if (!dependencies.includes(targetConfigKey)) {
108
- throw new Error(
109
- `插件 "${fromRegistry.name}" 未声明对 "${targetConfigKey}" 配置的依赖。` +
110
- `请在插件 metadata 的 configDependencies 中添加 "${targetConfigKey}"`,
111
- );
112
- }
113
-
114
- return this.getPluginConfig<T>(targetConfigKey);
115
- }
116
-
117
- /**
118
- * 读取系统配置(不包含插件配置)
119
- * @returns 系统配置
120
- */
121
- getSystemConfig(): SystemConfig {
122
- const rawConfig = (global as any).spaceflowConfig || {};
123
- return {
124
- dependencies: rawConfig.dependencies,
125
- support: rawConfig.support,
126
- };
127
- }
128
- }
@@ -1,75 +0,0 @@
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
- }
@@ -1,35 +0,0 @@
1
- import { z } from "zod";
2
- import { createConfigLoader } from "./config-loader";
3
-
4
- const schemaFactory = () =>
5
- z.object({
6
- /** 飞书应用 ID */
7
- appId: z
8
- .string()
9
- .default(process.env.FEISHU_APP_ID || "")
10
- .describe("飞书应用 ID"),
11
- /** 飞书应用密钥 */
12
- appSecret: z
13
- .string()
14
- .default(process.env.FEISHU_APP_SECRET || "")
15
- .describe("飞书应用密钥"),
16
- /** 应用类型:自建应用或商店应用 */
17
- appType: z
18
- .enum(["self_build", "store"])
19
- .default((process.env.FEISHU_APP_TYPE as "self_build" | "store") || "self_build")
20
- .describe("应用类型"),
21
- /** 域名:飞书或 Lark */
22
- domain: z
23
- .enum(["feishu", "lark"])
24
- .default((process.env.FEISHU_DOMAIN as "feishu" | "lark") || "feishu")
25
- .describe("域名"),
26
- });
27
-
28
- /** 飞书配置类型 */
29
- export type FeishuConfig = z.infer<ReturnType<typeof schemaFactory>>;
30
-
31
- export const feishuConfig = createConfigLoader({
32
- configKey: "feishu",
33
- schemaFactory,
34
- description: "飞书 SDK 配置",
35
- });
@@ -1,29 +0,0 @@
1
- import { z } from "zod";
2
- import { createConfigLoader } from "./config-loader";
3
- import { detectProvider } from "../shared/git-provider/detect-provider";
4
-
5
- /** 从环境自动检测的默认值 */
6
- const detected = detectProvider();
7
-
8
- /** Git Provider 配置 Schema */
9
- const schemaFactory = () =>
10
- z.object({
11
- /** Git Provider 类型(自动检测或手动指定) */
12
- provider: z
13
- .enum(["gitea", "github", "gitlab"])
14
- .default(detected.provider)
15
- .describe("Git Provider 类型 (github | gitea | gitlab),未指定时自动检测"),
16
- /** Git Provider 服务器 URL */
17
- serverUrl: z.string().default(detected.serverUrl).describe("Git Provider 服务器 URL"),
18
- /** Git Provider API Token */
19
- token: z.string().default(detected.token).describe("Git Provider API Token"),
20
- });
21
-
22
- /** Git Provider 配置类型 */
23
- export type GitProviderConfig = z.infer<ReturnType<typeof schemaFactory>>;
24
-
25
- export const gitProviderConfig = createConfigLoader({
26
- configKey: "gitProvider",
27
- schemaFactory,
28
- description: "Git Provider 服务配置",
29
- });
@@ -1,110 +0,0 @@
1
- import { z } from "zod";
2
- import { createConfigLoader } from "./config-loader";
3
-
4
- const schemaFactory = () => {
5
- /** Claude Code 适配器配置 Schema */
6
- const ClaudeCodeConfigSchema = z.object({
7
- baseUrl: z
8
- .string()
9
- .default(process.env.CLAUDE_CODE_BASE_URL || "")
10
- .describe("API 基础 URL"),
11
- authToken: z
12
- .string()
13
- .default(process.env.CLAUDE_CODE_AUTH_TOKEN || "")
14
- .describe("认证令牌"),
15
- model: z
16
- .string()
17
- .default(process.env.CLAUDE_CODE_MODEL || "claude-sonnet-4-5")
18
- .describe("模型名称"),
19
- hasCompletedOnboarding: z.boolean().optional().describe("是否已完成 Claude Code 引导流程"),
20
- });
21
-
22
- /** OpenAI 适配器配置 Schema */
23
- const OpenAIConfigSchema = z.object({
24
- baseUrl: z
25
- .string()
26
- .default(process.env.OPENAI_BASE_URL || "")
27
- .describe("API 基础 URL"),
28
- apiKey: z
29
- .string()
30
- .default(process.env.OPENAI_API_KEY || "")
31
- .describe("API Key"),
32
- model: z
33
- .string()
34
- .default(process.env.OPENAI_MODEL || "gpt-4o")
35
- .describe("模型名称"),
36
- });
37
-
38
- /** OpenCode 适配器配置 Schema */
39
- const OpenCodeConfigSchema = z.object({
40
- serverUrl: z
41
- .string()
42
- .default(process.env.OPENCODE_SERVER_URL || "http://localhost:4096")
43
- .describe("服务器 URL"),
44
- baseUrl: z
45
- .string()
46
- .default(process.env.OPENCODE_BASE_URL || "")
47
- .describe("API 基础 URL"),
48
- apiKey: z
49
- .string()
50
- .default(process.env.OPENCODE_API_KEY || "")
51
- .describe("API Key"),
52
- providerID: z
53
- .string()
54
- .default(process.env.OPENCODE_PROVIDER_ID || "openai")
55
- .describe("Provider ID"),
56
- model: z
57
- .string()
58
- .default(process.env.OPENCODE_MODEL || "")
59
- .describe("模型名称"),
60
- });
61
-
62
- /** Gemini 适配器配置 Schema */
63
- const GeminiConfigSchema = z.object({
64
- baseUrl: z
65
- .string()
66
- .default(process.env.GEMINI_BASE_URL || "")
67
- .describe("API 基础 URL"),
68
- apiKey: z
69
- .string()
70
- .default(process.env.GEMINI_API_KEY || "")
71
- .describe("API Key"),
72
- model: z
73
- .string()
74
- .default(process.env.GEMINI_MODEL || "")
75
- .describe("模型名称"),
76
- });
77
-
78
- /** LLM 配置 Schema */
79
- const LlmConfigSchema = z.object({
80
- claudeCode: z
81
- .preprocess((v) => v ?? {}, ClaudeCodeConfigSchema)
82
- .describe("Claude Code 适配器配置"),
83
- openai: z.preprocess((v) => v ?? {}, OpenAIConfigSchema).describe("OpenAI 适配器配置"),
84
- openCode: z.preprocess((v) => v ?? {}, OpenCodeConfigSchema).describe("OpenCode 适配器配置"),
85
- gemini: z.preprocess((v) => v ?? {}, GeminiConfigSchema).describe("Gemini 适配器配置"),
86
- });
87
-
88
- return LlmConfigSchema;
89
- };
90
-
91
- /** LLM 系统配置类型 */
92
- export type LlmConfig = z.infer<ReturnType<typeof schemaFactory>>;
93
-
94
- /** Claude Code 适配器配置类型 */
95
- export type ClaudeCodeConfig = z.infer<LlmConfig["claudeCode"]>;
96
-
97
- /** OpenAI 适配器配置类型 */
98
- export type OpenAIConfig = z.infer<LlmConfig["openai"]>;
99
-
100
- /** OpenCode 适配器配置类型 */
101
- export type OpenCodeConfig = z.infer<LlmConfig["openCode"]>;
102
-
103
- /** Gemini 适配器配置类型 */
104
- export type GeminiConfig = z.infer<LlmConfig["gemini"]>;
105
-
106
- export const llmConfig = createConfigLoader({
107
- configKey: "llm",
108
- schemaFactory,
109
- description: "LLM 服务配置",
110
- });
@@ -1,15 +0,0 @@
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,33 +0,0 @@
1
- import { z } from "zod";
2
- import { createConfigLoader } from "./config-loader";
3
-
4
- /** Storage 配置 Schema */
5
- const schemaFactory = () =>
6
- z.object({
7
- /** 适配器类型:memory 或 file */
8
- adapter: z
9
- .enum(["memory", "file"])
10
- .default((process.env.STORAGE_ADAPTER as "memory" | "file") || "memory")
11
- .describe("适配器类型"),
12
- /** 文件适配器的存储路径(仅 file 适配器需要) */
13
- filePath: z.string().optional().describe("文件存储路径"),
14
- /** 默认过期时间(毫秒),0 表示永不过期 */
15
- defaultTtl: z
16
- .number()
17
- .default(process.env.STORAGE_DEFAULT_TTL ? parseInt(process.env.STORAGE_DEFAULT_TTL, 10) : 0)
18
- .describe("默认过期时间(毫秒)"),
19
- /** 最大 key 数量,0 表示不限制 */
20
- maxKeys: z
21
- .number()
22
- .default(process.env.STORAGE_MAX_KEYS ? parseInt(process.env.STORAGE_MAX_KEYS, 10) : 0)
23
- .describe("最大 key 数量"),
24
- });
25
-
26
- /** Storage 配置类型 */
27
- export type StorageConfig = z.infer<ReturnType<typeof schemaFactory>>;
28
-
29
- export const storageConfig = createConfigLoader({
30
- configKey: "storage",
31
- schemaFactory,
32
- description: "存储服务配置",
33
- });
File without changes
File without changes