@codeledger/selector 0.2.0 → 0.5.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/dist/bundle-invalidation.d.ts +33 -0
- package/dist/bundle-invalidation.d.ts.map +1 -0
- package/dist/bundle-invalidation.js +98 -0
- package/dist/bundle-invalidation.js.map +1 -0
- package/dist/bundle.d.ts.map +1 -1
- package/dist/bundle.js +16 -4
- package/dist/bundle.js.map +1 -1
- package/dist/candidates.d.ts +18 -0
- package/dist/candidates.d.ts.map +1 -1
- package/dist/candidates.js +76 -2
- package/dist/candidates.js.map +1 -1
- package/dist/confidence.d.ts +2 -2
- package/dist/confidence.d.ts.map +1 -1
- package/dist/confidence.js +118 -2
- package/dist/confidence.js.map +1 -1
- package/dist/conflict-zones.d.ts +18 -0
- package/dist/conflict-zones.d.ts.map +1 -0
- package/dist/conflict-zones.js +66 -0
- package/dist/conflict-zones.js.map +1 -0
- package/dist/debt-detection.d.ts +15 -0
- package/dist/debt-detection.d.ts.map +1 -0
- package/dist/debt-detection.js +80 -0
- package/dist/debt-detection.js.map +1 -0
- package/dist/index.d.ts +18 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -1
- package/dist/index.js.map +1 -1
- package/dist/intent/drift.d.ts +31 -0
- package/dist/intent/drift.d.ts.map +1 -0
- package/dist/intent/drift.js +120 -0
- package/dist/intent/drift.js.map +1 -0
- package/dist/intent/hash.d.ts +19 -0
- package/dist/intent/hash.d.ts.map +1 -0
- package/dist/intent/hash.js +38 -0
- package/dist/intent/hash.js.map +1 -0
- package/dist/intent/index.d.ts +5 -0
- package/dist/intent/index.d.ts.map +1 -0
- package/dist/intent/index.js +4 -0
- package/dist/intent/index.js.map +1 -0
- package/dist/intent/normalize.d.ts +23 -0
- package/dist/intent/normalize.d.ts.map +1 -0
- package/dist/intent/normalize.js +35 -0
- package/dist/intent/normalize.js.map +1 -0
- package/dist/intent/types.d.ts +37 -0
- package/dist/intent/types.d.ts.map +1 -0
- package/dist/intent/types.js +2 -0
- package/dist/intent/types.js.map +1 -0
- package/dist/knowledge-bundle.d.ts +41 -0
- package/dist/knowledge-bundle.d.ts.map +1 -0
- package/dist/knowledge-bundle.js +200 -0
- package/dist/knowledge-bundle.js.map +1 -0
- package/dist/knowledge-candidates.d.ts +27 -0
- package/dist/knowledge-candidates.d.ts.map +1 -0
- package/dist/knowledge-candidates.js +123 -0
- package/dist/knowledge-candidates.js.map +1 -0
- package/dist/knowledge-excerpt.d.ts +26 -0
- package/dist/knowledge-excerpt.d.ts.map +1 -0
- package/dist/knowledge-excerpt.js +179 -0
- package/dist/knowledge-excerpt.js.map +1 -0
- package/dist/knowledge-scorer.d.ts +33 -0
- package/dist/knowledge-scorer.d.ts.map +1 -0
- package/dist/knowledge-scorer.js +234 -0
- package/dist/knowledge-scorer.js.map +1 -0
- package/dist/loop-detection.d.ts +28 -0
- package/dist/loop-detection.d.ts.map +1 -0
- package/dist/loop-detection.js +124 -0
- package/dist/loop-detection.js.map +1 -0
- package/dist/mode-detect.d.ts +23 -0
- package/dist/mode-detect.d.ts.map +1 -0
- package/dist/mode-detect.js +76 -0
- package/dist/mode-detect.js.map +1 -0
- package/dist/scope-contract.d.ts +26 -0
- package/dist/scope-contract.d.ts.map +1 -0
- package/dist/scope-contract.js +79 -0
- package/dist/scope-contract.js.map +1 -0
- package/dist/scorer.d.ts.map +1 -1
- package/dist/scorer.js +21 -2
- package/dist/scorer.js.map +1 -1
- package/dist/security-surface.d.ts +13 -0
- package/dist/security-surface.d.ts.map +1 -0
- package/dist/security-surface.js +45 -0
- package/dist/security-surface.js.map +1 -0
- package/dist/task-type.d.ts.map +1 -1
- package/dist/task-type.js +4 -2
- package/dist/task-type.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalize.js","sourceRoot":"","sources":["../../src/intent/normalize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH;;GAEG;AACH,MAAM,UAAU,IAAI,CAAC,CAAS;IAC5B,OAAO,CAAC;SACL,IAAI,EAAE;SACN,WAAW,EAAE;SACb,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,+DAA+D;SACnF,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,gDAAgD;SACxE,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC,0DAA0D;SACrF,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;SACpB,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,oBAAoB;AAC9C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,OAAO,CAAC,EAAY;IAClC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;IAClD,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;AAChC,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { AddressedFile, BundleInvalidationReport } from '@codeledger/types';
|
|
2
|
+
/** Structured, normalized representation of the session's objective */
|
|
3
|
+
export interface TaskContractV1 {
|
|
4
|
+
version: 1;
|
|
5
|
+
objective: string;
|
|
6
|
+
deliverable: string | null;
|
|
7
|
+
scope_in: string[];
|
|
8
|
+
scope_out: string[];
|
|
9
|
+
constraints: string[];
|
|
10
|
+
acceptance_criteria: string[];
|
|
11
|
+
risk_flags: string[];
|
|
12
|
+
repo_paths_in_scope: string[];
|
|
13
|
+
timestamp: string;
|
|
14
|
+
}
|
|
15
|
+
export type DriftLevel = 'NONE' | 'MINOR' | 'MAJOR' | 'CRITICAL';
|
|
16
|
+
export interface DriftReason {
|
|
17
|
+
field: keyof Omit<TaskContractV1, 'version' | 'timestamp'>;
|
|
18
|
+
distance: number;
|
|
19
|
+
}
|
|
20
|
+
export interface DriftResult {
|
|
21
|
+
drift_score: number;
|
|
22
|
+
drift_level: DriftLevel;
|
|
23
|
+
reasons: DriftReason[];
|
|
24
|
+
}
|
|
25
|
+
/** Event record written to intent_drift.jsonl */
|
|
26
|
+
export interface IntentDriftEvent {
|
|
27
|
+
ts: string;
|
|
28
|
+
type: 'INTENT_DRIFT';
|
|
29
|
+
baseline_hash: string;
|
|
30
|
+
current_hash: string;
|
|
31
|
+
drift_score: number;
|
|
32
|
+
drift_level: DriftLevel;
|
|
33
|
+
reasons: DriftReason[];
|
|
34
|
+
recommended_action: 'NONE' | 'LOG_ONLY' | 'REFRESH_BUNDLE' | 'REQUIRE_ACK';
|
|
35
|
+
}
|
|
36
|
+
export type { AddressedFile, BundleInvalidationReport, };
|
|
37
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/intent/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAIjF,uEAAuE;AACvE,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,CAAC,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,UAAU,CAAC;AAEjE,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,IAAI,CAAC,cAAc,EAAE,SAAS,GAAG,WAAW,CAAC,CAAC;IAC3D,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,UAAU,CAAC;IACxB,OAAO,EAAE,WAAW,EAAE,CAAC;CACxB;AAED,iDAAiD;AACjD,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,cAAc,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,UAAU,CAAC;IACxB,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,kBAAkB,EAAE,MAAM,GAAG,UAAU,GAAG,gBAAgB,GAAG,aAAa,CAAC;CAC5E;AAGD,YAAY,EACV,aAAa,EACb,wBAAwB,GACzB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/intent/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Knowledge-mode bundle builder.
|
|
3
|
+
*
|
|
4
|
+
* Produces a CoworkBundle (context-bundle.json schema) using:
|
|
5
|
+
* - Knowledge-mode candidate generation
|
|
6
|
+
* - Knowledge-mode scoring (7 signals)
|
|
7
|
+
* - Existing stop-rule logic (reused)
|
|
8
|
+
* - Knowledge-mode excerpt extraction (head+headers)
|
|
9
|
+
*/
|
|
10
|
+
import type { CoworkBundle, KnowledgeScoredFile, KnowledgeWeights, WorkspaceIndex } from '@codeledger/types';
|
|
11
|
+
export interface KnowledgeBundleOptions {
|
|
12
|
+
intentText: string;
|
|
13
|
+
workspaceIndex: WorkspaceIndex;
|
|
14
|
+
weights?: KnowledgeWeights;
|
|
15
|
+
maxFiles?: number;
|
|
16
|
+
maxTokensEst?: number;
|
|
17
|
+
maxBytesEst?: number;
|
|
18
|
+
sufficiencyThreshold?: number;
|
|
19
|
+
excerptMaxLines?: number;
|
|
20
|
+
excerptMaxBytes?: number;
|
|
21
|
+
}
|
|
22
|
+
export declare function buildKnowledgeBundle(opts: KnowledgeBundleOptions): CoworkBundle;
|
|
23
|
+
/**
|
|
24
|
+
* Build trace artifact from scored results.
|
|
25
|
+
*/
|
|
26
|
+
export declare function buildKnowledgeTrace(scored: KnowledgeScoredFile[], weights: KnowledgeWeights, sufficiencyThreshold: number, terminatedAtRank: number, runId: string): {
|
|
27
|
+
run_id: string;
|
|
28
|
+
timestamp: string;
|
|
29
|
+
scoring_profile: 'knowledge';
|
|
30
|
+
signals: KnowledgeWeights;
|
|
31
|
+
stop_rule: {
|
|
32
|
+
sufficiency_threshold: number;
|
|
33
|
+
reached_at_rank: number;
|
|
34
|
+
};
|
|
35
|
+
ranked_top: Array<{
|
|
36
|
+
path: string;
|
|
37
|
+
score: number;
|
|
38
|
+
evidence: string[];
|
|
39
|
+
}>;
|
|
40
|
+
};
|
|
41
|
+
//# sourceMappingURL=knowledge-bundle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"knowledge-bundle.d.ts","sourceRoot":"","sources":["../src/knowledge-bundle.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EACV,YAAY,EAMZ,mBAAmB,EACnB,gBAAgB,EAChB,cAAc,EACf,MAAM,mBAAmB,CAAC;AAa3B,MAAM,WAAW,sBAAsB;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,cAAc,CAAC;IAC/B,OAAO,CAAC,EAAE,gBAAgB,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,sBAAsB,GAAG,YAAY,CAyN/E;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,mBAAmB,EAAE,EAC7B,OAAO,EAAE,gBAAgB,EACzB,oBAAoB,EAAE,MAAM,EAC5B,gBAAgB,EAAE,MAAM,EACxB,KAAK,EAAE,MAAM,GACZ;IACD,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,WAAW,CAAC;IAC7B,OAAO,EAAE,gBAAgB,CAAC;IAC1B,SAAS,EAAE;QAAE,qBAAqB,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,CAAA;KAAE,CAAC;IACtE,UAAU,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;CACxE,CAgBA"}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Knowledge-mode bundle builder.
|
|
3
|
+
*
|
|
4
|
+
* Produces a CoworkBundle (context-bundle.json schema) using:
|
|
5
|
+
* - Knowledge-mode candidate generation
|
|
6
|
+
* - Knowledge-mode scoring (7 signals)
|
|
7
|
+
* - Existing stop-rule logic (reused)
|
|
8
|
+
* - Knowledge-mode excerpt extraction (head+headers)
|
|
9
|
+
*/
|
|
10
|
+
import { createHash, randomUUID } from 'node:crypto';
|
|
11
|
+
import { tokenizeIntent, computeKnowledgeTokenWeights, inferAnchorFolders, generateKnowledgeCandidates, } from './knowledge-candidates.js';
|
|
12
|
+
import { scoreAllKnowledgeCandidates, DEFAULT_KNOWLEDGE_WEIGHTS, } from './knowledge-scorer.js';
|
|
13
|
+
import { extractKnowledgeExcerpt } from './knowledge-excerpt.js';
|
|
14
|
+
export function buildKnowledgeBundle(opts) {
|
|
15
|
+
const { intentText, workspaceIndex, weights = DEFAULT_KNOWLEDGE_WEIGHTS, maxFiles = 20, maxTokensEst = 12000, maxBytesEst = 350000, sufficiencyThreshold = 0.78, excerptMaxLines = 450, excerptMaxBytes = 24000, } = opts;
|
|
16
|
+
const nowMs = Date.now();
|
|
17
|
+
const runId = `run_${new Date().toISOString().replace(/[:.]/g, '-')}_${randomUUID().slice(0, 8)}`;
|
|
18
|
+
// Step 1: Tokenize intent
|
|
19
|
+
const intentTokens = tokenizeIntent(intentText);
|
|
20
|
+
const normalizedIntent = intentText.toLowerCase().trim();
|
|
21
|
+
// Step 2: Compute token weights
|
|
22
|
+
const tokenWeights = computeKnowledgeTokenWeights(intentTokens, workspaceIndex.files);
|
|
23
|
+
// Step 3: Infer anchor folders
|
|
24
|
+
const anchorFolders = inferAnchorFolders(intentTokens, workspaceIndex.files);
|
|
25
|
+
// Step 4: Generate candidates
|
|
26
|
+
const candidates = generateKnowledgeCandidates(workspaceIndex.files, intentTokens, tokenWeights);
|
|
27
|
+
// Step 5: Score all candidates
|
|
28
|
+
const scored = scoreAllKnowledgeCandidates(candidates, intentTokens, tokenWeights, anchorFolders, weights, nowMs);
|
|
29
|
+
// Step 6: Select with stop rule
|
|
30
|
+
const maxCumulative = scored.reduce((sum, f) => sum + Math.max(0, f.score), 0);
|
|
31
|
+
const selected = [];
|
|
32
|
+
let totalTokens = 0;
|
|
33
|
+
let totalBytes = 0;
|
|
34
|
+
let cumulativeScore = 0;
|
|
35
|
+
let terminationReason = 'threshold_reached';
|
|
36
|
+
let terminatedAtRank = 0;
|
|
37
|
+
let excludedDueToBudget = 0;
|
|
38
|
+
let excludedLowScore = 0;
|
|
39
|
+
// Build file info map for quick lookup
|
|
40
|
+
const fileMap = new Map(workspaceIndex.files.map((f) => [f.path, f]));
|
|
41
|
+
for (let rank = 0; rank < scored.length; rank++) {
|
|
42
|
+
const scoredFile = scored[rank];
|
|
43
|
+
const fileInfo = fileMap.get(scoredFile.path);
|
|
44
|
+
if (!fileInfo)
|
|
45
|
+
continue;
|
|
46
|
+
// Check stop conditions
|
|
47
|
+
if (selected.length >= maxFiles) {
|
|
48
|
+
terminationReason = 'max_files';
|
|
49
|
+
terminatedAtRank = rank;
|
|
50
|
+
excludedDueToBudget += scored.length - rank;
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
if (totalTokens >= maxTokensEst) {
|
|
54
|
+
terminationReason = 'max_tokens';
|
|
55
|
+
terminatedAtRank = rank;
|
|
56
|
+
excludedDueToBudget += scored.length - rank;
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
if (totalBytes >= maxBytesEst) {
|
|
60
|
+
terminationReason = 'max_bytes';
|
|
61
|
+
terminatedAtRank = rank;
|
|
62
|
+
excludedDueToBudget += scored.length - rank;
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
// Sufficiency threshold check
|
|
66
|
+
if (maxCumulative > 0 && selected.length > 0) {
|
|
67
|
+
const ratio = cumulativeScore / maxCumulative;
|
|
68
|
+
if (ratio >= sufficiencyThreshold) {
|
|
69
|
+
terminationReason = 'threshold_reached';
|
|
70
|
+
terminatedAtRank = rank;
|
|
71
|
+
excludedDueToBudget += scored.length - rank;
|
|
72
|
+
break;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// Extract excerpt
|
|
76
|
+
const excerpt = extractKnowledgeExcerpt(workspaceIndex.root, scoredFile.path, intentTokens, excerptMaxLines, excerptMaxBytes);
|
|
77
|
+
// Estimate tokens (5 tokens/line for natural language)
|
|
78
|
+
const tokenEst = Math.ceil(excerpt.lines_est * 5);
|
|
79
|
+
// Check if adding would blow budget (with 10% overshoot allowance)
|
|
80
|
+
if (totalTokens + tokenEst > maxTokensEst * 1.1 && selected.length > 0) {
|
|
81
|
+
excludedDueToBudget++;
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
// Build excerpt ref path
|
|
85
|
+
const excerptRef = `.codeledger/excerpts/${scoredFile.path.replace(/\//g, '__').replace(/\./g, '__')}.txt`;
|
|
86
|
+
const contentHash = createHash('md5')
|
|
87
|
+
.update(excerpt.content)
|
|
88
|
+
.digest('hex')
|
|
89
|
+
.slice(0, 12);
|
|
90
|
+
const selectedFile = {
|
|
91
|
+
path: scoredFile.path,
|
|
92
|
+
type: fileInfo.type,
|
|
93
|
+
score: Math.round(scoredFile.score * 1000) / 1000,
|
|
94
|
+
reasons: scoredFile.reasons,
|
|
95
|
+
signals: scoredFile.features,
|
|
96
|
+
size_bytes: fileInfo.size_bytes,
|
|
97
|
+
mtime: fileInfo.mtime,
|
|
98
|
+
hash: `h_${contentHash}`,
|
|
99
|
+
excerpt: {
|
|
100
|
+
ref: excerptRef,
|
|
101
|
+
bytes_est: excerpt.bytes_est,
|
|
102
|
+
lines_est: excerpt.lines_est,
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
selected.push(selectedFile);
|
|
106
|
+
totalTokens += tokenEst;
|
|
107
|
+
totalBytes += excerpt.bytes_est;
|
|
108
|
+
cumulativeScore += Math.max(0, scoredFile.score);
|
|
109
|
+
terminatedAtRank = rank + 1;
|
|
110
|
+
}
|
|
111
|
+
// Count low-score excluded files (score <= 0)
|
|
112
|
+
excludedLowScore = scored.filter((f) => f.score <= 0).length;
|
|
113
|
+
// Determine excerpt strategy used
|
|
114
|
+
const hasMarkdown = selected.some((f) => f.type === 'markdown');
|
|
115
|
+
const excerptStrategy = hasMarkdown
|
|
116
|
+
? 'head+headers'
|
|
117
|
+
: intentTokens.length > 0
|
|
118
|
+
? 'head+keyword_windows'
|
|
119
|
+
: 'head';
|
|
120
|
+
const budgets = {
|
|
121
|
+
max_files: maxFiles,
|
|
122
|
+
max_tokens_est: maxTokensEst,
|
|
123
|
+
max_bytes_est: maxBytesEst,
|
|
124
|
+
};
|
|
125
|
+
const stopRule = {
|
|
126
|
+
sufficiency_threshold: sufficiencyThreshold,
|
|
127
|
+
termination_reason: terminationReason,
|
|
128
|
+
terminated_at_rank: terminatedAtRank,
|
|
129
|
+
cumulative_score: Math.round(cumulativeScore * 1000) / 1000,
|
|
130
|
+
};
|
|
131
|
+
const SIGNALS = [
|
|
132
|
+
'keyword_match',
|
|
133
|
+
'filename_match',
|
|
134
|
+
'path_match',
|
|
135
|
+
'recency',
|
|
136
|
+
'size_penalty',
|
|
137
|
+
'doc_type_prior',
|
|
138
|
+
'folder_proximity',
|
|
139
|
+
'markdown_header_boost',
|
|
140
|
+
];
|
|
141
|
+
return {
|
|
142
|
+
bundle_version: '1.0',
|
|
143
|
+
run_id: runId,
|
|
144
|
+
created_at: new Date().toISOString(),
|
|
145
|
+
mode: 'knowledge',
|
|
146
|
+
workspace: {
|
|
147
|
+
root: workspaceIndex.root,
|
|
148
|
+
fingerprint: workspaceIndex.fingerprint,
|
|
149
|
+
file_count: workspaceIndex.file_count,
|
|
150
|
+
},
|
|
151
|
+
intent: {
|
|
152
|
+
text: intentText,
|
|
153
|
+
normalized: normalizedIntent,
|
|
154
|
+
tokens: intentTokens,
|
|
155
|
+
},
|
|
156
|
+
budgets,
|
|
157
|
+
stop_rule: stopRule,
|
|
158
|
+
selection: {
|
|
159
|
+
signals: [...SIGNALS],
|
|
160
|
+
signal_weights: weights,
|
|
161
|
+
excerpt_policy: {
|
|
162
|
+
max_excerpt_bytes: excerptMaxBytes,
|
|
163
|
+
max_lines: excerptMaxLines,
|
|
164
|
+
strategy: excerptStrategy,
|
|
165
|
+
},
|
|
166
|
+
},
|
|
167
|
+
selected,
|
|
168
|
+
excluded_summary: {
|
|
169
|
+
total_seen: workspaceIndex.file_count,
|
|
170
|
+
excluded_low_score: excludedLowScore,
|
|
171
|
+
excluded_due_to_budget: excludedDueToBudget,
|
|
172
|
+
},
|
|
173
|
+
links: {
|
|
174
|
+
trace_path: '.codeledger/trace.json',
|
|
175
|
+
excerpts_dir: '.codeledger/excerpts/',
|
|
176
|
+
progress_snapshot_path: '.codeledger/progress-snapshot.json',
|
|
177
|
+
},
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Build trace artifact from scored results.
|
|
182
|
+
*/
|
|
183
|
+
export function buildKnowledgeTrace(scored, weights, sufficiencyThreshold, terminatedAtRank, runId) {
|
|
184
|
+
return {
|
|
185
|
+
run_id: runId,
|
|
186
|
+
timestamp: new Date().toISOString(),
|
|
187
|
+
scoring_profile: 'knowledge',
|
|
188
|
+
signals: weights,
|
|
189
|
+
stop_rule: {
|
|
190
|
+
sufficiency_threshold: sufficiencyThreshold,
|
|
191
|
+
reached_at_rank: terminatedAtRank,
|
|
192
|
+
},
|
|
193
|
+
ranked_top: scored.slice(0, 30).map((f) => ({
|
|
194
|
+
path: f.path,
|
|
195
|
+
score: Math.round(f.score * 1000) / 1000,
|
|
196
|
+
evidence: f.reasons,
|
|
197
|
+
})),
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
//# sourceMappingURL=knowledge-bundle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"knowledge-bundle.js","sourceRoot":"","sources":["../src/knowledge-bundle.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Knowledge-mode candidate generation.
|
|
3
|
+
*
|
|
4
|
+
* Simpler than code-mode: no dependency graph, no test mapping, no fan-out.
|
|
5
|
+
* Instead: keyword IDF, folder proximity, recency, type filters.
|
|
6
|
+
*/
|
|
7
|
+
import type { WorkspaceFileInfo } from '@codeledger/types';
|
|
8
|
+
/**
|
|
9
|
+
* Tokenize intent text into keywords (stop-word filtered).
|
|
10
|
+
*/
|
|
11
|
+
export declare function tokenizeIntent(text: string): string[];
|
|
12
|
+
/**
|
|
13
|
+
* Compute IDF-like token weights based on file match frequency.
|
|
14
|
+
*/
|
|
15
|
+
export declare function computeKnowledgeTokenWeights(tokens: string[], files: WorkspaceFileInfo[]): Map<string, number>;
|
|
16
|
+
/**
|
|
17
|
+
* Infer "anchor" folders from intent tokens.
|
|
18
|
+
* If a token matches a top-level folder name, that folder is an anchor.
|
|
19
|
+
*/
|
|
20
|
+
export declare function inferAnchorFolders(tokens: string[], files: WorkspaceFileInfo[]): string[];
|
|
21
|
+
/**
|
|
22
|
+
* Generate knowledge-mode candidates.
|
|
23
|
+
* All files are candidates (scored by the knowledge scorer), but only
|
|
24
|
+
* supported file types get full content analysis.
|
|
25
|
+
*/
|
|
26
|
+
export declare function generateKnowledgeCandidates(files: WorkspaceFileInfo[], intentTokens: string[], tokenWeights: Map<string, number>): WorkspaceFileInfo[];
|
|
27
|
+
//# sourceMappingURL=knowledge-candidates.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"knowledge-candidates.d.ts","sourceRoot":"","sources":["../src/knowledge-candidates.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAkB3D;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAMrD;AAED;;GAEG;AACH,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,MAAM,EAAE,EAChB,KAAK,EAAE,iBAAiB,EAAE,GACzB,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CA6BrB;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,MAAM,EAAE,EAChB,KAAK,EAAE,iBAAiB,EAAE,GACzB,MAAM,EAAE,CAuBV;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,iBAAiB,EAAE,EAC1B,YAAY,EAAE,MAAM,EAAE,EACtB,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAChC,iBAAiB,EAAE,CAgCrB"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Knowledge-mode candidate generation.
|
|
3
|
+
*
|
|
4
|
+
* Simpler than code-mode: no dependency graph, no test mapping, no fan-out.
|
|
5
|
+
* Instead: keyword IDF, folder proximity, recency, type filters.
|
|
6
|
+
*/
|
|
7
|
+
const STOP_WORDS = new Set([
|
|
8
|
+
'the', 'a', 'an', 'and', 'or', 'but', 'in', 'on', 'at', 'to', 'for',
|
|
9
|
+
'of', 'with', 'by', 'from', 'is', 'it', 'that', 'this', 'be', 'as',
|
|
10
|
+
'are', 'was', 'were', 'been', 'being', 'have', 'has', 'had', 'do',
|
|
11
|
+
'does', 'did', 'will', 'would', 'could', 'should', 'may', 'might',
|
|
12
|
+
'shall', 'can', 'need', 'must', 'not', 'no', 'if', 'then', 'else',
|
|
13
|
+
'when', 'up', 'out', 'so', 'than', 'too', 'very', 'just', 'about',
|
|
14
|
+
'into', 'over', 'after', 'before', 'between', 'under', 'above',
|
|
15
|
+
'all', 'each', 'every', 'both', 'few', 'more', 'most', 'some', 'any',
|
|
16
|
+
'help', 'me', 'draft', 'write', 'create', 'make', 'give', 'tell',
|
|
17
|
+
'what', 'how', 'why', 'where', 'which',
|
|
18
|
+
]);
|
|
19
|
+
/** Supported file extensions for full content processing */
|
|
20
|
+
const SUPPORTED_EXTENSIONS = new Set(['.md', '.txt', '.json', '.yaml', '.yml']);
|
|
21
|
+
/**
|
|
22
|
+
* Tokenize intent text into keywords (stop-word filtered).
|
|
23
|
+
*/
|
|
24
|
+
export function tokenizeIntent(text) {
|
|
25
|
+
const lower = text.toLowerCase();
|
|
26
|
+
const words = lower
|
|
27
|
+
.split(/[^\p{L}\p{N}]+/u)
|
|
28
|
+
.filter((w) => w.length > 1 && !STOP_WORDS.has(w));
|
|
29
|
+
return [...new Set(words)];
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Compute IDF-like token weights based on file match frequency.
|
|
33
|
+
*/
|
|
34
|
+
export function computeKnowledgeTokenWeights(tokens, files) {
|
|
35
|
+
const weights = new Map();
|
|
36
|
+
for (const token of tokens) {
|
|
37
|
+
let matchCount = 0;
|
|
38
|
+
for (const file of files) {
|
|
39
|
+
const pathLower = file.path.toLowerCase();
|
|
40
|
+
if (pathLower.includes(token)) {
|
|
41
|
+
matchCount++;
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
if (file.content_keywords?.some((ck) => ck === token || ck === token + 's' || token === ck + 's')) {
|
|
45
|
+
matchCount++;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
if (matchCount === 0) {
|
|
49
|
+
weights.set(token, 0);
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
let idf = 1 / Math.sqrt(Math.max(1, matchCount));
|
|
53
|
+
if (token.length <= 2)
|
|
54
|
+
idf = Math.min(idf, 0.35);
|
|
55
|
+
if (matchCount > 20)
|
|
56
|
+
idf = Math.min(idf, 0.35);
|
|
57
|
+
idf = Math.max(0.35, Math.min(1.0, idf));
|
|
58
|
+
weights.set(token, idf);
|
|
59
|
+
}
|
|
60
|
+
return weights;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Infer "anchor" folders from intent tokens.
|
|
64
|
+
* If a token matches a top-level folder name, that folder is an anchor.
|
|
65
|
+
*/
|
|
66
|
+
export function inferAnchorFolders(tokens, files) {
|
|
67
|
+
// Collect all unique folder paths
|
|
68
|
+
const folders = new Set();
|
|
69
|
+
for (const file of files) {
|
|
70
|
+
const parts = file.path.split('/');
|
|
71
|
+
for (let i = 1; i < parts.length; i++) {
|
|
72
|
+
folders.add(parts.slice(0, i).join('/'));
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
const anchors = [];
|
|
76
|
+
for (const folder of folders) {
|
|
77
|
+
const folderLower = folder.toLowerCase();
|
|
78
|
+
const folderName = folderLower.split('/').pop() ?? '';
|
|
79
|
+
for (const token of tokens) {
|
|
80
|
+
if (folderName === token || folderName === token + 's' || token === folderName + 's') {
|
|
81
|
+
anchors.push(folder);
|
|
82
|
+
break;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return anchors;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Generate knowledge-mode candidates.
|
|
90
|
+
* All files are candidates (scored by the knowledge scorer), but only
|
|
91
|
+
* supported file types get full content analysis.
|
|
92
|
+
*/
|
|
93
|
+
export function generateKnowledgeCandidates(files, intentTokens, tokenWeights) {
|
|
94
|
+
// All files are candidates — the scorer handles ranking.
|
|
95
|
+
// Filter out zero-relevance files: if a file has no keyword match, no
|
|
96
|
+
// path match, and is an unsupported type, skip it to save scoring time.
|
|
97
|
+
const candidates = [];
|
|
98
|
+
for (const file of files) {
|
|
99
|
+
const pathLower = file.path.toLowerCase();
|
|
100
|
+
const isSupported = SUPPORTED_EXTENSIONS.has(file.extension.toLowerCase());
|
|
101
|
+
// Always include supported file types
|
|
102
|
+
if (isSupported) {
|
|
103
|
+
candidates.push(file);
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
// For unsupported types, only include if filename/path matches a keyword
|
|
107
|
+
let hasPathMatch = false;
|
|
108
|
+
for (const token of intentTokens) {
|
|
109
|
+
const w = tokenWeights.get(token) ?? 0;
|
|
110
|
+
if (w === 0)
|
|
111
|
+
continue;
|
|
112
|
+
if (pathLower.includes(token)) {
|
|
113
|
+
hasPathMatch = true;
|
|
114
|
+
break;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
if (hasPathMatch) {
|
|
118
|
+
candidates.push(file);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return candidates;
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=knowledge-candidates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"knowledge-candidates.js","sourceRoot":"","sources":["../src/knowledge-candidates.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Knowledge-mode excerpt extraction.
|
|
3
|
+
*
|
|
4
|
+
* Strategies:
|
|
5
|
+
* - head: First N lines (for text, JSON, YAML)
|
|
6
|
+
* - head+headers: First N lines + all markdown headers (for .md files)
|
|
7
|
+
* - head+keyword_windows: First N lines + keyword context windows
|
|
8
|
+
*/
|
|
9
|
+
import type { CoworkExcerptStrategy } from '@codeledger/types';
|
|
10
|
+
export interface KnowledgeExcerptResult {
|
|
11
|
+
content: string;
|
|
12
|
+
lines_est: number;
|
|
13
|
+
bytes_est: number;
|
|
14
|
+
strategy: CoworkExcerptStrategy;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Extract excerpt from a knowledge-mode file.
|
|
18
|
+
*
|
|
19
|
+
* @param root Workspace root
|
|
20
|
+
* @param filePath Relative file path
|
|
21
|
+
* @param keywords Intent keywords for window extraction
|
|
22
|
+
* @param maxLines Maximum excerpt lines (default 450)
|
|
23
|
+
* @param maxBytes Maximum excerpt bytes (default 24000)
|
|
24
|
+
*/
|
|
25
|
+
export declare function extractKnowledgeExcerpt(root: string, filePath: string, keywords: string[], maxLines?: number, maxBytes?: number): KnowledgeExcerptResult;
|
|
26
|
+
//# sourceMappingURL=knowledge-excerpt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"knowledge-excerpt.d.ts","sourceRoot":"","sources":["../src/knowledge-excerpt.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAI/D,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,qBAAqB,CAAC;CACjC;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAAE,EAClB,QAAQ,GAAE,MAAY,EACtB,QAAQ,GAAE,MAAc,GACvB,sBAAsB,CAoDxB"}
|