@untangle-code/config 0.0.0-stage → 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 +661 -0
- package/NOTICE +90 -0
- package/README.md +262 -2
- package/THIRD_PARTY_LICENSES.md +29 -0
- package/dist/chunker-budget.d.ts +58 -0
- package/dist/chunker-budget.d.ts.map +1 -0
- package/dist/chunker-budget.js +11 -0
- package/dist/chunker-budget.js.map +1 -0
- package/dist/defaults.d.ts +50 -0
- package/dist/defaults.d.ts.map +1 -0
- package/dist/defaults.js +179 -0
- package/dist/defaults.js.map +1 -0
- package/dist/discovery.d.ts +40 -0
- package/dist/discovery.d.ts.map +1 -0
- package/dist/discovery.js +76 -0
- package/dist/discovery.js.map +1 -0
- package/dist/env.d.ts +37 -0
- package/dist/env.d.ts.map +1 -0
- package/dist/env.js +100 -0
- package/dist/env.js.map +1 -0
- package/dist/hash.d.ts +37 -0
- package/dist/hash.d.ts.map +1 -0
- package/dist/hash.js +52 -0
- package/dist/hash.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +37 -0
- package/dist/index.js.map +1 -0
- package/dist/load.d.ts +61 -0
- package/dist/load.d.ts.map +1 -0
- package/dist/load.js +264 -0
- package/dist/load.js.map +1 -0
- package/dist/merge.d.ts +32 -0
- package/dist/merge.d.ts.map +1 -0
- package/dist/merge.js +65 -0
- package/dist/merge.js.map +1 -0
- package/dist/migrations.d.ts +26 -0
- package/dist/migrations.d.ts.map +1 -0
- package/dist/migrations.js +40 -0
- package/dist/migrations.js.map +1 -0
- package/dist/parse.d.ts +7 -0
- package/dist/parse.d.ts.map +1 -0
- package/dist/parse.js +14 -0
- package/dist/parse.js.map +1 -0
- package/dist/paths.d.ts +14 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +37 -0
- package/dist/paths.js.map +1 -0
- package/dist/schema.d.ts +5 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +19 -0
- package/dist/schema.js.map +1 -0
- package/dist/secrets.d.ts +33 -0
- package/dist/secrets.d.ts.map +1 -0
- package/dist/secrets.js +69 -0
- package/dist/secrets.js.map +1 -0
- package/dist/types.d.ts +323 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +20 -0
- package/dist/types.js.map +1 -0
- package/dist/user-config.d.ts +13 -0
- package/dist/user-config.d.ts.map +1 -0
- package/dist/user-config.js +34 -0
- package/dist/user-config.js.map +1 -0
- package/dist/validate.d.ts +36 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +337 -0
- package/dist/validate.js.map +1 -0
- package/package.json +65 -3
- package/schemas/config-v1.json +375 -0
- package/src/chunker-budget.ts +63 -0
- package/src/defaults.ts +207 -0
- package/src/discovery.ts +95 -0
- package/src/env.ts +141 -0
- package/src/hash.ts +71 -0
- package/src/index.ts +51 -0
- package/src/load.ts +346 -0
- package/src/merge.ts +69 -0
- package/src/migrations.ts +64 -0
- package/src/parse.ts +18 -0
- package/src/paths.ts +42 -0
- package/src/schema.ts +23 -0
- package/src/secrets.ts +78 -0
- package/src/types.ts +366 -0
- package/src/user-config.ts +48 -0
- package/src/validate.ts +430 -0
package/dist/schema.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON Schema export (architecture.md §6.3, §7.3; docs/BUILD_PLAN.md §3
|
|
3
|
+
* assigns the repo-level `schemas/` directory to this package's WP).
|
|
4
|
+
*
|
|
5
|
+
* NOTE (openIssues): the task that produced this package restricts writes to
|
|
6
|
+
* `packages/config/**`, so the authoritative file lives at
|
|
7
|
+
* `packages/config/schemas/config-v1.json`, not the (currently empty, WP-02
|
|
8
|
+
* owned per docs/BUILD_PLAN.md §4) repo-root `schemas/`. It still needs to be
|
|
9
|
+
* mirrored to `schemas/config-v1.json` by whoever is authorized to write
|
|
10
|
+
* there.
|
|
11
|
+
*/
|
|
12
|
+
import { readFileSync } from "node:fs";
|
|
13
|
+
import { fileURLToPath } from "node:url";
|
|
14
|
+
const schemaUrl = new URL("../schemas/config-v1.json", import.meta.url);
|
|
15
|
+
/** Absolute filesystem path to the hand-authored JSON Schema (Draft 2020-12) for `UntangleConfigV1`. */
|
|
16
|
+
export const CONFIG_SCHEMA_PATH = fileURLToPath(schemaUrl);
|
|
17
|
+
/** The parsed JSON Schema object itself, read once at module load. */
|
|
18
|
+
export const CONFIG_SCHEMA = JSON.parse(readFileSync(schemaUrl, "utf8"));
|
|
19
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,2BAA2B,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAExE,wGAAwG;AACxG,MAAM,CAAC,MAAM,kBAAkB,GAAW,aAAa,CAAC,SAAS,CAAC,CAAC;AAEnE,sEAAsE;AACtE,MAAM,CAAC,MAAM,aAAa,GAA4B,IAAI,CAAC,KAAK,CAC9D,YAAY,CAAC,SAAS,EAAE,MAAM,CAAC,CACL,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Secret references and redaction (spec.md §4.4/§4.5 `apiKeyEnv`; §24
|
|
3
|
+
* "API-Keys DÜRFEN nicht in Status, Logs oder Crash Reports erscheinen";
|
|
4
|
+
* architecture.md §23.2: "Der Wert wird nie in Effective Config Dumps
|
|
5
|
+
* geschrieben.").
|
|
6
|
+
*
|
|
7
|
+
* The primary guarantee is structural: `QdrantConfig`/`EmbeddingConfig` only
|
|
8
|
+
* ever carry `apiKeyEnv` — the NAME of an environment variable — never a
|
|
9
|
+
* resolved secret value, so an `EffectiveUntangleConfigV1` cannot contain a
|
|
10
|
+
* secret by construction. `redactSecrets` is a defense-in-depth belt: it
|
|
11
|
+
* scrubs any resolved-secret-shaped field (e.g. code elsewhere mistakenly
|
|
12
|
+
* attaching a resolved key onto a config object for convenience) before that
|
|
13
|
+
* object is serialized, dumped, or logged.
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Returns a deep copy of `value` with any field whose name looks like a
|
|
17
|
+
* resolved secret (`apiKey`, `token`, `password`, `secret`, `credential`, but
|
|
18
|
+
* NOT the `...Env` reference fields) replaced by a fixed placeholder. Safe to
|
|
19
|
+
* call on an `EffectiveUntangleConfigV1`, a partial layer, or arbitrary
|
|
20
|
+
* nested data.
|
|
21
|
+
*/
|
|
22
|
+
export declare function redactSecrets<T>(value: T): T;
|
|
23
|
+
/** `JSON.stringify` through {@link redactSecrets} — the one safe way to dump a config. */
|
|
24
|
+
export declare function toRedactedJson(value: unknown, space?: number): string;
|
|
25
|
+
/**
|
|
26
|
+
* Resolves an `apiKeyEnv` reference to its actual secret value AT CALL TIME.
|
|
27
|
+
* The result MUST NOT be stored back onto any config object — callers (e.g.
|
|
28
|
+
* a Qdrant/Ollama adapter) use it immediately for one connection attempt.
|
|
29
|
+
* Returns `undefined` when `envVarName` is unset or the variable is not
|
|
30
|
+
* present in `env`.
|
|
31
|
+
*/
|
|
32
|
+
export declare function resolveApiKey(envVarName: string | undefined, env?: NodeJS.ProcessEnv): string | undefined;
|
|
33
|
+
//# sourceMappingURL=secrets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secrets.d.ts","sourceRoot":"","sources":["../src/secrets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAiCH;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAE5C;AAED,0FAA0F;AAC1F,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAErE;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,MAAM,GAAG,SAAS,CAKpB"}
|
package/dist/secrets.js
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Secret references and redaction (spec.md §4.4/§4.5 `apiKeyEnv`; §24
|
|
3
|
+
* "API-Keys DÜRFEN nicht in Status, Logs oder Crash Reports erscheinen";
|
|
4
|
+
* architecture.md §23.2: "Der Wert wird nie in Effective Config Dumps
|
|
5
|
+
* geschrieben.").
|
|
6
|
+
*
|
|
7
|
+
* The primary guarantee is structural: `QdrantConfig`/`EmbeddingConfig` only
|
|
8
|
+
* ever carry `apiKeyEnv` — the NAME of an environment variable — never a
|
|
9
|
+
* resolved secret value, so an `EffectiveUntangleConfigV1` cannot contain a
|
|
10
|
+
* secret by construction. `redactSecrets` is a defense-in-depth belt: it
|
|
11
|
+
* scrubs any resolved-secret-shaped field (e.g. code elsewhere mistakenly
|
|
12
|
+
* attaching a resolved key onto a config object for convenience) before that
|
|
13
|
+
* object is serialized, dumped, or logged.
|
|
14
|
+
*/
|
|
15
|
+
const REDACTED_PLACEHOLDER = "[REDACTED]";
|
|
16
|
+
// Field name ends in one of these -> looks like a *resolved* secret value.
|
|
17
|
+
const SECRET_VALUE_KEY_PATTERN = /(apikey|secret|password|token|credential)$/i;
|
|
18
|
+
// ...unless it ends in "Env" (e.g. `apiKeyEnv`), which holds an env var NAME
|
|
19
|
+
// and is exactly what spec.md §24 requires to stay visible for transparency.
|
|
20
|
+
const ENV_REFERENCE_SUFFIX_PATTERN = /env$/i;
|
|
21
|
+
function looksLikeResolvedSecretKey(key) {
|
|
22
|
+
if (ENV_REFERENCE_SUFFIX_PATTERN.test(key)) {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
return SECRET_VALUE_KEY_PATTERN.test(key);
|
|
26
|
+
}
|
|
27
|
+
function redactRecursive(value) {
|
|
28
|
+
if (Array.isArray(value)) {
|
|
29
|
+
return value.map(redactRecursive);
|
|
30
|
+
}
|
|
31
|
+
if (value !== null && typeof value === "object") {
|
|
32
|
+
const result = {};
|
|
33
|
+
for (const [key, entryValue] of Object.entries(value)) {
|
|
34
|
+
result[key] = looksLikeResolvedSecretKey(key)
|
|
35
|
+
? REDACTED_PLACEHOLDER
|
|
36
|
+
: redactRecursive(entryValue);
|
|
37
|
+
}
|
|
38
|
+
return result;
|
|
39
|
+
}
|
|
40
|
+
return value;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Returns a deep copy of `value` with any field whose name looks like a
|
|
44
|
+
* resolved secret (`apiKey`, `token`, `password`, `secret`, `credential`, but
|
|
45
|
+
* NOT the `...Env` reference fields) replaced by a fixed placeholder. Safe to
|
|
46
|
+
* call on an `EffectiveUntangleConfigV1`, a partial layer, or arbitrary
|
|
47
|
+
* nested data.
|
|
48
|
+
*/
|
|
49
|
+
export function redactSecrets(value) {
|
|
50
|
+
return redactRecursive(value);
|
|
51
|
+
}
|
|
52
|
+
/** `JSON.stringify` through {@link redactSecrets} — the one safe way to dump a config. */
|
|
53
|
+
export function toRedactedJson(value, space) {
|
|
54
|
+
return JSON.stringify(redactSecrets(value), null, space);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Resolves an `apiKeyEnv` reference to its actual secret value AT CALL TIME.
|
|
58
|
+
* The result MUST NOT be stored back onto any config object — callers (e.g.
|
|
59
|
+
* a Qdrant/Ollama adapter) use it immediately for one connection attempt.
|
|
60
|
+
* Returns `undefined` when `envVarName` is unset or the variable is not
|
|
61
|
+
* present in `env`.
|
|
62
|
+
*/
|
|
63
|
+
export function resolveApiKey(envVarName, env = process.env) {
|
|
64
|
+
if (envVarName === undefined || envVarName.length === 0) {
|
|
65
|
+
return undefined;
|
|
66
|
+
}
|
|
67
|
+
return env[envVarName];
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=secrets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secrets.js","sourceRoot":"","sources":["../src/secrets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,MAAM,oBAAoB,GAAG,YAAY,CAAC;AAE1C,2EAA2E;AAC3E,MAAM,wBAAwB,GAAG,6CAA6C,CAAC;AAC/E,6EAA6E;AAC7E,6EAA6E;AAC7E,MAAM,4BAA4B,GAAG,OAAO,CAAC;AAE7C,SAAS,0BAA0B,CAAC,GAAW;IAC7C,IAAI,4BAA4B,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QAC3C,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,wBAAwB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC5C,CAAC;AAED,SAAS,eAAe,CAAC,KAAc;IACrC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IACpC,CAAC;IACD,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAChD,MAAM,MAAM,GAA4B,EAAE,CAAC;QAC3C,KAAK,MAAM,CAAC,GAAG,EAAE,UAAU,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACtD,MAAM,CAAC,GAAG,CAAC,GAAG,0BAA0B,CAAC,GAAG,CAAC;gBAC3C,CAAC,CAAC,oBAAoB;gBACtB,CAAC,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC;QAClC,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAI,KAAQ;IACvC,OAAO,eAAe,CAAC,KAAK,CAAM,CAAC;AACrC,CAAC;AAED,0FAA0F;AAC1F,MAAM,UAAU,cAAc,CAAC,KAAc,EAAE,KAAc;IAC3D,OAAO,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;AAC3D,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAC3B,UAA8B,EAC9B,MAAyB,OAAO,CAAC,GAAG;IAEpC,IAAI,UAAU,KAAK,SAAS,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxD,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,GAAG,CAAC,UAAU,CAAC,CAAC;AACzB,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration types (spec.md §4.2–§4.8, §5.7; product.md §11; portfolio.md
|
|
3
|
+
* §14.4; architecture.md §6.3, §23.2).
|
|
4
|
+
*
|
|
5
|
+
* These are the *raw*, *partial*-friendly shapes a `.untangle.json`,
|
|
6
|
+
* environment layer or CLI argument object may contribute. The fully merged,
|
|
7
|
+
* defaulted and validated shape produced by {@link "./load.js"} carries the
|
|
8
|
+
* same interfaces but with all optional fields the product defaults fill in
|
|
9
|
+
* actually present — see `EffectiveUntangleConfigV1` at the bottom of this
|
|
10
|
+
* file.
|
|
11
|
+
*/
|
|
12
|
+
import type { ContextArtifactConfig, RepositoryConfig } from "@untangle-code/domain";
|
|
13
|
+
export type { ContextArtifactConfig, ContextArtifactType } from "@untangle-code/domain";
|
|
14
|
+
export type { RepositoryConfig } from "@untangle-code/domain";
|
|
15
|
+
/** spec.md §4.4. */
|
|
16
|
+
export interface QdrantConfig {
|
|
17
|
+
mode: "managed" | "external";
|
|
18
|
+
url?: string;
|
|
19
|
+
/** Name of the environment variable holding the API key — never the key itself (architecture.md §23.2). */
|
|
20
|
+
apiKeyEnv?: string;
|
|
21
|
+
collectionPrefix?: string;
|
|
22
|
+
requestTimeoutMs?: number;
|
|
23
|
+
maxRetries?: number;
|
|
24
|
+
upsertMaxPoints?: number;
|
|
25
|
+
upsertBudgetBytes?: number;
|
|
26
|
+
}
|
|
27
|
+
/** Search backend selection. Relative local paths resolve against the repository root. */
|
|
28
|
+
export interface StorageConfig {
|
|
29
|
+
backend: "lancedb" | "qdrant";
|
|
30
|
+
/** Embedded LanceDB directory; defaults to `.untangle/index/lancedb`. */
|
|
31
|
+
path?: string;
|
|
32
|
+
}
|
|
33
|
+
/** spec.md §4.5. */
|
|
34
|
+
export interface EmbeddingConfig {
|
|
35
|
+
provider: "ollama";
|
|
36
|
+
mode: "auto" | "managed" | "external";
|
|
37
|
+
url?: string;
|
|
38
|
+
/** Name of the environment variable holding the API key — never the key itself (architecture.md §23.2). */
|
|
39
|
+
apiKeyEnv?: string;
|
|
40
|
+
model: string;
|
|
41
|
+
dimensions: number;
|
|
42
|
+
contextLength: number;
|
|
43
|
+
queryPrefix: string;
|
|
44
|
+
documentPrefix: string;
|
|
45
|
+
includePath: boolean;
|
|
46
|
+
batchSize: number;
|
|
47
|
+
maxConnections: number;
|
|
48
|
+
requestTimeoutMs: number;
|
|
49
|
+
}
|
|
50
|
+
/** spec.md §4.6. */
|
|
51
|
+
export interface IndexConfig {
|
|
52
|
+
watch: boolean;
|
|
53
|
+
reconcileIntervalMinutes: number;
|
|
54
|
+
maxFileSizeMb: number;
|
|
55
|
+
maxGraphFileSizeMb: number;
|
|
56
|
+
scanConcurrency: number;
|
|
57
|
+
embeddingConcurrency: number;
|
|
58
|
+
filesPerCheckpoint: number;
|
|
59
|
+
targetChunkTokens: number;
|
|
60
|
+
maxChunkTokens: number;
|
|
61
|
+
fallbackOverlapTokens: number;
|
|
62
|
+
includeDotFiles: boolean;
|
|
63
|
+
indexExtensionless: boolean;
|
|
64
|
+
extraExtensions: string[];
|
|
65
|
+
extensionLanguageMap: Record<string, string>;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Search defaults (Untangle decision — spec.md §13 defines the request/result
|
|
69
|
+
* shapes `SearchRequestV1`/`SearchResultV1` in domain, but names no
|
|
70
|
+
* `SearchConfig` fields; this shape documents which of those request knobs
|
|
71
|
+
* get a project-wide default and adds the boost weights spec.md §13.3 lists
|
|
72
|
+
* without assigning default magnitudes).
|
|
73
|
+
*/
|
|
74
|
+
export interface SearchConfig {
|
|
75
|
+
/** Default `limit` when a search request omits it. */
|
|
76
|
+
defaultLimit: number;
|
|
77
|
+
/** Default `candidateLimit` (pre-RRF/pre-filter pool size) when omitted. */
|
|
78
|
+
defaultCandidateLimit: number;
|
|
79
|
+
/** Hard ceiling a caller-supplied `candidateLimit` is clamped to. */
|
|
80
|
+
maxCandidateLimit: number;
|
|
81
|
+
/** Default `diversify` (MMR, architecture.md §18.5) when a request omits it. */
|
|
82
|
+
diversifyByDefault: boolean;
|
|
83
|
+
/** Default `minScore` when a request omits it. */
|
|
84
|
+
minScoreDefault?: number;
|
|
85
|
+
/**
|
|
86
|
+
* Calibrated absence decisions, keyed by the exact embedding profile id.
|
|
87
|
+
*
|
|
88
|
+
* These values are deliberately optional and have no product default: raw
|
|
89
|
+
* cosine scores are model-specific, and their useful separation also
|
|
90
|
+
* depends on the indexed corpus. A policy therefore only applies when its
|
|
91
|
+
* key, workspace id, and physical collection all match the active target.
|
|
92
|
+
*/
|
|
93
|
+
relevancePolicies?: Record<string, SearchRelevancePolicyBindingConfigV1>;
|
|
94
|
+
/** Relative weights of the additive score components (spec.md §13.3). */
|
|
95
|
+
boostWeights: {
|
|
96
|
+
exactSymbol: number;
|
|
97
|
+
exactPath: number;
|
|
98
|
+
repoPriority: number;
|
|
99
|
+
graphProximity: number;
|
|
100
|
+
recency: number;
|
|
101
|
+
duplicatePenalty: number;
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
/** Corpus binding for a calibrated search relevance policy (WP-231). */
|
|
105
|
+
export interface SearchRelevancePolicyBindingConfigV1 {
|
|
106
|
+
/** Exact logical workspace used while calibrating the thresholds. */
|
|
107
|
+
workspaceId: string;
|
|
108
|
+
/** Exact physical vector collection used while calibrating the thresholds. */
|
|
109
|
+
collection: string;
|
|
110
|
+
policy: SearchRelevancePolicyConfigV1;
|
|
111
|
+
}
|
|
112
|
+
/** Config representation of the search engine's calibrated relevance policy (WP-231). */
|
|
113
|
+
export interface SearchRelevancePolicyConfigV1 {
|
|
114
|
+
/** Human- and machine-readable provenance of the measurements behind the thresholds. */
|
|
115
|
+
calibrationId: string;
|
|
116
|
+
/** Absolute minimum cosine score of the strongest dense candidate, in [-1, 1]. */
|
|
117
|
+
minimumDenseScore: number;
|
|
118
|
+
/** Minimum difference between rank 1 and `denseReferenceRank`, in [0, 2]. */
|
|
119
|
+
minimumDenseSpread: number;
|
|
120
|
+
/** One-based dense rank used for the relative comparison; at least 2. */
|
|
121
|
+
denseReferenceRank: number;
|
|
122
|
+
/** Minimum IDF-weighted fraction of query evidence found together in one candidate. */
|
|
123
|
+
minimumCandidateIdfCoverage: number;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Graph traversal limits (Untangle decision — architecture.md §17.4 names
|
|
127
|
+
* `maxDepth`/`maxNodes`/`maxEdges`/`maxWallTimeMs` as per-query traversal
|
|
128
|
+
* limits without a config shape; this makes them project-configurable
|
|
129
|
+
* defaults). `includeDynamicImports` reflects the `dynamic_import` edge kind
|
|
130
|
+
* from spec.md §14.2 being switchable.
|
|
131
|
+
*/
|
|
132
|
+
export interface GraphConfig {
|
|
133
|
+
enabled: boolean;
|
|
134
|
+
maxTraversalDepth: number;
|
|
135
|
+
maxTraversalNodes: number;
|
|
136
|
+
maxTraversalEdges: number;
|
|
137
|
+
maxTraversalWallTimeMs: number;
|
|
138
|
+
includeDynamicImports: boolean;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Complexity engine switches (Untangle decision — spec.md §16 defines the
|
|
142
|
+
* metrics and algorithm IDs exhaustively but no `ComplexityConfig` shape;
|
|
143
|
+
* product.md §11's example config uses `enabled` and `cognitiveAlgorithm`,
|
|
144
|
+
* which anchor this shape). `cyclomaticVariant` selects which of classic
|
|
145
|
+
* (§16.2) and extended (§16.3) get computed; both are cheap to compute
|
|
146
|
+
* together so "both" is the default.
|
|
147
|
+
*/
|
|
148
|
+
export interface ComplexityConfig {
|
|
149
|
+
enabled: boolean;
|
|
150
|
+
/** Overridable for future algorithm versions; defaults to `COGNITIVE_ALGORITHM_ID` from domain. */
|
|
151
|
+
cognitiveAlgorithm: string;
|
|
152
|
+
cyclomaticVariant: "classic" | "extended" | "both";
|
|
153
|
+
maintainabilityIndexEnabled: boolean;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Change Intelligence configuration (Untangle decision — spec.md §17.6 gives
|
|
157
|
+
* the default risk score weights and requires every component to be
|
|
158
|
+
* disclosed with its weight and contribution, but does not name a config
|
|
159
|
+
* type). Weights MUST sum to `1.0` within a `±0.001` tolerance, mirroring the
|
|
160
|
+
* validation rule portfolio.md §14.4 states for `blueprint.weights`.
|
|
161
|
+
*/
|
|
162
|
+
export interface ChangeConfig {
|
|
163
|
+
enabled: boolean;
|
|
164
|
+
riskWeights: {
|
|
165
|
+
churn: number;
|
|
166
|
+
positiveCognitiveDelta: number;
|
|
167
|
+
positiveCyclomaticDelta: number;
|
|
168
|
+
blastRadius: number;
|
|
169
|
+
graphCentrality: number;
|
|
170
|
+
semanticChange: number;
|
|
171
|
+
testDistance: number;
|
|
172
|
+
};
|
|
173
|
+
symbolMatching: {
|
|
174
|
+
/** Minimum token/MinHash similarity (spec.md §17.3 step 4) to accept a rename/move candidate. */
|
|
175
|
+
tokenSimilarityMin: number;
|
|
176
|
+
/** Whether step 6 (embedding cosine at equal profile) participates at all. */
|
|
177
|
+
enableEmbeddingSimilarity: boolean;
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
/** spec.md §4.7. */
|
|
181
|
+
export interface QualityGateConfig {
|
|
182
|
+
mode: "off" | "warn" | "fail";
|
|
183
|
+
newCyclesAllowed: number;
|
|
184
|
+
cognitivePerSymbolMax?: number;
|
|
185
|
+
cognitiveDeltaPerSymbolMax?: number;
|
|
186
|
+
cyclomaticPerSymbolMax?: number;
|
|
187
|
+
cyclomaticDeltaPerSymbolMax?: number;
|
|
188
|
+
maxNestingPerSymbolMax?: number;
|
|
189
|
+
maintainabilityIndexMin?: number;
|
|
190
|
+
riskScoreMax?: number;
|
|
191
|
+
minimumParseQuality: "failed" | "partial" | "complete";
|
|
192
|
+
ignoreExistingViolations: boolean;
|
|
193
|
+
include?: string[];
|
|
194
|
+
exclude?: string[];
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Telemetry (spec.md §24: "Telemetrie MUSS standardmäßig aus sein" — telemetry
|
|
198
|
+
* MUST default to off; §23.2/§23.3 name the log/metrics facilities this
|
|
199
|
+
* switches). Shape beyond `enabled` is an Untangle decision.
|
|
200
|
+
*/
|
|
201
|
+
export interface TelemetryConfig {
|
|
202
|
+
/** Default `false` — local-first, opt-in only (spec.md §24). */
|
|
203
|
+
enabled: boolean;
|
|
204
|
+
logLevel: "error" | "warn" | "info" | "debug" | "trace";
|
|
205
|
+
/** Whether internal counters (spec.md §23.3) are exported to an external system. */
|
|
206
|
+
metricsExport: "none" | "prometheus";
|
|
207
|
+
}
|
|
208
|
+
/** portfolio.md §13. */
|
|
209
|
+
export interface PortfolioEnrichmentConfig {
|
|
210
|
+
/** Default `false` — no registry/network access without opt-in (portfolio.md §13). */
|
|
211
|
+
enabled: boolean;
|
|
212
|
+
registries: ("npm" | "pypi" | "crates" | "maven" | "nuget" | "go" | "composer")[];
|
|
213
|
+
registryUrls?: Record<string, string>;
|
|
214
|
+
/** Default `168` (one week). */
|
|
215
|
+
cacheTtlHours: number;
|
|
216
|
+
timeoutMs: number;
|
|
217
|
+
}
|
|
218
|
+
/** portfolio.md §14.4 — normative shape. */
|
|
219
|
+
export interface PortfolioConfig {
|
|
220
|
+
/** Default `true`. */
|
|
221
|
+
enabled?: boolean;
|
|
222
|
+
/** Default `false`. */
|
|
223
|
+
includeTransitive?: boolean;
|
|
224
|
+
/** Default `2`. */
|
|
225
|
+
conventionMinRepos?: number;
|
|
226
|
+
conventions?: {
|
|
227
|
+
pinned?: string[];
|
|
228
|
+
suppressed?: string[];
|
|
229
|
+
};
|
|
230
|
+
radar?: {
|
|
231
|
+
/** Default `0.5`. */
|
|
232
|
+
adoptShareMin?: number;
|
|
233
|
+
/** Default `0.2`. */
|
|
234
|
+
maintainShareMin?: number;
|
|
235
|
+
/** Default `540`. */
|
|
236
|
+
retireAfterDays?: number;
|
|
237
|
+
};
|
|
238
|
+
blueprint?: {
|
|
239
|
+
weights?: {
|
|
240
|
+
/** Default `0.40`. */
|
|
241
|
+
adoption?: number;
|
|
242
|
+
/** Default `0.20`. */
|
|
243
|
+
recency?: number;
|
|
244
|
+
/** Default `0.25`. */
|
|
245
|
+
health?: number;
|
|
246
|
+
/** Default `0.15`. */
|
|
247
|
+
versionConsistency?: number;
|
|
248
|
+
};
|
|
249
|
+
};
|
|
250
|
+
enrichment?: PortfolioEnrichmentConfig;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Main configuration schema (spec.md §4.2), extended with `portfolio`
|
|
254
|
+
* (portfolio.md §14.4, folded into `UntangleConfigV1` per portfolio.md
|
|
255
|
+
* §18.1's planned spec.md §4.2 amendment).
|
|
256
|
+
*/
|
|
257
|
+
export interface UntangleConfigV1 {
|
|
258
|
+
schemaVersion: 1;
|
|
259
|
+
workspaceId?: string;
|
|
260
|
+
projectId?: string;
|
|
261
|
+
repositories?: RepositoryConfig[];
|
|
262
|
+
storage?: StorageConfig;
|
|
263
|
+
qdrant?: QdrantConfig;
|
|
264
|
+
embeddings?: EmbeddingConfig;
|
|
265
|
+
index?: IndexConfig;
|
|
266
|
+
search?: SearchConfig;
|
|
267
|
+
graph?: GraphConfig;
|
|
268
|
+
complexity?: ComplexityConfig;
|
|
269
|
+
changes?: ChangeConfig;
|
|
270
|
+
qualityGate?: QualityGateConfig;
|
|
271
|
+
contextArtifacts?: ContextArtifactConfig[];
|
|
272
|
+
telemetry?: TelemetryConfig;
|
|
273
|
+
portfolio?: PortfolioConfig;
|
|
274
|
+
}
|
|
275
|
+
/** The set of `UntangleConfigV1` top-level keys, used to detect unknown fields (spec.md §4.8). */
|
|
276
|
+
export declare const UNTANGLE_CONFIG_V1_KEYS: readonly ["schemaVersion", "workspaceId", "projectId", "repositories", "storage", "qdrant", "embeddings", "index", "search", "graph", "complexity", "changes", "qualityGate", "contextArtifacts", "telemetry", "portfolio"];
|
|
277
|
+
/**
|
|
278
|
+
* Recursively makes every field of `T` optional, including inside array
|
|
279
|
+
* elements. Used for {@link RawConfigLayer}: a single JSON file, an env-var
|
|
280
|
+
* layer, or an `explicit` argument object commonly sets only a handful of
|
|
281
|
+
* leaves inside a nested config section (e.g. just `qdrant.collectionPrefix`)
|
|
282
|
+
* — a shallow `Partial<T>` would still require every OTHER field of
|
|
283
|
+
* `QdrantConfig` once `qdrant` is present at all, which is not how any of
|
|
284
|
+
* the six layers in spec.md §4.1 are actually written. Runtime validation
|
|
285
|
+
* (`validate.ts`) is what enforces which fields are truly required once all
|
|
286
|
+
* layers are merged with the product defaults.
|
|
287
|
+
*/
|
|
288
|
+
export type DeepPartial<T> = T extends (infer U)[] ? DeepPartial<U>[] : T extends object ? {
|
|
289
|
+
[K in keyof T]?: DeepPartial<T[K]>;
|
|
290
|
+
} : T;
|
|
291
|
+
/**
|
|
292
|
+
* A raw configuration layer as read from JSON, environment mapping or passed
|
|
293
|
+
* explicitly: every field optional (deeply — see {@link DeepPartial}),
|
|
294
|
+
* `schemaVersion` not required (defaults are applied and validated later).
|
|
295
|
+
* `$schema` is accepted and ignored (spec.md §11's example config carries it).
|
|
296
|
+
*/
|
|
297
|
+
export type RawConfigLayer = {
|
|
298
|
+
$schema?: string;
|
|
299
|
+
schemaVersion?: number;
|
|
300
|
+
} & DeepPartial<Omit<UntangleConfigV1, "schemaVersion">>;
|
|
301
|
+
/**
|
|
302
|
+
* The fully merged, defaulted and validated configuration
|
|
303
|
+
* ({@link "./load.js"}'s `loadConfig` result). All fields the product
|
|
304
|
+
* defaults (spec.md §4.5, this package's `defaults.ts`) supply are guaranteed
|
|
305
|
+
* present; `repositories` and `contextArtifacts` stay optional because they
|
|
306
|
+
* have no universal default (spec.md §4.3: the current project path MAY
|
|
307
|
+
* serve as an implicit single repository instead).
|
|
308
|
+
*/
|
|
309
|
+
export interface EffectiveUntangleConfigV1 extends UntangleConfigV1 {
|
|
310
|
+
schemaVersion: 1;
|
|
311
|
+
storage: StorageConfig;
|
|
312
|
+
qdrant: QdrantConfig;
|
|
313
|
+
embeddings: EmbeddingConfig;
|
|
314
|
+
index: IndexConfig;
|
|
315
|
+
search: SearchConfig;
|
|
316
|
+
graph: GraphConfig;
|
|
317
|
+
complexity: ComplexityConfig;
|
|
318
|
+
changes: ChangeConfig;
|
|
319
|
+
qualityGate: QualityGateConfig;
|
|
320
|
+
telemetry: TelemetryConfig;
|
|
321
|
+
portfolio: PortfolioConfig;
|
|
322
|
+
}
|
|
323
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAOrF,YAAY,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AACxF,YAAY,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,oBAAoB;AACpB,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,SAAS,GAAG,UAAU,CAAC;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,2GAA2G;IAC3G,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,0FAA0F;AAC1F,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC9B,yEAAyE;IACzE,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,oBAAoB;AACpB,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,QAAQ,CAAC;IACnB,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,CAAC;IACtC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,2GAA2G;IAC3G,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,OAAO,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,oBAAoB;AACpB,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,OAAO,CAAC;IACf,wBAAwB,EAAE,MAAM,CAAC;IACjC,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,eAAe,EAAE,MAAM,CAAC;IACxB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,cAAc,EAAE,MAAM,CAAC;IACvB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,eAAe,EAAE,OAAO,CAAC;IACzB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9C;AAED;;;;;;GAMG;AACH,MAAM,WAAW,YAAY;IAC3B,sDAAsD;IACtD,YAAY,EAAE,MAAM,CAAC;IACrB,4EAA4E;IAC5E,qBAAqB,EAAE,MAAM,CAAC;IAC9B,qEAAqE;IACrE,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gFAAgF;IAChF,kBAAkB,EAAE,OAAO,CAAC;IAC5B,kDAAkD;IAClD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;;;OAOG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,oCAAoC,CAAC,CAAC;IACzE,yEAAyE;IACzE,YAAY,EAAE;QACZ,WAAW,EAAE,MAAM,CAAC;QACpB,SAAS,EAAE,MAAM,CAAC;QAClB,YAAY,EAAE,MAAM,CAAC;QACrB,cAAc,EAAE,MAAM,CAAC;QACvB,OAAO,EAAE,MAAM,CAAC;QAChB,gBAAgB,EAAE,MAAM,CAAC;KAC1B,CAAC;CACH;AAED,wEAAwE;AACxE,MAAM,WAAW,oCAAoC;IACnD,qEAAqE;IACrE,WAAW,EAAE,MAAM,CAAC;IACpB,8EAA8E;IAC9E,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,6BAA6B,CAAC;CACvC;AAED,yFAAyF;AACzF,MAAM,WAAW,6BAA6B;IAC5C,wFAAwF;IACxF,aAAa,EAAE,MAAM,CAAC;IACtB,kFAAkF;IAClF,iBAAiB,EAAE,MAAM,CAAC;IAC1B,6EAA6E;IAC7E,kBAAkB,EAAE,MAAM,CAAC;IAC3B,yEAAyE;IACzE,kBAAkB,EAAE,MAAM,CAAC;IAC3B,uFAAuF;IACvF,2BAA2B,EAAE,MAAM,CAAC;CACrC;AAED;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,sBAAsB,EAAE,MAAM,CAAC;IAC/B,qBAAqB,EAAE,OAAO,CAAC;CAChC;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,mGAAmG;IACnG,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iBAAiB,EAAE,SAAS,GAAG,UAAU,GAAG,MAAM,CAAC;IACnD,2BAA2B,EAAE,OAAO,CAAC;CACtC;AAED;;;;;;GAMG;AACH,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE;QACX,KAAK,EAAE,MAAM,CAAC;QACd,sBAAsB,EAAE,MAAM,CAAC;QAC/B,uBAAuB,EAAE,MAAM,CAAC;QAChC,WAAW,EAAE,MAAM,CAAC;QACpB,eAAe,EAAE,MAAM,CAAC;QACxB,cAAc,EAAE,MAAM,CAAC;QACvB,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,cAAc,EAAE;QACd,iGAAiG;QACjG,kBAAkB,EAAE,MAAM,CAAC;QAC3B,8EAA8E;QAC9E,yBAAyB,EAAE,OAAO,CAAC;KACpC,CAAC;CACH;AAED,oBAAoB;AACpB,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC;IAC9B,gBAAgB,EAAE,MAAM,CAAC;IACzB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,0BAA0B,CAAC,EAAE,MAAM,CAAC;IACpC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mBAAmB,EAAE,QAAQ,GAAG,SAAS,GAAG,UAAU,CAAC;IACvD,wBAAwB,EAAE,OAAO,CAAC;IAClC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,gEAAgE;IAChE,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;IACxD,oFAAoF;IACpF,aAAa,EAAE,MAAM,GAAG,YAAY,CAAC;CACtC;AAED,wBAAwB;AACxB,MAAM,WAAW,yBAAyB;IACxC,sFAAsF;IACtF,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,CAAC,KAAK,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG,OAAO,GAAG,IAAI,GAAG,UAAU,CAAC,EAAE,CAAC;IAClF,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,gCAAgC;IAChC,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,4CAA4C;AAC5C,MAAM,WAAW,eAAe;IAC9B,sBAAsB;IACtB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,uBAAuB;IACvB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,mBAAmB;IACnB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,WAAW,CAAC,EAAE;QACZ,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;QAClB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;KACvB,CAAC;IACF,KAAK,CAAC,EAAE;QACN,qBAAqB;QACrB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,qBAAqB;QACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,qBAAqB;QACrB,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,CAAC;IACF,SAAS,CAAC,EAAE;QACV,OAAO,CAAC,EAAE;YACR,sBAAsB;YACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;YAClB,sBAAsB;YACtB,OAAO,CAAC,EAAE,MAAM,CAAC;YACjB,sBAAsB;YACtB,MAAM,CAAC,EAAE,MAAM,CAAC;YAChB,sBAAsB;YACtB,kBAAkB,CAAC,EAAE,MAAM,CAAC;SAC7B,CAAC;KACH,CAAC;IACF,UAAU,CAAC,EAAE,yBAAyB,CAAC;CACxC;AAED;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,aAAa,EAAE,CAAC,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAClC,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,UAAU,CAAC,EAAE,eAAe,CAAC;IAC7B,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC,gBAAgB,CAAC,EAAE,qBAAqB,EAAE,CAAC;IAC3C,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,SAAS,CAAC,EAAE,eAAe,CAAC;CAC7B;AAED,kGAAkG;AAClG,eAAO,MAAM,uBAAuB,6NAiBoB,CAAC;AAEzD;;;;;;;;;;GAUG;AACH,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,GAC9C,WAAW,CAAC,CAAC,CAAC,EAAE,GAChB,CAAC,SAAS,MAAM,GACd;KAAG,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAAE,GACtC,CAAC,CAAC;AAER;;;;;GAKG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,GAAG,WAAW,CAAC,IAAI,CAAC,gBAAgB,EAAE,eAAe,CAAC,CAAC,CAAC;AAEzD;;;;;;;GAOG;AACH,MAAM,WAAW,yBAA0B,SAAQ,gBAAgB;IACjE,aAAa,EAAE,CAAC,CAAC;IACjB,OAAO,EAAE,aAAa,CAAC;IACvB,MAAM,EAAE,YAAY,CAAC;IACrB,UAAU,EAAE,eAAe,CAAC;IAC5B,KAAK,EAAE,WAAW,CAAC;IACnB,MAAM,EAAE,YAAY,CAAC;IACrB,KAAK,EAAE,WAAW,CAAC;IACnB,UAAU,EAAE,gBAAgB,CAAC;IAC7B,OAAO,EAAE,YAAY,CAAC;IACtB,WAAW,EAAE,iBAAiB,CAAC;IAC/B,SAAS,EAAE,eAAe,CAAC;IAC3B,SAAS,EAAE,eAAe,CAAC;CAC5B"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/** The set of `UntangleConfigV1` top-level keys, used to detect unknown fields (spec.md §4.8). */
|
|
2
|
+
export const UNTANGLE_CONFIG_V1_KEYS = [
|
|
3
|
+
"schemaVersion",
|
|
4
|
+
"workspaceId",
|
|
5
|
+
"projectId",
|
|
6
|
+
"repositories",
|
|
7
|
+
"storage",
|
|
8
|
+
"qdrant",
|
|
9
|
+
"embeddings",
|
|
10
|
+
"index",
|
|
11
|
+
"search",
|
|
12
|
+
"graph",
|
|
13
|
+
"complexity",
|
|
14
|
+
"changes",
|
|
15
|
+
"qualityGate",
|
|
16
|
+
"contextArtifacts",
|
|
17
|
+
"telemetry",
|
|
18
|
+
"portfolio",
|
|
19
|
+
];
|
|
20
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAwSA,kGAAkG;AAClG,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,eAAe;IACf,aAAa;IACb,WAAW;IACX,cAAc;IACd,SAAS;IACT,QAAQ;IACR,YAAY;IACZ,OAAO;IACP,QAAQ;IACR,OAAO;IACP,YAAY;IACZ,SAAS;IACT,aAAa;IACb,kBAAkB;IAClB,WAAW;IACX,WAAW;CAC2C,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare const USER_CONFIG_FILE_NAME = "config.json";
|
|
2
|
+
/**
|
|
3
|
+
* Resolves the per-OS Untangle config directory:
|
|
4
|
+
* - Linux: `$XDG_CONFIG_HOME/untangle` or `~/.config/untangle`;
|
|
5
|
+
* - macOS: `~/Library/Application Support/untangle`;
|
|
6
|
+
* - Windows: `%APPDATA%\untangle` or `~/AppData/Roaming/untangle`.
|
|
7
|
+
*
|
|
8
|
+
* `env` and `platform` are injectable for deterministic tests.
|
|
9
|
+
*/
|
|
10
|
+
export declare function resolveUserConfigDir(env?: NodeJS.ProcessEnv, platform?: NodeJS.Platform): string;
|
|
11
|
+
/** Full path to the user config file, or `undefined` when it does not exist. */
|
|
12
|
+
export declare function resolveUserConfigPath(env?: NodeJS.ProcessEnv, platform?: NodeJS.Platform): string | undefined;
|
|
13
|
+
//# sourceMappingURL=user-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user-config.d.ts","sourceRoot":"","sources":["../src/user-config.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,qBAAqB,gBAAgB,CAAC;AAEnD;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,QAAQ,GAAE,MAAM,CAAC,QAA2B,GAC3C,MAAM,CAgBR;AAED,gFAAgF;AAChF,wBAAgB,qBAAqB,CACnC,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,QAAQ,GAAE,MAAM,CAAC,QAA2B,GAC3C,MAAM,GAAG,SAAS,CAGpB"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* User configuration location (spec.md §4.1 layer 5: "Nutzerkonfiguration im
|
|
3
|
+
* OS-Konfigurationsverzeichnis"). The exact directory and file name are an
|
|
4
|
+
* Untangle decision — spec.md does not name them.
|
|
5
|
+
*/
|
|
6
|
+
import { existsSync } from "node:fs";
|
|
7
|
+
import { homedir } from "node:os";
|
|
8
|
+
import { join } from "node:path";
|
|
9
|
+
export const USER_CONFIG_FILE_NAME = "config.json";
|
|
10
|
+
/**
|
|
11
|
+
* Resolves the per-OS Untangle config directory:
|
|
12
|
+
* - Linux: `$XDG_CONFIG_HOME/untangle` or `~/.config/untangle`;
|
|
13
|
+
* - macOS: `~/Library/Application Support/untangle`;
|
|
14
|
+
* - Windows: `%APPDATA%\untangle` or `~/AppData/Roaming/untangle`.
|
|
15
|
+
*
|
|
16
|
+
* `env` and `platform` are injectable for deterministic tests.
|
|
17
|
+
*/
|
|
18
|
+
export function resolveUserConfigDir(env = process.env, platform = process.platform) {
|
|
19
|
+
if (platform === "win32") {
|
|
20
|
+
const appData = env["APPDATA"];
|
|
21
|
+
return join(appData && appData.length > 0 ? appData : join(homedir(), "AppData", "Roaming"), "untangle");
|
|
22
|
+
}
|
|
23
|
+
if (platform === "darwin") {
|
|
24
|
+
return join(homedir(), "Library", "Application Support", "untangle");
|
|
25
|
+
}
|
|
26
|
+
const xdgConfigHome = env["XDG_CONFIG_HOME"];
|
|
27
|
+
return join(xdgConfigHome && xdgConfigHome.length > 0 ? xdgConfigHome : join(homedir(), ".config"), "untangle");
|
|
28
|
+
}
|
|
29
|
+
/** Full path to the user config file, or `undefined` when it does not exist. */
|
|
30
|
+
export function resolveUserConfigPath(env = process.env, platform = process.platform) {
|
|
31
|
+
const candidate = join(resolveUserConfigDir(env, platform), USER_CONFIG_FILE_NAME);
|
|
32
|
+
return existsSync(candidate) ? candidate : undefined;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=user-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user-config.js","sourceRoot":"","sources":["../src/user-config.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,CAAC,MAAM,qBAAqB,GAAG,aAAa,CAAC;AAEnD;;;;;;;GAOG;AACH,MAAM,UAAU,oBAAoB,CAClC,MAAyB,OAAO,CAAC,GAAG,EACpC,WAA4B,OAAO,CAAC,QAAQ;IAE5C,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC;QAC/B,OAAO,IAAI,CACT,OAAO,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,SAAS,CAAC,EAC/E,UAAU,CACX,CAAC;IACJ,CAAC;IACD,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC1B,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,qBAAqB,EAAE,UAAU,CAAC,CAAC;IACvE,CAAC;IACD,MAAM,aAAa,GAAG,GAAG,CAAC,iBAAiB,CAAC,CAAC;IAC7C,OAAO,IAAI,CACT,aAAa,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,EACtF,UAAU,CACX,CAAC;AACJ,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,qBAAqB,CACnC,MAAyB,OAAO,CAAC,GAAG,EACpC,WAA4B,OAAO,CAAC,QAAQ;IAE5C,MAAM,SAAS,GAAG,IAAI,CAAC,oBAAoB,CAAC,GAAG,EAAE,QAAQ,CAAC,EAAE,qBAAqB,CAAC,CAAC;IACnF,OAAO,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;AACvD,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export interface ConfigIssue {
|
|
2
|
+
/** An `ErrorCode` (domain) for errors; a short machine-readable slug for warnings. */
|
|
3
|
+
code: string;
|
|
4
|
+
message: string;
|
|
5
|
+
/** Dotted path into the config object, e.g. `"embeddings.mode"`. */
|
|
6
|
+
path: string;
|
|
7
|
+
}
|
|
8
|
+
export interface ValidationResult {
|
|
9
|
+
errors: ConfigIssue[];
|
|
10
|
+
warnings: ConfigIssue[];
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Validates a fully layer-merged (but not yet necessarily complete-with-defaults)
|
|
14
|
+
* configuration object. Returns warnings for unknown top-level fields and
|
|
15
|
+
* errors for invalid enums, unresolvable core values, and structural
|
|
16
|
+
* uniqueness violations (spec.md §4.3 repository ids; portfolio.md §14.4
|
|
17
|
+
* blueprint weight sum).
|
|
18
|
+
*/
|
|
19
|
+
export declare function validateEffectiveConfig(config: Record<string, unknown>): ValidationResult;
|
|
20
|
+
/**
|
|
21
|
+
* Throws `UntangleError("CONFIG_INVALID", …)` when `errors` is non-empty
|
|
22
|
+
* (spec.md §4.8: invalid enums / unresolvable core values MUST abort
|
|
23
|
+
* startup). Callers decide when to call this — `loadConfig` itself never
|
|
24
|
+
* throws for either warnings or errors, so a caller can inspect both lists
|
|
25
|
+
* first (e.g. to print them) before deciding to abort.
|
|
26
|
+
*/
|
|
27
|
+
export declare function assertConfigValid(errors: readonly ConfigIssue[]): void;
|
|
28
|
+
/**
|
|
29
|
+
* Pre-upsert dimension check (spec.md §4.8: "Falsch konfigurierte Dimensionen
|
|
30
|
+
* MÜSSEN vor dem ersten Index-Upsert erkannt werden."). Callers invoke this
|
|
31
|
+
* with the configured `embeddings.dimensions` and the dimension already
|
|
32
|
+
* committed to an existing Qdrant collection (from `MetadataStore`/
|
|
33
|
+
* `VectorStore` introspection) before ANY upsert into that collection.
|
|
34
|
+
*/
|
|
35
|
+
export declare function assertEmbeddingDimensionsMatch(configuredDimensions: number, existingCollectionDimensions: number | undefined): void;
|
|
36
|
+
//# sourceMappingURL=validate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"AAeA,MAAM,WAAW,WAAW;IAC1B,sFAAsF;IACtF,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,oEAAoE;IACpE,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,QAAQ,EAAE,WAAW,EAAE,CAAC;CACzB;AAkJD;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,gBAAgB,CA0MzF;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,WAAW,EAAE,GAAG,IAAI,CAatE;AAED;;;;;;GAMG;AACH,wBAAgB,8BAA8B,CAC5C,oBAAoB,EAAE,MAAM,EAC5B,4BAA4B,EAAE,MAAM,GAAG,SAAS,GAC/C,IAAI,CAcN"}
|