@ksm0709/context 0.0.5 → 0.0.6
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/index.js +168 -10
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -818,14 +818,17 @@ var DEFAULTS = {
|
|
|
818
818
|
turnEndFile: "turn-end.md",
|
|
819
819
|
knowledgeSources: ["AGENTS.md"],
|
|
820
820
|
knowledgeDir: "docs",
|
|
821
|
-
templateDir: ".opencode/context/templates"
|
|
821
|
+
templateDir: ".opencode/context/templates",
|
|
822
|
+
indexFilename: "INDEX.md",
|
|
823
|
+
maxDomainDepth: 2
|
|
822
824
|
};
|
|
823
825
|
var LIMITS = {
|
|
824
826
|
maxPromptFileSize: 64 * 1024,
|
|
825
827
|
maxIndexEntries: 100,
|
|
826
828
|
maxTotalInjectionSize: 128 * 1024,
|
|
827
829
|
maxScanDepth: 3,
|
|
828
|
-
maxSummaryLength: 100
|
|
830
|
+
maxSummaryLength: 100,
|
|
831
|
+
maxIndexFileSize: 32 * 1024
|
|
829
832
|
};
|
|
830
833
|
|
|
831
834
|
// src/lib/config.ts
|
|
@@ -837,7 +840,10 @@ function getDefaultConfig() {
|
|
|
837
840
|
},
|
|
838
841
|
knowledge: {
|
|
839
842
|
dir: DEFAULTS.knowledgeDir,
|
|
840
|
-
sources: [...DEFAULTS.knowledgeSources]
|
|
843
|
+
sources: [...DEFAULTS.knowledgeSources],
|
|
844
|
+
mode: "auto",
|
|
845
|
+
indexFilename: DEFAULTS.indexFilename,
|
|
846
|
+
maxDomainDepth: DEFAULTS.maxDomainDepth
|
|
841
847
|
}
|
|
842
848
|
};
|
|
843
849
|
}
|
|
@@ -850,7 +856,10 @@ function mergeWithDefaults(partial) {
|
|
|
850
856
|
},
|
|
851
857
|
knowledge: {
|
|
852
858
|
dir: partial.knowledge?.dir ?? defaults.knowledge.dir,
|
|
853
|
-
sources: partial.knowledge?.sources ?? defaults.knowledge.sources
|
|
859
|
+
sources: partial.knowledge?.sources ?? defaults.knowledge.sources,
|
|
860
|
+
mode: partial.knowledge?.mode ?? defaults.knowledge.mode,
|
|
861
|
+
indexFilename: partial.knowledge?.indexFilename ?? defaults.knowledge.indexFilename,
|
|
862
|
+
maxDomainDepth: partial.knowledge?.maxDomainDepth ?? defaults.knowledge.maxDomainDepth
|
|
854
863
|
}
|
|
855
864
|
};
|
|
856
865
|
}
|
|
@@ -939,6 +948,131 @@ function formatKnowledgeIndex(entries) {
|
|
|
939
948
|
return lines.join(`
|
|
940
949
|
`);
|
|
941
950
|
}
|
|
951
|
+
function countMdFiles(dir, indexFilename) {
|
|
952
|
+
try {
|
|
953
|
+
const items = readdirSync(dir);
|
|
954
|
+
return items.filter((item) => extname(item) === ".md" && item !== indexFilename && statSync(join2(dir, item)).isFile()).length;
|
|
955
|
+
} catch {
|
|
956
|
+
return 0;
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
function scanDomainsRecursive(baseDir, projectDir, indexFilename, currentDepth, maxDepth, results) {
|
|
960
|
+
if (currentDepth > maxDepth)
|
|
961
|
+
return;
|
|
962
|
+
try {
|
|
963
|
+
const items = readdirSync(baseDir);
|
|
964
|
+
for (const item of items) {
|
|
965
|
+
const fullPath = join2(baseDir, item);
|
|
966
|
+
try {
|
|
967
|
+
if (!statSync(fullPath).isDirectory())
|
|
968
|
+
continue;
|
|
969
|
+
const indexPath = join2(fullPath, indexFilename);
|
|
970
|
+
if (existsSync(indexPath) && statSync(indexPath).isFile()) {
|
|
971
|
+
const rawContent = readFileSync2(indexPath, "utf-8");
|
|
972
|
+
const indexContent = rawContent.slice(0, LIMITS.maxIndexFileSize);
|
|
973
|
+
results.push({
|
|
974
|
+
domain: item,
|
|
975
|
+
path: relative(projectDir, fullPath),
|
|
976
|
+
indexContent,
|
|
977
|
+
noteCount: countMdFiles(fullPath, indexFilename)
|
|
978
|
+
});
|
|
979
|
+
}
|
|
980
|
+
scanDomainsRecursive(fullPath, projectDir, indexFilename, currentDepth + 1, maxDepth, results);
|
|
981
|
+
} catch {}
|
|
982
|
+
}
|
|
983
|
+
} catch {}
|
|
984
|
+
}
|
|
985
|
+
function scanDomains(projectDir, knowledgeDir, indexFilename, maxDepth) {
|
|
986
|
+
const baseDir = join2(projectDir, knowledgeDir);
|
|
987
|
+
if (!existsSync(baseDir))
|
|
988
|
+
return [];
|
|
989
|
+
const results = [];
|
|
990
|
+
scanDomainsRecursive(baseDir, projectDir, indexFilename, 1, maxDepth, results);
|
|
991
|
+
return results;
|
|
992
|
+
}
|
|
993
|
+
function detectKnowledgeMode(projectDir, knowledgeDir, indexFilename, configMode) {
|
|
994
|
+
if (configMode !== "auto")
|
|
995
|
+
return configMode;
|
|
996
|
+
const domains = scanDomains(projectDir, knowledgeDir, indexFilename, 1);
|
|
997
|
+
return domains.length > 0 ? "domain" : "flat";
|
|
998
|
+
}
|
|
999
|
+
function formatDomainIndex(index) {
|
|
1000
|
+
const hasDomains = index.domains.length > 0;
|
|
1001
|
+
const hasFiles = index.individualFiles.length > 0;
|
|
1002
|
+
if (!hasDomains && !hasFiles)
|
|
1003
|
+
return "";
|
|
1004
|
+
const lines = ["## Available Knowledge", ""];
|
|
1005
|
+
if (hasDomains) {
|
|
1006
|
+
lines.push("### Domains", "");
|
|
1007
|
+
for (const domain of index.domains) {
|
|
1008
|
+
lines.push(`#### ${domain.path}/ (${domain.noteCount} notes)`, "");
|
|
1009
|
+
lines.push(domain.indexContent, "");
|
|
1010
|
+
}
|
|
1011
|
+
}
|
|
1012
|
+
if (hasFiles) {
|
|
1013
|
+
if (hasDomains) {
|
|
1014
|
+
lines.push("### Individual Files", "");
|
|
1015
|
+
}
|
|
1016
|
+
for (const file of index.individualFiles) {
|
|
1017
|
+
lines.push(`- ${file.filename}${file.summary ? ` \u2014 ${file.summary}` : ""}`);
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
return lines.join(`
|
|
1021
|
+
`);
|
|
1022
|
+
}
|
|
1023
|
+
function collectRootFiles(projectDir, knowledgeDir, indexFilename) {
|
|
1024
|
+
const baseDir = join2(projectDir, knowledgeDir);
|
|
1025
|
+
if (!existsSync(baseDir))
|
|
1026
|
+
return [];
|
|
1027
|
+
const entries = [];
|
|
1028
|
+
try {
|
|
1029
|
+
const items = readdirSync(baseDir);
|
|
1030
|
+
for (const item of items) {
|
|
1031
|
+
const fullPath = join2(baseDir, item);
|
|
1032
|
+
try {
|
|
1033
|
+
const stat = statSync(fullPath);
|
|
1034
|
+
if (stat.isFile() && extname(item) === ".md" && item !== indexFilename) {
|
|
1035
|
+
entries.push({
|
|
1036
|
+
filename: relative(projectDir, fullPath),
|
|
1037
|
+
summary: extractSummary(fullPath)
|
|
1038
|
+
});
|
|
1039
|
+
}
|
|
1040
|
+
} catch {}
|
|
1041
|
+
}
|
|
1042
|
+
} catch {}
|
|
1043
|
+
return entries;
|
|
1044
|
+
}
|
|
1045
|
+
function buildKnowledgeIndexV2(projectDir, knowledgeConfig) {
|
|
1046
|
+
const dir = knowledgeConfig.dir ?? "docs";
|
|
1047
|
+
const indexFilename = knowledgeConfig.indexFilename ?? "INDEX.md";
|
|
1048
|
+
const maxDepth = knowledgeConfig.maxDomainDepth ?? 2;
|
|
1049
|
+
const configMode = knowledgeConfig.mode ?? "auto";
|
|
1050
|
+
const mode = detectKnowledgeMode(projectDir, dir, indexFilename, configMode);
|
|
1051
|
+
if (mode === "flat") {
|
|
1052
|
+
const allSources = [dir, ...knowledgeConfig.sources].filter(Boolean);
|
|
1053
|
+
const entries = buildKnowledgeIndex(projectDir, allSources);
|
|
1054
|
+
return { mode: "flat", domains: [], individualFiles: entries };
|
|
1055
|
+
}
|
|
1056
|
+
const domains = scanDomains(projectDir, dir, indexFilename, maxDepth);
|
|
1057
|
+
const rootFiles = collectRootFiles(projectDir, dir, indexFilename);
|
|
1058
|
+
const sourcesEntries = [];
|
|
1059
|
+
for (const source of knowledgeConfig.sources) {
|
|
1060
|
+
const fullPath = join2(projectDir, source);
|
|
1061
|
+
if (!existsSync(fullPath))
|
|
1062
|
+
continue;
|
|
1063
|
+
try {
|
|
1064
|
+
const stat = statSync(fullPath);
|
|
1065
|
+
if (stat.isFile() && extname(source) === ".md") {
|
|
1066
|
+
sourcesEntries.push({
|
|
1067
|
+
filename: source,
|
|
1068
|
+
summary: extractSummary(fullPath)
|
|
1069
|
+
});
|
|
1070
|
+
}
|
|
1071
|
+
} catch {}
|
|
1072
|
+
}
|
|
1073
|
+
const individualFiles = [...rootFiles, ...sourcesEntries];
|
|
1074
|
+
return { mode: "domain", domains, individualFiles };
|
|
1075
|
+
}
|
|
942
1076
|
|
|
943
1077
|
// src/lib/prompt-reader.ts
|
|
944
1078
|
import { readFileSync as readFileSync3 } from "fs";
|
|
@@ -983,9 +1117,16 @@ var DEFAULT_TURN_START = `## Knowledge Context
|
|
|
983
1117
|
### \uC791\uC5C5 \uC804 \uD544\uC218
|
|
984
1118
|
|
|
985
1119
|
- \uC544\uB798 **Available Knowledge** \uBAA9\uB85D\uC5D0\uC11C \uD604\uC7AC \uC791\uC5C5\uACFC \uAD00\uB828\uB41C \uBB38\uC11C\uB97C **\uBA3C\uC800** \uC77D\uC73C\uC138\uC694
|
|
1120
|
+
- \uB3C4\uBA54\uC778 \uD3F4\uB354 \uAD6C\uC870\uAC00 \uC788\uB2E4\uBA74 INDEX.md\uC758 \uC694\uC57D\uC744 \uCC38\uACE0\uD558\uC5EC \uD544\uC694\uD55C \uB178\uD2B8\uB9CC \uC120\uD0DD\uC801\uC73C\uB85C \uC77D\uC73C\uC138\uC694
|
|
986
1121
|
- \uBB38\uC11C \uB0B4 [[\uB9C1\uD06C]]\uB97C \uB530\uB77C\uAC00\uBA70 \uAD00\uB828 \uB178\uD2B8\uB97C \uD0D0\uC0C9\uD558\uC138\uC694 -- \uB9C1\uD06C\uB97C \uB193\uCE58\uBA74 \uC911\uC694\uD55C \uB9E5\uB77D\uC744 \uC783\uC2B5\uB2C8\uB2E4
|
|
987
1122
|
- \uC9C0\uC2DD \uD30C\uC77C\uC5D0 \uAE30\uB85D\uB41C \uC544\uD0A4\uD14D\uCC98 \uACB0\uC815, \uD328\uD134, \uC81C\uC57D\uC0AC\uD56D\uC744 \uBC18\uB4DC\uC2DC \uB530\uB974\uC138\uC694
|
|
988
1123
|
|
|
1124
|
+
### \uAC1C\uBC1C \uC6D0\uCE59
|
|
1125
|
+
|
|
1126
|
+
- **TDD** (Test-Driven Development): \uD14C\uC2A4\uD2B8\uB97C \uBA3C\uC800 \uC791\uC131\uD558\uACE0(RED), \uAD6C\uD604\uD558\uC5EC \uD1B5\uACFC\uC2DC\uD0A8 \uB4A4(GREEN), \uB9AC\uD329\uD1A0\uB9C1\uD558\uC138\uC694
|
|
1127
|
+
- **DDD** (Domain-Driven Design): \uB3C4\uBA54\uC778 \uAC1C\uB150\uC744 \uCF54\uB4DC \uAD6C\uC870\uC5D0 \uBC18\uC601\uD558\uC138\uC694. \uD0C0\uC785\uACFC \uBAA8\uB4C8\uC740 \uBE44\uC988\uB2C8\uC2A4 \uB3C4\uBA54\uC778\uC744 \uAE30\uC900\uC73C\uB85C \uBD84\uB9AC\uD558\uC138\uC694
|
|
1128
|
+
- **\uD14C\uC2A4\uD2B8 \uCEE4\uBC84\uB9AC\uC9C0**: \uC0C8\uB85C \uC791\uC131\uD558\uAC70\uB098 \uBCC0\uACBD\uD55C \uCF54\uB4DC\uB294 \uD14C\uC2A4\uD2B8 \uCEE4\uBC84\uB9AC\uC9C0 80% \uC774\uC0C1\uC744 \uBAA9\uD45C\uB85C \uD558\uC138\uC694. \uAD6C\uD604 \uC804\uC5D0 \uD14C\uC2A4\uD2B8\uBD80\uD130 \uC791\uC131\uD558\uBA74 \uC790\uC5F0\uC2A4\uB7FD\uAC8C \uB2EC\uC131\uB429\uB2C8\uB2E4
|
|
1129
|
+
|
|
989
1130
|
### \uC6B0\uC120\uC21C\uC704
|
|
990
1131
|
|
|
991
1132
|
- AGENTS.md\uC758 \uC9C0\uC2DC\uC0AC\uD56D\uC774 \uD56D\uC0C1 \uCD5C\uC6B0\uC120
|
|
@@ -999,8 +1140,10 @@ var DEFAULT_TURN_END = `## \uC791\uC5C5 \uB9C8\uBB34\uB9AC \uCCB4\uD06C\uB9AC\uC
|
|
|
999
1140
|
### \uD004\uB9AC\uD2F0 \uBCF4\uC7A5
|
|
1000
1141
|
|
|
1001
1142
|
- [ ] \uBCC0\uACBD\uD55C \uCF54\uB4DC\uC5D0 \uB300\uD574 lint \uC2E4\uD589
|
|
1002
|
-
- [ ] \
|
|
1143
|
+
- [ ] \uBCC0\uACBD\uD55C \uCF54\uB4DC\uC5D0 \uB300\uD574 formatter \uC2E4\uD589 (lint\uC640 \uBCC4\uAC1C)
|
|
1003
1144
|
- [ ] \uAE30\uC874 \uD14C\uC2A4\uD2B8 \uD1B5\uACFC \uD655\uC778
|
|
1145
|
+
- [ ] \uBCC0\uACBD \uBC94\uC704 \uD655\uC778: \uC694\uCCAD\uACFC \uBB34\uAD00\uD55C \uD30C\uC77C\uC744 \uAC74\uB4DC\uB9AC\uC9C0 \uC54A\uC558\uB294\uAC00?
|
|
1146
|
+
- [ ] \uC0C8\uB85C \uC791\uC131\uD558\uAC70\uB098 \uBCC0\uACBD\uD55C \uCF54\uB4DC\uC758 \uD14C\uC2A4\uD2B8 \uCEE4\uBC84\uB9AC\uC9C0 80% \uC774\uC0C1 \uB2EC\uC131
|
|
1004
1147
|
|
|
1005
1148
|
### \uC9C0\uC2DD \uC815\uB9AC (Zettelkasten)
|
|
1006
1149
|
|
|
@@ -1020,13 +1163,14 @@ var DEFAULT_TURN_END = `## \uC791\uC5C5 \uB9C8\uBB34\uB9AC \uCCB4\uD06C\uB9AC\uC
|
|
|
1020
1163
|
- [ ] \uC704 \uC0C1\uD669\uC5D0 \uD574\uB2F9\uD558\uB294 \uBC1C\uACAC\uC774 \uC788\uC5C8\uB2E4\uBA74 \uB178\uD2B8\uB97C \uC791\uC131\uD588\uB294\uAC00?
|
|
1021
1164
|
- [ ] \uAD00\uB828 \uAE30\uC874 \uB178\uD2B8\uC5D0 [[\uB9C1\uD06C]]\uB97C \uCD94\uAC00\uD588\uB294\uAC00?
|
|
1022
1165
|
- [ ] \uAE30\uC874 \uB178\uD2B8\uC758 \uB0B4\uC6A9\uC774 \uBCC0\uACBD\uC0AC\uD56D\uACFC \uBD88\uC77C\uCE58\uD558\uBA74 \uC5C5\uB370\uC774\uD2B8\uD588\uB294\uAC00?
|
|
1166
|
+
- [ ] \uB178\uD2B8\uB97C \uB3C4\uBA54\uC778 \uD3F4\uB354\uC5D0 \uC800\uC7A5\uD588\uB2E4\uBA74 \uD574\uB2F9 INDEX.md\uC5D0 \uCD94\uAC00\uD588\uB294\uAC00?
|
|
1023
1167
|
|
|
1024
1168
|
#### \uB178\uD2B8 \uC791\uC131 \uADDC\uCE59
|
|
1025
1169
|
|
|
1026
1170
|
- \uCCAB \uC904: \uBA85\uD655\uD55C \uC81C\uBAA9 (\`# Title\`)
|
|
1027
1171
|
- \uD575\uC2EC \uB0B4\uC6A9\uC744 \uC790\uC2E0\uC758 \uC5B8\uC5B4\uB85C \uAC04\uACB0\uD558\uAC8C \uC11C\uC220
|
|
1028
1172
|
- \uAD00\uB828 \uB178\uD2B8\uB97C \`[[relative/path/file.md]]\` \uD615\uD0DC\uC758 wikilink\uB85C \uC5F0\uACB0
|
|
1029
|
-
- knowledge \uB514\uB809\uD1A0\uB9AC (\uAE30\uBCF8: \`docs/\`)\uC5D0 \uC800\uC7A5
|
|
1173
|
+
- knowledge \uB514\uB809\uD1A0\uB9AC (\uAE30\uBCF8: \`docs/\`)\uC5D0 \uC800\uC7A5. \uB3C4\uBA54\uC778 \uD3F4\uB354\uAC00 \uC788\uB2E4\uBA74 \uC801\uC808\uD55C \uB3C4\uBA54\uC778\uC5D0 \uC800\uC7A5
|
|
1030
1174
|
`;
|
|
1031
1175
|
var DEFAULT_ADR_TEMPLATE = `# ADR-NNN: [\uC81C\uBAA9]
|
|
1032
1176
|
|
|
@@ -1220,6 +1364,20 @@ var DEFAULT_INSIGHT_TEMPLATE = `# Insight: [\uBC1C\uACAC \uC81C\uBAA9]
|
|
|
1220
1364
|
|
|
1221
1365
|
- [[\uAD00\uB828-insight.md]] / [[\uC601\uD5A5\uBC1B\uB294-\uD328\uD134.md]] / [[\uAD00\uB828-ADR.md]]
|
|
1222
1366
|
`;
|
|
1367
|
+
var DEFAULT_INDEX_TEMPLATE = `# [Domain] Domain
|
|
1368
|
+
|
|
1369
|
+
Overview: [1-2 sentence description of this domain]
|
|
1370
|
+
|
|
1371
|
+
## Notes
|
|
1372
|
+
|
|
1373
|
+
| File | Summary | Read When... |
|
|
1374
|
+
|------|---------|--------------|
|
|
1375
|
+
| [[example.md]] | Example summary | Working on X |
|
|
1376
|
+
|
|
1377
|
+
## Related Domains
|
|
1378
|
+
|
|
1379
|
+
- [[../other-domain/INDEX.md]] -- Description
|
|
1380
|
+
`;
|
|
1223
1381
|
var TEMPLATE_FILES = {
|
|
1224
1382
|
"adr.md": DEFAULT_ADR_TEMPLATE,
|
|
1225
1383
|
"pattern.md": DEFAULT_PATTERN_TEMPLATE,
|
|
@@ -1228,7 +1386,8 @@ var TEMPLATE_FILES = {
|
|
|
1228
1386
|
"decision.md": DEFAULT_DECISION_TEMPLATE,
|
|
1229
1387
|
"context.md": DEFAULT_CONTEXT_TEMPLATE,
|
|
1230
1388
|
"runbook.md": DEFAULT_RUNBOOK_TEMPLATE,
|
|
1231
|
-
"insight.md": DEFAULT_INSIGHT_TEMPLATE
|
|
1389
|
+
"insight.md": DEFAULT_INSIGHT_TEMPLATE,
|
|
1390
|
+
"index.md": DEFAULT_INDEX_TEMPLATE
|
|
1232
1391
|
};
|
|
1233
1392
|
function scaffoldIfNeeded(projectDir) {
|
|
1234
1393
|
const contextDir = join3(projectDir, ".opencode", "context");
|
|
@@ -1318,9 +1477,8 @@ ${lines}` }];
|
|
|
1318
1477
|
return;
|
|
1319
1478
|
const turnStartPath = join4(directory, config.prompts.turnStart ?? join4(DEFAULTS.promptDir, DEFAULTS.turnStartFile));
|
|
1320
1479
|
const turnStart = readPromptFile(turnStartPath);
|
|
1321
|
-
const
|
|
1322
|
-
const
|
|
1323
|
-
const indexContent = formatKnowledgeIndex(entries);
|
|
1480
|
+
const knowledgeIndex = buildKnowledgeIndexV2(directory, config.knowledge);
|
|
1481
|
+
const indexContent = knowledgeIndex.mode === "flat" ? formatKnowledgeIndex(knowledgeIndex.individualFiles) : formatDomainIndex(knowledgeIndex);
|
|
1324
1482
|
const combinedContent = [turnStart, indexContent].filter(Boolean).join(`
|
|
1325
1483
|
|
|
1326
1484
|
`);
|