scopecairn 0.12.1 → 0.14.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 +16 -4
- package/dist/{chunk-G5RA43OH.js → chunk-4VHUOZ7J.js} +36 -46
- package/dist/{chunk-2BIPX6YJ.js → chunk-GQFBQRDD.js} +4 -67
- package/dist/{chunk-QIYOLER3.js → chunk-HTJIVHYW.js} +67 -15
- package/dist/chunk-K7D5EIMF.js +461 -0
- package/dist/{chunk-PR3BGBXP.js → chunk-SJ6A2QGE.js} +13 -7
- package/dist/chunk-UUPA64KG.js +59 -0
- package/dist/chunk-UVKHDHBU.js +71 -0
- package/dist/classify-HAX4TC7I.js +8 -0
- package/dist/cli.js +925 -830
- package/dist/{contextBuilder-FXORTIGD.js → contextBuilder-HVF5CRXG.js} +5 -4
- package/dist/{extractor-665DZW2D.js → extractor-E3JH7YUA.js} +1 -1
- package/dist/protected-MW57HNV6.js +21 -0
- package/dist/retrieve-TDD2N24I.js +9 -0
- package/dist/{search-OLYYFEQV.js → search-RFQREAFV.js} +2 -1
- package/package.json +53 -53
- package/dist/scope-RA4EDS4A.js +0 -9
- package/skills/scopecairn/SKILL.md +0 -32
package/README.md
CHANGED
|
@@ -76,6 +76,16 @@ No MCP server, no embeddings, no network calls, no telemetry.
|
|
|
76
76
|
click-for-details side panel (callers, callees, centrality scores).
|
|
77
77
|
Nodes sized by symbols/PageRank, colored by Louvain community.
|
|
78
78
|
Pan, zoom, hover inspect. Double-click to open, no server.
|
|
79
|
+
- **Decision log** — `scopecairn decide "pakai X karena Y"` records an
|
|
80
|
+
architectural decision once; it is carried into every later
|
|
81
|
+
`context` call, so the agent stops re-litigating settled choices.
|
|
82
|
+
- **Definition of Done check** — `verify --dod` rates each DoD item and
|
|
83
|
+
is honest about what it cannot know: `pass` only for what the machine
|
|
84
|
+
verified (scope, index freshness), `warn`/`fail` where it has evidence,
|
|
85
|
+
`manual` for judgement calls. Never a fabricated "done".
|
|
86
|
+
- **Local usage report** — `status --usage` reads the local invocation
|
|
87
|
+
log: commands used, closed-loop rate (`scan` after a task), average
|
|
88
|
+
symbols per task. Local only, never leaves the machine.
|
|
79
89
|
- **Graph export for external tools** — `scopecairn graph --export
|
|
80
90
|
mermaid|graphml|dot|json` writes `.scopecairn/graph.<ext>` for PR
|
|
81
91
|
diagrams (Mermaid), Gephi/Cytoscape (GraphML), Graphviz (DOT),
|
|
@@ -136,9 +146,10 @@ scopecairn scan # index repository (--rebuild, --cle
|
|
|
136
146
|
scopecairn context "tambah fitur auth" # AI agent task context + scope
|
|
137
147
|
scopecairn impact src/indexer.ts # blast radius & affected tests (--run-tests)
|
|
138
148
|
scopecairn graph buildContext # inspect relations, path (--to), export (--export)
|
|
139
|
-
scopecairn verify
|
|
140
|
-
scopecairn status
|
|
149
|
+
scopecairn verify --dod # pre-commit safety guard (--diff, --arch, --dod)
|
|
150
|
+
scopecairn status --usage # index statistics & health checks (--doctor, --html)
|
|
141
151
|
scopecairn read symbol indexFileSymbols # symbol-level source excerpt
|
|
152
|
+
scopecairn decide "graf di SQLite, tanpa embedding" # catat keputusan arsitektur
|
|
142
153
|
```
|
|
143
154
|
|
|
144
155
|
Per-agent installers (instead of `init --agents …`):
|
|
@@ -162,8 +173,8 @@ ScopeCairn organizes its capabilities into **6 core commands** aligned with code
|
|
|
162
173
|
| `context "<task>"` | **AI Agent Context & Scope:** Main agent entry point with auto-refresh, task classification, relevant context, task scope, and Task Guard. Options: `--escalate`, `--mode NORMAL\|FAST\|SAFE\|AUDIT`, `--max-tokens N`, `--no-history`, `--with-diff`, `--json`. |
|
|
163
174
|
| `impact <target>` | **Blast Radius & Test Selection:** Change impact analysis across direct, indirect, tests, UI components, and API clients. Options: `--run-tests` (run affected tests directly), `--tests` (list affected tests only), `--repos [list]` (cross-repo blast radius). |
|
|
164
175
|
| `graph [symbol]` | **Knowledge Graph & Navigation:** Symbol relations, PageRank centrality, community clusters, and cycle status. Options: `--to <target>` (shortest multi-hop call path), `--export <fmt>` (`mermaid\|graphml\|dot\|json`). |
|
|
165
|
-
| `verify` | **Pre-Commit Safety Guard:** Working tree check against protected files, task scope creep, and circular dependency regressions. Options: `--diff` (structural symbol-level diff vs HEAD), `--arch` (architectural layer rules), `--strict`, `--task <t>`. |
|
|
166
|
-
| `status` | **Health & Diagnostics:** Index statistics and metadata. Options: `--doctor` (integration and adapter health check), `--verbose`, `--html` (generate local HTML dashboard). |
|
|
176
|
+
| `verify` | **Pre-Commit Safety Guard:** Working tree check against protected files, task scope creep, and circular dependency regressions. Options: `--diff` (structural symbol-level diff vs HEAD), `--arch` (architectural layer rules), `--dod` (Definition of Done: verified / warned / manual, never a claimed pass), `--strict`, `--task <t>`. |
|
|
177
|
+
| `status` | **Health & Diagnostics:** Index statistics and metadata. Options: `--doctor` (integration and adapter health check), `--usage` (local usage & compliance report), `--verbose`, `--html` (generate local HTML dashboard). |
|
|
167
178
|
|
|
168
179
|
### Helper & Setup Commands
|
|
169
180
|
|
|
@@ -171,6 +182,7 @@ ScopeCairn organizes its capabilities into **6 core commands** aligned with code
|
|
|
171
182
|
| ------- | ----------- |
|
|
172
183
|
| `init [path]` | Initial indexing + Skill, Workflow, detected agent skills (`--agents …\|all`). |
|
|
173
184
|
| `read symbol <name>` | Symbol-level source excerpt (not whole files). |
|
|
185
|
+
| `decide "…"` | Record an architectural decision into `.scopecairn/decisions.md` (no argument: list them). Read back by `context`. |
|
|
174
186
|
| `benchmark [--tune]` | Retrieval recall, irrelevant ratio, context reduction + weight tuning (dev-only, hidden from `--help`). |
|
|
175
187
|
| `<agent> install` | Agent installers: `antigravity`, `claude`, `cursor`, `windsurf`, `copilot`, `kiro`, `opencode`. |
|
|
176
188
|
|
|
@@ -17,7 +17,7 @@ function loadDatabaseSync() {
|
|
|
17
17
|
}
|
|
18
18
|
var DATA_DIR_NAME = ".scopecairn";
|
|
19
19
|
var DB_FILE_NAME = "scopecairn.db";
|
|
20
|
-
var SCHEMA_VERSION =
|
|
20
|
+
var SCHEMA_VERSION = 8;
|
|
21
21
|
function dataDir(repoRoot) {
|
|
22
22
|
return path.join(repoRoot, DATA_DIR_NAME);
|
|
23
23
|
}
|
|
@@ -85,6 +85,17 @@ function openDb(repoRoot) {
|
|
|
85
85
|
reason TEXT NOT NULL DEFAULT ''
|
|
86
86
|
);
|
|
87
87
|
CREATE INDEX IF NOT EXISTS idx_task_context_task ON task_context(task_id);
|
|
88
|
+
-- Scope yang DIRENDER ke agent (Required/Optional/Protected), disimpan
|
|
89
|
+
-- per task. Tanpa ini verify --task harus menghitung ulang scope dari
|
|
90
|
+
-- task string, dan hasilnya bisa berbeda dari yang benar-benar dilihat
|
|
91
|
+
-- agent (co-change history, --escalate, task SIMPLE) \u2192 false positive.
|
|
92
|
+
CREATE TABLE IF NOT EXISTS task_scope (
|
|
93
|
+
task_id INTEGER NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,
|
|
94
|
+
path TEXT NOT NULL,
|
|
95
|
+
tier TEXT NOT NULL,
|
|
96
|
+
PRIMARY KEY (task_id, path)
|
|
97
|
+
);
|
|
98
|
+
CREATE INDEX IF NOT EXISTS idx_task_scope_task ON task_scope(task_id);
|
|
88
99
|
-- Fase 5: invocation log untuk compliance rate (AI-5, \xA718).
|
|
89
100
|
CREATE TABLE IF NOT EXISTS invocations (
|
|
90
101
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
@@ -138,6 +149,15 @@ function openDb(repoRoot) {
|
|
|
138
149
|
);
|
|
139
150
|
CREATE INDEX IF NOT EXISTS idx_commit_files_sha ON commit_files(sha);
|
|
140
151
|
CREATE INDEX IF NOT EXISTS idx_commit_files_path ON commit_files(path);
|
|
152
|
+
-- Cache fan-in (jumlah relasi masuk per simbol). Dipakai ranking
|
|
153
|
+
-- retrieval: tanpa cache, retrieve() menghitung ulang
|
|
154
|
+
-- GROUP BY target_id di seluruh tabel relationships pada SETIAP
|
|
155
|
+
-- pemanggilan \u2014 O(E) penuh, dan itu bottleneck utama di repo besar.
|
|
156
|
+
-- Dipopulate ulang di akhir scanRepository (satu lintasan GROUP BY).
|
|
157
|
+
CREATE TABLE IF NOT EXISTS fanin (
|
|
158
|
+
node_id INTEGER PRIMARY KEY,
|
|
159
|
+
n INTEGER NOT NULL
|
|
160
|
+
);
|
|
141
161
|
CREATE VIRTUAL TABLE IF NOT EXISTS commit_fts USING fts5(
|
|
142
162
|
sha UNINDEXED, subject, body, paths
|
|
143
163
|
);
|
|
@@ -157,10 +177,17 @@ function openDb(repoRoot) {
|
|
|
157
177
|
`UPDATE relationships SET evidence = 'INFERRED'
|
|
158
178
|
WHERE relationship_type IN ('QUERIES','ROUTES_TO','TESTS') AND evidence = 'EXTRACTED'`
|
|
159
179
|
);
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
180
|
+
const CALLS_BACKFILL_KEY = "migration_calls_evidence_v1";
|
|
181
|
+
const callsBackfilled = db.prepare(`SELECT value FROM meta WHERE key = ?`).get(CALLS_BACKFILL_KEY);
|
|
182
|
+
if (!callsBackfilled) {
|
|
183
|
+
db.exec(
|
|
184
|
+
`UPDATE relationships SET evidence = 'AMBIGUOUS'
|
|
185
|
+
WHERE relationship_type = 'CALLS' AND confidence < 1.0 AND evidence = 'EXTRACTED'`
|
|
186
|
+
);
|
|
187
|
+
db.prepare(`INSERT INTO meta(key, value) VALUES (?, '1') ON CONFLICT(key) DO NOTHING`).run(
|
|
188
|
+
CALLS_BACKFILL_KEY
|
|
189
|
+
);
|
|
190
|
+
}
|
|
164
191
|
return db;
|
|
165
192
|
}
|
|
166
193
|
function hashContent(buf) {
|
|
@@ -295,54 +322,17 @@ function ensureProtectedFile(repoRoot) {
|
|
|
295
322
|
}
|
|
296
323
|
}
|
|
297
324
|
|
|
298
|
-
// src/scope/scope.ts
|
|
299
|
-
function computeScope(highFiles, mediumFiles, testFiles, patterns, historyOptional) {
|
|
300
|
-
const required = [];
|
|
301
|
-
const optional = [];
|
|
302
|
-
const protectedFiles = [];
|
|
303
|
-
const seen = /* @__PURE__ */ new Set();
|
|
304
|
-
const place = (f) => {
|
|
305
|
-
if (seen.has(f)) return;
|
|
306
|
-
seen.add(f);
|
|
307
|
-
if (isProtected(f, patterns)) protectedFiles.push(f);
|
|
308
|
-
else if (highFiles.includes(f)) required.push(f);
|
|
309
|
-
else optional.push(f);
|
|
310
|
-
};
|
|
311
|
-
for (const f of highFiles) place(f);
|
|
312
|
-
for (const f of mediumFiles) place(f);
|
|
313
|
-
for (const t of testFiles) {
|
|
314
|
-
if (seen.has(t)) continue;
|
|
315
|
-
seen.add(t);
|
|
316
|
-
if (isProtected(t, patterns)) protectedFiles.push(t);
|
|
317
|
-
else optional.push(t);
|
|
318
|
-
}
|
|
319
|
-
for (const h of historyOptional ?? []) {
|
|
320
|
-
if (seen.has(h)) continue;
|
|
321
|
-
seen.add(h);
|
|
322
|
-
if (isProtected(h, patterns)) protectedFiles.push(h);
|
|
323
|
-
else optional.push(h);
|
|
324
|
-
}
|
|
325
|
-
return { required, optional, protected: protectedFiles };
|
|
326
|
-
}
|
|
327
|
-
function scopeBlock(scope) {
|
|
328
|
-
const fmt = (xs) => xs.length > 0 ? xs.join(", ") : "-";
|
|
329
|
-
return `## Scope
|
|
330
|
-
Required: ${fmt(scope.required)}
|
|
331
|
-
Optional: ${fmt(scope.optional)}
|
|
332
|
-
Protected: ${fmt(scope.protected)}
|
|
333
|
-
`;
|
|
334
|
-
}
|
|
335
|
-
|
|
336
325
|
export {
|
|
337
326
|
dataDir,
|
|
338
327
|
dbPath,
|
|
339
328
|
openDb,
|
|
340
329
|
hashContent,
|
|
330
|
+
DEFAULT_PROTECTED_PATTERNS,
|
|
341
331
|
matchPattern,
|
|
342
332
|
loadProtectedPatterns,
|
|
343
333
|
isProtected,
|
|
334
|
+
SECRET_PATTERNS,
|
|
335
|
+
isSecretFile,
|
|
344
336
|
isIndexableMetaFile,
|
|
345
|
-
ensureProtectedFile
|
|
346
|
-
computeScope,
|
|
347
|
-
scopeBlock
|
|
337
|
+
ensureProtectedFile
|
|
348
338
|
};
|
|
@@ -2,71 +2,10 @@
|
|
|
2
2
|
import {
|
|
3
3
|
logError
|
|
4
4
|
} from "./chunk-OPA4TMAT.js";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
"a",
|
|
10
|
-
"an",
|
|
11
|
-
"of",
|
|
12
|
-
"to",
|
|
13
|
-
"in",
|
|
14
|
-
"for",
|
|
15
|
-
"on",
|
|
16
|
-
"with",
|
|
17
|
-
"and",
|
|
18
|
-
"or",
|
|
19
|
-
"src",
|
|
20
|
-
"lib",
|
|
21
|
-
"app",
|
|
22
|
-
"test",
|
|
23
|
-
"tests",
|
|
24
|
-
"spec"
|
|
25
|
-
]);
|
|
26
|
-
function stemVariants(t) {
|
|
27
|
-
const out = /* @__PURE__ */ new Set([t]);
|
|
28
|
-
if (t.endsWith("ies") && t.length > 4) out.add(t.slice(0, -3) + "y");
|
|
29
|
-
else if (t.endsWith("es") && t.length > 4 && /(s|x|z|ch|sh)es$/.test(t)) out.add(t.slice(0, -2));
|
|
30
|
-
else if (t.endsWith("s") && t.length > 3 && !t.endsWith("ss")) out.add(t.slice(0, -1));
|
|
31
|
-
if (t.endsWith("ing") && t.length > 5) {
|
|
32
|
-
const base = t.slice(0, -3);
|
|
33
|
-
out.add(base);
|
|
34
|
-
out.add(base + "e");
|
|
35
|
-
}
|
|
36
|
-
if (t.endsWith("ation") && t.length > 7) {
|
|
37
|
-
const base = t.slice(0, -5);
|
|
38
|
-
out.add(base);
|
|
39
|
-
}
|
|
40
|
-
return [...out];
|
|
41
|
-
}
|
|
42
|
-
var EXPLICIT_STEM = /* @__PURE__ */ new Map([
|
|
43
|
-
["configuration", "config"],
|
|
44
|
-
["configurations", "config"],
|
|
45
|
-
["configured", "config"],
|
|
46
|
-
["ranking", "rank"],
|
|
47
|
-
["ranked", "rank"],
|
|
48
|
-
["weights", "weight"],
|
|
49
|
-
["dependencies", "dependency"],
|
|
50
|
-
["dependency", "depend"],
|
|
51
|
-
["extraction", "extract"],
|
|
52
|
-
["extracted", "extract"]
|
|
53
|
-
]);
|
|
54
|
-
function tokenizeIdentifier(raw) {
|
|
55
|
-
const parts = raw.replace(/[\\/]/g, " ").replace(/[.:\-_"']/g, " ").replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2").toLowerCase().split(/[^a-z0-9]+/g).filter((t) => t.length >= 2 && !STOP.has(t));
|
|
56
|
-
const out = /* @__PURE__ */ new Set();
|
|
57
|
-
for (const t of parts) {
|
|
58
|
-
out.add(t);
|
|
59
|
-
for (const v of stemVariants(t)) {
|
|
60
|
-
if (v.length >= 2 && !STOP.has(v)) out.add(v);
|
|
61
|
-
}
|
|
62
|
-
const e = EXPLICIT_STEM.get(t);
|
|
63
|
-
if (e && !STOP.has(e)) out.add(e);
|
|
64
|
-
}
|
|
65
|
-
return [...out];
|
|
66
|
-
}
|
|
67
|
-
function tokenizeTask(text) {
|
|
68
|
-
return tokenizeIdentifier(text);
|
|
69
|
-
}
|
|
5
|
+
import {
|
|
6
|
+
tokenizeIdentifier,
|
|
7
|
+
tokenizeTask
|
|
8
|
+
} from "./chunk-UVKHDHBU.js";
|
|
70
9
|
|
|
71
10
|
// src/retrieval/history/index.ts
|
|
72
11
|
function stripConventionalPrefix(subject) {
|
|
@@ -309,8 +248,6 @@ function leaveOneOut(db, shas, opts = {}) {
|
|
|
309
248
|
}
|
|
310
249
|
|
|
311
250
|
export {
|
|
312
|
-
tokenizeIdentifier,
|
|
313
|
-
tokenizeTask,
|
|
314
251
|
syncCommitFts,
|
|
315
252
|
HISTORY_HALF_LIFE_DAYS,
|
|
316
253
|
HISTORY_MIN_SCORE,
|
|
@@ -1,17 +1,53 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
-
|
|
3
|
+
demoteHeadings
|
|
4
|
+
} from "./chunk-ZV4BSIQM.js";
|
|
5
|
+
import {
|
|
4
6
|
isProtected,
|
|
5
|
-
loadProtectedPatterns
|
|
6
|
-
|
|
7
|
-
} from "./chunk-G5RA43OH.js";
|
|
7
|
+
loadProtectedPatterns
|
|
8
|
+
} from "./chunk-4VHUOZ7J.js";
|
|
8
9
|
import {
|
|
9
10
|
coChangeSet,
|
|
10
11
|
groupHistoryFiles
|
|
11
|
-
} from "./chunk-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
} from "./chunk-GQFBQRDD.js";
|
|
13
|
+
|
|
14
|
+
// src/scope/scope.ts
|
|
15
|
+
function computeScope(highFiles, mediumFiles, testFiles, patterns, historyOptional) {
|
|
16
|
+
const required = [];
|
|
17
|
+
const optional = [];
|
|
18
|
+
const protectedFiles = [];
|
|
19
|
+
const seen = /* @__PURE__ */ new Set();
|
|
20
|
+
const place = (f) => {
|
|
21
|
+
if (seen.has(f)) return;
|
|
22
|
+
seen.add(f);
|
|
23
|
+
if (isProtected(f, patterns)) protectedFiles.push(f);
|
|
24
|
+
else if (highFiles.includes(f)) required.push(f);
|
|
25
|
+
else optional.push(f);
|
|
26
|
+
};
|
|
27
|
+
for (const f of highFiles) place(f);
|
|
28
|
+
for (const f of mediumFiles) place(f);
|
|
29
|
+
for (const t of testFiles) {
|
|
30
|
+
if (seen.has(t)) continue;
|
|
31
|
+
seen.add(t);
|
|
32
|
+
if (isProtected(t, patterns)) protectedFiles.push(t);
|
|
33
|
+
else optional.push(t);
|
|
34
|
+
}
|
|
35
|
+
for (const h of historyOptional ?? []) {
|
|
36
|
+
if (seen.has(h)) continue;
|
|
37
|
+
seen.add(h);
|
|
38
|
+
if (isProtected(h, patterns)) protectedFiles.push(h);
|
|
39
|
+
else optional.push(h);
|
|
40
|
+
}
|
|
41
|
+
return { required, optional, protected: protectedFiles };
|
|
42
|
+
}
|
|
43
|
+
function scopeBlock(scope) {
|
|
44
|
+
const fmt = (xs) => xs.length > 0 ? xs.join(", ") : "-";
|
|
45
|
+
return `## Scope
|
|
46
|
+
Required: ${fmt(scope.required)}
|
|
47
|
+
Optional: ${fmt(scope.optional)}
|
|
48
|
+
Protected: ${fmt(scope.protected)}
|
|
49
|
+
`;
|
|
50
|
+
}
|
|
15
51
|
|
|
16
52
|
// src/scope/guard.ts
|
|
17
53
|
var TASK_GUARD_RULES = [
|
|
@@ -48,6 +84,12 @@ function buildContext(db, task, result, cls, opts) {
|
|
|
48
84
|
if (files.length >= 3) break;
|
|
49
85
|
}
|
|
50
86
|
const cand = files.length > 0 ? files.map((f) => `\`${f}\``).join(", ") : "pencarian langsung (tidak ada simbol cocok di index)";
|
|
87
|
+
const simpleScope = computeScope(
|
|
88
|
+
files,
|
|
89
|
+
[],
|
|
90
|
+
[],
|
|
91
|
+
loadProtectedPatterns(opts?.repoRoot ?? ".")
|
|
92
|
+
);
|
|
51
93
|
return {
|
|
52
94
|
markdown: `# Task Context
|
|
53
95
|
|
|
@@ -63,7 +105,8 @@ Task sederhana. Gunakan pencarian langsung. Kandidat: ${cand}
|
|
|
63
105
|
medium: [],
|
|
64
106
|
tests: [],
|
|
65
107
|
dependencies: [],
|
|
66
|
-
hotspots: []
|
|
108
|
+
hotspots: [],
|
|
109
|
+
scope: simpleScope
|
|
67
110
|
};
|
|
68
111
|
}
|
|
69
112
|
const ranked = result.ranked;
|
|
@@ -97,15 +140,14 @@ Task sederhana. Gunakan pencarian langsung. Kandidat: ${cand}
|
|
|
97
140
|
const ph = highFiles.map(() => "?").join(",");
|
|
98
141
|
try {
|
|
99
142
|
const rows = db.prepare(
|
|
100
|
-
`SELECT DISTINCT
|
|
143
|
+
`SELECT DISTINCT f1.path AS t
|
|
101
144
|
FROM relationships r
|
|
102
145
|
JOIN symbols s1 ON s1.id = r.source_id
|
|
103
146
|
JOIN symbols s2 ON s2.id = r.target_id
|
|
104
147
|
JOIN files f1 ON f1.id = s1.file_id
|
|
105
148
|
JOIN files f2 ON f2.id = s2.file_id
|
|
106
|
-
WHERE r.relationship_type = 'TESTS'
|
|
107
|
-
|
|
108
|
-
).all(...highFiles, ...highFiles);
|
|
149
|
+
WHERE r.relationship_type = 'TESTS' AND f2.path IN (${ph})`
|
|
150
|
+
).all(...highFiles);
|
|
109
151
|
for (const r of rows) testSet.add(r.t);
|
|
110
152
|
} catch {
|
|
111
153
|
}
|
|
@@ -270,7 +312,8 @@ ${tests.map((t) => `- ${t}`).join("\n") || "-"}
|
|
|
270
312
|
medium: medFiles,
|
|
271
313
|
tests,
|
|
272
314
|
dependencies: deps,
|
|
273
|
-
hotspots
|
|
315
|
+
hotspots,
|
|
316
|
+
scope
|
|
274
317
|
};
|
|
275
318
|
}
|
|
276
319
|
const md = `# Task Context
|
|
@@ -301,7 +344,15 @@ ${tests.map((t) => `- ${t}`).join("\n") || "-"}
|
|
|
301
344
|
|
|
302
345
|
` + historyBlock + cycleWarn + scopeBlock(scope) + `
|
|
303
346
|
` + guardBlock(extraDoD.length > 0 ? extraDoD : void 0);
|
|
304
|
-
return {
|
|
347
|
+
return {
|
|
348
|
+
markdown: md,
|
|
349
|
+
high: highFiles,
|
|
350
|
+
medium: medFiles,
|
|
351
|
+
tests,
|
|
352
|
+
dependencies: deps,
|
|
353
|
+
hotspots,
|
|
354
|
+
scope
|
|
355
|
+
};
|
|
305
356
|
}
|
|
306
357
|
function resolveEffectiveMode(mode, cls, knowledge) {
|
|
307
358
|
return mode === "NORMAL" && cls.complexity === "SIMPLE" && cls.estimatedFiles <= 1 && !knowledge ? "FAST" : mode;
|
|
@@ -339,6 +390,7 @@ function buildContextPayload(input) {
|
|
|
339
390
|
}
|
|
340
391
|
|
|
341
392
|
export {
|
|
393
|
+
DEFINITION_OF_DONE,
|
|
342
394
|
buildContext,
|
|
343
395
|
resolveEffectiveMode,
|
|
344
396
|
buildContextPayload
|