@shrkcrft/config 0.1.0-alpha.1
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 +15 -0
- package/dist/config-loader.d.ts +10 -0
- package/dist/config-loader.d.ts.map +1 -0
- package/dist/config-loader.js +59 -0
- package/dist/config-schema.d.ts +41 -0
- package/dist/config-schema.d.ts.map +1 -0
- package/dist/config-schema.js +56 -0
- package/dist/config-validator.d.ts +12 -0
- package/dist/config-validator.d.ts.map +1 -0
- package/dist/config-validator.js +20 -0
- package/dist/default-config.d.ts +5 -0
- package/dist/default-config.d.ts.map +1 -0
- package/dist/default-config.js +32 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/project-config-resolver.d.ts +7 -0
- package/dist/project-config-resolver.d.ts.map +1 -0
- package/dist/project-config-resolver.js +37 -0
- package/dist/sharkcraft-config.d.ts +102 -0
- package/dist/sharkcraft-config.d.ts.map +1 -0
- package/dist/sharkcraft-config.js +14 -0
- package/package.json +51 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 SharkCraft contributors
|
|
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/README.md
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# @shrkcrft/config
|
|
2
|
+
|
|
3
|
+
SharkCraft config loader: sharkcraft.config.ts discovery, defaults, zod-validated schema.
|
|
4
|
+
|
|
5
|
+
Part of [SharkCraft](https://github.com/sharkcraft/sharkcraft) — a deterministic, local-first toolkit that gives AI coding agents durable project context. See the main repo for documentation, examples, and the `shrk` CLI.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
bun add @shrkcrft/config
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## License
|
|
14
|
+
|
|
15
|
+
MIT — see [LICENSE](./LICENSE).
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type AppError, type Result } from '@shrkcrft/core';
|
|
2
|
+
import type { ISharkCraftConfig } from './sharkcraft-config.js';
|
|
3
|
+
export interface LoadedConfig {
|
|
4
|
+
config: ISharkCraftConfig;
|
|
5
|
+
projectRoot: string;
|
|
6
|
+
sharkcraftDir: string;
|
|
7
|
+
configFile: string | null;
|
|
8
|
+
}
|
|
9
|
+
export declare function loadProjectConfig(startDir: string): Promise<Result<LoadedConfig, AppError>>;
|
|
10
|
+
//# sourceMappingURL=config-loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-loader.d.ts","sourceRoot":"","sources":["../src/config-loader.ts"],"names":[],"mappings":"AAGA,OAAO,EAAsC,KAAK,QAAQ,EAAE,KAAK,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAChG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAKhE,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,iBAAiB,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAID,wBAAsB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC,CA+DjG"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
|
|
2
|
+
if (typeof path === "string" && /^\.\.?\//.test(path)) {
|
|
3
|
+
return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
|
|
4
|
+
return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
|
|
5
|
+
});
|
|
6
|
+
}
|
|
7
|
+
return path;
|
|
8
|
+
};
|
|
9
|
+
import { existsSync } from 'node:fs';
|
|
10
|
+
import * as nodePath from 'node:path';
|
|
11
|
+
import { pathToFileURL } from 'node:url';
|
|
12
|
+
import { AppErrorImpl, ERROR_CODES, err, ok } from '@shrkcrft/core';
|
|
13
|
+
import { withDefaults } from "./default-config.js";
|
|
14
|
+
import { detectProjectRoot, findSharkcraftDir } from "./project-config-resolver.js";
|
|
15
|
+
import { SharkCraftConfigSchema } from "./config-schema.js";
|
|
16
|
+
const CONFIG_FILE_CANDIDATES = ['sharkcraft.config.ts', 'sharkcraft.config.js', 'sharkcraft.config.mjs'];
|
|
17
|
+
export async function loadProjectConfig(startDir) {
|
|
18
|
+
const projectInfo = detectProjectRoot(startDir);
|
|
19
|
+
const projectRoot = projectInfo.root;
|
|
20
|
+
const folder = findSharkcraftDir(projectRoot);
|
|
21
|
+
if (!folder) {
|
|
22
|
+
return err(new AppErrorImpl(ERROR_CODES.SHARKCRAFT_FOLDER_NOT_FOUND, `No sharkcraft/ folder found in ${projectRoot}`, { suggestion: 'Run `shrk init` to create one.', details: { projectRoot } }));
|
|
23
|
+
}
|
|
24
|
+
for (const candidate of CONFIG_FILE_CANDIDATES) {
|
|
25
|
+
const fullPath = nodePath.join(folder, candidate);
|
|
26
|
+
if (!existsSync(fullPath))
|
|
27
|
+
continue;
|
|
28
|
+
try {
|
|
29
|
+
const mod = (await import(__rewriteRelativeImportExtension(pathToFileURL(fullPath).href)));
|
|
30
|
+
const userConfig = (mod.default ?? mod) || {};
|
|
31
|
+
const parsed = SharkCraftConfigSchema.safeParse(userConfig);
|
|
32
|
+
if (!parsed.success) {
|
|
33
|
+
const summary = parsed.error.issues
|
|
34
|
+
.map((iss) => `${iss.path.join('.') || '<root>'}: ${iss.message}`)
|
|
35
|
+
.join('; ');
|
|
36
|
+
return err(new AppErrorImpl(ERROR_CODES.CONFIG_INVALID, `Invalid sharkcraft.config.ts: ${summary}`, {
|
|
37
|
+
details: { fullPath, issues: parsed.error.issues },
|
|
38
|
+
suggestion: 'Check the offending fields against ISharkCraftConfig.',
|
|
39
|
+
}));
|
|
40
|
+
}
|
|
41
|
+
return ok({
|
|
42
|
+
config: withDefaults(parsed.data),
|
|
43
|
+
projectRoot,
|
|
44
|
+
sharkcraftDir: folder,
|
|
45
|
+
configFile: fullPath,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
catch (e) {
|
|
49
|
+
return err(new AppErrorImpl(ERROR_CODES.CONFIG_INVALID, `Failed to load config: ${fullPath}`, { details: { fullPath }, cause: e }));
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
// Fallback: no config file, use defaults
|
|
53
|
+
return ok({
|
|
54
|
+
config: withDefaults(null),
|
|
55
|
+
projectRoot,
|
|
56
|
+
sharkcraftDir: folder,
|
|
57
|
+
configFile: null,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* Zod schema for sharkcraft.config.ts. Used by the loader and the doctor to
|
|
4
|
+
* surface clear errors for malformed configs. We don't replace ISharkCraftConfig
|
|
5
|
+
* with the inferred type because hand-written interfaces document intent better.
|
|
6
|
+
*/
|
|
7
|
+
export declare const SharkCraftConfigSchema: z.ZodObject<{
|
|
8
|
+
projectName: z.ZodOptional<z.ZodString>;
|
|
9
|
+
description: z.ZodOptional<z.ZodString>;
|
|
10
|
+
sharkcraftDir: z.ZodOptional<z.ZodString>;
|
|
11
|
+
knowledgeFiles: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
12
|
+
docsFiles: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
13
|
+
ruleFiles: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
14
|
+
pathFiles: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
15
|
+
templateFiles: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
16
|
+
pipelineFiles: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
17
|
+
defaultMaxTokens: z.ZodOptional<z.ZodNumber>;
|
|
18
|
+
defaultScope: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
19
|
+
actionHintDiagnostics: z.ZodOptional<z.ZodBoolean>;
|
|
20
|
+
metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
21
|
+
presetFiles: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
22
|
+
boundaryFiles: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
23
|
+
contextTestFiles: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
24
|
+
agentTestFiles: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
25
|
+
verificationCommands: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
26
|
+
id: z.ZodString;
|
|
27
|
+
label: z.ZodOptional<z.ZodString>;
|
|
28
|
+
command: z.ZodString;
|
|
29
|
+
trusted: z.ZodOptional<z.ZodBoolean>;
|
|
30
|
+
}, z.core.$strip>>>;
|
|
31
|
+
surface: z.ZodOptional<z.ZodObject<{
|
|
32
|
+
profile: z.ZodOptional<z.ZodString>;
|
|
33
|
+
enabled: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
34
|
+
hidden: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
35
|
+
}, z.core.$strict>>;
|
|
36
|
+
usage: z.ZodOptional<z.ZodObject<{
|
|
37
|
+
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
38
|
+
}, z.core.$strict>>;
|
|
39
|
+
}, z.core.$strict>;
|
|
40
|
+
export type SharkCraftConfigInput = z.infer<typeof SharkCraftConfigSchema>;
|
|
41
|
+
//# sourceMappingURL=config-schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-schema.d.ts","sourceRoot":"","sources":["../src/config-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;GAIG;AACH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAmDxB,CAAC;AAEZ,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* Zod schema for sharkcraft.config.ts. Used by the loader and the doctor to
|
|
4
|
+
* surface clear errors for malformed configs. We don't replace ISharkCraftConfig
|
|
5
|
+
* with the inferred type because hand-written interfaces document intent better.
|
|
6
|
+
*/
|
|
7
|
+
export const SharkCraftConfigSchema = z
|
|
8
|
+
.object({
|
|
9
|
+
projectName: z.string().optional(),
|
|
10
|
+
description: z.string().optional(),
|
|
11
|
+
sharkcraftDir: z.string().optional(),
|
|
12
|
+
knowledgeFiles: z.array(z.string()).optional(),
|
|
13
|
+
docsFiles: z.array(z.string()).optional(),
|
|
14
|
+
ruleFiles: z.array(z.string()).optional(),
|
|
15
|
+
pathFiles: z.array(z.string()).optional(),
|
|
16
|
+
templateFiles: z.array(z.string()).optional(),
|
|
17
|
+
pipelineFiles: z.array(z.string()).optional(),
|
|
18
|
+
defaultMaxTokens: z.number().int().positive().optional(),
|
|
19
|
+
defaultScope: z.array(z.string()).optional(),
|
|
20
|
+
actionHintDiagnostics: z.boolean().optional(),
|
|
21
|
+
metadata: z.record(z.string(), z.unknown()).optional(),
|
|
22
|
+
// Local registry extensions consumed by the inspector.
|
|
23
|
+
presetFiles: z.array(z.string()).optional(),
|
|
24
|
+
boundaryFiles: z.array(z.string()).optional(),
|
|
25
|
+
contextTestFiles: z.array(z.string()).optional(),
|
|
26
|
+
agentTestFiles: z.array(z.string()).optional(),
|
|
27
|
+
// Verification commands available to `shrk apply --validate --verification`.
|
|
28
|
+
verificationCommands: z
|
|
29
|
+
.array(z.object({
|
|
30
|
+
id: z.string(),
|
|
31
|
+
label: z.string().optional(),
|
|
32
|
+
command: z.string(),
|
|
33
|
+
trusted: z.boolean().optional(),
|
|
34
|
+
}))
|
|
35
|
+
.optional(),
|
|
36
|
+
// Adaptive surface gating.
|
|
37
|
+
surface: z
|
|
38
|
+
.object({
|
|
39
|
+
// Named profile (built-in or pack-contributed).
|
|
40
|
+
// Profile.hidden + profile.enabled merge with the explicit
|
|
41
|
+
// arrays below (config wins on conflicts).
|
|
42
|
+
profile: z.string().optional(),
|
|
43
|
+
enabled: z.array(z.string()).optional(),
|
|
44
|
+
hidden: z.array(z.string()).optional(),
|
|
45
|
+
})
|
|
46
|
+
.strict()
|
|
47
|
+
.optional(),
|
|
48
|
+
// Local usage log opt-out (default: enabled).
|
|
49
|
+
usage: z
|
|
50
|
+
.object({
|
|
51
|
+
enabled: z.boolean().optional(),
|
|
52
|
+
})
|
|
53
|
+
.strict()
|
|
54
|
+
.optional(),
|
|
55
|
+
})
|
|
56
|
+
.strict();
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ISharkCraftConfig } from './sharkcraft-config.js';
|
|
2
|
+
export interface ConfigValidationIssue {
|
|
3
|
+
field: string;
|
|
4
|
+
message: string;
|
|
5
|
+
severity: 'error' | 'warning';
|
|
6
|
+
}
|
|
7
|
+
export interface ConfigValidationResult {
|
|
8
|
+
valid: boolean;
|
|
9
|
+
issues: ConfigValidationIssue[];
|
|
10
|
+
}
|
|
11
|
+
export declare function validateConfig(config: ISharkCraftConfig): ConfigValidationResult;
|
|
12
|
+
//# sourceMappingURL=config-validator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-validator.d.ts","sourceRoot":"","sources":["../src/config-validator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEhE,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;CAC/B;AAED,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,qBAAqB,EAAE,CAAC;CACjC;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,iBAAiB,GAAG,sBAAsB,CAuBhF"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export function validateConfig(config) {
|
|
2
|
+
const issues = [];
|
|
3
|
+
if (config.defaultMaxTokens !== undefined && config.defaultMaxTokens <= 0) {
|
|
4
|
+
issues.push({
|
|
5
|
+
field: 'defaultMaxTokens',
|
|
6
|
+
message: 'defaultMaxTokens must be > 0',
|
|
7
|
+
severity: 'error',
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
for (const field of ['knowledgeFiles', 'ruleFiles', 'pathFiles', 'templateFiles', 'docsFiles']) {
|
|
11
|
+
const v = config[field];
|
|
12
|
+
if (v !== undefined && !Array.isArray(v)) {
|
|
13
|
+
issues.push({ field, message: `${field} must be an array of strings`, severity: 'error' });
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
if (config.projectName !== undefined && typeof config.projectName !== 'string') {
|
|
17
|
+
issues.push({ field: 'projectName', message: 'projectName must be a string', severity: 'error' });
|
|
18
|
+
}
|
|
19
|
+
return { valid: issues.every((i) => i.severity !== 'error'), issues };
|
|
20
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type ISharkCraftConfig } from './sharkcraft-config.js';
|
|
2
|
+
export declare const DEFAULT_MAX_TOKENS = 4000;
|
|
3
|
+
export declare function getDefaultConfig(): Required<Pick<ISharkCraftConfig, 'sharkcraftDir' | 'knowledgeFiles' | 'ruleFiles' | 'pathFiles' | 'templateFiles' | 'pipelineFiles' | 'docsFiles' | 'defaultMaxTokens' | 'defaultScope'>>;
|
|
4
|
+
export declare function withDefaults(config: ISharkCraftConfig | null | undefined): ISharkCraftConfig;
|
|
5
|
+
//# sourceMappingURL=default-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"default-config.d.ts","sourceRoot":"","sources":["../src/default-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAQL,KAAK,iBAAiB,EACvB,MAAM,wBAAwB,CAAC;AAEhC,eAAO,MAAM,kBAAkB,OAAO,CAAC;AAEvC,wBAAgB,gBAAgB,IAAI,QAAQ,CAC1C,IAAI,CACF,iBAAiB,EACf,eAAe,GACf,gBAAgB,GAChB,WAAW,GACX,WAAW,GACX,eAAe,GACf,eAAe,GACf,WAAW,GACX,kBAAkB,GAClB,cAAc,CACjB,CACF,CAYA;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI,GAAG,SAAS,GAAG,iBAAiB,CAe5F"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { DEFAULT_DOC_FILES, DEFAULT_KNOWLEDGE_FILES, DEFAULT_PATH_FILES, DEFAULT_PIPELINE_FILES, DEFAULT_RULE_FILES, DEFAULT_SHARKCRAFT_DIR, DEFAULT_TEMPLATE_FILES, } from "./sharkcraft-config.js";
|
|
2
|
+
export const DEFAULT_MAX_TOKENS = 4000;
|
|
3
|
+
export function getDefaultConfig() {
|
|
4
|
+
return {
|
|
5
|
+
sharkcraftDir: DEFAULT_SHARKCRAFT_DIR,
|
|
6
|
+
knowledgeFiles: [...DEFAULT_KNOWLEDGE_FILES],
|
|
7
|
+
ruleFiles: [...DEFAULT_RULE_FILES],
|
|
8
|
+
pathFiles: [...DEFAULT_PATH_FILES],
|
|
9
|
+
templateFiles: [...DEFAULT_TEMPLATE_FILES],
|
|
10
|
+
pipelineFiles: [...DEFAULT_PIPELINE_FILES],
|
|
11
|
+
docsFiles: [...DEFAULT_DOC_FILES],
|
|
12
|
+
defaultMaxTokens: DEFAULT_MAX_TOKENS,
|
|
13
|
+
defaultScope: [],
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
export function withDefaults(config) {
|
|
17
|
+
const defaults = getDefaultConfig();
|
|
18
|
+
if (!config)
|
|
19
|
+
return defaults;
|
|
20
|
+
return {
|
|
21
|
+
...defaults,
|
|
22
|
+
...config,
|
|
23
|
+
knowledgeFiles: config.knowledgeFiles ?? defaults.knowledgeFiles,
|
|
24
|
+
ruleFiles: config.ruleFiles ?? defaults.ruleFiles,
|
|
25
|
+
pathFiles: config.pathFiles ?? defaults.pathFiles,
|
|
26
|
+
templateFiles: config.templateFiles ?? defaults.templateFiles,
|
|
27
|
+
pipelineFiles: config.pipelineFiles ?? defaults.pipelineFiles,
|
|
28
|
+
docsFiles: config.docsFiles ?? defaults.docsFiles,
|
|
29
|
+
defaultMaxTokens: config.defaultMaxTokens ?? defaults.defaultMaxTokens,
|
|
30
|
+
defaultScope: config.defaultScope ?? defaults.defaultScope,
|
|
31
|
+
};
|
|
32
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export * from './sharkcraft-config.js';
|
|
2
|
+
export * from './default-config.js';
|
|
3
|
+
export * from './config-loader.js';
|
|
4
|
+
export * from './config-validator.js';
|
|
5
|
+
export * from './project-config-resolver.js';
|
|
6
|
+
export * from './config-schema.js';
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,uBAAuB,CAAC;AACtC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,oBAAoB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export interface ProjectRootInfo {
|
|
2
|
+
root: string;
|
|
3
|
+
markers: string[];
|
|
4
|
+
}
|
|
5
|
+
export declare function detectProjectRoot(startDir: string): ProjectRootInfo;
|
|
6
|
+
export declare function findSharkcraftDir(projectRoot: string, configuredDir?: string): string | null;
|
|
7
|
+
//# sourceMappingURL=project-config-resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-config-resolver.d.ts","sourceRoot":"","sources":["../src/project-config-resolver.ts"],"names":[],"mappings":"AAYA,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,eAAe,CAYnE;AAED,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,aAAa,SAAe,GAAG,MAAM,GAAG,IAAI,CAUlG"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { existsSync, statSync } from 'node:fs';
|
|
2
|
+
import * as nodePath from 'node:path';
|
|
3
|
+
const PROJECT_ROOT_MARKERS = [
|
|
4
|
+
'package.json',
|
|
5
|
+
'bun.lockb',
|
|
6
|
+
'pnpm-workspace.yaml',
|
|
7
|
+
'nx.json',
|
|
8
|
+
'tsconfig.base.json',
|
|
9
|
+
'.git',
|
|
10
|
+
];
|
|
11
|
+
export function detectProjectRoot(startDir) {
|
|
12
|
+
let current = nodePath.resolve(startDir);
|
|
13
|
+
const seen = [];
|
|
14
|
+
while (true) {
|
|
15
|
+
const found = PROJECT_ROOT_MARKERS.filter((m) => existsSync(nodePath.join(current, m)));
|
|
16
|
+
if (found.length > 0)
|
|
17
|
+
return { root: current, markers: found };
|
|
18
|
+
const parent = nodePath.dirname(current);
|
|
19
|
+
if (parent === current) {
|
|
20
|
+
return { root: nodePath.resolve(startDir), markers: seen };
|
|
21
|
+
}
|
|
22
|
+
current = parent;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
export function findSharkcraftDir(projectRoot, configuredDir = 'sharkcraft') {
|
|
26
|
+
const candidate = nodePath.join(projectRoot, configuredDir);
|
|
27
|
+
if (existsSync(candidate)) {
|
|
28
|
+
try {
|
|
29
|
+
if (statSync(candidate).isDirectory())
|
|
30
|
+
return candidate;
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
export interface ISharkCraftConfig {
|
|
2
|
+
/** Optional project identifier used in outputs / context. */
|
|
3
|
+
projectName?: string;
|
|
4
|
+
/** Human-readable one-line project description. */
|
|
5
|
+
description?: string;
|
|
6
|
+
/** Folder (relative to project root) containing SharkCraft project data. */
|
|
7
|
+
sharkcraftDir?: string;
|
|
8
|
+
/** Knowledge entry files (TS or markdown). Relative to sharkcraftDir. */
|
|
9
|
+
knowledgeFiles?: string[];
|
|
10
|
+
/** Markdown doc files (optional human depth). Relative to sharkcraftDir. */
|
|
11
|
+
docsFiles?: string[];
|
|
12
|
+
/** Rule registry files. */
|
|
13
|
+
ruleFiles?: string[];
|
|
14
|
+
/** Path-convention registry files. */
|
|
15
|
+
pathFiles?: string[];
|
|
16
|
+
/** Template registry files. */
|
|
17
|
+
templateFiles?: string[];
|
|
18
|
+
/** Pipeline registry files. */
|
|
19
|
+
pipelineFiles?: string[];
|
|
20
|
+
/** Default token budget for context retrieval. */
|
|
21
|
+
defaultMaxTokens?: number;
|
|
22
|
+
/** Default frameworks/scopes this project belongs to. */
|
|
23
|
+
defaultScope?: string[];
|
|
24
|
+
/** Toggle action-hint quality diagnostics in doctor. Default true. */
|
|
25
|
+
actionHintDiagnostics?: boolean;
|
|
26
|
+
/** Free-form metadata. */
|
|
27
|
+
metadata?: Record<string, unknown>;
|
|
28
|
+
/**
|
|
29
|
+
* Verification commands available to `shrk apply --validate --verification <id>`.
|
|
30
|
+
* Only commands defined here (with `trusted: true`) run by default. Pack-
|
|
31
|
+
* contributed commands are intentionally **not** auto-run in v1 — pass
|
|
32
|
+
* `--allow-pack-commands` to opt in to a future feature.
|
|
33
|
+
*/
|
|
34
|
+
verificationCommands?: readonly IVerificationCommand[];
|
|
35
|
+
/**
|
|
36
|
+
* Local preset/boundary/context-test/agent-test files. Populated by the
|
|
37
|
+
* inspector but typed here for completeness.
|
|
38
|
+
*/
|
|
39
|
+
presetFiles?: readonly string[];
|
|
40
|
+
boundaryFiles?: readonly string[];
|
|
41
|
+
contextTestFiles?: readonly string[];
|
|
42
|
+
agentTestFiles?: readonly string[];
|
|
43
|
+
/**
|
|
44
|
+
* Adaptive surface gating.
|
|
45
|
+
*
|
|
46
|
+
* - `enabled`: experimental commands the project opts into.
|
|
47
|
+
* Pack-contributed commands and entries marked `hidden: true` in
|
|
48
|
+
* the catalog default to tier=`experimental`; they're listed by
|
|
49
|
+
* `shrk surface list` but invisible in `--help` and refuse on
|
|
50
|
+
* invocation until added here.
|
|
51
|
+
* - `hidden`: extended commands the project chooses to hide from
|
|
52
|
+
* `--help`. They remain callable. Used by shape-aware init to
|
|
53
|
+
* hide monorepo-only commands in a single-app repo.
|
|
54
|
+
*
|
|
55
|
+
* Core commands cannot appear in either list — the resolver flags
|
|
56
|
+
* such configs in `shrk surface list --json` and `shrk doctor`.
|
|
57
|
+
*/
|
|
58
|
+
surface?: ISurfaceConfig;
|
|
59
|
+
/**
|
|
60
|
+
* Local usage log opt-out.
|
|
61
|
+
*
|
|
62
|
+
* Defaults to `{ enabled: true }`. When disabled, no entries are
|
|
63
|
+
* written to `.sharkcraft/usage/commands.jsonl`. The env var
|
|
64
|
+
* `SHARKCRAFT_USAGE_DISABLED=1` also disables the writer
|
|
65
|
+
* regardless of this field.
|
|
66
|
+
*/
|
|
67
|
+
usage?: IUsageConfig;
|
|
68
|
+
}
|
|
69
|
+
export interface ISurfaceConfig {
|
|
70
|
+
/**
|
|
71
|
+
* Named profile (e.g. `small-app`, `monorepo`,
|
|
72
|
+
* `pack-author`, `ci`, `agent`). Built-in profiles ship from the
|
|
73
|
+
* engine; packs may contribute additional profiles via the pack
|
|
74
|
+
* manifest. When set, the profile's `hidden[]` + `enabled[]`
|
|
75
|
+
* merge with the explicit arrays below (config wins on conflicts).
|
|
76
|
+
*/
|
|
77
|
+
profile?: string;
|
|
78
|
+
enabled?: readonly string[];
|
|
79
|
+
hidden?: readonly string[];
|
|
80
|
+
}
|
|
81
|
+
export interface IUsageConfig {
|
|
82
|
+
enabled?: boolean;
|
|
83
|
+
}
|
|
84
|
+
export interface IVerificationCommand {
|
|
85
|
+
/** Stable id used by `--verification <id>`. */
|
|
86
|
+
id: string;
|
|
87
|
+
/** Human-readable label. */
|
|
88
|
+
label?: string;
|
|
89
|
+
/** Shell command to execute. */
|
|
90
|
+
command: string;
|
|
91
|
+
/** `true` opts the command into the default run set. */
|
|
92
|
+
trusted?: boolean;
|
|
93
|
+
}
|
|
94
|
+
export declare const DEFAULT_SHARKCRAFT_DIR = "sharkcraft";
|
|
95
|
+
export declare const DEFAULT_KNOWLEDGE_FILES: string[];
|
|
96
|
+
export declare const DEFAULT_RULE_FILES: string[];
|
|
97
|
+
export declare const DEFAULT_PATH_FILES: string[];
|
|
98
|
+
export declare const DEFAULT_TEMPLATE_FILES: string[];
|
|
99
|
+
export declare const DEFAULT_PIPELINE_FILES: string[];
|
|
100
|
+
export declare const DEFAULT_DOC_FILES: string[];
|
|
101
|
+
export declare function defineSharkCraftConfig(config: ISharkCraftConfig): ISharkCraftConfig;
|
|
102
|
+
//# sourceMappingURL=sharkcraft-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sharkcraft-config.d.ts","sourceRoot":"","sources":["../src/sharkcraft-config.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB;IAChC,6DAA6D;IAC7D,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,mDAAmD;IACnD,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,4EAA4E;IAC5E,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,yEAAyE;IACzE,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAE1B,4EAA4E;IAC5E,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IAErB,2BAA2B;IAC3B,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IAErB,sCAAsC;IACtC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IAErB,+BAA+B;IAC/B,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IAEzB,+BAA+B;IAC/B,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IAEzB,kDAAkD;IAClD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B,yDAAyD;IACzD,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IAExB,sEAAsE;IACtE,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAEhC,0BAA0B;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAEnC;;;;;OAKG;IACH,oBAAoB,CAAC,EAAE,SAAS,oBAAoB,EAAE,CAAC;IAEvD;;;OAGG;IACH,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,gBAAgB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAEnC;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,EAAE,cAAc,CAAC;IAEzB;;;;;;;OAOG;IACH,KAAK,CAAC,EAAE,YAAY,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,oBAAoB;IACnC,+CAA+C;IAC/C,EAAE,EAAE,MAAM,CAAC;IACX,4BAA4B;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gCAAgC;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,wDAAwD;IACxD,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,eAAO,MAAM,sBAAsB,eAAe,CAAC;AAEnD,eAAO,MAAM,uBAAuB,UAAyC,CAAC;AAC9E,eAAO,MAAM,kBAAkB,UAAqC,CAAC;AACrE,eAAO,MAAM,kBAAkB,UAAqC,CAAC;AACrE,eAAO,MAAM,sBAAsB,UAA6C,CAAC;AACjF,eAAO,MAAM,sBAAsB,UAA6C,CAAC;AACjF,eAAO,MAAM,iBAAiB,UAI7B,CAAC;AAEF,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,iBAAiB,GAAG,iBAAiB,CAEnF"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export const DEFAULT_SHARKCRAFT_DIR = 'sharkcraft';
|
|
2
|
+
export const DEFAULT_KNOWLEDGE_FILES = ['knowledge.ts', 'knowledge/index.ts'];
|
|
3
|
+
export const DEFAULT_RULE_FILES = ['rules.ts', 'knowledge/rules.ts'];
|
|
4
|
+
export const DEFAULT_PATH_FILES = ['paths.ts', 'knowledge/paths.ts'];
|
|
5
|
+
export const DEFAULT_TEMPLATE_FILES = ['templates.ts', 'knowledge/templates.ts'];
|
|
6
|
+
export const DEFAULT_PIPELINE_FILES = ['pipelines.ts', 'knowledge/pipelines.ts'];
|
|
7
|
+
export const DEFAULT_DOC_FILES = [
|
|
8
|
+
'docs/overview.md',
|
|
9
|
+
'docs/architecture.md',
|
|
10
|
+
'docs/quick-start.md',
|
|
11
|
+
];
|
|
12
|
+
export function defineSharkCraftConfig(config) {
|
|
13
|
+
return config;
|
|
14
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@shrkcrft/config",
|
|
3
|
+
"version": "0.1.0-alpha.1",
|
|
4
|
+
"description": "SharkCraft config loader: sharkcraft.config.ts discovery, defaults, zod-validated schema.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "SharkCraft contributors",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"main": "./dist/index.js",
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"import": "./dist/index.js",
|
|
14
|
+
"default": "./dist/index.js"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist",
|
|
19
|
+
"README.md",
|
|
20
|
+
"LICENSE"
|
|
21
|
+
],
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "git+https://github.com/sharkcraft/sharkcraft.git",
|
|
25
|
+
"directory": "packages/config"
|
|
26
|
+
},
|
|
27
|
+
"homepage": "https://github.com/sharkcraft/sharkcraft",
|
|
28
|
+
"bugs": {
|
|
29
|
+
"url": "https://github.com/sharkcraft/sharkcraft/issues"
|
|
30
|
+
},
|
|
31
|
+
"keywords": [
|
|
32
|
+
"sharkcraft",
|
|
33
|
+
"config",
|
|
34
|
+
"loader",
|
|
35
|
+
"zod"
|
|
36
|
+
],
|
|
37
|
+
"engines": {
|
|
38
|
+
"bun": ">=1.1.0",
|
|
39
|
+
"node": ">=18"
|
|
40
|
+
},
|
|
41
|
+
"scripts": {
|
|
42
|
+
"typecheck": "tsc --noEmit -p tsconfig.json"
|
|
43
|
+
},
|
|
44
|
+
"dependencies": {
|
|
45
|
+
"@shrkcrft/core": "^0.1.0-alpha.1",
|
|
46
|
+
"zod": "^3.25.0 || ^4.0.0"
|
|
47
|
+
},
|
|
48
|
+
"publishConfig": {
|
|
49
|
+
"access": "public"
|
|
50
|
+
}
|
|
51
|
+
}
|