@lnai/core 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/dist/index.d.ts +313 -0
- package/dist/index.js +915 -0
- package/dist/index.js.map +1 -0
- package/package.json +58 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Krystian Jonca
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
declare const UNIFIED_DIR = ".ai";
|
|
4
|
+
declare const TOOL_IDS: readonly ["claudeCode", "opencode"];
|
|
5
|
+
type ToolId = (typeof TOOL_IDS)[number];
|
|
6
|
+
declare const CONFIG_FILES: {
|
|
7
|
+
readonly config: "config.json";
|
|
8
|
+
readonly settings: "settings.json";
|
|
9
|
+
readonly agents: "AGENTS.md";
|
|
10
|
+
};
|
|
11
|
+
declare const CONFIG_DIRS: {
|
|
12
|
+
readonly rules: "rules";
|
|
13
|
+
readonly skills: "skills";
|
|
14
|
+
readonly subagents: "subagents";
|
|
15
|
+
};
|
|
16
|
+
declare const TOOL_OUTPUT_DIRS: Record<ToolId, string>;
|
|
17
|
+
|
|
18
|
+
declare class LnaiError extends Error {
|
|
19
|
+
readonly code: string;
|
|
20
|
+
constructor(message: string, code: string);
|
|
21
|
+
}
|
|
22
|
+
declare class ParseError extends LnaiError {
|
|
23
|
+
readonly filePath: string;
|
|
24
|
+
constructor(message: string, filePath: string, cause?: Error);
|
|
25
|
+
}
|
|
26
|
+
declare class ValidationError extends LnaiError {
|
|
27
|
+
readonly path: string[];
|
|
28
|
+
readonly value?: unknown;
|
|
29
|
+
constructor(message: string, path: string[], value?: unknown);
|
|
30
|
+
}
|
|
31
|
+
declare class FileNotFoundError extends LnaiError {
|
|
32
|
+
readonly filePath: string;
|
|
33
|
+
constructor(message: string, filePath: string);
|
|
34
|
+
}
|
|
35
|
+
declare class WriteError extends LnaiError {
|
|
36
|
+
readonly filePath: string;
|
|
37
|
+
constructor(message: string, filePath: string, cause?: Error);
|
|
38
|
+
}
|
|
39
|
+
declare class PluginError extends LnaiError {
|
|
40
|
+
readonly pluginId: string;
|
|
41
|
+
constructor(message: string, pluginId: string, cause?: Error);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** MCP Server configuration (Claude format as source of truth) */
|
|
45
|
+
declare const mcpServerSchema: z.ZodObject<{
|
|
46
|
+
command: z.ZodOptional<z.ZodString>;
|
|
47
|
+
args: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
48
|
+
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
49
|
+
type: z.ZodOptional<z.ZodEnum<{
|
|
50
|
+
http: "http";
|
|
51
|
+
sse: "sse";
|
|
52
|
+
}>>;
|
|
53
|
+
url: z.ZodOptional<z.ZodString>;
|
|
54
|
+
headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
55
|
+
}, z.core.$strip>;
|
|
56
|
+
declare const permissionsSchema: z.ZodObject<{
|
|
57
|
+
allow: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
58
|
+
ask: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
59
|
+
deny: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
60
|
+
}, z.core.$strip>;
|
|
61
|
+
declare const toolConfigSchema: z.ZodObject<{
|
|
62
|
+
enabled: z.ZodBoolean;
|
|
63
|
+
versionControl: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
64
|
+
}, z.core.$strip>;
|
|
65
|
+
declare const toolIdSchema: z.ZodEnum<{
|
|
66
|
+
claudeCode: "claudeCode";
|
|
67
|
+
opencode: "opencode";
|
|
68
|
+
}>;
|
|
69
|
+
/** Settings configuration (Claude format as source of truth) */
|
|
70
|
+
declare const settingsSchema: z.ZodObject<{
|
|
71
|
+
permissions: z.ZodOptional<z.ZodObject<{
|
|
72
|
+
allow: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
73
|
+
ask: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
74
|
+
deny: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
75
|
+
}, z.core.$strip>>;
|
|
76
|
+
mcpServers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
77
|
+
command: z.ZodOptional<z.ZodString>;
|
|
78
|
+
args: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
79
|
+
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
80
|
+
type: z.ZodOptional<z.ZodEnum<{
|
|
81
|
+
http: "http";
|
|
82
|
+
sse: "sse";
|
|
83
|
+
}>>;
|
|
84
|
+
url: z.ZodOptional<z.ZodString>;
|
|
85
|
+
headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
86
|
+
}, z.core.$strip>>>;
|
|
87
|
+
overrides: z.ZodOptional<z.ZodObject<{
|
|
88
|
+
claudeCode: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
89
|
+
opencode: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
90
|
+
}, z.core.$strip>>;
|
|
91
|
+
}, z.core.$strip>;
|
|
92
|
+
/** Main config.json structure. Uses partial object to allow partial tool configs. */
|
|
93
|
+
declare const configSchema: z.ZodObject<{
|
|
94
|
+
tools: z.ZodOptional<z.ZodObject<{
|
|
95
|
+
claudeCode: z.ZodOptional<z.ZodObject<{
|
|
96
|
+
enabled: z.ZodBoolean;
|
|
97
|
+
versionControl: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
98
|
+
}, z.core.$strip>>;
|
|
99
|
+
opencode: z.ZodOptional<z.ZodObject<{
|
|
100
|
+
enabled: z.ZodBoolean;
|
|
101
|
+
versionControl: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
102
|
+
}, z.core.$strip>>;
|
|
103
|
+
}, z.core.$strip>>;
|
|
104
|
+
}, z.core.$strip>;
|
|
105
|
+
/** Skill frontmatter (name and description required) */
|
|
106
|
+
declare const skillFrontmatterSchema: z.ZodObject<{
|
|
107
|
+
name: z.ZodString;
|
|
108
|
+
description: z.ZodString;
|
|
109
|
+
}, z.core.$strip>;
|
|
110
|
+
/** Rule frontmatter (paths required) */
|
|
111
|
+
declare const ruleFrontmatterSchema: z.ZodObject<{
|
|
112
|
+
paths: z.ZodArray<z.ZodString>;
|
|
113
|
+
}, z.core.$strip>;
|
|
114
|
+
type McpServer = z.infer<typeof mcpServerSchema>;
|
|
115
|
+
type Permissions = z.infer<typeof permissionsSchema>;
|
|
116
|
+
type ToolConfig = z.infer<typeof toolConfigSchema>;
|
|
117
|
+
type Settings = z.infer<typeof settingsSchema>;
|
|
118
|
+
type Config = z.infer<typeof configSchema>;
|
|
119
|
+
type SkillFrontmatter = z.infer<typeof skillFrontmatterSchema>;
|
|
120
|
+
type RuleFrontmatter = z.infer<typeof ruleFrontmatterSchema>;
|
|
121
|
+
|
|
122
|
+
type PermissionLevel = "allow" | "ask" | "deny";
|
|
123
|
+
interface MarkdownFile<T = unknown> {
|
|
124
|
+
path: string;
|
|
125
|
+
frontmatter: T;
|
|
126
|
+
content: string;
|
|
127
|
+
}
|
|
128
|
+
/** @deprecated Use typed MarkdownFile<T> instead */
|
|
129
|
+
interface MarkdownFrontmatter {
|
|
130
|
+
description?: string;
|
|
131
|
+
paths?: string[];
|
|
132
|
+
name?: string;
|
|
133
|
+
}
|
|
134
|
+
/** All parsed configuration from the .ai directory */
|
|
135
|
+
interface UnifiedState {
|
|
136
|
+
config: {
|
|
137
|
+
tools?: Partial<Record<ToolId, {
|
|
138
|
+
enabled: boolean;
|
|
139
|
+
versionControl?: boolean;
|
|
140
|
+
}>>;
|
|
141
|
+
};
|
|
142
|
+
settings: {
|
|
143
|
+
permissions?: {
|
|
144
|
+
allow?: string[];
|
|
145
|
+
ask?: string[];
|
|
146
|
+
deny?: string[];
|
|
147
|
+
};
|
|
148
|
+
mcpServers?: Record<string, unknown>;
|
|
149
|
+
overrides?: Partial<Record<ToolId, Record<string, unknown>>>;
|
|
150
|
+
} | null;
|
|
151
|
+
agents: string | null;
|
|
152
|
+
rules: MarkdownFile<RuleFrontmatter>[];
|
|
153
|
+
skills: MarkdownFile<SkillFrontmatter>[];
|
|
154
|
+
}
|
|
155
|
+
interface OutputFile {
|
|
156
|
+
path: string;
|
|
157
|
+
type: "json" | "text" | "symlink";
|
|
158
|
+
content?: unknown;
|
|
159
|
+
target?: string;
|
|
160
|
+
}
|
|
161
|
+
interface ValidationErrorDetail {
|
|
162
|
+
path: string[];
|
|
163
|
+
message: string;
|
|
164
|
+
value?: unknown;
|
|
165
|
+
}
|
|
166
|
+
interface ValidationWarningDetail {
|
|
167
|
+
path: string[];
|
|
168
|
+
message: string;
|
|
169
|
+
}
|
|
170
|
+
/** Feature not supported by a particular tool */
|
|
171
|
+
interface SkippedFeatureDetail {
|
|
172
|
+
feature: string;
|
|
173
|
+
reason: string;
|
|
174
|
+
}
|
|
175
|
+
interface ValidationResult {
|
|
176
|
+
valid: boolean;
|
|
177
|
+
errors: ValidationErrorDetail[];
|
|
178
|
+
warnings: ValidationWarningDetail[];
|
|
179
|
+
skipped: SkippedFeatureDetail[];
|
|
180
|
+
}
|
|
181
|
+
interface ChangeResult {
|
|
182
|
+
path: string;
|
|
183
|
+
action: "create" | "update" | "delete" | "unchanged";
|
|
184
|
+
oldHash?: string;
|
|
185
|
+
newHash?: string;
|
|
186
|
+
}
|
|
187
|
+
interface SyncResult {
|
|
188
|
+
tool: ToolId;
|
|
189
|
+
changes: ChangeResult[];
|
|
190
|
+
validation: ValidationResult;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
declare function parseFrontmatter(content: string): {
|
|
194
|
+
frontmatter: Record<string, unknown>;
|
|
195
|
+
content: string;
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Parse the unified .ai/ configuration directory.
|
|
200
|
+
* Reads config.json, settings.json, AGENTS.md, rules, and skills.
|
|
201
|
+
*/
|
|
202
|
+
declare function parseUnifiedConfig(rootDir: string): Promise<UnifiedState>;
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Validate config.json structure using Zod
|
|
206
|
+
*/
|
|
207
|
+
declare function validateConfig(config: unknown): ValidationResult;
|
|
208
|
+
/**
|
|
209
|
+
* Validate settings.json structure using Zod
|
|
210
|
+
*/
|
|
211
|
+
declare function validateSettings(settings: unknown): ValidationResult;
|
|
212
|
+
/**
|
|
213
|
+
* Validate the unified configuration state
|
|
214
|
+
* @param state - Parsed unified state
|
|
215
|
+
* @returns Validation result
|
|
216
|
+
*/
|
|
217
|
+
declare function validateUnifiedState(state: UnifiedState): ValidationResult;
|
|
218
|
+
|
|
219
|
+
interface Plugin {
|
|
220
|
+
id: ToolId;
|
|
221
|
+
name: string;
|
|
222
|
+
/** Detect if this tool's configuration exists in the given directory */
|
|
223
|
+
detect(rootDir: string): Promise<boolean>;
|
|
224
|
+
/** Import existing tool configuration into unified state */
|
|
225
|
+
import(rootDir: string): Promise<Partial<UnifiedState> | null>;
|
|
226
|
+
/** Export unified state to this tool's native format */
|
|
227
|
+
export(state: UnifiedState, rootDir: string): Promise<OutputFile[]>;
|
|
228
|
+
/** Validate unified state for this tool */
|
|
229
|
+
validate(state: UnifiedState): ValidationResult;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Claude Code plugin for exporting to .claude/ format
|
|
234
|
+
*
|
|
235
|
+
* Output structure:
|
|
236
|
+
* - .claude/CLAUDE.md (symlink -> ../.ai/AGENTS.md)
|
|
237
|
+
* - .claude/rules/ (symlink -> ../.ai/rules)
|
|
238
|
+
* - .claude/skills/<name>/ (symlink -> ../../.ai/skills/<name>)
|
|
239
|
+
* - .claude/settings.json (generated settings merged with .ai/.claude/settings.json)
|
|
240
|
+
* - .claude/<path> (symlink -> ../.ai/.claude/<path>) for other override files
|
|
241
|
+
*/
|
|
242
|
+
declare const claudeCodePlugin: Plugin;
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* OpenCode plugin for exporting to opencode.json format
|
|
246
|
+
*
|
|
247
|
+
* Output structure:
|
|
248
|
+
* - .opencode/AGENTS.md (symlink -> ../.ai/AGENTS.md)
|
|
249
|
+
* - .opencode/rules/ (symlink -> ../.ai/rules)
|
|
250
|
+
* - .opencode/skills/<name>/ (symlink -> ../../.ai/skills/<name>)
|
|
251
|
+
* - opencode.json (generated config merged with .ai/.opencode/opencode.json)
|
|
252
|
+
* - .opencode/<path> (symlink -> ../.ai/.opencode/<path>) for other override files
|
|
253
|
+
*/
|
|
254
|
+
declare const opencodePlugin: Plugin;
|
|
255
|
+
|
|
256
|
+
declare class PluginRegistry {
|
|
257
|
+
private plugins;
|
|
258
|
+
register(plugin: Plugin): void;
|
|
259
|
+
get(id: ToolId): Plugin | undefined;
|
|
260
|
+
getAll(): Plugin[];
|
|
261
|
+
getIds(): ToolId[];
|
|
262
|
+
has(id: ToolId): boolean;
|
|
263
|
+
}
|
|
264
|
+
declare const pluginRegistry: PluginRegistry;
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Options for the sync pipeline
|
|
268
|
+
*/
|
|
269
|
+
interface SyncOptions {
|
|
270
|
+
/** Root directory containing .ai/ config */
|
|
271
|
+
rootDir: string;
|
|
272
|
+
/** Only sync specific tools (default: all enabled) */
|
|
273
|
+
tools?: ToolId[];
|
|
274
|
+
/** Preview changes without writing files */
|
|
275
|
+
dryRun?: boolean;
|
|
276
|
+
/** Enable verbose output */
|
|
277
|
+
verbose?: boolean;
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Run the sync pipeline to export .ai/ config to native tool formats.
|
|
281
|
+
*/
|
|
282
|
+
declare function runSyncPipeline(options: SyncOptions): Promise<SyncResult[]>;
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Options for the file writer
|
|
286
|
+
*/
|
|
287
|
+
interface WriterOptions {
|
|
288
|
+
/** Root directory for output */
|
|
289
|
+
rootDir: string;
|
|
290
|
+
/** Preview changes without writing */
|
|
291
|
+
dryRun?: boolean;
|
|
292
|
+
}
|
|
293
|
+
declare function computeHash(content: string): string;
|
|
294
|
+
declare function writeFiles(files: OutputFile[], options: WriterOptions): Promise<ChangeResult[]>;
|
|
295
|
+
/**
|
|
296
|
+
* Update .gitignore with paths that should not be version controlled.
|
|
297
|
+
* Manages a dedicated "lnai-generated" section to avoid conflicts with user entries.
|
|
298
|
+
*/
|
|
299
|
+
declare function updateGitignore(rootDir: string, paths: string[]): Promise<void>;
|
|
300
|
+
|
|
301
|
+
interface InitOptions {
|
|
302
|
+
rootDir: string;
|
|
303
|
+
tools?: ToolId[];
|
|
304
|
+
minimal?: boolean;
|
|
305
|
+
}
|
|
306
|
+
interface InitResult {
|
|
307
|
+
created: string[];
|
|
308
|
+
}
|
|
309
|
+
declare function hasUnifiedConfig(rootDir: string): Promise<boolean>;
|
|
310
|
+
declare function generateDefaultConfig(tools?: ToolId[]): Config;
|
|
311
|
+
declare function initUnifiedConfig(options: InitOptions): Promise<InitResult>;
|
|
312
|
+
|
|
313
|
+
export { CONFIG_DIRS, CONFIG_FILES, type ChangeResult, type Config, FileNotFoundError, type InitOptions, type InitResult, LnaiError, type MarkdownFile, type MarkdownFrontmatter, type McpServer, type OutputFile, ParseError, type PermissionLevel, type Permissions, type Plugin, PluginError, type RuleFrontmatter, type Settings, type SkillFrontmatter, type SkippedFeatureDetail, type SyncOptions, type SyncResult, TOOL_IDS, TOOL_OUTPUT_DIRS, type ToolConfig, type ToolId, UNIFIED_DIR, type UnifiedState, ValidationError, type ValidationErrorDetail, type ValidationResult, type ValidationWarningDetail, WriteError, type WriterOptions, claudeCodePlugin, computeHash, configSchema, generateDefaultConfig, hasUnifiedConfig, initUnifiedConfig, mcpServerSchema, opencodePlugin, parseFrontmatter, parseUnifiedConfig, permissionsSchema, pluginRegistry, ruleFrontmatterSchema, runSyncPipeline, settingsSchema, skillFrontmatterSchema, toolConfigSchema, toolIdSchema, updateGitignore, validateConfig, validateSettings, validateUnifiedState, writeFiles };
|