conflux-ai 0.1.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/LICENSE +21 -0
- package/README.md +203 -0
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.js +1667 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/index.d.ts +1509 -0
- package/dist/index.js +294 -0
- package/dist/index.js.map +1 -0
- package/package.json +78 -0
- package/schemas/ai-config.schema.json +572 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
// src/core/config.ts
|
|
2
|
+
import { readFileSync, existsSync } from "fs";
|
|
3
|
+
import { join } from "path";
|
|
4
|
+
import yaml from "js-yaml";
|
|
5
|
+
|
|
6
|
+
// src/core/schema.ts
|
|
7
|
+
import { z } from "zod";
|
|
8
|
+
var InstructionRuleSchema = z.object({
|
|
9
|
+
path: z.string().describe("Path to the rule file (markdown)"),
|
|
10
|
+
description: z.string().optional().describe("What this rule covers"),
|
|
11
|
+
globs: z.array(z.string()).optional().describe("File globs this rule applies to"),
|
|
12
|
+
alwaysApply: z.boolean().optional().default(true).describe("Always apply regardless of glob")
|
|
13
|
+
});
|
|
14
|
+
var InstructionReferenceSchema = z.object({
|
|
15
|
+
path: z.string().describe("Path to the reference document"),
|
|
16
|
+
description: z.string().optional().describe("What this document covers")
|
|
17
|
+
});
|
|
18
|
+
var InstructionsConfigSchema = z.object({
|
|
19
|
+
primary: z.string().default("AGENTS.md").describe("Primary instruction file name"),
|
|
20
|
+
references: z.array(InstructionReferenceSchema).optional().describe("Reference documents to include"),
|
|
21
|
+
rules: z.array(InstructionRuleSchema).optional().describe("Granular rule files")
|
|
22
|
+
});
|
|
23
|
+
var HookEntrySchema = z.object({
|
|
24
|
+
command: z.string().describe("Command to execute"),
|
|
25
|
+
timeout: z.number().int().positive().optional().describe("Timeout in seconds"),
|
|
26
|
+
description: z.string().optional().describe("What this hook does"),
|
|
27
|
+
matcher: z.string().optional().describe("Regex matcher (e.g., tool name pattern)")
|
|
28
|
+
});
|
|
29
|
+
var HooksConfigSchema = z.record(
|
|
30
|
+
z.string(),
|
|
31
|
+
z.array(HookEntrySchema)
|
|
32
|
+
).describe("Lifecycle event hooks keyed by event name");
|
|
33
|
+
var McpServerSchema = z.object({
|
|
34
|
+
command: z.string().describe("Command to run the MCP server"),
|
|
35
|
+
args: z.array(z.string()).optional().describe("Command arguments"),
|
|
36
|
+
env: z.record(z.string(), z.string()).optional().describe("Environment variables")
|
|
37
|
+
});
|
|
38
|
+
var McpConfigSchema = z.object({
|
|
39
|
+
env: z.record(z.string(), z.string()).optional().describe("Global env vars for all MCP servers"),
|
|
40
|
+
servers: z.record(z.string(), McpServerSchema).describe("MCP server configurations")
|
|
41
|
+
});
|
|
42
|
+
var PermissionsConfigSchema = z.object({
|
|
43
|
+
default: z.enum(["prompt", "allow", "deny"]).default("prompt").describe("Default permission mode"),
|
|
44
|
+
allow: z.array(z.string()).optional().describe("Globally allowed operations"),
|
|
45
|
+
deny: z.array(z.string()).optional().describe("Globally denied operations")
|
|
46
|
+
});
|
|
47
|
+
var LocalSkillSchema = z.object({
|
|
48
|
+
name: z.string().describe("Skill name (invoked by this name)"),
|
|
49
|
+
path: z.string().describe("Path to SKILL.md file"),
|
|
50
|
+
description: z.string().optional().describe("What this skill does"),
|
|
51
|
+
tags: z.array(z.string()).optional().describe("Tags for categorization")
|
|
52
|
+
});
|
|
53
|
+
var ExternalSkillSchema = z.object({
|
|
54
|
+
name: z.string().describe("Skill name"),
|
|
55
|
+
source: z.string().describe("Source repo or package (e.g., 'org/repo')"),
|
|
56
|
+
sourceType: z.enum(["github", "npm", "url"]).describe("Type of source"),
|
|
57
|
+
skillPath: z.string().describe("Path to the skill within the source"),
|
|
58
|
+
description: z.string().optional()
|
|
59
|
+
});
|
|
60
|
+
var SkillsConfigSchema = z.object({
|
|
61
|
+
local: z.array(LocalSkillSchema).optional().describe("Locally defined skills"),
|
|
62
|
+
external: z.array(ExternalSkillSchema).optional().describe("Skills from external sources")
|
|
63
|
+
});
|
|
64
|
+
var ProviderOverrideSchema = z.object({
|
|
65
|
+
instructions: InstructionsConfigSchema.partial().optional(),
|
|
66
|
+
hooks: HooksConfigSchema.optional(),
|
|
67
|
+
mcp: McpConfigSchema.partial().optional(),
|
|
68
|
+
permissions: PermissionsConfigSchema.partial().optional(),
|
|
69
|
+
skills: SkillsConfigSchema.partial().optional()
|
|
70
|
+
});
|
|
71
|
+
var ProvidersConfigSchema = z.object({
|
|
72
|
+
enabled: z.array(z.string()).optional().describe("Providers to enable (omitted = auto-detect)"),
|
|
73
|
+
overrides: z.record(z.string(), ProviderOverrideSchema).optional().describe("Per-provider overrides")
|
|
74
|
+
});
|
|
75
|
+
var ConfluxMetaSchema = z.object({
|
|
76
|
+
created: z.string().optional().describe("Creation date"),
|
|
77
|
+
schema: z.string().optional().describe("Schema URL for validation"),
|
|
78
|
+
description: z.string().optional().describe("Project description")
|
|
79
|
+
});
|
|
80
|
+
var UnifiedConfigSchema = z.object({
|
|
81
|
+
version: z.literal(1).describe("Config schema version (must be 1)"),
|
|
82
|
+
instructions: InstructionsConfigSchema.optional().describe("Project instructions for AI agents"),
|
|
83
|
+
hooks: HooksConfigSchema.optional().describe("Lifecycle event hooks"),
|
|
84
|
+
mcp: McpConfigSchema.optional().describe("MCP server configurations"),
|
|
85
|
+
permissions: PermissionsConfigSchema.optional().describe("Permission rules"),
|
|
86
|
+
skills: SkillsConfigSchema.optional().describe("Reusable skill/command definitions"),
|
|
87
|
+
providers: ProvidersConfigSchema.optional().describe("Provider enablement and overrides"),
|
|
88
|
+
meta: ConfluxMetaSchema.optional().describe("Metadata")
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
// src/core/config.ts
|
|
92
|
+
import { ZodError } from "zod";
|
|
93
|
+
function loadConfig(projectPath) {
|
|
94
|
+
const configPath = join(projectPath, ".ai", "config.yaml");
|
|
95
|
+
if (!existsSync(configPath)) {
|
|
96
|
+
throw new ConfigNotFoundError(
|
|
97
|
+
`No .ai/config.yaml found in ${projectPath}. Run "conflux init" to create one.`
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
let raw;
|
|
101
|
+
try {
|
|
102
|
+
const content = readFileSync(configPath, "utf-8");
|
|
103
|
+
raw = yaml.load(content);
|
|
104
|
+
} catch (err) {
|
|
105
|
+
if (err instanceof ConfigNotFoundError) throw err;
|
|
106
|
+
throw new ConfigParseError(
|
|
107
|
+
`Failed to parse ${configPath}: ${err.message}`
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
return validateConfig(raw, configPath);
|
|
111
|
+
}
|
|
112
|
+
function validateConfig(raw, source) {
|
|
113
|
+
try {
|
|
114
|
+
return UnifiedConfigSchema.parse(raw);
|
|
115
|
+
} catch (err) {
|
|
116
|
+
if (err instanceof ZodError) {
|
|
117
|
+
const issues = err.issues.map((i) => ` - ${i.path.join(".") || "(root)"}: ${i.message}`).join("\n");
|
|
118
|
+
const label = source ? ` in ${source}` : "";
|
|
119
|
+
throw new ConfigValidationError(`Schema validation failed${label}:
|
|
120
|
+
${issues}`);
|
|
121
|
+
}
|
|
122
|
+
throw err;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
var ConfigNotFoundError = class extends Error {
|
|
126
|
+
constructor(message) {
|
|
127
|
+
super(message);
|
|
128
|
+
this.name = "ConfigNotFoundError";
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
var ConfigParseError = class extends Error {
|
|
132
|
+
constructor(message) {
|
|
133
|
+
super(message);
|
|
134
|
+
this.name = "ConfigParseError";
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
var ConfigValidationError = class extends Error {
|
|
138
|
+
constructor(message) {
|
|
139
|
+
super(message);
|
|
140
|
+
this.name = "ConfigValidationError";
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
// src/core/resolver.ts
|
|
145
|
+
import { existsSync as existsSync2 } from "fs";
|
|
146
|
+
import { join as join2, dirname, resolve, parse } from "path";
|
|
147
|
+
function resolveConfigPaths(startPath) {
|
|
148
|
+
const configs = [];
|
|
149
|
+
let current = resolve(startPath);
|
|
150
|
+
const root = parse(current).root;
|
|
151
|
+
while (current !== root) {
|
|
152
|
+
const configPath = join2(current, ".ai", "config.yaml");
|
|
153
|
+
if (existsSync2(configPath)) {
|
|
154
|
+
configs.unshift(configPath);
|
|
155
|
+
}
|
|
156
|
+
const parent = dirname(current);
|
|
157
|
+
if (parent === current) break;
|
|
158
|
+
current = parent;
|
|
159
|
+
}
|
|
160
|
+
return configs;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// src/core/merger.ts
|
|
164
|
+
function mergeConfigs(configs) {
|
|
165
|
+
if (configs.length === 0) {
|
|
166
|
+
throw new Error("No configs to merge");
|
|
167
|
+
}
|
|
168
|
+
if (configs.length === 1) {
|
|
169
|
+
return configs[0];
|
|
170
|
+
}
|
|
171
|
+
let merged = { version: 1 };
|
|
172
|
+
for (const config of configs) {
|
|
173
|
+
merged = mergeTwo(merged, config);
|
|
174
|
+
}
|
|
175
|
+
return merged;
|
|
176
|
+
}
|
|
177
|
+
function mergeTwo(base, override) {
|
|
178
|
+
const result = { version: override.version ?? base.version };
|
|
179
|
+
if (override.instructions || base.instructions) {
|
|
180
|
+
const mergedInstructions = {
|
|
181
|
+
primary: "AGENTS.md",
|
|
182
|
+
...base.instructions,
|
|
183
|
+
...override.instructions
|
|
184
|
+
};
|
|
185
|
+
mergedInstructions.references = override.instructions?.references ?? base.instructions?.references;
|
|
186
|
+
mergedInstructions.rules = override.instructions?.rules ?? base.instructions?.rules;
|
|
187
|
+
result.instructions = mergedInstructions;
|
|
188
|
+
}
|
|
189
|
+
if (override.hooks || base.hooks) {
|
|
190
|
+
result.hooks = {
|
|
191
|
+
...base.hooks,
|
|
192
|
+
...override.hooks
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
if (override.mcp || base.mcp) {
|
|
196
|
+
result.mcp = {
|
|
197
|
+
env: { ...base.mcp?.env ?? {}, ...override.mcp?.env ?? {} },
|
|
198
|
+
servers: { ...base.mcp?.servers ?? {}, ...override.mcp?.servers ?? {} }
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
if (override.permissions || base.permissions) {
|
|
202
|
+
result.permissions = {
|
|
203
|
+
default: "prompt",
|
|
204
|
+
...base.permissions,
|
|
205
|
+
...override.permissions,
|
|
206
|
+
allow: override.permissions?.allow ?? base.permissions?.allow,
|
|
207
|
+
deny: override.permissions?.deny ?? base.permissions?.deny
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
if (override.skills || base.skills) {
|
|
211
|
+
result.skills = {
|
|
212
|
+
local: override.skills?.local ?? base.skills?.local,
|
|
213
|
+
external: override.skills?.external ?? base.skills?.external
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
if (override.providers || base.providers) {
|
|
217
|
+
result.providers = {
|
|
218
|
+
enabled: override.providers?.enabled ?? base.providers?.enabled,
|
|
219
|
+
overrides: { ...base.providers?.overrides ?? {}, ...override.providers?.overrides ?? {} }
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
if (override.meta || base.meta) {
|
|
223
|
+
result.meta = { ...base.meta, ...override.meta };
|
|
224
|
+
}
|
|
225
|
+
return result;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// src/providers/registry.ts
|
|
229
|
+
var ProviderRegistry = class {
|
|
230
|
+
providers = /* @__PURE__ */ new Map();
|
|
231
|
+
/** Register a provider (built-in or external) */
|
|
232
|
+
register(provider) {
|
|
233
|
+
if (this.providers.has(provider.id)) {
|
|
234
|
+
throw new Error(
|
|
235
|
+
`Provider "${provider.id}" is already registered. Remove it first before re-registering.`
|
|
236
|
+
);
|
|
237
|
+
}
|
|
238
|
+
this.providers.set(provider.id, provider);
|
|
239
|
+
}
|
|
240
|
+
/** Unregister a provider */
|
|
241
|
+
unregister(id) {
|
|
242
|
+
return this.providers.delete(id);
|
|
243
|
+
}
|
|
244
|
+
/** Get a provider by ID */
|
|
245
|
+
get(id) {
|
|
246
|
+
return this.providers.get(id);
|
|
247
|
+
}
|
|
248
|
+
/** List all registered providers */
|
|
249
|
+
list() {
|
|
250
|
+
return Array.from(this.providers.values());
|
|
251
|
+
}
|
|
252
|
+
/** Detect which providers apply to the given project */
|
|
253
|
+
detect(projectPath) {
|
|
254
|
+
return this.list().filter((p) => p.detect(projectPath));
|
|
255
|
+
}
|
|
256
|
+
/** Get providers that support a specific capability */
|
|
257
|
+
withCapability(capability) {
|
|
258
|
+
return this.list().filter((p) => p.capabilities.includes(capability));
|
|
259
|
+
}
|
|
260
|
+
/** Get count of registered providers */
|
|
261
|
+
get size() {
|
|
262
|
+
return this.providers.size;
|
|
263
|
+
}
|
|
264
|
+
};
|
|
265
|
+
var registry = new ProviderRegistry();
|
|
266
|
+
|
|
267
|
+
// src/core/types.ts
|
|
268
|
+
var ProviderCapability = /* @__PURE__ */ ((ProviderCapability2) => {
|
|
269
|
+
ProviderCapability2["INSTRUCTIONS"] = "instructions";
|
|
270
|
+
ProviderCapability2["HOOKS"] = "hooks";
|
|
271
|
+
ProviderCapability2["MCP"] = "mcp";
|
|
272
|
+
ProviderCapability2["PERMISSIONS"] = "permissions";
|
|
273
|
+
ProviderCapability2["SKILLS"] = "skills";
|
|
274
|
+
return ProviderCapability2;
|
|
275
|
+
})(ProviderCapability || {});
|
|
276
|
+
|
|
277
|
+
// src/providers/base.ts
|
|
278
|
+
var AIProvider = class {
|
|
279
|
+
// ─── Utility ────────────────────────────────────────────────
|
|
280
|
+
/** Check if this provider supports a specific capability */
|
|
281
|
+
hasCapability(cap) {
|
|
282
|
+
return this.capabilities.includes(cap);
|
|
283
|
+
}
|
|
284
|
+
};
|
|
285
|
+
export {
|
|
286
|
+
AIProvider,
|
|
287
|
+
ProviderCapability,
|
|
288
|
+
loadConfig,
|
|
289
|
+
mergeConfigs,
|
|
290
|
+
registry,
|
|
291
|
+
resolveConfigPaths,
|
|
292
|
+
validateConfig
|
|
293
|
+
};
|
|
294
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/config.ts","../src/core/schema.ts","../src/core/resolver.ts","../src/core/merger.ts","../src/providers/registry.ts","../src/core/types.ts","../src/providers/base.ts"],"sourcesContent":["import { readFileSync, existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport yaml from \"js-yaml\";\nimport { UnifiedConfigSchema, type UnifiedConfig } from \"./schema.js\";\nimport { ZodError } from \"zod\";\n\n/**\n * Load and parse a .ai/config.yaml file from the given project path.\n * Throws if the file is missing, invalid YAML, or fails schema validation.\n */\nexport function loadConfig(projectPath: string): UnifiedConfig {\n const configPath = join(projectPath, \".ai\", \"config.yaml\");\n\n if (!existsSync(configPath)) {\n throw new ConfigNotFoundError(\n `No .ai/config.yaml found in ${projectPath}. Run \"conflux init\" to create one.`\n );\n }\n\n let raw: unknown;\n try {\n const content = readFileSync(configPath, \"utf-8\");\n raw = yaml.load(content);\n } catch (err) {\n if (err instanceof ConfigNotFoundError) throw err;\n throw new ConfigParseError(\n `Failed to parse ${configPath}: ${(err as Error).message}`\n );\n }\n\n return validateConfig(raw, configPath);\n}\n\n/**\n * Validate an already-parsed config object against the Zod schema.\n */\nexport function validateConfig(raw: unknown, source?: string): UnifiedConfig {\n try {\n return UnifiedConfigSchema.parse(raw);\n } catch (err) {\n if (err instanceof ZodError) {\n const issues = err.issues\n .map((i) => ` - ${i.path.join(\".\") || \"(root)\"}: ${i.message}`)\n .join(\"\\n\");\n const label = source ? ` in ${source}` : \"\";\n throw new ConfigValidationError(`Schema validation failed${label}:\\n${issues}`);\n }\n throw err;\n }\n}\n\n/**\n * Check if a .ai/config.yaml exists in the project.\n */\nexport function configExists(projectPath: string): boolean {\n return existsSync(join(projectPath, \".ai\", \"config.yaml\"));\n}\n\n// ============================================================================\n// Custom Errors\n// ============================================================================\n\nexport class ConfigNotFoundError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ConfigNotFoundError\";\n }\n}\n\nexport class ConfigParseError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ConfigParseError\";\n }\n}\n\nexport class ConfigValidationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ConfigValidationError\";\n }\n}\n","import { z } from \"zod\";\n\n// ============================================================================\n// Dimension 1: Instructions\n// ============================================================================\n\nexport const InstructionRuleSchema = z.object({\n path: z.string().describe(\"Path to the rule file (markdown)\"),\n description: z.string().optional().describe(\"What this rule covers\"),\n globs: z.array(z.string()).optional().describe(\"File globs this rule applies to\"),\n alwaysApply: z.boolean().optional().default(true).describe(\"Always apply regardless of glob\"),\n});\n\nexport const InstructionReferenceSchema = z.object({\n path: z.string().describe(\"Path to the reference document\"),\n description: z.string().optional().describe(\"What this document covers\"),\n});\n\nexport const InstructionsConfigSchema = z.object({\n primary: z.string().default(\"AGENTS.md\").describe(\"Primary instruction file name\"),\n references: z.array(InstructionReferenceSchema).optional().describe(\"Reference documents to include\"),\n rules: z.array(InstructionRuleSchema).optional().describe(\"Granular rule files\"),\n});\n\n// ============================================================================\n// Dimension 2: Hooks\n// ============================================================================\n\nexport const HookEntrySchema = z.object({\n command: z.string().describe(\"Command to execute\"),\n timeout: z.number().int().positive().optional().describe(\"Timeout in seconds\"),\n description: z.string().optional().describe(\"What this hook does\"),\n matcher: z.string().optional().describe(\"Regex matcher (e.g., tool name pattern)\"),\n});\n\nexport const HooksConfigSchema = z.record(\n z.string(),\n z.array(HookEntrySchema)\n).describe(\"Lifecycle event hooks keyed by event name\");\n\n// ============================================================================\n// Dimension 3: MCP Servers\n// ============================================================================\n\nexport const McpServerSchema = z.object({\n command: z.string().describe(\"Command to run the MCP server\"),\n args: z.array(z.string()).optional().describe(\"Command arguments\"),\n env: z.record(z.string(), z.string()).optional().describe(\"Environment variables\"),\n});\n\nexport const McpConfigSchema = z.object({\n env: z.record(z.string(), z.string()).optional().describe(\"Global env vars for all MCP servers\"),\n servers: z.record(z.string(), McpServerSchema).describe(\"MCP server configurations\"),\n});\n\n// ============================================================================\n// Dimension 4: Permissions\n// ============================================================================\n\nexport const PermissionsConfigSchema = z.object({\n default: z.enum([\"prompt\", \"allow\", \"deny\"]).default(\"prompt\").describe(\"Default permission mode\"),\n allow: z.array(z.string()).optional().describe(\"Globally allowed operations\"),\n deny: z.array(z.string()).optional().describe(\"Globally denied operations\"),\n});\n\n// ============================================================================\n// Dimension 5: Skills\n// ============================================================================\n\nexport const LocalSkillSchema = z.object({\n name: z.string().describe(\"Skill name (invoked by this name)\"),\n path: z.string().describe(\"Path to SKILL.md file\"),\n description: z.string().optional().describe(\"What this skill does\"),\n tags: z.array(z.string()).optional().describe(\"Tags for categorization\"),\n});\n\nexport const ExternalSkillSchema = z.object({\n name: z.string().describe(\"Skill name\"),\n source: z.string().describe(\"Source repo or package (e.g., 'org/repo')\"),\n sourceType: z.enum([\"github\", \"npm\", \"url\"]).describe(\"Type of source\"),\n skillPath: z.string().describe(\"Path to the skill within the source\"),\n description: z.string().optional(),\n});\n\nexport const SkillsConfigSchema = z.object({\n local: z.array(LocalSkillSchema).optional().describe(\"Locally defined skills\"),\n external: z.array(ExternalSkillSchema).optional().describe(\"Skills from external sources\"),\n});\n\n// ============================================================================\n// Provider Configuration\n// ============================================================================\n\nexport const ProviderOverrideSchema = z.object({\n instructions: InstructionsConfigSchema.partial().optional(),\n hooks: HooksConfigSchema.optional(),\n mcp: McpConfigSchema.partial().optional(),\n permissions: PermissionsConfigSchema.partial().optional(),\n skills: SkillsConfigSchema.partial().optional(),\n});\n\nexport const ProvidersConfigSchema = z.object({\n enabled: z.array(z.string()).optional().describe(\"Providers to enable (omitted = auto-detect)\"),\n overrides: z.record(z.string(), ProviderOverrideSchema).optional().describe(\"Per-provider overrides\"),\n});\n\n// ============================================================================\n// Metadata\n// ============================================================================\n\nexport const ConfluxMetaSchema = z.object({\n created: z.string().optional().describe(\"Creation date\"),\n schema: z.string().optional().describe(\"Schema URL for validation\"),\n description: z.string().optional().describe(\"Project description\"),\n});\n\n// ============================================================================\n// Full Unified Config\n// ============================================================================\n\nexport const UnifiedConfigSchema = z.object({\n version: z.literal(1).describe(\"Config schema version (must be 1)\"),\n instructions: InstructionsConfigSchema.optional().describe(\"Project instructions for AI agents\"),\n hooks: HooksConfigSchema.optional().describe(\"Lifecycle event hooks\"),\n mcp: McpConfigSchema.optional().describe(\"MCP server configurations\"),\n permissions: PermissionsConfigSchema.optional().describe(\"Permission rules\"),\n skills: SkillsConfigSchema.optional().describe(\"Reusable skill/command definitions\"),\n providers: ProvidersConfigSchema.optional().describe(\"Provider enablement and overrides\"),\n meta: ConfluxMetaSchema.optional().describe(\"Metadata\"),\n});\n\n// ============================================================================\n// Derived Types\n// ============================================================================\n\nexport type UnifiedConfig = z.infer<typeof UnifiedConfigSchema>;\nexport type InstructionsConfig = z.infer<typeof InstructionsConfigSchema>;\nexport type HooksConfig = z.infer<typeof HooksConfigSchema>;\nexport type McpConfig = z.infer<typeof McpConfigSchema>;\nexport type PermissionsConfig = z.infer<typeof PermissionsConfigSchema>;\nexport type SkillsConfig = z.infer<typeof SkillsConfigSchema>;\nexport type ProvidersConfig = z.infer<typeof ProvidersConfigSchema>;\nexport type ProviderOverride = z.infer<typeof ProviderOverrideSchema>;\nexport type HookEntry = z.infer<typeof HookEntrySchema>;\nexport type McpServer = z.infer<typeof McpServerSchema>;\nexport type LocalSkill = z.infer<typeof LocalSkillSchema>;\nexport type ExternalSkill = z.infer<typeof ExternalSkillSchema>;\nexport type InstructionRule = z.infer<typeof InstructionRuleSchema>;\n","import { existsSync } from \"node:fs\";\nimport { join, dirname, resolve, parse } from \"node:path\";\n\n/**\n * Resolve configuration file paths in a monorepo-aware manner.\n *\n * Walks UP from the given path looking for .ai/config.yaml files.\n * Returns paths from outermost to innermost (global → project → subproject).\n */\nexport function resolveConfigPaths(startPath: string): string[] {\n const configs: string[] = [];\n let current = resolve(startPath);\n\n // Walk up the directory tree\n const root = parse(current).root;\n while (current !== root) {\n const configPath = join(current, \".ai\", \"config.yaml\");\n if (existsSync(configPath)) {\n configs.unshift(configPath); // outermost first\n }\n const parent = dirname(current);\n if (parent === current) break;\n current = parent;\n }\n\n return configs;\n}\n\n/**\n * Find the nearest .ai/config.yaml from a given path.\n * Returns null if no config is found.\n */\nexport function findNearestConfig(startPath: string): string | null {\n const configs = resolveConfigPaths(startPath);\n return configs.length > 0 ? configs[configs.length - 1]! : null;\n}\n","import type { UnifiedConfig } from \"./schema.js\";\n\n/**\n * Merge multiple layered configs (e.g., global → project → local overrides).\n *\n * Strategy: later configs take precedence (shallow merge for top-level keys).\n * Arrays from later configs REPLACE earlier arrays (not concatenate).\n * Objects from later configs are DEEP-MERGED with earlier objects.\n */\nexport function mergeConfigs(configs: UnifiedConfig[]): UnifiedConfig {\n if (configs.length === 0) {\n throw new Error(\"No configs to merge\");\n }\n\n if (configs.length === 1) {\n return configs[0]!;\n }\n\n let merged: UnifiedConfig = { version: 1 };\n\n for (const config of configs) {\n merged = mergeTwo(merged, config);\n }\n\n return merged;\n}\n\nfunction mergeTwo(base: UnifiedConfig, override: UnifiedConfig): UnifiedConfig {\n const result: UnifiedConfig = { version: override.version ?? base.version };\n\n // Deep-merge instructions\n if (override.instructions || base.instructions) {\n const mergedInstructions = {\n primary: \"AGENTS.md\",\n ...base.instructions,\n ...override.instructions,\n };\n // Arrays use replacement semantics\n mergedInstructions.references = override.instructions?.references ?? base.instructions?.references;\n mergedInstructions.rules = override.instructions?.rules ?? base.instructions?.rules;\n result.instructions = mergedInstructions;\n }\n\n // Deep-merge hooks\n if (override.hooks || base.hooks) {\n result.hooks = {\n ...base.hooks,\n ...override.hooks,\n };\n }\n\n // Deep-merge MCP\n if (override.mcp || base.mcp) {\n result.mcp = {\n env: { ...(base.mcp?.env ?? {}), ...(override.mcp?.env ?? {}) },\n servers: { ...(base.mcp?.servers ?? {}), ...(override.mcp?.servers ?? {}) },\n };\n }\n\n // Deep-merge permissions\n if (override.permissions || base.permissions) {\n result.permissions = {\n default: \"prompt\" as const,\n ...base.permissions,\n ...override.permissions,\n allow: override.permissions?.allow ?? base.permissions?.allow,\n deny: override.permissions?.deny ?? base.permissions?.deny,\n };\n }\n\n // Deep-merge skills\n if (override.skills || base.skills) {\n result.skills = {\n local: override.skills?.local ?? base.skills?.local,\n external: override.skills?.external ?? base.skills?.external,\n };\n }\n\n // Deep-merge providers\n if (override.providers || base.providers) {\n result.providers = {\n enabled: override.providers?.enabled ?? base.providers?.enabled,\n overrides: { ...(base.providers?.overrides ?? {}), ...(override.providers?.overrides ?? {}) },\n };\n }\n\n // Deep-merge meta\n if (override.meta || base.meta) {\n result.meta = { ...base.meta, ...override.meta };\n }\n\n return result;\n}\n","import { AIProvider, ProviderCapability } from \"./base.js\";\n\n/**\n * Provider registry — singleton that holds all registered AI tool providers.\n */\nclass ProviderRegistry {\n private providers = new Map<string, AIProvider>();\n\n /** Register a provider (built-in or external) */\n register(provider: AIProvider): void {\n if (this.providers.has(provider.id)) {\n throw new Error(\n `Provider \"${provider.id}\" is already registered. Remove it first before re-registering.`\n );\n }\n this.providers.set(provider.id, provider);\n }\n\n /** Unregister a provider */\n unregister(id: string): boolean {\n return this.providers.delete(id);\n }\n\n /** Get a provider by ID */\n get(id: string): AIProvider | undefined {\n return this.providers.get(id);\n }\n\n /** List all registered providers */\n list(): AIProvider[] {\n return Array.from(this.providers.values());\n }\n\n /** Detect which providers apply to the given project */\n detect(projectPath: string): AIProvider[] {\n return this.list().filter((p) => p.detect(projectPath));\n }\n\n /** Get providers that support a specific capability */\n withCapability(capability: ProviderCapability): AIProvider[] {\n return this.list().filter((p) => p.capabilities.includes(capability));\n }\n\n /** Get count of registered providers */\n get size(): number {\n return this.providers.size;\n }\n}\n\n/** Singleton registry instance */\nexport const registry = new ProviderRegistry();\n","// ============================================================================\n// Core Type Definitions for Conflux\n// Re-exports all types from the Zod schema (single source of truth).\n// ============================================================================\n\nexport type {\n UnifiedConfig,\n InstructionsConfig,\n HooksConfig,\n McpConfig,\n PermissionsConfig,\n SkillsConfig,\n ProvidersConfig,\n ProviderOverride,\n HookEntry,\n McpServer,\n LocalSkill,\n ExternalSkill,\n InstructionRule,\n} from \"./schema.js\";\n\n// ============================================================================\n// Provider Capability\n// ============================================================================\n\nexport enum ProviderCapability {\n INSTRUCTIONS = \"instructions\",\n HOOKS = \"hooks\",\n MCP = \"mcp\",\n PERMISSIONS = \"permissions\",\n SKILLS = \"skills\",\n}\n\n// ============================================================================\n// Generated File\n// ============================================================================\n\nexport interface GeneratedFile {\n /** Relative path from project root */\n path: string;\n /** File content to write */\n content: string;\n /** Write mode */\n mode?: \"write\" | \"symlink\" | \"merge\";\n /** File format (drives serialization) */\n format?: \"json\" | \"yaml\" | \"toml\" | \"markdown\" | \"text\";\n /** Content hash for drift detection */\n hash?: string;\n}\n\n// ============================================================================\n// Sync Result\n// ============================================================================\n\nexport interface SyncResult {\n provider: string;\n filesWritten: GeneratedFile[];\n filesRemoved: string[];\n errors: string[];\n warnings: string[];\n}\n\n// ============================================================================\n// Drift Report\n// ============================================================================\n\nexport interface DriftReport {\n provider: string;\n inSync: boolean;\n lastSyncTime: Date | null;\n modifiedFiles: Array<{\n path: string;\n expectedHash: string;\n actualHash: string;\n }>;\n missingFiles: string[];\n extraFiles: string[];\n}\n\n// ============================================================================\n// Discovered Config (from import)\n// ============================================================================\n\nexport interface DiscoveredConfig {\n instructions: string[];\n hooks: Record<string, unknown> | null;\n mcp: Record<string, unknown> | null;\n permissions: Record<string, unknown> | null;\n skills: string[];\n}\n\n// ============================================================================\n// Sync Options\n// ============================================================================\n\nexport interface SyncOptions {\n dryRun: boolean;\n verbose: boolean;\n force: boolean;\n}\n\n// ============================================================================\n// Sync State (for drift detection)\n// ============================================================================\n\nexport interface FileState {\n hash: string;\n generatedFrom: string;\n type?: \"file\" | \"symlink\";\n target?: string;\n}\n\nexport interface ProviderSyncState {\n synced: boolean;\n lastSync: string | null;\n files: Record<string, FileState>;\n}\n\nexport interface SyncState {\n version: number;\n lastSync: string;\n configHash: string;\n providers: Record<string, ProviderSyncState>;\n}\n","import type {\n UnifiedConfig,\n GeneratedFile,\n SyncResult,\n DriftReport,\n DiscoveredConfig,\n SyncOptions,\n InstructionsConfig,\n HooksConfig,\n McpConfig,\n PermissionsConfig,\n SkillsConfig,\n ProviderCapability,\n} from \"../core/types.js\";\n\nexport { ProviderCapability } from \"../core/types.js\";\nexport type {\n GeneratedFile,\n SyncResult,\n DriftReport,\n DiscoveredConfig,\n SyncOptions,\n UnifiedConfig,\n InstructionsConfig,\n HooksConfig,\n McpConfig,\n PermissionsConfig,\n SkillsConfig,\n};\n\n/**\n * Abstract base class for AI coding tool providers.\n * Each supported tool (Claude Code, Codex, Cursor, etc.)\n * extends this class and implements the tool-specific logic.\n */\nexport abstract class AIProvider {\n /** Unique identifier (e.g., \"claude-code\", \"cursor\") */\n abstract readonly id: string;\n\n /** Human-readable name */\n abstract readonly name: string;\n\n /** Provider version (for compatibility tracking) */\n abstract readonly version: string;\n\n /** Description of what this provider supports */\n abstract readonly capabilities: ProviderCapability[];\n\n // ─── Detection ──────────────────────────────────────────────\n\n /** Whether this tool's configuration exists in the project */\n abstract detect(projectPath: string): boolean;\n\n /** Discover existing config files for this tool */\n abstract discoverExisting(projectPath: string): DiscoveredConfig;\n\n // ─── Sync Operations ────────────────────────────────────────\n\n /** Sync all applicable dimensions for this provider */\n abstract sync(\n projectPath: string,\n config: UnifiedConfig,\n options?: SyncOptions\n ): Promise<SyncResult>;\n\n /** Remove all generated config files for this provider */\n abstract clean(projectPath: string): Promise<string[]>;\n\n // ─── Drift Detection ────────────────────────────────────────\n\n /** Check if generated files have drifted from source */\n abstract checkDrift(\n projectPath: string,\n config: UnifiedConfig,\n state: SyncState\n ): Promise<DriftReport>;\n\n // ─── Per-Dimension Generators ────────────────────────────────\n\n /** Generate instruction files for this tool */\n abstract generateInstructions(config: InstructionsConfig): GeneratedFile[];\n\n /** Generate hook configurations for this tool */\n abstract generateHooks(\n config: HooksConfig,\n overrides?: HooksConfig\n ): GeneratedFile[];\n\n /** Generate MCP server configuration for this tool */\n abstract generateMcp(\n config: McpConfig,\n env?: Record<string, string>\n ): GeneratedFile[];\n\n /** Generate permission configuration for this tool */\n abstract generatePermissions(config: PermissionsConfig): GeneratedFile[];\n\n /** Generate skill files for this tool */\n abstract generateSkills(\n config: SkillsConfig,\n projectPath: string\n ): GeneratedFile[];\n\n // ─── Utility ────────────────────────────────────────────────\n\n /** Check if this provider supports a specific capability */\n hasCapability(cap: ProviderCapability): boolean {\n return this.capabilities.includes(cap);\n }\n}\n\n// Need to import SyncState at the type level\nimport type { SyncState } from \"../core/types.js\";\n"],"mappings":"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","names":["existsSync","join","ProviderCapability"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "conflux-ai",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Unified configuration manager for AI coding tools — define once in .ai/config.yaml, sync to Claude Code, Codex, Cursor, Windsurf, Copilot, and more.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"bin": {
|
|
15
|
+
"conflux": "./dist/cli/index.js"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist",
|
|
19
|
+
"schemas",
|
|
20
|
+
"README.md",
|
|
21
|
+
"LICENSE"
|
|
22
|
+
],
|
|
23
|
+
"scripts": {
|
|
24
|
+
"dev": "tsup --watch",
|
|
25
|
+
"build": "tsup",
|
|
26
|
+
"start": "node dist/cli/index.js",
|
|
27
|
+
"test": "vitest run",
|
|
28
|
+
"test:watch": "vitest",
|
|
29
|
+
"lint": "tsc --noEmit",
|
|
30
|
+
"schema": "tsx scripts/generate-schema.ts",
|
|
31
|
+
"prepublishOnly": "npm run build && npm run schema"
|
|
32
|
+
},
|
|
33
|
+
"keywords": [
|
|
34
|
+
"ai",
|
|
35
|
+
"agent",
|
|
36
|
+
"config",
|
|
37
|
+
"claude-code",
|
|
38
|
+
"codex",
|
|
39
|
+
"cursor",
|
|
40
|
+
"windsurf",
|
|
41
|
+
"copilot",
|
|
42
|
+
"gemini-cli",
|
|
43
|
+
"aider",
|
|
44
|
+
"mcp",
|
|
45
|
+
"cli",
|
|
46
|
+
"unified-config",
|
|
47
|
+
"ai-coding-tools",
|
|
48
|
+
"developer-tools"
|
|
49
|
+
],
|
|
50
|
+
"repository": {
|
|
51
|
+
"type": "git",
|
|
52
|
+
"url": "git+https://github.com/conflux-ai/conflux.git"
|
|
53
|
+
},
|
|
54
|
+
"homepage": "https://github.com/conflux-ai/conflux#readme",
|
|
55
|
+
"bugs": {
|
|
56
|
+
"url": "https://github.com/conflux-ai/conflux/issues"
|
|
57
|
+
},
|
|
58
|
+
"license": "MIT",
|
|
59
|
+
"author": "",
|
|
60
|
+
"engines": {
|
|
61
|
+
"node": ">=18"
|
|
62
|
+
},
|
|
63
|
+
"dependencies": {
|
|
64
|
+
"chalk": "^5.4.1",
|
|
65
|
+
"commander": "^13.1.0",
|
|
66
|
+
"js-yaml": "^4.1.0",
|
|
67
|
+
"zod": "^3.24.2",
|
|
68
|
+
"zod-to-json-schema": "^3.24.1"
|
|
69
|
+
},
|
|
70
|
+
"devDependencies": {
|
|
71
|
+
"@types/js-yaml": "^4.0.9",
|
|
72
|
+
"@types/node": "^22.13.0",
|
|
73
|
+
"tsup": "^8.4.0",
|
|
74
|
+
"tsx": "^4.19.0",
|
|
75
|
+
"typescript": "^5.7.3",
|
|
76
|
+
"vitest": "^3.0.4"
|
|
77
|
+
}
|
|
78
|
+
}
|