@grunnverk/kilde 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/.github/ISSUE_TEMPLATE/bug_report.md +40 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +31 -0
- package/.github/pull_request_template.md +48 -0
- package/.github/workflows/deploy-docs.yml +59 -0
- package/.github/workflows/npm-publish.yml +48 -0
- package/.github/workflows/test.yml +48 -0
- package/CHANGELOG.md +92 -0
- package/CONTRIBUTING.md +438 -0
- package/LICENSE +190 -0
- package/PROJECT_SUMMARY.md +318 -0
- package/README.md +444 -0
- package/RELEASE_CHECKLIST.md +182 -0
- package/dist/application.js +166 -0
- package/dist/application.js.map +1 -0
- package/dist/commands/release.js +326 -0
- package/dist/commands/release.js.map +1 -0
- package/dist/constants.js +122 -0
- package/dist/constants.js.map +1 -0
- package/dist/logging.js +176 -0
- package/dist/logging.js.map +1 -0
- package/dist/main.js +24 -0
- package/dist/main.js.map +1 -0
- package/dist/mcp-server.js +17467 -0
- package/dist/mcp-server.js.map +7 -0
- package/dist/utils/config.js +89 -0
- package/dist/utils/config.js.map +1 -0
- package/docs/AI_GUIDE.md +618 -0
- package/eslint.config.mjs +85 -0
- package/guide/architecture.md +776 -0
- package/guide/commands.md +580 -0
- package/guide/configuration.md +779 -0
- package/guide/mcp-integration.md +708 -0
- package/guide/overview.md +225 -0
- package/package.json +91 -0
- package/scripts/build-mcp.js +115 -0
- package/scripts/test-mcp-compliance.js +254 -0
- package/src/application.ts +246 -0
- package/src/commands/release.ts +450 -0
- package/src/constants.ts +162 -0
- package/src/logging.ts +210 -0
- package/src/main.ts +25 -0
- package/src/mcp/prompts/index.ts +98 -0
- package/src/mcp/resources.ts +121 -0
- package/src/mcp/server.ts +195 -0
- package/src/mcp/tools.ts +219 -0
- package/src/types.ts +131 -0
- package/src/utils/config.ts +181 -0
- package/tests/application.test.ts +114 -0
- package/tests/commands/commit.test.ts +248 -0
- package/tests/commands/release.test.ts +325 -0
- package/tests/constants.test.ts +118 -0
- package/tests/logging.test.ts +142 -0
- package/tests/mcp/prompts/index.test.ts +202 -0
- package/tests/mcp/resources.test.ts +166 -0
- package/tests/mcp/tools.test.ts +211 -0
- package/tests/utils/config.test.ts +212 -0
- package/tsconfig.json +32 -0
- package/vite.config.ts +107 -0
- package/vitest.config.ts +40 -0
- package/website/index.html +14 -0
- package/website/src/App.css +142 -0
- package/website/src/App.tsx +34 -0
- package/website/src/components/Commands.tsx +182 -0
- package/website/src/components/Configuration.tsx +214 -0
- package/website/src/components/Examples.tsx +234 -0
- package/website/src/components/Footer.css +99 -0
- package/website/src/components/Footer.tsx +93 -0
- package/website/src/components/GettingStarted.tsx +94 -0
- package/website/src/components/Hero.css +95 -0
- package/website/src/components/Hero.tsx +50 -0
- package/website/src/components/Navigation.css +102 -0
- package/website/src/components/Navigation.tsx +57 -0
- package/website/src/index.css +36 -0
- package/website/src/main.tsx +10 -0
- package/website/vite.config.ts +12 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import fs from 'fs/promises';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import yaml from 'js-yaml';
|
|
4
|
+
import { getLogger } from '../logging.js';
|
|
5
|
+
import { KILDE_DEFAULTS } from '../constants.js';
|
|
6
|
+
|
|
7
|
+
const CONFIG_FILES = [
|
|
8
|
+
'.kilde/config.yaml',
|
|
9
|
+
'.kilde/config.yml',
|
|
10
|
+
'.kilderc.yaml',
|
|
11
|
+
'.kilderc.yml',
|
|
12
|
+
'.kilderc.json',
|
|
13
|
+
'kilde.config.json'
|
|
14
|
+
];
|
|
15
|
+
/**
|
|
16
|
+
* Load configuration from file
|
|
17
|
+
*/ async function loadConfig(cwd = process.cwd()) {
|
|
18
|
+
const logger = getLogger();
|
|
19
|
+
for (const filename of CONFIG_FILES){
|
|
20
|
+
const configPath = path.join(cwd, filename);
|
|
21
|
+
try {
|
|
22
|
+
const content = await fs.readFile(configPath, 'utf-8');
|
|
23
|
+
let config;
|
|
24
|
+
if (filename.endsWith('.json')) {
|
|
25
|
+
config = JSON.parse(content);
|
|
26
|
+
} else if (filename.endsWith('.yaml') || filename.endsWith('.yml')) {
|
|
27
|
+
config = yaml.load(content);
|
|
28
|
+
} else {
|
|
29
|
+
// Try JSON first, then YAML
|
|
30
|
+
try {
|
|
31
|
+
config = JSON.parse(content);
|
|
32
|
+
} catch {
|
|
33
|
+
config = yaml.load(content);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
// Return config as-is
|
|
37
|
+
logger.verbose(`Loaded configuration from ${configPath}`);
|
|
38
|
+
return config;
|
|
39
|
+
} catch (error) {
|
|
40
|
+
if (error.code !== 'ENOENT') {
|
|
41
|
+
logger.warn(`CONFIG_LOAD_FAILED: Failed to load configuration file | Path: ${configPath} | Error: ${error.message} | Action: Using defaults`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
logger.verbose('No configuration file found, using defaults');
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Get default configuration
|
|
50
|
+
*/ function getDefaultConfig() {
|
|
51
|
+
return KILDE_DEFAULTS;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Deep merge two objects
|
|
55
|
+
*/ function deepMerge(target, source) {
|
|
56
|
+
const result = {
|
|
57
|
+
...target
|
|
58
|
+
};
|
|
59
|
+
for(const key in source){
|
|
60
|
+
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|
61
|
+
const sourceValue = source[key];
|
|
62
|
+
const targetValue = result[key];
|
|
63
|
+
if (sourceValue && typeof sourceValue === 'object' && !Array.isArray(sourceValue) && targetValue && typeof targetValue === 'object' && !Array.isArray(targetValue)) {
|
|
64
|
+
result[key] = deepMerge(targetValue, sourceValue);
|
|
65
|
+
} else if (sourceValue !== undefined) {
|
|
66
|
+
result[key] = sourceValue;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return result;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Merge loaded config with defaults
|
|
74
|
+
*/ function mergeWithDefaults(config) {
|
|
75
|
+
const defaults = getDefaultConfig();
|
|
76
|
+
if (!config) {
|
|
77
|
+
return defaults;
|
|
78
|
+
}
|
|
79
|
+
return deepMerge(defaults, config);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Get effective configuration (loaded + defaults)
|
|
83
|
+
*/ async function getEffectiveConfig(cwd = process.cwd()) {
|
|
84
|
+
const loaded = await loadConfig(cwd);
|
|
85
|
+
return mergeWithDefaults(loaded);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export { getDefaultConfig, getEffectiveConfig, loadConfig, mergeWithDefaults };
|
|
89
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sources":["../../src/utils/config.ts"],"sourcesContent":["import fs from 'fs/promises';\nimport path from 'path';\nimport yaml from 'js-yaml';\nimport { getLogger } from '../logging';\nimport { Config } from '@grunnverk/core';\nimport { KILDE_DEFAULTS } from '../constants';\n\nconst CONFIG_FILES = [\n '.kilde/config.yaml',\n '.kilde/config.yml',\n '.kilderc.yaml',\n '.kilderc.yml',\n '.kilderc.json',\n 'kilde.config.json',\n];\n\n/**\n * Load configuration from file\n */\nexport async function loadConfig(cwd: string = process.cwd()): Promise<Config | null> {\n const logger = getLogger();\n\n for (const filename of CONFIG_FILES) {\n const configPath = path.join(cwd, filename);\n\n try {\n const content = await fs.readFile(configPath, 'utf-8');\n\n let config: any;\n if (filename.endsWith('.json')) {\n config = JSON.parse(content);\n } else if (filename.endsWith('.yaml') || filename.endsWith('.yml')) {\n config = yaml.load(content);\n } else {\n // Try JSON first, then YAML\n try {\n config = JSON.parse(content);\n } catch {\n config = yaml.load(content);\n }\n }\n\n // Return config as-is\n logger.verbose(`Loaded configuration from ${configPath}`);\n return config as Config;\n } catch (error: any) {\n if (error.code !== 'ENOENT') {\n logger.warn(`CONFIG_LOAD_FAILED: Failed to load configuration file | Path: ${configPath} | Error: ${error.message} | Action: Using defaults`);\n }\n }\n }\n\n logger.verbose('No configuration file found, using defaults');\n return null;\n}\n\n/**\n * Get default configuration\n */\nexport function getDefaultConfig(): Config {\n return KILDE_DEFAULTS;\n}\n\n/**\n * Deep merge two objects\n */\nfunction deepMerge<T extends Record<string, any>>(target: T, source: Partial<T>): T {\n const result = { ...target };\n\n for (const key in source) {\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n const sourceValue = source[key];\n const targetValue = result[key];\n\n if (sourceValue && typeof sourceValue === 'object' && !Array.isArray(sourceValue) &&\n targetValue && typeof targetValue === 'object' && !Array.isArray(targetValue)) {\n result[key] = deepMerge(targetValue, sourceValue) as any;\n } else if (sourceValue !== undefined) {\n result[key] = sourceValue as any;\n }\n }\n }\n\n return result;\n}\n\n/**\n * Merge loaded config with defaults\n */\nexport function mergeWithDefaults(config: Config | null): Config {\n const defaults = getDefaultConfig();\n\n if (!config) {\n return defaults;\n }\n\n return deepMerge(defaults, config);\n}\n\n/**\n * Get effective configuration (loaded + defaults)\n */\nexport async function getEffectiveConfig(cwd: string = process.cwd()): Promise<Config> {\n const loaded = await loadConfig(cwd);\n return mergeWithDefaults(loaded);\n}\n\n/**\n * Create a sample configuration file\n */\nexport function createSampleConfig(): string {\n const config = {\n // Global settings\n verbose: false,\n debug: false,\n model: 'gpt-4o-mini',\n openaiReasoning: 'low',\n outputDirectory: 'output/kilde',\n\n // Commit configuration\n commit: {\n sendit: false,\n interactive: false,\n messageLimit: 3,\n maxDiffBytes: 20480,\n },\n\n // Release configuration\n release: {\n interactive: false,\n messageLimit: 3,\n maxDiffBytes: 20480,\n },\n };\n\n return yaml.dump(config, {\n indent: 2,\n lineWidth: 100,\n noRefs: true,\n });\n}\n\n/**\n * Save sample configuration to file\n */\nexport async function saveSampleConfig(cwd: string = process.cwd()): Promise<string> {\n const logger = getLogger();\n const configDir = path.join(cwd, '.kilde');\n const configPath = path.join(configDir, 'config.yaml');\n\n try {\n // Create directory if it doesn't exist\n await fs.mkdir(configDir, { recursive: true });\n\n // Write sample config\n const sampleConfig = createSampleConfig();\n await fs.writeFile(configPath, sampleConfig, 'utf-8');\n\n logger.info(`Created sample configuration file at ${configPath}`);\n return configPath;\n } catch (error: any) {\n logger.error(`Failed to create sample configuration: ${error.message}`);\n throw error;\n }\n}\n\n/**\n * Check if configuration file exists\n */\nexport async function configFileExists(cwd: string = process.cwd()): Promise<boolean> {\n for (const filename of CONFIG_FILES) {\n const configPath = path.join(cwd, filename);\n try {\n await fs.access(configPath);\n return true;\n } catch {\n // File doesn't exist, continue checking\n }\n }\n return false;\n}\n"],"names":["CONFIG_FILES","loadConfig","cwd","process","logger","getLogger","filename","configPath","path","join","content","fs","readFile","config","endsWith","JSON","parse","yaml","load","verbose","error","code","warn","message","getDefaultConfig","KILDE_DEFAULTS","deepMerge","target","source","result","key","Object","prototype","hasOwnProperty","call","sourceValue","targetValue","Array","isArray","undefined","mergeWithDefaults","defaults","getEffectiveConfig","loaded"],"mappings":"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"}
|