@yourtechtribe-labs/koncept-core 0.1.0-alpha.6 → 0.2.0-alpha.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/README.md +1 -1
- package/dist/affected.d.ts +62 -0
- package/dist/affected.d.ts.map +1 -0
- package/dist/affected.js +134 -0
- package/dist/affected.js.map +1 -0
- package/dist/index.d.ts +6 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/indexer.d.ts.map +1 -1
- package/dist/indexer.js +2 -1
- package/dist/indexer.js.map +1 -1
- package/dist/schema.d.ts +66 -3
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +32 -2
- package/dist/schema.js.map +1 -1
- package/dist/suggest-links.d.ts +24 -0
- package/dist/suggest-links.d.ts.map +1 -0
- package/dist/suggest-links.js +72 -0
- package/dist/suggest-links.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> Core schema, parser, and indexer for [koncepto](https://github.com/yourtechtribe-labs/koncept-mcp) — semantic concept graphs for codebases.
|
|
4
4
|
|
|
5
|
-
**Status**: pre-alpha (`v0.
|
|
5
|
+
**Status**: pre-alpha (`v0.2.0-alpha.0`).
|
|
6
6
|
|
|
7
7
|
## What this package contains
|
|
8
8
|
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Impact analysis — given a list of changed files, report which concepts and
|
|
3
|
+
* invariants are touched. Pure function over already-loaded Concept[]; the
|
|
4
|
+
* caller (CLI / MCP tool) is responsible for fetching concepts and the diff.
|
|
5
|
+
*
|
|
6
|
+
* Path comparison is forward-slash + lowercase (NTFS is case-insensitive; git
|
|
7
|
+
* on `core.ignorecase=true` may surface either case). Matching is exact after
|
|
8
|
+
* normalization — no glob, no prefix.
|
|
9
|
+
*/
|
|
10
|
+
import type { AutomatedCheck, Concept, ConceptType, Role, Severity } from './schema.js';
|
|
11
|
+
export type MatchedRole = Role | 'source_of_truth';
|
|
12
|
+
export interface AffectedInvariant {
|
|
13
|
+
concept_id: string;
|
|
14
|
+
concept_name: string;
|
|
15
|
+
invariant_id: string;
|
|
16
|
+
description: string;
|
|
17
|
+
severity: Severity;
|
|
18
|
+
check: AutomatedCheck;
|
|
19
|
+
}
|
|
20
|
+
export interface AffectedConcept {
|
|
21
|
+
id: string;
|
|
22
|
+
name: string;
|
|
23
|
+
type: ConceptType;
|
|
24
|
+
matched_files: Array<{
|
|
25
|
+
file: string;
|
|
26
|
+
role: MatchedRole;
|
|
27
|
+
}>;
|
|
28
|
+
other_participants: string[];
|
|
29
|
+
invariants: AffectedInvariant[];
|
|
30
|
+
max_severity: Severity | null;
|
|
31
|
+
}
|
|
32
|
+
export interface AffectedReport {
|
|
33
|
+
changed_files: string[];
|
|
34
|
+
concepts: AffectedConcept[];
|
|
35
|
+
unmatched_files: string[];
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Extracts the bare ids from `related_concepts`, normalizing the union
|
|
39
|
+
* (string | {id, type}). Single point of access so future schema evolution
|
|
40
|
+
* (e.g. removing the bare-string form) only touches this function.
|
|
41
|
+
*/
|
|
42
|
+
export declare function resolveRelatedIds(concept: Concept): string[];
|
|
43
|
+
/**
|
|
44
|
+
* Pure computation: which concepts are touched by `changedFiles`?
|
|
45
|
+
*/
|
|
46
|
+
export declare function computeAffected(concepts: Concept[], changedFiles: string[]): AffectedReport;
|
|
47
|
+
/**
|
|
48
|
+
* Convenience loader: parse every YAML under `.koncept/concepts/` and return
|
|
49
|
+
* the valid Concept[] plus any parse errors. CLI/MCP server uses this when
|
|
50
|
+
* they don't already have a parsed list (otherwise call `computeAffected`
|
|
51
|
+
* directly with the concepts they hold).
|
|
52
|
+
*/
|
|
53
|
+
export interface LoadConceptsResult {
|
|
54
|
+
concepts: Concept[];
|
|
55
|
+
parseErrors: Array<{
|
|
56
|
+
filePath: string;
|
|
57
|
+
message: string;
|
|
58
|
+
field?: string;
|
|
59
|
+
}>;
|
|
60
|
+
}
|
|
61
|
+
export declare function loadConcepts(rootDir: string): Promise<LoadConceptsResult>;
|
|
62
|
+
//# sourceMappingURL=affected.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"affected.d.ts","sourceRoot":"","sources":["../src/affected.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,OAAO,KAAK,EACV,cAAc,EACd,OAAO,EACP,WAAW,EACX,IAAI,EACJ,QAAQ,EACT,MAAM,aAAa,CAAA;AAEpB,MAAM,MAAM,WAAW,GAAG,IAAI,GAAG,iBAAiB,CAAA;AAElD,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAA;IAClB,YAAY,EAAE,MAAM,CAAA;IACpB,YAAY,EAAE,MAAM,CAAA;IACpB,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,QAAQ,CAAA;IAClB,KAAK,EAAE,cAAc,CAAA;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,WAAW,CAAA;IACjB,aAAa,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,WAAW,CAAA;KAAE,CAAC,CAAA;IACzD,kBAAkB,EAAE,MAAM,EAAE,CAAA;IAC5B,UAAU,EAAE,iBAAiB,EAAE,CAAA;IAC/B,YAAY,EAAE,QAAQ,GAAG,IAAI,CAAA;CAC9B;AAED,MAAM,WAAW,cAAc;IAC7B,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB,QAAQ,EAAE,eAAe,EAAE,CAAA;IAC3B,eAAe,EAAE,MAAM,EAAE,CAAA;CAC1B;AAQD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,EAAE,CAE5D;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,OAAO,EAAE,EACnB,YAAY,EAAE,MAAM,EAAE,GACrB,cAAc,CAkBhB;AAsFD;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,OAAO,EAAE,CAAA;IACnB,WAAW,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAC1E;AAID,wBAAsB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAoB/E"}
|
package/dist/affected.js
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Impact analysis — given a list of changed files, report which concepts and
|
|
3
|
+
* invariants are touched. Pure function over already-loaded Concept[]; the
|
|
4
|
+
* caller (CLI / MCP tool) is responsible for fetching concepts and the diff.
|
|
5
|
+
*
|
|
6
|
+
* Path comparison is forward-slash + lowercase (NTFS is case-insensitive; git
|
|
7
|
+
* on `core.ignorecase=true` may surface either case). Matching is exact after
|
|
8
|
+
* normalization — no glob, no prefix.
|
|
9
|
+
*/
|
|
10
|
+
import { glob } from 'glob';
|
|
11
|
+
import { parseConceptFile } from './parser.js';
|
|
12
|
+
import { normalizeForward } from './paths.js';
|
|
13
|
+
const SEVERITY_RANK = { high: 3, medium: 2, low: 1 };
|
|
14
|
+
function normalizeKey(p) {
|
|
15
|
+
return normalizeForward(p).toLowerCase();
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Extracts the bare ids from `related_concepts`, normalizing the union
|
|
19
|
+
* (string | {id, type}). Single point of access so future schema evolution
|
|
20
|
+
* (e.g. removing the bare-string form) only touches this function.
|
|
21
|
+
*/
|
|
22
|
+
export function resolveRelatedIds(concept) {
|
|
23
|
+
return concept.related_concepts.map((r) => (typeof r === 'string' ? r : r.id));
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Pure computation: which concepts are touched by `changedFiles`?
|
|
27
|
+
*/
|
|
28
|
+
export function computeAffected(concepts, changedFiles) {
|
|
29
|
+
const normalizedChanged = changedFiles.map(normalizeKey);
|
|
30
|
+
const fileToConcepts = buildFileIndex(concepts);
|
|
31
|
+
const { matched, matchedKeys } = matchChangedFiles(fileToConcepts, changedFiles, normalizedChanged);
|
|
32
|
+
for (const affected of matched.values()) {
|
|
33
|
+
const concept = concepts.find((c) => c.id === affected.id);
|
|
34
|
+
affected.other_participants = computeOtherParticipants(concept, affected);
|
|
35
|
+
}
|
|
36
|
+
const unmatched = changedFiles.filter((_, i) => !matchedKeys.has(normalizedChanged[i]));
|
|
37
|
+
return {
|
|
38
|
+
changed_files: changedFiles.map(normalizeForward),
|
|
39
|
+
concepts: [...matched.values()].sort(byMaxSeverityThenId),
|
|
40
|
+
unmatched_files: unmatched.map(normalizeForward),
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
function buildFileIndex(concepts) {
|
|
44
|
+
const map = new Map();
|
|
45
|
+
for (const concept of concepts) {
|
|
46
|
+
pushFileEntry(map, normalizeKey(concept.source_of_truth.file), concept, 'source_of_truth');
|
|
47
|
+
for (const p of concept.participants) {
|
|
48
|
+
pushFileEntry(map, normalizeKey(p.file), concept, p.role);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return map;
|
|
52
|
+
}
|
|
53
|
+
function matchChangedFiles(fileToConcepts, changedFiles, normalizedChanged) {
|
|
54
|
+
const matched = new Map();
|
|
55
|
+
const matchedKeys = new Set();
|
|
56
|
+
for (let i = 0; i < normalizedChanged.length; i++) {
|
|
57
|
+
const key = normalizedChanged[i];
|
|
58
|
+
const hits = fileToConcepts.get(key);
|
|
59
|
+
if (!hits)
|
|
60
|
+
continue;
|
|
61
|
+
matchedKeys.add(key);
|
|
62
|
+
for (const { concept, role } of hits) {
|
|
63
|
+
const existing = matched.get(concept.id) ?? makeAffected(concept);
|
|
64
|
+
const dup = existing.matched_files.some((m) => normalizeKey(m.file) === key && m.role === role);
|
|
65
|
+
if (!dup)
|
|
66
|
+
existing.matched_files.push({ file: normalizeForward(changedFiles[i]), role });
|
|
67
|
+
matched.set(concept.id, existing);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return { matched, matchedKeys };
|
|
71
|
+
}
|
|
72
|
+
function computeOtherParticipants(concept, affected) {
|
|
73
|
+
const all = new Set(concept.participants.map((p) => normalizeForward(p.file)));
|
|
74
|
+
all.add(normalizeForward(concept.source_of_truth.file));
|
|
75
|
+
const matchedSet = new Set(affected.matched_files.map((m) => normalizeKey(m.file)));
|
|
76
|
+
return [...all].filter((f) => !matchedSet.has(f.toLowerCase())).sort();
|
|
77
|
+
}
|
|
78
|
+
function pushFileEntry(map, key, concept, role) {
|
|
79
|
+
const list = map.get(key) ?? [];
|
|
80
|
+
list.push({ concept, role });
|
|
81
|
+
map.set(key, list);
|
|
82
|
+
}
|
|
83
|
+
function makeAffected(concept) {
|
|
84
|
+
const invariants = concept.invariants.map((inv) => ({
|
|
85
|
+
concept_id: concept.id,
|
|
86
|
+
concept_name: concept.name,
|
|
87
|
+
invariant_id: inv.id,
|
|
88
|
+
description: inv.description,
|
|
89
|
+
severity: inv.severity,
|
|
90
|
+
check: inv.check,
|
|
91
|
+
}));
|
|
92
|
+
invariants.sort((a, b) => SEVERITY_RANK[b.severity] - SEVERITY_RANK[a.severity]);
|
|
93
|
+
const maxSev = invariants.length > 0 ? invariants[0].severity : null;
|
|
94
|
+
return {
|
|
95
|
+
id: concept.id,
|
|
96
|
+
name: concept.name,
|
|
97
|
+
type: concept.type,
|
|
98
|
+
matched_files: [],
|
|
99
|
+
other_participants: [],
|
|
100
|
+
invariants,
|
|
101
|
+
max_severity: maxSev,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
function byMaxSeverityThenId(a, b) {
|
|
105
|
+
const av = a.max_severity ? SEVERITY_RANK[a.max_severity] : 0;
|
|
106
|
+
const bv = b.max_severity ? SEVERITY_RANK[b.max_severity] : 0;
|
|
107
|
+
if (av !== bv)
|
|
108
|
+
return bv - av;
|
|
109
|
+
return a.id.localeCompare(b.id);
|
|
110
|
+
}
|
|
111
|
+
const CONCEPTS_GLOB = '.koncept/concepts/*.yaml';
|
|
112
|
+
export async function loadConcepts(rootDir) {
|
|
113
|
+
const files = await glob(CONCEPTS_GLOB, {
|
|
114
|
+
cwd: rootDir,
|
|
115
|
+
absolute: true,
|
|
116
|
+
nodir: true,
|
|
117
|
+
posix: true,
|
|
118
|
+
});
|
|
119
|
+
const parsed = await Promise.all(files.map((f) => parseConceptFile(f)));
|
|
120
|
+
const concepts = [];
|
|
121
|
+
const parseErrors = [];
|
|
122
|
+
for (const r of parsed) {
|
|
123
|
+
if (r.concept !== null) {
|
|
124
|
+
concepts.push(r.concept);
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
for (const e of r.errors) {
|
|
128
|
+
parseErrors.push({ filePath: r.filePath, message: e.message, field: e.field });
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return { concepts, parseErrors };
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=affected.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"affected.js","sourceRoot":"","sources":["../src/affected.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
export { VERSION } from './version.js';
|
|
2
|
-
export { ConceptSchema, IndexEntrySchema, RoleEnum, ConceptTypeEnum, SeverityEnum, StatusEnum, } from './schema.js';
|
|
3
|
-
export type { Concept, IndexEntry, Participant, Invariant, SourceOfTruth, Role, ConceptType, Severity, Status, } from './schema.js';
|
|
2
|
+
export { ConceptSchema, IndexEntrySchema, RoleEnum, ConceptTypeEnum, SeverityEnum, StatusEnum, AutomatedCheckSchema, LinkTypeEnum, LinkRefSchema, } from './schema.js';
|
|
3
|
+
export type { Concept, IndexEntry, Participant, Invariant, SourceOfTruth, Role, ConceptType, Severity, Status, AutomatedCheck, LinkType, LinkRef, } from './schema.js';
|
|
4
4
|
export { parseConceptString, parseConceptFile } from './parser.js';
|
|
5
5
|
export type { ParseResult, ParseError, ParseErrorType } from './parser.js';
|
|
6
6
|
export { indexConcepts, writeIndex, isIndexClean } from './indexer.js';
|
|
7
7
|
export type { IndexResult, IndexErrorEntry, DuplicateId, UnresolvedRelated, MissingFile, } from './indexer.js';
|
|
8
8
|
export { searchEntries } from './search.js';
|
|
9
9
|
export type { SearchHit, MatchField } from './search.js';
|
|
10
|
+
export { computeAffected, loadConcepts, resolveRelatedIds } from './affected.js';
|
|
11
|
+
export type { AffectedReport, AffectedConcept, AffectedInvariant, MatchedRole, LoadConceptsResult, } from './affected.js';
|
|
12
|
+
export { suggestLinks } from './suggest-links.js';
|
|
13
|
+
export type { LinkSuggestion, SuggestLinksOptions } from './suggest-links.js';
|
|
10
14
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAItC,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,QAAQ,EACR,eAAe,EACf,YAAY,EACZ,UAAU,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAItC,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,QAAQ,EACR,eAAe,EACf,YAAY,EACZ,UAAU,EACV,oBAAoB,EACpB,YAAY,EACZ,aAAa,GACd,MAAM,aAAa,CAAA;AACpB,YAAY,EACV,OAAO,EACP,UAAU,EACV,WAAW,EACX,SAAS,EACT,aAAa,EACb,IAAI,EACJ,WAAW,EACX,QAAQ,EACR,MAAM,EACN,cAAc,EACd,QAAQ,EACR,OAAO,GACR,MAAM,aAAa,CAAA;AAGpB,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAClE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAG1E,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AACtE,YAAY,EACV,WAAW,EACX,eAAe,EACf,WAAW,EACX,iBAAiB,EACjB,WAAW,GACZ,MAAM,cAAc,CAAA;AAGrB,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAGxD,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AAChF,YAAY,EACV,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,WAAW,EACX,kBAAkB,GACnB,MAAM,eAAe,CAAA;AAGtB,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,YAAY,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -4,11 +4,15 @@
|
|
|
4
4
|
export { VERSION } from './version.js';
|
|
5
5
|
// Schema — top-level types + main schemas. Sub-schemas (Participant, Invariant,
|
|
6
6
|
// SourceOfTruth) and the kebab-id regex stay internal.
|
|
7
|
-
export { ConceptSchema, IndexEntrySchema, RoleEnum, ConceptTypeEnum, SeverityEnum, StatusEnum, } from './schema.js';
|
|
7
|
+
export { ConceptSchema, IndexEntrySchema, RoleEnum, ConceptTypeEnum, SeverityEnum, StatusEnum, AutomatedCheckSchema, LinkTypeEnum, LinkRefSchema, } from './schema.js';
|
|
8
8
|
// Parser
|
|
9
9
|
export { parseConceptString, parseConceptFile } from './parser.js';
|
|
10
10
|
// Indexer
|
|
11
11
|
export { indexConcepts, writeIndex, isIndexClean } from './indexer.js';
|
|
12
12
|
// Search
|
|
13
13
|
export { searchEntries } from './search.js';
|
|
14
|
+
// Affected (impact analysis)
|
|
15
|
+
export { computeAffected, loadConcepts, resolveRelatedIds } from './affected.js';
|
|
16
|
+
// Auto-link inference
|
|
17
|
+
export { suggestLinks } from './suggest-links.js';
|
|
14
18
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,iDAAiD;AACjD,uEAAuE;AACvE,4CAA4C;AAE5C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAEtC,gFAAgF;AAChF,uDAAuD;AACvD,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,QAAQ,EACR,eAAe,EACf,YAAY,EACZ,UAAU,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,iDAAiD;AACjD,uEAAuE;AACvE,4CAA4C;AAE5C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAEtC,gFAAgF;AAChF,uDAAuD;AACvD,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,QAAQ,EACR,eAAe,EACf,YAAY,EACZ,UAAU,EACV,oBAAoB,EACpB,YAAY,EACZ,aAAa,GACd,MAAM,aAAa,CAAA;AAgBpB,SAAS;AACT,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAGlE,UAAU;AACV,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAStE,SAAS;AACT,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAG3C,6BAA6B;AAC7B,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AAShF,sBAAsB;AACtB,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA"}
|
package/dist/indexer.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"indexer.d.ts","sourceRoot":"","sources":["../src/indexer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,OAAO,EAAoB,KAAK,UAAU,EAAE,MAAM,aAAa,CAAA;AAE/D,OAAO,KAAK,EAAW,UAAU,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"indexer.d.ts","sourceRoot":"","sources":["../src/indexer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,OAAO,EAAoB,KAAK,UAAU,EAAE,MAAM,aAAa,CAAA;AAE/D,OAAO,KAAK,EAAW,UAAU,EAAE,MAAM,aAAa,CAAA;AAGtD,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,EAAE,CAAA;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAA;IACjB,gBAAgB,EAAE,MAAM,CAAA;CACzB;AAED,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,UAAU,EAAE,CAAA;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,UAAU,EAAE,CAAA;IACrB,MAAM,EAAE,eAAe,EAAE,CAAA;IACzB,YAAY,EAAE,WAAW,EAAE,CAAA;IAC3B,iBAAiB,EAAE,iBAAiB,EAAE,CAAA;IACtC,YAAY,EAAE,WAAW,EAAE,CAAA;CAC5B;AAKD;;;GAGG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAoFzE;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAGtF;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAOzD"}
|
package/dist/indexer.js
CHANGED
|
@@ -13,6 +13,7 @@ import { stat, writeFile } from 'node:fs/promises';
|
|
|
13
13
|
import { join } from 'node:path';
|
|
14
14
|
import { parseConceptFile } from './parser.js';
|
|
15
15
|
import { resolveRelative, normalizeForward } from './paths.js';
|
|
16
|
+
import { resolveRelatedIds } from './affected.js';
|
|
16
17
|
const CONCEPTS_GLOB = '.koncept/concepts/*.yaml';
|
|
17
18
|
const INDEX_FILENAME = '.koncept/index.json';
|
|
18
19
|
/**
|
|
@@ -60,7 +61,7 @@ export async function indexConcepts(rootDir) {
|
|
|
60
61
|
// resolve (the duplicate is reported separately via `duplicateIds`).
|
|
61
62
|
const knownIds = new Set(idToFiles.keys());
|
|
62
63
|
await Promise.all(concepts.map(async ({ concept, filePath }) => {
|
|
63
|
-
for (const relatedId of concept
|
|
64
|
+
for (const relatedId of resolveRelatedIds(concept)) {
|
|
64
65
|
if (!knownIds.has(relatedId)) {
|
|
65
66
|
result.unresolvedRelated.push({
|
|
66
67
|
conceptId: concept.id,
|
package/dist/indexer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"indexer.js","sourceRoot":"","sources":["../src/indexer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAC3B,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,gBAAgB,EAAmB,MAAM,aAAa,CAAA;AAC/D,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"indexer.js","sourceRoot":"","sources":["../src/indexer.ts"],"names":[],"mappings":"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"}
|
package/dist/schema.d.ts
CHANGED
|
@@ -54,6 +54,18 @@ export declare const ParticipantSchema: z.ZodObject<{
|
|
|
54
54
|
purpose: z.ZodString;
|
|
55
55
|
}, z.core.$strip>;
|
|
56
56
|
export type Participant = z.infer<typeof ParticipantSchema>;
|
|
57
|
+
export declare const AutomatedCheckSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
58
|
+
kind: z.ZodLiteral<"none">;
|
|
59
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
60
|
+
kind: z.ZodLiteral<"grep">;
|
|
61
|
+
pattern: z.ZodString;
|
|
62
|
+
in: z.ZodArray<z.ZodString>;
|
|
63
|
+
should_match: z.ZodDefault<z.ZodBoolean>;
|
|
64
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
65
|
+
kind: z.ZodLiteral<"command">;
|
|
66
|
+
cmd: z.ZodString;
|
|
67
|
+
}, z.core.$strip>], "kind">;
|
|
68
|
+
export type AutomatedCheck = z.infer<typeof AutomatedCheckSchema>;
|
|
57
69
|
export declare const InvariantSchema: z.ZodObject<{
|
|
58
70
|
id: z.ZodString;
|
|
59
71
|
description: z.ZodString;
|
|
@@ -62,9 +74,40 @@ export declare const InvariantSchema: z.ZodObject<{
|
|
|
62
74
|
medium: "medium";
|
|
63
75
|
low: "low";
|
|
64
76
|
}>;
|
|
65
|
-
|
|
77
|
+
check: z.ZodDefault<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
78
|
+
kind: z.ZodLiteral<"none">;
|
|
79
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
80
|
+
kind: z.ZodLiteral<"grep">;
|
|
81
|
+
pattern: z.ZodString;
|
|
82
|
+
in: z.ZodArray<z.ZodString>;
|
|
83
|
+
should_match: z.ZodDefault<z.ZodBoolean>;
|
|
84
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
85
|
+
kind: z.ZodLiteral<"command">;
|
|
86
|
+
cmd: z.ZodString;
|
|
87
|
+
}, z.core.$strip>], "kind">>;
|
|
66
88
|
}, z.core.$strip>;
|
|
67
89
|
export type Invariant = z.infer<typeof InvariantSchema>;
|
|
90
|
+
export declare const LinkTypeEnum: z.ZodEnum<{
|
|
91
|
+
extends: "extends";
|
|
92
|
+
refines: "refines";
|
|
93
|
+
"conflicts-with": "conflicts-with";
|
|
94
|
+
"superseded-by": "superseded-by";
|
|
95
|
+
requires: "requires";
|
|
96
|
+
related: "related";
|
|
97
|
+
}>;
|
|
98
|
+
export type LinkType = z.infer<typeof LinkTypeEnum>;
|
|
99
|
+
export declare const LinkRefSchema: z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
100
|
+
id: z.ZodString;
|
|
101
|
+
type: z.ZodDefault<z.ZodEnum<{
|
|
102
|
+
extends: "extends";
|
|
103
|
+
refines: "refines";
|
|
104
|
+
"conflicts-with": "conflicts-with";
|
|
105
|
+
"superseded-by": "superseded-by";
|
|
106
|
+
requires: "requires";
|
|
107
|
+
related: "related";
|
|
108
|
+
}>>;
|
|
109
|
+
}, z.core.$strip>]>;
|
|
110
|
+
export type LinkRef = z.infer<typeof LinkRefSchema>;
|
|
68
111
|
export declare const ConceptSchema: z.ZodObject<{
|
|
69
112
|
id: z.ZodString;
|
|
70
113
|
name: z.ZodString;
|
|
@@ -103,10 +146,30 @@ export declare const ConceptSchema: z.ZodObject<{
|
|
|
103
146
|
medium: "medium";
|
|
104
147
|
low: "low";
|
|
105
148
|
}>;
|
|
106
|
-
|
|
149
|
+
check: z.ZodDefault<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
150
|
+
kind: z.ZodLiteral<"none">;
|
|
151
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
152
|
+
kind: z.ZodLiteral<"grep">;
|
|
153
|
+
pattern: z.ZodString;
|
|
154
|
+
in: z.ZodArray<z.ZodString>;
|
|
155
|
+
should_match: z.ZodDefault<z.ZodBoolean>;
|
|
156
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
157
|
+
kind: z.ZodLiteral<"command">;
|
|
158
|
+
cmd: z.ZodString;
|
|
159
|
+
}, z.core.$strip>], "kind">>;
|
|
107
160
|
}, z.core.$strip>>>;
|
|
108
161
|
risks_if_broken: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
109
|
-
related_concepts: z.ZodDefault<z.ZodArray<z.ZodString
|
|
162
|
+
related_concepts: z.ZodDefault<z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
163
|
+
id: z.ZodString;
|
|
164
|
+
type: z.ZodDefault<z.ZodEnum<{
|
|
165
|
+
extends: "extends";
|
|
166
|
+
refines: "refines";
|
|
167
|
+
"conflicts-with": "conflicts-with";
|
|
168
|
+
"superseded-by": "superseded-by";
|
|
169
|
+
requires: "requires";
|
|
170
|
+
related: "related";
|
|
171
|
+
}>>;
|
|
172
|
+
}, z.core.$strip>]>>>;
|
|
110
173
|
tags: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
111
174
|
created: z.ZodString;
|
|
112
175
|
last_updated: z.ZodString;
|
package/dist/schema.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAIvB;;;;GAIG;AACH,eAAO,MAAM,cAAc,QAAsB,CAAA;AAQjD,eAAO,MAAM,QAAQ;;;;;EAAiD,CAAA;AACtE,MAAM,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,QAAQ,CAAC,CAAA;AAE3C,eAAO,MAAM,eAAe;;;;;;EAM1B,CAAA;AACF,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAA;AAEzD,eAAO,MAAM,YAAY;;;;EAAoC,CAAA;AAC7D,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAA;AAEnD,eAAO,MAAM,UAAU;;;;EAAiD,CAAA;AACxE,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAA;AAI/C,eAAO,MAAM,mBAAmB;;;iBAG9B,CAAA;AACF,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAA;AAE/D,eAAO,MAAM,iBAAiB;;;;;;;;;iBAI5B,CAAA;AACF,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAIvB;;;;GAIG;AACH,eAAO,MAAM,cAAc,QAAsB,CAAA;AAQjD,eAAO,MAAM,QAAQ;;;;;EAAiD,CAAA;AACtE,MAAM,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,QAAQ,CAAC,CAAA;AAE3C,eAAO,MAAM,eAAe;;;;;;EAM1B,CAAA;AACF,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAA;AAEzD,eAAO,MAAM,YAAY;;;;EAAoC,CAAA;AAC7D,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAA;AAEnD,eAAO,MAAM,UAAU;;;;EAAiD,CAAA;AACxE,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAA;AAI/C,eAAO,MAAM,mBAAmB;;;iBAG9B,CAAA;AACF,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAA;AAE/D,eAAO,MAAM,iBAAiB;;;;;;;;;iBAI5B,CAAA;AACF,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAA;AAM3D,eAAO,MAAM,oBAAoB;;;;;;;;;;2BAY/B,CAAA;AACF,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAA;AAEjE,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;iBAK1B,CAAA;AACF,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAA;AAIvD,eAAO,MAAM,YAAY;;;;;;;EAOvB,CAAA;AACF,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAA;AAEnD,eAAO,MAAM,aAAa;;;;;;;;;;mBAGxB,CAAA;AACF,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAA;AAInD,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAoBxB,CAAA;AACF,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAA;AAInD,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;iBAQ3B,CAAA;AACF,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAA"}
|
package/dist/schema.js
CHANGED
|
@@ -36,12 +36,42 @@ export const ParticipantSchema = z.object({
|
|
|
36
36
|
role: RoleEnum,
|
|
37
37
|
purpose: z.string().min(1),
|
|
38
38
|
});
|
|
39
|
+
// AutomatedCheck — discriminated union describing HOW (if at all) the
|
|
40
|
+
// invariant is verified. `kind: none` = manual reviewer (default).
|
|
41
|
+
// `kind: grep` = regex over participant files. `kind: command` = escape hatch
|
|
42
|
+
// running an arbitrary shell command (the runner decides safety policy).
|
|
43
|
+
export const AutomatedCheckSchema = z.discriminatedUnion('kind', [
|
|
44
|
+
z.object({ kind: z.literal('none') }),
|
|
45
|
+
z.object({
|
|
46
|
+
kind: z.literal('grep'),
|
|
47
|
+
pattern: z.string().min(1),
|
|
48
|
+
in: z.array(z.string().min(1)).min(1),
|
|
49
|
+
should_match: z.boolean().default(true),
|
|
50
|
+
}),
|
|
51
|
+
z.object({
|
|
52
|
+
kind: z.literal('command'),
|
|
53
|
+
cmd: z.string().min(1),
|
|
54
|
+
}),
|
|
55
|
+
]);
|
|
39
56
|
export const InvariantSchema = z.object({
|
|
40
57
|
id: KebabId,
|
|
41
58
|
description: z.string().min(1),
|
|
42
59
|
severity: SeverityEnum,
|
|
43
|
-
|
|
60
|
+
check: AutomatedCheckSchema.default({ kind: 'none' }),
|
|
44
61
|
});
|
|
62
|
+
// ─── Related concepts (typed links) ──────────────────────────────────────────
|
|
63
|
+
export const LinkTypeEnum = z.enum([
|
|
64
|
+
'extends',
|
|
65
|
+
'refines',
|
|
66
|
+
'conflicts-with',
|
|
67
|
+
'superseded-by',
|
|
68
|
+
'requires',
|
|
69
|
+
'related',
|
|
70
|
+
]);
|
|
71
|
+
export const LinkRefSchema = z.union([
|
|
72
|
+
KebabId,
|
|
73
|
+
z.object({ id: KebabId, type: LinkTypeEnum.default('related') }),
|
|
74
|
+
]);
|
|
45
75
|
// ─── Concept (top-level) ─────────────────────────────────────────────────────
|
|
46
76
|
export const ConceptSchema = z.object({
|
|
47
77
|
id: KebabId,
|
|
@@ -53,7 +83,7 @@ export const ConceptSchema = z.object({
|
|
|
53
83
|
participants: z.array(ParticipantSchema).default([]),
|
|
54
84
|
invariants: z.array(InvariantSchema).default([]),
|
|
55
85
|
risks_if_broken: z.array(z.string().min(1)).default([]),
|
|
56
|
-
related_concepts: z.array(
|
|
86
|
+
related_concepts: z.array(LinkRefSchema).default([]),
|
|
57
87
|
tags: z.array(z.string().min(1)).default([]),
|
|
58
88
|
// Provenance
|
|
59
89
|
created: z.string().min(1),
|
package/dist/schema.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,gFAAgF;AAEhF;;;;GAIG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,mBAAmB,CAAA;AAEjD,MAAM,OAAO,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,cAAc,EAAE;IAC/C,OAAO,EAAE,gEAAgE;CAC1E,CAAC,CAAA;AAEF,gFAAgF;AAEhF,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAA;AAGtE,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,IAAI,CAAC;IACpC,sBAAsB;IACtB,wBAAwB;IACxB,WAAW;IACX,YAAY;IACZ,mBAAmB;CACpB,CAAC,CAAA;AAGF,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAA;AAG7D,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,YAAY,EAAE,YAAY,CAAC,CAAC,CAAA;AAGxE,gFAAgF;AAEhF,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1C,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IACpC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;CACxB,CAAC,CAAA;AAGF,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACvB,IAAI,EAAE,QAAQ;IACd,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;CAC3B,CAAC,CAAA;AAGF,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC;IACtC,EAAE,EAAE,OAAO;IACX,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9B,QAAQ,EAAE,YAAY;IACtB,
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-link inference — surface candidate `related_concepts` based on
|
|
3
|
+
* objective signals: shared participants (including source_of_truth) and
|
|
4
|
+
* shared tags. Suggestions only; never mutates concepts.
|
|
5
|
+
*
|
|
6
|
+
* Already-linked pairs (a→b OR b→a in `related_concepts`) are excluded so
|
|
7
|
+
* the user is never reminded of links they have already curated.
|
|
8
|
+
*/
|
|
9
|
+
import type { Concept } from './schema.js';
|
|
10
|
+
export interface SuggestLinksOptions {
|
|
11
|
+
/** Minimum shared tags to count tag-only suggestion (default 2). */
|
|
12
|
+
minSharedTags?: number;
|
|
13
|
+
}
|
|
14
|
+
export interface LinkSuggestion {
|
|
15
|
+
/** Lexicographically ordered (a.id < b.id) for canonical pairs. */
|
|
16
|
+
a: string;
|
|
17
|
+
b: string;
|
|
18
|
+
shared_participants: string[];
|
|
19
|
+
shared_tags: string[];
|
|
20
|
+
/** Higher = stronger candidate. Participants weight 2, tags weight 1. */
|
|
21
|
+
score: number;
|
|
22
|
+
}
|
|
23
|
+
export declare function suggestLinks(concepts: Concept[], opts?: SuggestLinksOptions): LinkSuggestion[];
|
|
24
|
+
//# sourceMappingURL=suggest-links.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"suggest-links.d.ts","sourceRoot":"","sources":["../src/suggest-links.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAE1C,MAAM,WAAW,mBAAmB;IAClC,oEAAoE;IACpE,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B,mEAAmE;IACnE,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;IACT,mBAAmB,EAAE,MAAM,EAAE,CAAA;IAC7B,WAAW,EAAE,MAAM,EAAE,CAAA;IACrB,yEAAyE;IACzE,KAAK,EAAE,MAAM,CAAA;CACd;AAID,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,OAAO,EAAE,EACnB,IAAI,GAAE,mBAAwB,GAC7B,cAAc,EAAE,CA6BlB"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-link inference — surface candidate `related_concepts` based on
|
|
3
|
+
* objective signals: shared participants (including source_of_truth) and
|
|
4
|
+
* shared tags. Suggestions only; never mutates concepts.
|
|
5
|
+
*
|
|
6
|
+
* Already-linked pairs (a→b OR b→a in `related_concepts`) are excluded so
|
|
7
|
+
* the user is never reminded of links they have already curated.
|
|
8
|
+
*/
|
|
9
|
+
import { normalizeForward } from './paths.js';
|
|
10
|
+
import { resolveRelatedIds } from './affected.js';
|
|
11
|
+
const DEFAULT_MIN_SHARED_TAGS = 2;
|
|
12
|
+
export function suggestLinks(concepts, opts = {}) {
|
|
13
|
+
const minTags = opts.minSharedTags ?? DEFAULT_MIN_SHARED_TAGS;
|
|
14
|
+
const fileSets = concepts.map(filesOf);
|
|
15
|
+
const tagSets = concepts.map((c) => new Set(c.tags));
|
|
16
|
+
const linkedPairs = buildLinkedPairs(concepts);
|
|
17
|
+
const suggestions = [];
|
|
18
|
+
for (let i = 0; i < concepts.length; i++) {
|
|
19
|
+
for (let j = i + 1; j < concepts.length; j++) {
|
|
20
|
+
const a = concepts[i];
|
|
21
|
+
const b = concepts[j];
|
|
22
|
+
if (linkedPairs.has(pairKey(a.id, b.id)))
|
|
23
|
+
continue;
|
|
24
|
+
const sharedFiles = intersectSorted(fileSets[i], fileSets[j]);
|
|
25
|
+
const sharedTags = intersectSorted(tagSets[i], tagSets[j]);
|
|
26
|
+
if (sharedFiles.length === 0 && sharedTags.length < minTags)
|
|
27
|
+
continue;
|
|
28
|
+
suggestions.push({
|
|
29
|
+
a: a.id < b.id ? a.id : b.id,
|
|
30
|
+
b: a.id < b.id ? b.id : a.id,
|
|
31
|
+
shared_participants: sharedFiles,
|
|
32
|
+
shared_tags: sharedTags,
|
|
33
|
+
score: sharedFiles.length * 2 + sharedTags.length,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return suggestions.sort((x, y) => {
|
|
38
|
+
if (x.score !== y.score)
|
|
39
|
+
return y.score - x.score;
|
|
40
|
+
if (x.a !== y.a)
|
|
41
|
+
return x.a.localeCompare(y.a);
|
|
42
|
+
return x.b.localeCompare(y.b);
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
function filesOf(c) {
|
|
46
|
+
const set = new Set();
|
|
47
|
+
set.add(normalizeForward(c.source_of_truth.file).toLowerCase());
|
|
48
|
+
for (const p of c.participants) {
|
|
49
|
+
set.add(normalizeForward(p.file).toLowerCase());
|
|
50
|
+
}
|
|
51
|
+
return set;
|
|
52
|
+
}
|
|
53
|
+
function buildLinkedPairs(concepts) {
|
|
54
|
+
const set = new Set();
|
|
55
|
+
for (const c of concepts) {
|
|
56
|
+
for (const related of resolveRelatedIds(c)) {
|
|
57
|
+
set.add(pairKey(c.id, related));
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return set;
|
|
61
|
+
}
|
|
62
|
+
function pairKey(a, b) {
|
|
63
|
+
return a < b ? `${a}|${b}` : `${b}|${a}`;
|
|
64
|
+
}
|
|
65
|
+
function intersectSorted(a, b) {
|
|
66
|
+
const out = [];
|
|
67
|
+
for (const v of a)
|
|
68
|
+
if (b.has(v))
|
|
69
|
+
out.push(v);
|
|
70
|
+
return out.sort();
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=suggest-links.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"suggest-links.js","sourceRoot":"","sources":["../src/suggest-links.ts"],"names":[],"mappings":"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"}
|