@ksm0709/context 0.0.18 → 0.0.19
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 +4 -0
- package/dist/cli/index.js +169 -37
- package/dist/index.js +98 -62
- package/dist/omx/index.mjs +780 -0
- package/package.json +8 -4
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
// src/index.ts
|
|
3
|
-
import { join as
|
|
3
|
+
import { isAbsolute, join as join5 } from "path";
|
|
4
4
|
|
|
5
5
|
// node_modules/jsonc-parser/lib/esm/impl/scanner.js
|
|
6
6
|
function createScanner(text, ignoreTrivia = false) {
|
|
@@ -808,18 +808,19 @@ var ParseErrorCode;
|
|
|
808
808
|
|
|
809
809
|
// src/lib/config.ts
|
|
810
810
|
import { readFileSync } from "fs";
|
|
811
|
-
import { join } from "path";
|
|
811
|
+
import { join as join2 } from "path";
|
|
812
812
|
|
|
813
813
|
// src/constants.ts
|
|
814
814
|
var DEFAULTS = {
|
|
815
|
-
configPath: ".
|
|
816
|
-
promptDir: ".
|
|
815
|
+
configPath: ".context/config.jsonc",
|
|
816
|
+
promptDir: ".context/prompts",
|
|
817
817
|
turnStartFile: "turn-start.md",
|
|
818
818
|
turnEndFile: "turn-end.md",
|
|
819
819
|
knowledgeSources: ["AGENTS.md"],
|
|
820
|
-
templateDir: ".
|
|
820
|
+
templateDir: ".context/templates",
|
|
821
821
|
indexFilename: "INDEX.md",
|
|
822
|
-
maxDomainDepth: 2
|
|
822
|
+
maxDomainDepth: 2,
|
|
823
|
+
knowledgeDir: "docs"
|
|
823
824
|
};
|
|
824
825
|
var LIMITS = {
|
|
825
826
|
maxPromptFileSize: 64 * 1024,
|
|
@@ -830,12 +831,27 @@ var LIMITS = {
|
|
|
830
831
|
maxIndexFileSize: 32 * 1024
|
|
831
832
|
};
|
|
832
833
|
|
|
834
|
+
// src/lib/context-dir.ts
|
|
835
|
+
import { existsSync } from "fs";
|
|
836
|
+
import { join } from "path";
|
|
837
|
+
function resolveContextDir(projectDir) {
|
|
838
|
+
const nextContextDir = ".context";
|
|
839
|
+
if (existsSync(join(projectDir, nextContextDir))) {
|
|
840
|
+
return nextContextDir;
|
|
841
|
+
}
|
|
842
|
+
const legacyContextDir = ".opencode/context";
|
|
843
|
+
if (existsSync(join(projectDir, legacyContextDir))) {
|
|
844
|
+
return legacyContextDir;
|
|
845
|
+
}
|
|
846
|
+
return nextContextDir;
|
|
847
|
+
}
|
|
848
|
+
|
|
833
849
|
// src/lib/config.ts
|
|
834
850
|
function getDefaultConfig() {
|
|
835
851
|
return {
|
|
836
852
|
prompts: {
|
|
837
|
-
turnStart:
|
|
838
|
-
turnEnd:
|
|
853
|
+
turnStart: join2(DEFAULTS.promptDir, DEFAULTS.turnStartFile),
|
|
854
|
+
turnEnd: join2(DEFAULTS.promptDir, DEFAULTS.turnEndFile)
|
|
839
855
|
},
|
|
840
856
|
knowledge: {
|
|
841
857
|
dir: "docs",
|
|
@@ -863,7 +879,7 @@ function mergeWithDefaults(partial) {
|
|
|
863
879
|
};
|
|
864
880
|
}
|
|
865
881
|
function loadConfig(projectDir) {
|
|
866
|
-
const configPath =
|
|
882
|
+
const configPath = join2(projectDir, resolveContextDir(projectDir), "config.jsonc");
|
|
867
883
|
try {
|
|
868
884
|
const raw = readFileSync(configPath, "utf-8");
|
|
869
885
|
const parsed = parse2(raw);
|
|
@@ -876,8 +892,8 @@ function loadConfig(projectDir) {
|
|
|
876
892
|
}
|
|
877
893
|
|
|
878
894
|
// src/lib/knowledge-index.ts
|
|
879
|
-
import { readdirSync, readFileSync as readFileSync2, statSync, existsSync } from "fs";
|
|
880
|
-
import { join as
|
|
895
|
+
import { readdirSync, readFileSync as readFileSync2, statSync, existsSync as existsSync2 } from "fs";
|
|
896
|
+
import { join as join3, relative, extname } from "path";
|
|
881
897
|
function extractSummary(filePath) {
|
|
882
898
|
try {
|
|
883
899
|
const content = readFileSync2(filePath, "utf-8");
|
|
@@ -900,7 +916,7 @@ function scanDir(dir, projectDir, depth, entries) {
|
|
|
900
916
|
for (const item of items) {
|
|
901
917
|
if (entries.length >= LIMITS.maxIndexEntries)
|
|
902
918
|
break;
|
|
903
|
-
const fullPath =
|
|
919
|
+
const fullPath = join3(dir, item);
|
|
904
920
|
try {
|
|
905
921
|
const stat = statSync(fullPath);
|
|
906
922
|
if (stat.isDirectory()) {
|
|
@@ -920,8 +936,8 @@ function buildKnowledgeIndex(projectDir, sources) {
|
|
|
920
936
|
for (const source of sources) {
|
|
921
937
|
if (entries.length >= LIMITS.maxIndexEntries)
|
|
922
938
|
break;
|
|
923
|
-
const fullPath =
|
|
924
|
-
if (!
|
|
939
|
+
const fullPath = join3(projectDir, source);
|
|
940
|
+
if (!existsSync2(fullPath))
|
|
925
941
|
continue;
|
|
926
942
|
try {
|
|
927
943
|
const stat = statSync(fullPath);
|
|
@@ -950,7 +966,7 @@ function formatKnowledgeIndex(entries) {
|
|
|
950
966
|
function countMdFiles(dir, indexFilename) {
|
|
951
967
|
try {
|
|
952
968
|
const items = readdirSync(dir);
|
|
953
|
-
return items.filter((item) => extname(item) === ".md" && item !== indexFilename && statSync(
|
|
969
|
+
return items.filter((item) => extname(item) === ".md" && item !== indexFilename && statSync(join3(dir, item)).isFile()).length;
|
|
954
970
|
} catch {
|
|
955
971
|
return 0;
|
|
956
972
|
}
|
|
@@ -961,12 +977,12 @@ function scanDomainsRecursive(baseDir, projectDir, indexFilename, currentDepth,
|
|
|
961
977
|
try {
|
|
962
978
|
const items = readdirSync(baseDir);
|
|
963
979
|
for (const item of items) {
|
|
964
|
-
const fullPath =
|
|
980
|
+
const fullPath = join3(baseDir, item);
|
|
965
981
|
try {
|
|
966
982
|
if (!statSync(fullPath).isDirectory())
|
|
967
983
|
continue;
|
|
968
|
-
const indexPath =
|
|
969
|
-
if (
|
|
984
|
+
const indexPath = join3(fullPath, indexFilename);
|
|
985
|
+
if (existsSync2(indexPath) && statSync(indexPath).isFile()) {
|
|
970
986
|
const rawContent = readFileSync2(indexPath, "utf-8");
|
|
971
987
|
const indexContent = rawContent.slice(0, LIMITS.maxIndexFileSize);
|
|
972
988
|
results.push({
|
|
@@ -982,8 +998,8 @@ function scanDomainsRecursive(baseDir, projectDir, indexFilename, currentDepth,
|
|
|
982
998
|
} catch {}
|
|
983
999
|
}
|
|
984
1000
|
function scanDomains(projectDir, knowledgeDir, indexFilename, maxDepth) {
|
|
985
|
-
const baseDir =
|
|
986
|
-
if (!
|
|
1001
|
+
const baseDir = join3(projectDir, knowledgeDir);
|
|
1002
|
+
if (!existsSync2(baseDir))
|
|
987
1003
|
return [];
|
|
988
1004
|
const results = [];
|
|
989
1005
|
scanDomainsRecursive(baseDir, projectDir, indexFilename, 1, maxDepth, results);
|
|
@@ -1020,14 +1036,14 @@ function formatDomainIndex(index) {
|
|
|
1020
1036
|
`);
|
|
1021
1037
|
}
|
|
1022
1038
|
function collectRootFiles(projectDir, knowledgeDir, indexFilename) {
|
|
1023
|
-
const baseDir =
|
|
1024
|
-
if (!
|
|
1039
|
+
const baseDir = join3(projectDir, knowledgeDir);
|
|
1040
|
+
if (!existsSync2(baseDir))
|
|
1025
1041
|
return [];
|
|
1026
1042
|
const entries = [];
|
|
1027
1043
|
try {
|
|
1028
1044
|
const items = readdirSync(baseDir);
|
|
1029
1045
|
for (const item of items) {
|
|
1030
|
-
const fullPath =
|
|
1046
|
+
const fullPath = join3(baseDir, item);
|
|
1031
1047
|
try {
|
|
1032
1048
|
const stat = statSync(fullPath);
|
|
1033
1049
|
if (stat.isFile() && extname(item) === ".md" && item !== indexFilename) {
|
|
@@ -1056,8 +1072,8 @@ function buildKnowledgeIndexV2(projectDir, knowledgeConfig) {
|
|
|
1056
1072
|
const rootFiles = collectRootFiles(projectDir, dir, indexFilename);
|
|
1057
1073
|
const sourcesEntries = [];
|
|
1058
1074
|
for (const source of knowledgeConfig.sources) {
|
|
1059
|
-
const fullPath =
|
|
1060
|
-
if (!
|
|
1075
|
+
const fullPath = join3(projectDir, source);
|
|
1076
|
+
if (!existsSync2(fullPath))
|
|
1061
1077
|
continue;
|
|
1062
1078
|
try {
|
|
1063
1079
|
const stat = statSync(fullPath);
|
|
@@ -1086,14 +1102,18 @@ function readPromptFile(filePath) {
|
|
|
1086
1102
|
return "";
|
|
1087
1103
|
}
|
|
1088
1104
|
}
|
|
1105
|
+
function resolvePromptVariables(content, vars) {
|
|
1106
|
+
const normalized = (vars.knowledgeDir || "docs").replace(/\\/g, "/").replace(/\/+$/, "");
|
|
1107
|
+
return content.replaceAll("{{knowledgeDir}}", normalized);
|
|
1108
|
+
}
|
|
1089
1109
|
|
|
1090
1110
|
// src/lib/scaffold.ts
|
|
1091
|
-
import { existsSync as
|
|
1092
|
-
import { join as
|
|
1111
|
+
import { existsSync as existsSync3, mkdirSync, readFileSync as readFileSync4, writeFileSync } from "fs";
|
|
1112
|
+
import { join as join4 } from "path";
|
|
1093
1113
|
// package.json
|
|
1094
1114
|
var package_default = {
|
|
1095
1115
|
name: "@ksm0709/context",
|
|
1096
|
-
version: "0.0.
|
|
1116
|
+
version: "0.0.19",
|
|
1097
1117
|
author: {
|
|
1098
1118
|
name: "TaehoKang",
|
|
1099
1119
|
email: "ksm07091@gmail.com"
|
|
@@ -1108,6 +1128,11 @@ var package_default = {
|
|
|
1108
1128
|
import: "./dist/index.js",
|
|
1109
1129
|
types: "./dist/index.d.ts",
|
|
1110
1130
|
default: "./dist/index.js"
|
|
1131
|
+
},
|
|
1132
|
+
"./omx": {
|
|
1133
|
+
import: "./dist/omx/index.mjs",
|
|
1134
|
+
types: "./dist/omx/index.d.ts",
|
|
1135
|
+
default: "./dist/omx/index.mjs"
|
|
1111
1136
|
}
|
|
1112
1137
|
},
|
|
1113
1138
|
repository: {
|
|
@@ -1118,10 +1143,10 @@ var package_default = {
|
|
|
1118
1143
|
access: "public"
|
|
1119
1144
|
},
|
|
1120
1145
|
scripts: {
|
|
1121
|
-
build: "bun build ./src/index.ts --outdir dist --target bun && bun build ./src/cli/index.ts --outdir dist/cli --target bun",
|
|
1146
|
+
build: "bun build ./src/index.ts --outdir dist --target bun && bun build ./src/cli/index.ts --outdir dist/cli --target bun && bun build ./src/omx/index.ts --outdir dist/omx --target node --format esm --external jsonc-parser && mv dist/omx/index.js dist/omx/index.mjs",
|
|
1122
1147
|
test: "vitest run",
|
|
1123
1148
|
lint: "eslint src --ext .ts",
|
|
1124
|
-
prepublishOnly: "bun build ./src/index.ts --outdir dist --target bun && bun build ./src/cli/index.ts --outdir dist/cli --target bun"
|
|
1149
|
+
prepublishOnly: "bun build ./src/index.ts --outdir dist --target bun && bun build ./src/cli/index.ts --outdir dist/cli --target bun && bun build ./src/omx/index.ts --outdir dist/omx --target node --format esm --external jsonc-parser && mv dist/omx/index.js dist/omx/index.mjs"
|
|
1125
1150
|
},
|
|
1126
1151
|
files: [
|
|
1127
1152
|
"dist"
|
|
@@ -1130,7 +1155,6 @@ var package_default = {
|
|
|
1130
1155
|
"@opencode-ai/plugin": ">=1.0.0"
|
|
1131
1156
|
},
|
|
1132
1157
|
dependencies: {
|
|
1133
|
-
"@ksm0709/context": "^0.0.17",
|
|
1134
1158
|
"jsonc-parser": "^3.0.0"
|
|
1135
1159
|
},
|
|
1136
1160
|
devDependencies: {
|
|
@@ -1156,8 +1180,8 @@ var DEFAULT_CONFIG = `{
|
|
|
1156
1180
|
// Context Plugin Configuration
|
|
1157
1181
|
// See: https://github.com/ksm0709/context
|
|
1158
1182
|
"prompts": {
|
|
1159
|
-
"turnStart": "
|
|
1160
|
-
"turnEnd": "
|
|
1183
|
+
"turnStart": "prompts/turn-start.md",
|
|
1184
|
+
"turnEnd": "prompts/turn-end.md"
|
|
1161
1185
|
},
|
|
1162
1186
|
"knowledge": {
|
|
1163
1187
|
"dir": "docs",
|
|
@@ -1215,21 +1239,21 @@ var DEFAULT_TURN_END = `## \uC791\uC5C5 \uB9C8\uBB34\uB9AC
|
|
|
1215
1239
|
|
|
1216
1240
|
| \uC0C1\uD669 | \uD15C\uD50C\uB9BF | \uD30C\uC77C\uBA85 \uD328\uD134 |
|
|
1217
1241
|
| ------------------------------- | --------------------------------------------------- | --------------------------- |
|
|
1218
|
-
| \uC544\uD0A4\uD14D\uCC98/\uAE30\uC220 \uC2A4\uD0DD \uC911\uB300 \uACB0\uC815 | [ADR](.
|
|
1219
|
-
| \uBC18\uBCF5 \uC0AC\uC6A9\uD560 \uCF54\uB4DC \uD328\uD134 \uBC1C\uACAC | [Pattern](.
|
|
1220
|
-
| \uBE44\uC790\uBA85\uD55C \uBC84\uADF8 \uD574\uACB0 | [Bug](.
|
|
1221
|
-
| \uC678\uBD80 API/\uB77C\uC774\uBE0C\uB7EC\uB9AC \uC608\uC0C1\uC678 \uB3D9\uC791 | [Gotcha](.
|
|
1222
|
-
| \uC791\uC740 \uAE30\uC220\uC801 \uC120\uD0DD | [Decision](.
|
|
1223
|
-
| \uBAA8\uB4C8/\uD504\uB85C\uC81D\uD2B8 \uAC1C\uC694 \uD544\uC694 | [Context](.
|
|
1224
|
-
| \uBC18\uBCF5 \uAC00\uB2A5\uD55C \uD504\uB85C\uC138\uC2A4 \uC815\uB9BD | [Runbook](.
|
|
1225
|
-
| \uC2E4\uD5D8/\uB514\uBC84\uAE45 \uC911 \uD559\uC2B5 | [Insight](.
|
|
1242
|
+
| \uC544\uD0A4\uD14D\uCC98/\uAE30\uC220 \uC2A4\uD0DD \uC911\uB300 \uACB0\uC815 | [ADR](.context/templates/adr.md) | \`adr-NNN-\uC81C\uBAA9.md\` |
|
|
1243
|
+
| \uBC18\uBCF5 \uC0AC\uC6A9\uD560 \uCF54\uB4DC \uD328\uD134 \uBC1C\uACAC | [Pattern](.context/templates/pattern.md) | \`pattern-\uC81C\uBAA9.md\` |
|
|
1244
|
+
| \uBE44\uC790\uBA85\uD55C \uBC84\uADF8 \uD574\uACB0 | [Bug](.context/templates/bug.md) | \`bug-\uC81C\uBAA9.md\` |
|
|
1245
|
+
| \uC678\uBD80 API/\uB77C\uC774\uBE0C\uB7EC\uB9AC \uC608\uC0C1\uC678 \uB3D9\uC791 | [Gotcha](.context/templates/gotcha.md) | \`gotcha-\uB77C\uC774\uBE0C\uB7EC\uB9AC-\uC81C\uBAA9.md\` |
|
|
1246
|
+
| \uC791\uC740 \uAE30\uC220\uC801 \uC120\uD0DD | [Decision](.context/templates/decision.md) | \`decision-\uC81C\uBAA9.md\` |
|
|
1247
|
+
| \uBAA8\uB4C8/\uD504\uB85C\uC81D\uD2B8 \uAC1C\uC694 \uD544\uC694 | [Context](.context/templates/context.md) | \`context-\uC81C\uBAA9.md\` |
|
|
1248
|
+
| \uBC18\uBCF5 \uAC00\uB2A5\uD55C \uD504\uB85C\uC138\uC2A4 \uC815\uB9BD | [Runbook](.context/templates/runbook.md) | \`runbook-\uC81C\uBAA9.md\` |
|
|
1249
|
+
| \uC2E4\uD5D8/\uB514\uBC84\uAE45 \uC911 \uD559\uC2B5 | [Insight](.context/templates/insight.md) | \`insight-\uC81C\uBAA9.md\` |
|
|
1226
1250
|
|
|
1227
1251
|
\uD574\uB2F9 \uC0AC\uD56D\uC774 \uC5C6\uC73C\uBA74 \uC774 \uB2E8\uACC4\uB294 \uAC74\uB108\uB6F0\uC138\uC694.
|
|
1228
1252
|
|
|
1229
1253
|
- \uAD00\uB828 \uD15C\uD50C\uB9BF \uD30C\uC77C\uC744 \uC77D\uACE0 \uADF8 \uAD6C\uC870\uC5D0 \uB9DE\uCDB0 \uB0B4\uC6A9\uC744 \uC815\uB9AC\uD558\uC138\uC694
|
|
1230
1254
|
- \uB178\uD2B8 \uCCAB \uC904\uC740 \uBA85\uD655\uD55C \uC81C\uBAA9(\`# Title\`)\uC73C\uB85C \uC2DC\uC791\uD558\uC138\uC694
|
|
1231
1255
|
- \uD575\uC2EC \uB0B4\uC6A9\uC744 \uC790\uAE30 \uC5B8\uC5B4\uB85C \uAC04\uACB0\uD558\uAC8C \uC11C\uC220\uD558\uACE0, \uAD00\uB828 \uB178\uD2B8\uB294 \`[[relative/path/file.md]]\` \uD615\uD0DC\uB85C \uC5F0\uACB0\uD558\uC138\uC694
|
|
1232
|
-
- knowledge \uB514\uB809\uD1A0\uB9AC(
|
|
1256
|
+
- knowledge \uB514\uB809\uD1A0\uB9AC(\`{{knowledgeDir}}/\`) \uB610\uB294 \uC801\uC808\uD55C \uB3C4\uBA54\uC778 \uD3F4\uB354\uC5D0 \uC800\uC7A5\uD558\uACE0, \uD544\uC694\uD55C \uACBD\uC6B0 \uAE30\uC874 INDEX.md\uB098 \uAD00\uB828 \uB178\uD2B8\uB97C \uD568\uAED8 \uAC31\uC2E0\uD558\uC138\uC694
|
|
1233
1257
|
|
|
1234
1258
|
\uAE30\uC874 \uC124\uCE58\uC758 \uC0AC\uC6A9\uC790 \uD504\uB86C\uD504\uD2B8 \uD30C\uC77C\uC740 \uC790\uB3D9\uC73C\uB85C \uBC14\uB00C\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uC0C8 \uAE30\uBCF8 \uD504\uB86C\uD504\uD2B8\uAC00 \uD544\uC694\uD558\uBA74 \`context update prompt\`\uB85C \uBA85\uC2DC\uC801\uC73C\uB85C \uC0C8\uB85C\uACE0\uCE68\uD558\uC138\uC694.
|
|
1235
1259
|
`;
|
|
@@ -1451,20 +1475,20 @@ var TEMPLATE_FILES = {
|
|
|
1451
1475
|
"index.md": DEFAULT_INDEX_TEMPLATE
|
|
1452
1476
|
};
|
|
1453
1477
|
function scaffoldIfNeeded(projectDir) {
|
|
1454
|
-
const contextDir =
|
|
1455
|
-
if (
|
|
1478
|
+
const contextDir = join4(projectDir, resolveContextDir(projectDir));
|
|
1479
|
+
if (existsSync3(contextDir)) {
|
|
1456
1480
|
return false;
|
|
1457
1481
|
}
|
|
1458
1482
|
try {
|
|
1459
|
-
const promptsDir =
|
|
1483
|
+
const promptsDir = join4(contextDir, "prompts");
|
|
1460
1484
|
mkdirSync(promptsDir, { recursive: true });
|
|
1461
|
-
const templatesDir =
|
|
1485
|
+
const templatesDir = join4(contextDir, "templates");
|
|
1462
1486
|
mkdirSync(templatesDir, { recursive: true });
|
|
1463
|
-
writeFileSync(
|
|
1464
|
-
writeFileSync(
|
|
1465
|
-
writeFileSync(
|
|
1487
|
+
writeFileSync(join4(contextDir, "config.jsonc"), DEFAULT_CONFIG, "utf-8");
|
|
1488
|
+
writeFileSync(join4(promptsDir, DEFAULTS.turnStartFile), DEFAULT_TURN_START, "utf-8");
|
|
1489
|
+
writeFileSync(join4(promptsDir, DEFAULTS.turnEndFile), DEFAULT_TURN_END, "utf-8");
|
|
1466
1490
|
for (const [filename, content] of Object.entries(TEMPLATE_FILES)) {
|
|
1467
|
-
writeFileSync(
|
|
1491
|
+
writeFileSync(join4(templatesDir, filename), content, "utf-8");
|
|
1468
1492
|
}
|
|
1469
1493
|
writeVersion(contextDir, PLUGIN_VERSION);
|
|
1470
1494
|
return true;
|
|
@@ -1474,25 +1498,25 @@ function scaffoldIfNeeded(projectDir) {
|
|
|
1474
1498
|
}
|
|
1475
1499
|
function getStoredVersion(projectDir) {
|
|
1476
1500
|
try {
|
|
1477
|
-
return readFileSync4(
|
|
1501
|
+
return readFileSync4(join4(projectDir, resolveContextDir(projectDir), ".version"), "utf-8").trim();
|
|
1478
1502
|
} catch {
|
|
1479
1503
|
return null;
|
|
1480
1504
|
}
|
|
1481
1505
|
}
|
|
1482
1506
|
function writeVersion(contextDir, version) {
|
|
1483
|
-
writeFileSync(
|
|
1507
|
+
writeFileSync(join4(contextDir, ".version"), version, "utf-8");
|
|
1484
1508
|
}
|
|
1485
1509
|
function autoUpdateTemplates(projectDir) {
|
|
1486
|
-
const contextDir =
|
|
1487
|
-
if (!
|
|
1510
|
+
const contextDir = join4(projectDir, resolveContextDir(projectDir));
|
|
1511
|
+
if (!existsSync3(contextDir))
|
|
1488
1512
|
return [];
|
|
1489
1513
|
const stored = getStoredVersion(projectDir);
|
|
1490
1514
|
if (stored === PLUGIN_VERSION)
|
|
1491
1515
|
return [];
|
|
1492
|
-
mkdirSync(
|
|
1516
|
+
mkdirSync(join4(contextDir, "templates"), { recursive: true });
|
|
1493
1517
|
const updated = [];
|
|
1494
1518
|
for (const [filename, content] of Object.entries(TEMPLATE_FILES)) {
|
|
1495
|
-
const filePath =
|
|
1519
|
+
const filePath = join4(contextDir, "templates", filename);
|
|
1496
1520
|
try {
|
|
1497
1521
|
const existing = readFileSync4(filePath, "utf-8");
|
|
1498
1522
|
if (existing === content)
|
|
@@ -1506,14 +1530,23 @@ function autoUpdateTemplates(projectDir) {
|
|
|
1506
1530
|
}
|
|
1507
1531
|
|
|
1508
1532
|
// src/index.ts
|
|
1533
|
+
function resolvePromptPath(directory, contextDir, promptPath) {
|
|
1534
|
+
if (isAbsolute(promptPath))
|
|
1535
|
+
return promptPath;
|
|
1536
|
+
if (promptPath.startsWith(".context/") || promptPath.startsWith(".opencode/")) {
|
|
1537
|
+
return join5(directory, promptPath);
|
|
1538
|
+
}
|
|
1539
|
+
return join5(directory, contextDir, promptPath);
|
|
1540
|
+
}
|
|
1509
1541
|
var plugin = async ({ directory, client }) => {
|
|
1510
1542
|
const scaffolded = scaffoldIfNeeded(directory);
|
|
1543
|
+
const contextDir = resolveContextDir(directory);
|
|
1511
1544
|
if (scaffolded) {
|
|
1512
1545
|
await client.app.log({
|
|
1513
1546
|
body: {
|
|
1514
1547
|
service: "context",
|
|
1515
1548
|
level: "info",
|
|
1516
|
-
message:
|
|
1549
|
+
message: `Scaffold created at ${contextDir}/`
|
|
1517
1550
|
}
|
|
1518
1551
|
});
|
|
1519
1552
|
} else {
|
|
@@ -1536,8 +1569,10 @@ var plugin = async ({ directory, client }) => {
|
|
|
1536
1569
|
const lastUserMsg = output.messages.filter((m) => m.info.role === "user").at(-1);
|
|
1537
1570
|
if (!lastUserMsg)
|
|
1538
1571
|
return;
|
|
1539
|
-
const
|
|
1540
|
-
const
|
|
1572
|
+
const promptVars = { knowledgeDir: config.knowledge.dir ?? "docs" };
|
|
1573
|
+
const turnStartPath = resolvePromptPath(directory, contextDir, config.prompts.turnStart ?? join5(DEFAULTS.promptDir, DEFAULTS.turnStartFile));
|
|
1574
|
+
const turnStartRaw = readPromptFile(turnStartPath) ?? "";
|
|
1575
|
+
const turnStart = resolvePromptVariables(turnStartRaw, promptVars);
|
|
1541
1576
|
const knowledgeIndex = buildKnowledgeIndexV2(directory, config.knowledge);
|
|
1542
1577
|
const indexContent = knowledgeIndex.mode === "flat" ? formatKnowledgeIndex(knowledgeIndex.individualFiles) : formatDomainIndex(knowledgeIndex);
|
|
1543
1578
|
const combinedContent = [turnStart, indexContent].filter(Boolean).join(`
|
|
@@ -1552,10 +1587,11 @@ var plugin = async ({ directory, client }) => {
|
|
|
1552
1587
|
text: combinedContent
|
|
1553
1588
|
});
|
|
1554
1589
|
}
|
|
1555
|
-
const turnEndPath =
|
|
1556
|
-
const
|
|
1557
|
-
if (!
|
|
1590
|
+
const turnEndPath = resolvePromptPath(directory, contextDir, config.prompts.turnEnd ?? join5(DEFAULTS.promptDir, DEFAULTS.turnEndFile));
|
|
1591
|
+
const turnEndRaw = readPromptFile(turnEndPath);
|
|
1592
|
+
if (!turnEndRaw)
|
|
1558
1593
|
return;
|
|
1594
|
+
const turnEnd = resolvePromptVariables(turnEndRaw, promptVars);
|
|
1559
1595
|
const msgId = `context-turn-end-${Date.now()}`;
|
|
1560
1596
|
output.messages.push({
|
|
1561
1597
|
info: {
|