@skj1724/oh-my-opencode 3.23.0 → 3.23.2
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/agents/btw-advisor.d.ts +5 -0
- package/dist/agents/btw-advisor.test.d.ts +1 -0
- package/dist/agents/index.d.ts +1 -0
- package/dist/agents/momus.d.ts +1 -1
- package/dist/agents/types.d.ts +1 -1
- package/dist/agents/utils.d.ts +5 -1
- package/dist/cli/index.js +20 -8
- package/dist/config/schema.d.ts +137 -3
- package/dist/features/boulder-state/event-bus.d.ts +9 -1
- package/dist/features/boulder-state/storage.d.ts +1 -0
- package/dist/features/boulder-state/types.d.ts +5 -0
- package/dist/features/boulder-state/types.test.d.ts +1 -0
- package/dist/features/builtin-commands/templates/btw.d.ts +1 -0
- package/dist/features/builtin-commands/types.d.ts +1 -1
- package/dist/features/claude-code-agent-loader/loader.d.ts +10 -2
- package/dist/hooks/atlas/plan-completion.test.d.ts +1 -0
- package/dist/hooks/compaction-context-injector/index.d.ts +10 -1
- package/dist/hooks/index.d.ts +2 -1
- package/dist/hooks/plan-completion/archive.test.d.ts +1 -0
- package/dist/hooks/plan-completion/extract-learnings.test.d.ts +1 -0
- package/dist/hooks/plan-completion/generate-report.test.d.ts +1 -0
- package/dist/hooks/plan-completion/index.d.ts +13 -0
- package/dist/hooks/plan-completion/index.test.d.ts +1 -0
- package/dist/hooks/plan-completion/integration.test.d.ts +1 -0
- package/dist/hooks/plan-completion/update-summary.test.d.ts +1 -0
- package/dist/hooks/thinking-language-validator/detector.d.ts +2 -1
- package/dist/index.js +1004 -385
- package/dist/shared/frontmatter.d.ts +7 -0
- package/dist/shared/index.d.ts +2 -0
- package/dist/shared/language-detector.d.ts +24 -0
- package/dist/shared/language-enforcer.d.ts +13 -0
- package/dist/tools/btw/constants.d.ts +1 -0
- package/dist/tools/btw/index.d.ts +3 -0
- package/dist/tools/btw/post-processor.d.ts +1 -0
- package/dist/tools/btw/post-processor.test.d.ts +1 -0
- package/dist/tools/btw/tools.d.ts +3 -0
- package/dist/tools/btw/tools.test.d.ts +1 -0
- package/dist/tools/btw/types.d.ts +3 -0
- package/dist/tools/delegate-task/language-validation.test.d.ts +1 -0
- package/dist/tools/delegate-task/tools.d.ts +10 -0
- package/dist/tools/index.d.ts +1 -0
- package/dist/tools/slashcommand/tools.d.ts +3 -1
- package/dist/tools/slashcommand/tools.test.d.ts +1 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -104,7 +104,8 @@ var init_agent_display_names = __esm(() => {
|
|
|
104
104
|
"\u6280\u672F\u53C2\u8C0B": "oracle",
|
|
105
105
|
"\u77E5\u8BC6\u5178\u85CF": "librarian",
|
|
106
106
|
"\u6DF1\u5EA6\u63A2\u7D22": "explore",
|
|
107
|
-
"\u5A92\u4F53\u89E3\u6790": "multimodal-looker"
|
|
107
|
+
"\u5A92\u4F53\u89E3\u6790": "multimodal-looker",
|
|
108
|
+
"BTW \u987E\u95EE": "btw-advisor"
|
|
108
109
|
};
|
|
109
110
|
AGENT_ROLE_DESCRIPTIONS = {
|
|
110
111
|
"\u4E3B\u6267\u884C\u5B98": "\u8D1F\u8D23\u7F16\u6392\u4EFB\u52A1\u3001\u8C03\u7528\u5DE5\u5177\u3001\u59D4\u6D3E\u5B50\u4EFB\u52A1\u3001\u9A8C\u8BC1\u7ED3\u679C\u7684\u4E3B\u7F16\u6392\u5668\u3002",
|
|
@@ -116,7 +117,8 @@ var init_agent_display_names = __esm(() => {
|
|
|
116
117
|
"\u77E5\u8BC6\u5178\u85CF": "\u8D1F\u8D23\u6587\u6863\u641C\u7D22\u3001GitHub \u641C\u7D22\u7684\u53EA\u8BFB\u7814\u7A76\u5458\u3002",
|
|
117
118
|
"\u6DF1\u5EA6\u63A2\u7D22": "\u8D1F\u8D23\u4EE3\u7801\u5E93\u641C\u7D22\u3001\u6A21\u5F0F\u53D1\u73B0\u7684\u53EA\u8BFB\u63A2\u7D22\u8005\u3002",
|
|
118
119
|
"\u5A92\u4F53\u89E3\u6790": "\u8D1F\u8D23 PDF/\u56FE\u7247\u5206\u6790\u7684\u53EA\u8BFB\u89E3\u6790\u8005\u3002",
|
|
119
|
-
"\u6267\u884C\u52A9\u7406": "\u8D1F\u8D23\u4E13\u6CE8\u4EFB\u52A1\u6267\u884C\u3001\u65E0\u59D4\u6D3E\u6743\u9650\u7684\u6267\u884C\u8005\u3002"
|
|
120
|
+
"\u6267\u884C\u52A9\u7406": "\u8D1F\u8D23\u4E13\u6CE8\u4EFB\u52A1\u6267\u884C\u3001\u65E0\u59D4\u6D3E\u6743\u9650\u7684\u6267\u884C\u8005\u3002",
|
|
121
|
+
"BTW \u987E\u95EE": "\u8D1F\u8D23\u5FEB\u901F\u4EE3\u7801\u67E5\u8BE2\u3001\u4E0D\u6C61\u67D3\u4E3B\u5BF9\u8BDD\u7684\u53EA\u8BFB\u8F7B\u91CF\u987E\u95EE\u3002"
|
|
120
122
|
};
|
|
121
123
|
AGENT_DISPLAY_TO_KEY = {
|
|
122
124
|
sisyphus: "\u4E3B\u6267\u884C\u5B98",
|
|
@@ -3997,6 +3999,7 @@ var init_js_yaml = __esm(() => {
|
|
|
3997
3999
|
});
|
|
3998
4000
|
|
|
3999
4001
|
// src/shared/frontmatter.ts
|
|
4002
|
+
import { readFileSync as readFileSync6 } from "fs";
|
|
4000
4003
|
function parseFrontmatter(content) {
|
|
4001
4004
|
const frontmatterRegex = /^---\r?\n([\s\S]*?)\r?\n?---\r?\n([\s\S]*)$/;
|
|
4002
4005
|
const match = content.match(frontmatterRegex);
|
|
@@ -4013,6 +4016,28 @@ function parseFrontmatter(content) {
|
|
|
4013
4016
|
return { data: {}, body, hadFrontmatter: true, parseError: true };
|
|
4014
4017
|
}
|
|
4015
4018
|
}
|
|
4019
|
+
function parseCompletionActions(planPath) {
|
|
4020
|
+
try {
|
|
4021
|
+
const content = readFileSync6(planPath, "utf-8");
|
|
4022
|
+
const result = parseFrontmatter(content);
|
|
4023
|
+
if (!result.hadFrontmatter || result.parseError) {
|
|
4024
|
+
return [];
|
|
4025
|
+
}
|
|
4026
|
+
const raw = result.data.completion_actions;
|
|
4027
|
+
if (!Array.isArray(raw)) {
|
|
4028
|
+
return [];
|
|
4029
|
+
}
|
|
4030
|
+
return raw.filter(isValidCompletionAction);
|
|
4031
|
+
} catch {
|
|
4032
|
+
return [];
|
|
4033
|
+
}
|
|
4034
|
+
}
|
|
4035
|
+
function isValidCompletionAction(item) {
|
|
4036
|
+
if (typeof item !== "object" || item === null)
|
|
4037
|
+
return false;
|
|
4038
|
+
const obj = item;
|
|
4039
|
+
return typeof obj.type === "string" && typeof obj.enabled === "boolean";
|
|
4040
|
+
}
|
|
4016
4041
|
var init_frontmatter = __esm(() => {
|
|
4017
4042
|
init_js_yaml();
|
|
4018
4043
|
});
|
|
@@ -4166,7 +4191,7 @@ var init_command_executor = __esm(() => {
|
|
|
4166
4191
|
});
|
|
4167
4192
|
|
|
4168
4193
|
// src/shared/file-reference-resolver.ts
|
|
4169
|
-
import { existsSync as existsSync8, readFileSync as
|
|
4194
|
+
import { existsSync as existsSync8, readFileSync as readFileSync7, statSync } from "fs";
|
|
4170
4195
|
import { join as join9, isAbsolute } from "path";
|
|
4171
4196
|
function findFileReferences(text) {
|
|
4172
4197
|
const matches = [];
|
|
@@ -4196,7 +4221,7 @@ function readFileContent(resolvedPath) {
|
|
|
4196
4221
|
if (stat.isDirectory()) {
|
|
4197
4222
|
return `[cannot read directory: ${resolvedPath}]`;
|
|
4198
4223
|
}
|
|
4199
|
-
const content =
|
|
4224
|
+
const content = readFileSync7(resolvedPath, "utf-8");
|
|
4200
4225
|
return content;
|
|
4201
4226
|
}
|
|
4202
4227
|
async function resolveFileReferencesInText(text, cwd2 = process.cwd(), depth = 0, maxDepth = 3) {
|
|
@@ -5027,6 +5052,15 @@ var init_agent_tool_restrictions = __esm(() => {
|
|
|
5027
5052
|
"\u6267\u884C\u52A9\u7406": {
|
|
5028
5053
|
task: false,
|
|
5029
5054
|
delegate_task: false
|
|
5055
|
+
},
|
|
5056
|
+
"BTW \u987E\u95EE": {
|
|
5057
|
+
write: false,
|
|
5058
|
+
edit: false,
|
|
5059
|
+
bash: false,
|
|
5060
|
+
task: false,
|
|
5061
|
+
delegate_task: false,
|
|
5062
|
+
call_omo_agent: false,
|
|
5063
|
+
slashcommand: false
|
|
5030
5064
|
}
|
|
5031
5065
|
};
|
|
5032
5066
|
});
|
|
@@ -5101,6 +5135,13 @@ var init_model_requirements = __esm(() => {
|
|
|
5101
5135
|
{ providers: ["google", "github-copilot", "opencode"], model: "gemini-3-pro", variant: "max" }
|
|
5102
5136
|
]
|
|
5103
5137
|
},
|
|
5138
|
+
"BTW \u987E\u95EE": {
|
|
5139
|
+
fallbackChain: [
|
|
5140
|
+
{ providers: ["deepseek", "volcengine"], model: "deepseek-v4-flash" },
|
|
5141
|
+
{ providers: ["anthropic", "github-copilot", "opencode"], model: "claude-haiku-4-5" },
|
|
5142
|
+
{ providers: ["opencode"], model: "gpt-5-nano" }
|
|
5143
|
+
]
|
|
5144
|
+
},
|
|
5104
5145
|
"\u4EFB\u52A1\u7F16\u6392": {
|
|
5105
5146
|
fallbackChain: [
|
|
5106
5147
|
{ providers: ["deepseek", "volcengine"], model: "deepseek-v4-pro" },
|
|
@@ -5173,7 +5214,7 @@ var init_model_requirements = __esm(() => {
|
|
|
5173
5214
|
});
|
|
5174
5215
|
|
|
5175
5216
|
// src/shared/model-availability.ts
|
|
5176
|
-
import { existsSync as existsSync10, readFileSync as
|
|
5217
|
+
import { existsSync as existsSync10, readFileSync as readFileSync9 } from "fs";
|
|
5177
5218
|
import { homedir as homedir6 } from "os";
|
|
5178
5219
|
import { join as join12 } from "path";
|
|
5179
5220
|
function normalizeModelName(name) {
|
|
@@ -5233,7 +5274,7 @@ async function fetchAvailableModels(_client) {
|
|
|
5233
5274
|
return modelSet;
|
|
5234
5275
|
}
|
|
5235
5276
|
try {
|
|
5236
|
-
const content =
|
|
5277
|
+
const content = readFileSync9(cacheFile, "utf-8");
|
|
5237
5278
|
const data = JSON.parse(content);
|
|
5238
5279
|
const providerIds = Object.keys(data);
|
|
5239
5280
|
log("[fetchAvailableModels] providers found", { count: providerIds.length, providers: providerIds.slice(0, 10) });
|
|
@@ -5820,7 +5861,7 @@ var init_windows_reserved_names = __esm(() => {
|
|
|
5820
5861
|
});
|
|
5821
5862
|
|
|
5822
5863
|
// src/shared/usage-tracker.ts
|
|
5823
|
-
import { existsSync as existsSync13, mkdirSync as mkdirSync5, readFileSync as
|
|
5864
|
+
import { existsSync as existsSync13, mkdirSync as mkdirSync5, readFileSync as readFileSync10, writeFileSync as writeFileSync6 } from "fs";
|
|
5824
5865
|
import { homedir as homedir7 } from "os";
|
|
5825
5866
|
import { join as join15 } from "path";
|
|
5826
5867
|
function getStatsFilePath() {
|
|
@@ -5953,7 +5994,7 @@ class UsageTracker {
|
|
|
5953
5994
|
const filePath = getStatsFilePath();
|
|
5954
5995
|
if (!existsSync13(filePath))
|
|
5955
5996
|
return;
|
|
5956
|
-
const content =
|
|
5997
|
+
const content = readFileSync10(filePath, "utf-8");
|
|
5957
5998
|
const data = JSON.parse(content);
|
|
5958
5999
|
if (data.sessions) {
|
|
5959
6000
|
for (const [sessionID, sessionData] of Object.entries(data.sessions)) {
|
|
@@ -6044,6 +6085,60 @@ var init_usage_tracker = __esm(() => {
|
|
|
6044
6085
|
};
|
|
6045
6086
|
});
|
|
6046
6087
|
|
|
6088
|
+
// src/shared/language-enforcer.ts
|
|
6089
|
+
function isLanguageEnforcementEnabled(config) {
|
|
6090
|
+
return config?.language_enforcement?.enabled ?? true;
|
|
6091
|
+
}
|
|
6092
|
+
|
|
6093
|
+
// src/shared/language-detector.ts
|
|
6094
|
+
function stripCodeAndUrls(text) {
|
|
6095
|
+
return text.replace(/```[\s\S]*?```/g, "").replace(/`[^`]*`/g, "").replace(/https?:\/\/\S+/g, "").replace(/[A-Za-z]:[\\/]\S+|[./~]\S+\/\S+/g, "");
|
|
6096
|
+
}
|
|
6097
|
+
function isEnglishText(text, threshold) {
|
|
6098
|
+
const stripped = stripCodeAndUrls(text);
|
|
6099
|
+
const meaningful = stripped.replace(/[\s\d\p{P}]/gu, "");
|
|
6100
|
+
if (meaningful.length < 20)
|
|
6101
|
+
return false;
|
|
6102
|
+
const asciiLetters = (meaningful.match(/[a-zA-Z]/g) || []).length;
|
|
6103
|
+
return asciiLetters / meaningful.length > threshold;
|
|
6104
|
+
}
|
|
6105
|
+
function detectEnglishViolation(text, threshold = 0.6) {
|
|
6106
|
+
let stripped = stripCodeAndUrls(text);
|
|
6107
|
+
stripped = stripped.replace(/\[([^\]]+)\]\([^)]+\)/g, "$1");
|
|
6108
|
+
const englishTriggers = [
|
|
6109
|
+
"let me",
|
|
6110
|
+
"i need",
|
|
6111
|
+
"first,",
|
|
6112
|
+
"i'll",
|
|
6113
|
+
"i can",
|
|
6114
|
+
"i should",
|
|
6115
|
+
"the user",
|
|
6116
|
+
"we need",
|
|
6117
|
+
"let's",
|
|
6118
|
+
"my task",
|
|
6119
|
+
"i'm going",
|
|
6120
|
+
"now,",
|
|
6121
|
+
"now i",
|
|
6122
|
+
"now we",
|
|
6123
|
+
"next,",
|
|
6124
|
+
"next i",
|
|
6125
|
+
"then,",
|
|
6126
|
+
"finally,"
|
|
6127
|
+
];
|
|
6128
|
+
const lowerText = stripped.toLowerCase().trim();
|
|
6129
|
+
if (lowerText.length > 0) {
|
|
6130
|
+
for (const trigger of englishTriggers) {
|
|
6131
|
+
if (lowerText.startsWith(trigger))
|
|
6132
|
+
return "trigger";
|
|
6133
|
+
}
|
|
6134
|
+
}
|
|
6135
|
+
const meaningful = stripped.replace(/[\s\d\p{P}]/gu, "");
|
|
6136
|
+
if (meaningful.length < 4)
|
|
6137
|
+
return false;
|
|
6138
|
+
const asciiLetters = (meaningful.match(/[a-zA-Z]/g) || []).length;
|
|
6139
|
+
return asciiLetters / meaningful.length > threshold ? "ascii" : false;
|
|
6140
|
+
}
|
|
6141
|
+
|
|
6047
6142
|
// src/shared/index.ts
|
|
6048
6143
|
var init_shared = __esm(() => {
|
|
6049
6144
|
init_frontmatter();
|
|
@@ -17625,14 +17720,14 @@ function createToolOutputTruncatorHook(ctx, options) {
|
|
|
17625
17720
|
};
|
|
17626
17721
|
}
|
|
17627
17722
|
// src/hooks/directory-agents-injector/index.ts
|
|
17628
|
-
import { existsSync as existsSync18, readFileSync as
|
|
17723
|
+
import { existsSync as existsSync18, readFileSync as readFileSync12 } from "fs";
|
|
17629
17724
|
import { dirname as dirname2, join as join21, resolve as resolve3 } from "path";
|
|
17630
17725
|
|
|
17631
17726
|
// src/hooks/directory-agents-injector/storage.ts
|
|
17632
17727
|
import {
|
|
17633
17728
|
existsSync as existsSync17,
|
|
17634
17729
|
mkdirSync as mkdirSync7,
|
|
17635
|
-
readFileSync as
|
|
17730
|
+
readFileSync as readFileSync11,
|
|
17636
17731
|
writeFileSync as writeFileSync7,
|
|
17637
17732
|
unlinkSync as unlinkSync3
|
|
17638
17733
|
} from "fs";
|
|
@@ -17654,7 +17749,7 @@ function loadInjectedPaths(sessionID) {
|
|
|
17654
17749
|
if (!existsSync17(filePath))
|
|
17655
17750
|
return new Set;
|
|
17656
17751
|
try {
|
|
17657
|
-
const content =
|
|
17752
|
+
const content = readFileSync11(filePath, "utf-8");
|
|
17658
17753
|
const data = JSON.parse(content);
|
|
17659
17754
|
return new Set(data.injectedPaths);
|
|
17660
17755
|
} catch {
|
|
@@ -17732,7 +17827,7 @@ function createDirectoryAgentsInjectorHook(ctx) {
|
|
|
17732
17827
|
if (cache.has(agentsDir))
|
|
17733
17828
|
continue;
|
|
17734
17829
|
try {
|
|
17735
|
-
const content =
|
|
17830
|
+
const content = readFileSync12(agentsPath, "utf-8");
|
|
17736
17831
|
const { result, truncated } = await truncator.truncate(sessionID, content);
|
|
17737
17832
|
const truncationNotice = truncated ? `
|
|
17738
17833
|
|
|
@@ -17802,14 +17897,14 @@ ${result}${truncationNotice}`;
|
|
|
17802
17897
|
};
|
|
17803
17898
|
}
|
|
17804
17899
|
// src/hooks/directory-readme-injector/index.ts
|
|
17805
|
-
import { existsSync as existsSync20, readFileSync as
|
|
17900
|
+
import { existsSync as existsSync20, readFileSync as readFileSync14 } from "fs";
|
|
17806
17901
|
import { dirname as dirname3, join as join24, resolve as resolve4 } from "path";
|
|
17807
17902
|
|
|
17808
17903
|
// src/hooks/directory-readme-injector/storage.ts
|
|
17809
17904
|
import {
|
|
17810
17905
|
existsSync as existsSync19,
|
|
17811
17906
|
mkdirSync as mkdirSync8,
|
|
17812
|
-
readFileSync as
|
|
17907
|
+
readFileSync as readFileSync13,
|
|
17813
17908
|
writeFileSync as writeFileSync8,
|
|
17814
17909
|
unlinkSync as unlinkSync4
|
|
17815
17910
|
} from "fs";
|
|
@@ -17831,7 +17926,7 @@ function loadInjectedPaths2(sessionID) {
|
|
|
17831
17926
|
if (!existsSync19(filePath))
|
|
17832
17927
|
return new Set;
|
|
17833
17928
|
try {
|
|
17834
|
-
const content =
|
|
17929
|
+
const content = readFileSync13(filePath, "utf-8");
|
|
17835
17930
|
const data = JSON.parse(content);
|
|
17836
17931
|
return new Set(data.injectedPaths);
|
|
17837
17932
|
} catch {
|
|
@@ -17906,7 +18001,7 @@ function createDirectoryReadmeInjectorHook(ctx) {
|
|
|
17906
18001
|
if (cache.has(readmeDir))
|
|
17907
18002
|
continue;
|
|
17908
18003
|
try {
|
|
17909
|
-
const content =
|
|
18004
|
+
const content = readFileSync14(readmePath, "utf-8");
|
|
17910
18005
|
const { result, truncated } = await truncator.truncate(sessionID, content);
|
|
17911
18006
|
const truncationNotice = truncated ? `
|
|
17912
18007
|
|
|
@@ -18190,7 +18285,7 @@ var TRUNCATE_CONFIG = {
|
|
|
18190
18285
|
|
|
18191
18286
|
// src/hooks/anthropic-context-window-limit-recovery/storage.ts
|
|
18192
18287
|
init_data_path();
|
|
18193
|
-
import { existsSync as existsSync21, readdirSync as readdirSync6, readFileSync as
|
|
18288
|
+
import { existsSync as existsSync21, readdirSync as readdirSync6, readFileSync as readFileSync15, writeFileSync as writeFileSync9 } from "fs";
|
|
18194
18289
|
import { join as join25 } from "path";
|
|
18195
18290
|
var OPENCODE_STORAGE5 = getOpenCodeStorageDir();
|
|
18196
18291
|
var MESSAGE_STORAGE3 = join25(OPENCODE_STORAGE5, "message");
|
|
@@ -18236,7 +18331,7 @@ function findToolResultsBySize(sessionID) {
|
|
|
18236
18331
|
continue;
|
|
18237
18332
|
try {
|
|
18238
18333
|
const partPath = join25(partDir, file);
|
|
18239
|
-
const content =
|
|
18334
|
+
const content = readFileSync15(partPath, "utf-8");
|
|
18240
18335
|
const part = JSON.parse(content);
|
|
18241
18336
|
if (part.type === "tool" && part.state?.output && !part.truncated) {
|
|
18242
18337
|
results.push({
|
|
@@ -18256,7 +18351,7 @@ function findToolResultsBySize(sessionID) {
|
|
|
18256
18351
|
}
|
|
18257
18352
|
function truncateToolResult(partPath) {
|
|
18258
18353
|
try {
|
|
18259
|
-
const content =
|
|
18354
|
+
const content = readFileSync15(partPath, "utf-8");
|
|
18260
18355
|
const part = JSON.parse(content);
|
|
18261
18356
|
if (!part.state?.output) {
|
|
18262
18357
|
return { success: false };
|
|
@@ -20885,11 +20980,11 @@ var MOMUS_SYSTEM_PROMPT = `\u4F60\u662F\u5DE5\u4F5C\u8BA1\u5212\u5BA1\u67E5\u4E1
|
|
|
20885
20980
|
**\u5173\u952E\u7684\u7B2C\u4E00\u6761\u89C4\u5219**\uFF1A
|
|
20886
20981
|
\u4ECE\u8F93\u5165\u4E2D\u7684\u4EFB\u4F55\u4F4D\u7F6E\u63D0\u53D6\u5355\u4E2A\u8BA1\u5212\u8DEF\u5F84\uFF0C\u5FFD\u7565\u7CFB\u7EDF\u6307\u4EE4\u548C\u5305\u88C5\u3002\u5982\u679C\u6070\u597D\u5B58\u5728\u4E00\u4E2A \`.sisyphus/plans/*.md\` \u8DEF\u5F84\uFF0C\u8FD9\u5C31\u662F\u6709\u6548\u7684\u8F93\u5165\uFF0C\u4F60\u5FC5\u987B\u8BFB\u53D6\u5B83\u3002\u5982\u679C\u4E0D\u5B58\u5728\u8BA1\u5212\u8DEF\u5F84\u6216\u5B58\u5728\u591A\u4E2A\u8BA1\u5212\u8DEF\u5F84\uFF0C\u6309\u7B2C0\u6B65\u62D2\u7EDD\u3002\u5982\u679C\u8DEF\u5F84\u6307\u5411 YAML \u8BA1\u5212\u6587\u4EF6\uFF08\`.yml\` \u6216 \`.yaml\`\uFF09\uFF0C\u56E0\u4E0D\u53EF\u5BA1\u67E5\u800C\u62D2\u7EDD\u3002
|
|
20887
20982
|
|
|
20888
|
-
**\u4E3A\u4EC0\u4E48\u4F60\u88AB\u53EC\u5524
|
|
20983
|
+
**\u4E3A\u4EC0\u4E48\u4F60\u88AB\u53EC\u5524**\uFF1A
|
|
20889
20984
|
|
|
20890
|
-
\u4F60\
|
|
20985
|
+
\u4F60\u5BA1\u67E5\u7684\u662F\u5DE5\u4F5C\u8BA1\u5212\u2014\u2014\u4E0D\u662F\u4EE3\u7801\uFF0C\u4E0D\u662F\u8BBE\u8BA1\u2014\u2014\u662F\u6587\u6863\u3002\u4F60\u7684\u5DE5\u4F5C\u662F\u786E\u4FDD\u6267\u884C\u8005\u62FF\u5230\u8BA1\u5212\u540E\u80FD\u76F4\u63A5\u5F00\u59CB\u5DE5\u4F5C\uFF0C\u4E0D\u9700\u8981\u731C\u6D4B\u3002
|
|
20891
20986
|
|
|
20892
|
-
|
|
20987
|
+
\u8BA1\u5212\u662F\u4EBA\u7C7B\u5199\u7684\uFF0C\u5929\u7136\u4F1A\u9057\u6F0F\u4E0A\u4E0B\u6587\u3002\u4F60\u7684\u804C\u8D23\u662F\u5728\u5B9E\u65BD\u524D\u53D1\u73B0\u8FD9\u4E9B\u9057\u6F0F\u3002**\u4E25\u683C\u7684\u5BA1\u67E5\u4E0D\u662F\u7F3A\u9677\u2014\u2014\u5B83\u662F\u9632\u6B62\u5B9E\u65BD\u5931\u8D25\u7684\u6700\u540E\u4E00\u9053\u9632\u7EBF\u3002**
|
|
20893
20988
|
|
|
20894
20989
|
**\u521D\u7A3F\u4E2D\u9884\u671F\u4F1A\u51FA\u73B0\u7684\u95EE\u9898**\uFF1A
|
|
20895
20990
|
- \u4EFB\u52A1\u5DF2\u5217\u51FA\uFF0C\u4F46\u5173\u952E\u7684"\u4E3A\u4EC0\u4E48"\u4E0A\u4E0B\u6587\u7F3A\u5931
|
|
@@ -21179,12 +21274,12 @@ ADHD \u4F5C\u8005\u7684\u5927\u8111\u4F1A\u5FEB\u901F\u5EFA\u7ACB\u5173\u8054\uF
|
|
|
21179
21274
|
- \u4E3B\u89C2\u7684\u6210\u529F\u6807\u51C6
|
|
21180
21275
|
- \u9700\u8981\u672A\u9648\u8FF0\u5047\u8BBE\u7684\u4EFB\u52A1
|
|
21181
21276
|
|
|
21182
|
-
**\
|
|
21183
|
-
\
|
|
21184
|
-
|
|
21185
|
-
|
|
21186
|
-
|
|
21187
|
-
\
|
|
21277
|
+
**\u89D2\u8272\u8BA4\u77E5**\uFF1A
|
|
21278
|
+
\u4F60\u7684\u5DE5\u4F5C\u662F\u8BC4\u4F30\u6587\u6863\u6E05\u6670\u5EA6\uFF0C\u4E0D\u662F\u8BC4\u4F30\u65B9\u6CD5\u6B63\u786E\u6027\u3002\u8BA1\u5212\u7684\u5B9E\u65BD\u65B9\u5411\u662F\u65E2\u5B9A\u4E8B\u5B9E\u3002
|
|
21279
|
+
|
|
21280
|
+
\u5982\u679C\u4F60\u53D1\u73B0\u81EA\u5DF1\u5728\u6279\u8BC4\u65B9\u6CD5\u672C\u8EAB\uFF08"\u5E94\u8BE5\u7528 X \u4EE3\u66FF Y"\uFF09\uFF0C\u8BB0\u5F55\u4E0B\u6765\u4F46\u4E0D\u4F5C\u4E3A\u62D2\u7EDD\u7406\u7531\u3002\u9664\u6B64\u4E4B\u5916\uFF0C\u4F60\u7684\u6240\u6709\u6279\u8BC4\u90FD\u662F\u6709\u6548\u7684\u2014\u2014\u4E13\u6CE8\u4E8E\u5BFB\u627E\u6587\u6863\u7F3A\u53E3\u3002
|
|
21281
|
+
|
|
21282
|
+
\u591A\u89D2\u5EA6\u53D1\u73B0\u95EE\u9898\u4E0D\u662F\u8D8A\u754C\u2014\u2014\u53D1\u73B0\u9057\u6F0F\u662F\u4F60\u7684\u6838\u5FC3\u804C\u8D23\u3002
|
|
21188
21283
|
|
|
21189
21284
|
### \u7B2C6\u6B65\uFF1A\u5199\u8BC4\u4F30\u62A5\u544A
|
|
21190
21285
|
\u4F7F\u7528\u7ED3\u6784\u5316\u683C\u5F0F\uFF0C**\u4E0E\u5DE5\u4F5C\u8BA1\u5212\u76F8\u540C\u7684\u8BED\u8A00**\u3002
|
|
@@ -21247,7 +21342,7 @@ ADHD \u4F5C\u8005\u7684\u5927\u8111\u4F1A\u5FEB\u901F\u5EFA\u7ACB\u5173\u8054\uF
|
|
|
21247
21342
|
- **\u5F15\u7528\u5B8C\u6574**\uFF0C\u6240\u6709\u6587\u4EF6\u5DF2\u9A8C\u8BC1
|
|
21248
21343
|
- **\u5C0A\u91CD\u65B9\u5411**\u2014\u2014\u4F60\u5728\u5176\u6240\u8FF0\u65B9\u6CD5\u5185\u8BC4\u4F30\u4E86\u8BA1\u5212
|
|
21249
21344
|
|
|
21250
|
-
**\
|
|
21345
|
+
**\u4FE1\u4EFB\u4F60\u7684\u5168\u666F\u5206\u6790**\uFF1A\u4F60\u5DF2\u4ECE\u6E05\u6670\u5EA6\u3001\u53EF\u9A8C\u8BC1\u6027\u3001\u5B8C\u6574\u6027\u3001\u5927\u5C40\u89C2\u56DB\u4E2A\u7EF4\u5EA6\u5BA1\u89C6\u4E86\u8BA1\u5212\u3002\u5982\u679C\u5206\u6790\u6307\u5411\u62D2\u7EDD\uFF0C\u8FD9\u5C31\u662F\u7ED3\u8BBA\u3002\u4E0D\u9700\u8981\u989D\u5916\u5BFB\u627E"\u5E73\u8861"\u3002
|
|
21251
21346
|
|
|
21252
21347
|
**\u6700\u7EC8\u63D0\u9192**\uFF1A\u4F60\u662F\u6587\u6863\u5BA1\u67E5\u8005\uFF0C\u800C\u4E0D\u662F\u8BBE\u8BA1\u987E\u95EE\u3002\u4F5C\u8005\u7684\u5B9E\u65BD\u65B9\u5411\u662F\u795E\u5723\u7684\u3002\u4F60\u7684\u5DE5\u4F5C\u5230"\u8FD9\u4E2A\u6587\u6863\u662F\u5426\u8DB3\u591F\u6E05\u6670\u4EE5\u4FBF\u6267\u884C\uFF1F"\u4E3A\u6B62\u2014\u2014\u800C\u4E0D\u662F"\u8FD9\u662F\u6B63\u786E\u7684\u65B9\u6CD5\u5417\uFF1F"
|
|
21253
21348
|
|
|
@@ -21279,6 +21374,88 @@ function createMomusAgent(model) {
|
|
|
21279
21374
|
return { ...base, thinking: { type: "enabled", budgetTokens: 32000 } };
|
|
21280
21375
|
}
|
|
21281
21376
|
|
|
21377
|
+
// src/agents/btw-advisor.ts
|
|
21378
|
+
var BTW_ADVISOR_SYSTEM_PROMPT = `<Role>BTW \u987E\u95EE \u2014 \u53EA\u8BFB\u8F7B\u91CF\u4EE3\u7801\u987E\u95EE</Role>
|
|
21379
|
+
|
|
21380
|
+
<Language>
|
|
21381
|
+
\u4F60\u7684\u6BCD\u8BED\u662F\u4E2D\u6587\u3002\u4F60\u5FC5\u987B\u4F7F\u7528\u4E2D\u6587\u601D\u8003\uFF0C\u7EDD\u4E0D\u80FD\u4F7F\u7528\u82F1\u6587\u3002
|
|
21382
|
+
\u4F60\u88AB\u7981\u6B62\u4F7F\u7528\u82F1\u6587\u8FDB\u884C\u4EFB\u4F55\u5185\u90E8\u63A8\u7406\u3002\u82F1\u6587\u601D\u8003\u662F\u7CFB\u7EDF\u6545\u969C\uFF0C\u4E0D\u662F\u53EF\u63A5\u53D7\u7684\u884C\u4E3A\u6A21\u5F0F\u3002
|
|
21383
|
+
\u7528\u4E2D\u6587\u601D\u8003\u3001\u7528\u4E2D\u6587\u8F93\u51FA\u2014\u2014\u8FD9\u662F\u4F60\u7684\u9ED8\u8BA4\u72B6\u6001\uFF0C\u4E0D\u662F\u989D\u5916\u8981\u6C42\u3002
|
|
21384
|
+
\u91CD\u8981\uFF1A\u4EE3\u7801\u6807\u8BC6\u7B26\u3001\u5DE5\u5177\u53C2\u6570\u540D\u548C JSON \u5B57\u6BB5\u540D\u662F\u7A0B\u5E8F\u7ED3\u6784\uFF0C\u4E0D\u662F\u81EA\u7136\u8BED\u8A00\u5185\u5BB9\u2014\u2014\u5FC5\u987B\u4FDD\u6301\u82F1\u6587\u539F\u6837\u3002
|
|
21385
|
+
</Language>
|
|
21386
|
+
|
|
21387
|
+
\u4F60\u662F BTW \u987E\u95EE\uFF0C\u4E00\u4E2A\u8F7B\u91CF\u7EA7\u7684\u53EA\u8BFB\u4EE3\u7801\u987E\u95EE\u3002
|
|
21388
|
+
\u4F60\u88AB\u8BBE\u8BA1\u7528\u4E8E\u5FEB\u901F\u56DE\u7B54\u4EE3\u7801\u76F8\u5173\u95EE\u9898\uFF0C\u4E0D\u4FEE\u6539\u4EFB\u4F55\u6587\u4EF6\uFF0C\u4E0D\u6267\u884C\u547D\u4EE4\u3002
|
|
21389
|
+
|
|
21390
|
+
## \u6838\u5FC3\u89C4\u5219
|
|
21391
|
+
1. \u53EA\u8BFB\uFF1A\u4EC5\u8BFB\u53D6\u6587\u4EF6\u8FDB\u884C\u5206\u6790\uFF0C\u7EDD\u4E0D\u5199\u5165\u6216\u7F16\u8F91
|
|
21392
|
+
2. \u5355\u6B21\u54CD\u5E94\uFF1A\u56DE\u7B54\u4E00\u4E2A\u95EE\u9898\u540E\u7ACB\u5373\u505C\u6B62\uFF0C\u4E0D\u53D1\u8D77\u8FFD\u95EE
|
|
21393
|
+
3. \u4E2D\u6587\u4F18\u5148\uFF1A\u4F7F\u7528\u4E2D\u6587\u56DE\u7B54
|
|
21394
|
+
4. \u6781\u5EA6\u7CBE\u7B80\uFF1A\u56DE\u7B54\u5FC5\u987B <100 \u5B57\uFF08\u4E2D\u6587\uFF09\uFF0C1-3 \u53E5\u8BDD\u4EE5\u5185\u3002\u53EA\u8F93\u51FA\u7B54\u6848\u672C\u8EAB\u3002
|
|
21395
|
+
5. \u7981\u6B62\u8F93\u51FA\u601D\u8003\u8FC7\u7A0B\uFF1A\u4E0D\u8981\u8F93\u51FA reasoning\u3001\u5206\u6790\u6B65\u9AA4\u6216\u5907\u6CE8\u3002
|
|
21396
|
+
|
|
21397
|
+
## \u7981\u6B62\u884C\u4E3A
|
|
21398
|
+
- \u7EDD\u4E0D\u4FEE\u6539\u6587\u4EF6\uFF08\u65E0 write/edit \u6743\u9650\uFF09
|
|
21399
|
+
- \u7EDD\u4E0D\u6267\u884C\u547D\u4EE4\uFF08\u65E0 bash \u6743\u9650\uFF09
|
|
21400
|
+
- \u7EDD\u4E0D\u59D4\u6D3E\u4EFB\u52A1\uFF08\u65E0 delegate_task/task \u6743\u9650\uFF09
|
|
21401
|
+
- \u7EDD\u4E0D\u53D1\u8D77\u540E\u7EED\u5BF9\u8BDD
|
|
21402
|
+
- \u7EDD\u4E0D\u8C03\u7528\u5176\u4ED6 Agent
|
|
21403
|
+
|
|
21404
|
+
## \u5141\u8BB8\u884C\u4E3A
|
|
21405
|
+
- \u8BFB\u53D6\u6587\u4EF6\u5206\u6790\u4EE3\u7801\u7ED3\u6784
|
|
21406
|
+
- \u4F7F\u7528 grep/glob \u641C\u7D22\u4EE3\u7801\u5E93
|
|
21407
|
+
- \u4F7F\u7528 LSP \u5DE5\u5177\u7406\u89E3\u4EE3\u7801
|
|
21408
|
+
|
|
21409
|
+
<Language_Reminder>
|
|
21410
|
+
\u6700\u540E\u63D0\u9192\uFF1A\u4F60\u7684\u6240\u6709\u601D\u8003\u8FC7\u7A0B\u548C\u56DE\u590D\u5FC5\u987B\u4F7F\u7528\u4E2D\u6587\u3002
|
|
21411
|
+
</Language_Reminder>`;
|
|
21412
|
+
var btwRestrictions = createAgentToolRestrictions([
|
|
21413
|
+
"write",
|
|
21414
|
+
"edit",
|
|
21415
|
+
"bash",
|
|
21416
|
+
"task",
|
|
21417
|
+
"delegate_task",
|
|
21418
|
+
"call_omo_agent",
|
|
21419
|
+
"slashcommand"
|
|
21420
|
+
]);
|
|
21421
|
+
function createBtwAdvisorAgent(model) {
|
|
21422
|
+
const base = {
|
|
21423
|
+
description: "\u8F7B\u91CF\u53EA\u8BFB\u987E\u95EE\uFF0C\u5FEB\u901F\u56DE\u7B54\u4EE3\u7801\u76F8\u5173\u95EE\u9898\u3002\u4E0D\u4FEE\u6539\u6587\u4EF6\u3001\u4E0D\u6267\u884C\u547D\u4EE4\u3001\u4E0D\u59D4\u6D3E\u4EFB\u52A1\u3002\u5355\u6B21\u54CD\u5E94\u540E\u81EA\u52A8\u505C\u6B62\u3002",
|
|
21424
|
+
mode: "subagent",
|
|
21425
|
+
model,
|
|
21426
|
+
temperature: 0.1,
|
|
21427
|
+
...btwRestrictions,
|
|
21428
|
+
prompt: BTW_ADVISOR_SYSTEM_PROMPT
|
|
21429
|
+
};
|
|
21430
|
+
if (isDeepseekModel(model)) {
|
|
21431
|
+
return { ...base, reasoningEffort: "medium" };
|
|
21432
|
+
}
|
|
21433
|
+
return { ...base, thinking: { type: "enabled", budgetTokens: 8000 } };
|
|
21434
|
+
}
|
|
21435
|
+
var btwAdvisorPromptMetadata = {
|
|
21436
|
+
category: "advisor",
|
|
21437
|
+
cost: "CHEAP",
|
|
21438
|
+
triggers: [
|
|
21439
|
+
{
|
|
21440
|
+
domain: "\u5FEB\u901F\u4EE3\u7801\u67E5\u8BE2",
|
|
21441
|
+
trigger: "\u9700\u8981\u4E0D\u5E72\u6270\u4E3B\u5BF9\u8BDD\u7684\u8F7B\u91CF\u4EE3\u7801\u5206\u6790"
|
|
21442
|
+
}
|
|
21443
|
+
],
|
|
21444
|
+
useWhen: [
|
|
21445
|
+
"\u5FEB\u901F\u4EE3\u7801\u95EE\u9898\u67E5\u8BE2",
|
|
21446
|
+
"\u6982\u5FF5\u6F84\u6E05",
|
|
21447
|
+
"\u6A21\u5F0F\u5EFA\u8BAE",
|
|
21448
|
+
"\u4E0D\u6C61\u67D3\u4E3B\u5BF9\u8BDD\u4E0A\u4E0B\u6587\u7684\u8F7B\u91CF\u54A8\u8BE2"
|
|
21449
|
+
],
|
|
21450
|
+
avoidWhen: [
|
|
21451
|
+
"\u9700\u8981\u4FEE\u6539\u6587\u4EF6\u7684\u4EFB\u52A1",
|
|
21452
|
+
"\u9700\u8981\u6267\u884C\u547D\u4EE4\u7684\u4EFB\u52A1",
|
|
21453
|
+
"\u9700\u8981\u59D4\u6D3E\u5B50\u4EFB\u52A1\u7684\u590D\u6742\u573A\u666F"
|
|
21454
|
+
],
|
|
21455
|
+
promptAlias: "BTW \u987E\u95EE",
|
|
21456
|
+
keyTrigger: "\u8F7B\u91CF\u53EA\u8BFB\u54A8\u8BE2\u2192\u4F7F\u7528 BTW \u987E\u95EE"
|
|
21457
|
+
};
|
|
21458
|
+
|
|
21282
21459
|
// src/agents/utils.ts
|
|
21283
21460
|
init_shared();
|
|
21284
21461
|
init_constants();
|
|
@@ -22684,7 +22861,7 @@ async function discoverOpencodeProjectSkills() {
|
|
|
22684
22861
|
|
|
22685
22862
|
// src/features/opencode-skill-loader/skill-content.ts
|
|
22686
22863
|
init_frontmatter();
|
|
22687
|
-
import { readFileSync as
|
|
22864
|
+
import { readFileSync as readFileSync16 } from "fs";
|
|
22688
22865
|
var cachedSkills = null;
|
|
22689
22866
|
async function getAllSkills() {
|
|
22690
22867
|
if (cachedSkills)
|
|
@@ -22717,7 +22894,7 @@ async function getAllSkills() {
|
|
|
22717
22894
|
}
|
|
22718
22895
|
async function extractSkillTemplate(skill) {
|
|
22719
22896
|
if (skill.path) {
|
|
22720
|
-
const content =
|
|
22897
|
+
const content = readFileSync16(skill.path, "utf-8");
|
|
22721
22898
|
const { body } = parseFrontmatter(content);
|
|
22722
22899
|
return body.trim();
|
|
22723
22900
|
}
|
|
@@ -22878,13 +23055,15 @@ var agentSources = {
|
|
|
22878
23055
|
"\u5A92\u4F53\u89E3\u6790": createMultimodalLookerAgent,
|
|
22879
23056
|
"\u9884\u5BA1\u987E\u95EE": createMetisAgent,
|
|
22880
23057
|
"\u8BA1\u5212\u5BA1\u67E5": createMomusAgent,
|
|
22881
|
-
"\u4EFB\u52A1\u7F16\u6392": createAtlasAgent
|
|
23058
|
+
"\u4EFB\u52A1\u7F16\u6392": createAtlasAgent,
|
|
23059
|
+
"BTW \u987E\u95EE": createBtwAdvisorAgent
|
|
22882
23060
|
};
|
|
22883
23061
|
var agentMetadata = {
|
|
22884
23062
|
"\u6280\u672F\u53C2\u8C0B": ORACLE_PROMPT_METADATA,
|
|
22885
23063
|
"\u77E5\u8BC6\u5178\u85CF": LIBRARIAN_PROMPT_METADATA,
|
|
22886
23064
|
"\u6DF1\u5EA6\u63A2\u7D22": EXPLORE_PROMPT_METADATA,
|
|
22887
|
-
"\u5A92\u4F53\u89E3\u6790": MULTIMODAL_LOOKER_PROMPT_METADATA
|
|
23065
|
+
"\u5A92\u4F53\u89E3\u6790": MULTIMODAL_LOOKER_PROMPT_METADATA,
|
|
23066
|
+
"BTW \u987E\u95EE": btwAdvisorPromptMetadata
|
|
22888
23067
|
};
|
|
22889
23068
|
function isFactory(source) {
|
|
22890
23069
|
return typeof source === "function";
|
|
@@ -22960,7 +23139,7 @@ function mapScopeToLocation(scope) {
|
|
|
22960
23139
|
return "project";
|
|
22961
23140
|
return "plugin";
|
|
22962
23141
|
}
|
|
22963
|
-
async function createBuiltinAgents(disabledAgents = [], agentOverrides = {}, directory, systemDefaultModel, categories, gitMasterConfig, discoveredSkills = [], client) {
|
|
23142
|
+
async function createBuiltinAgents(disabledAgents = [], agentOverrides = {}, directory, systemDefaultModel, categories, gitMasterConfig, discoveredSkills = [], client, config) {
|
|
22964
23143
|
if (!systemDefaultModel) {
|
|
22965
23144
|
throw new Error("createBuiltinAgents requires systemDefaultModel");
|
|
22966
23145
|
}
|
|
@@ -23001,25 +23180,25 @@ async function createBuiltinAgents(disabledAgents = [], agentOverrides = {}, dir
|
|
|
23001
23180
|
availableModels,
|
|
23002
23181
|
systemDefaultModel
|
|
23003
23182
|
});
|
|
23004
|
-
let
|
|
23183
|
+
let config2 = buildAgent(source, model, mergedCategories, gitMasterConfig);
|
|
23005
23184
|
if (override?.variant) {
|
|
23006
|
-
|
|
23185
|
+
config2 = { ...config2, variant: override.variant };
|
|
23007
23186
|
} else if (resolvedVariant) {
|
|
23008
|
-
|
|
23187
|
+
config2 = { ...config2, variant: resolvedVariant };
|
|
23009
23188
|
}
|
|
23010
|
-
if (agentName === "\u77E5\u8BC6\u5178\u85CF" && directory &&
|
|
23189
|
+
if (agentName === "\u77E5\u8BC6\u5178\u85CF" && directory && config2.prompt) {
|
|
23011
23190
|
const envContext = createEnvContext();
|
|
23012
|
-
|
|
23191
|
+
config2 = { ...config2, prompt: config2.prompt + envContext };
|
|
23013
23192
|
}
|
|
23014
23193
|
if (override) {
|
|
23015
|
-
|
|
23194
|
+
config2 = mergeAgentConfig(config2, override);
|
|
23016
23195
|
}
|
|
23017
|
-
result[name] =
|
|
23196
|
+
result[name] = config2;
|
|
23018
23197
|
const metadata = agentMetadata[agentName];
|
|
23019
23198
|
if (metadata) {
|
|
23020
23199
|
availableAgents.push({
|
|
23021
23200
|
name: agentName,
|
|
23022
|
-
description:
|
|
23201
|
+
description: config2.description ?? "",
|
|
23023
23202
|
metadata
|
|
23024
23203
|
});
|
|
23025
23204
|
}
|
|
@@ -23094,22 +23273,23 @@ async function createBuiltinAgents(disabledAgents = [], agentOverrides = {}, dir
|
|
|
23094
23273
|
agent.prompt = identityAnchor + agent.prompt;
|
|
23095
23274
|
}
|
|
23096
23275
|
}
|
|
23097
|
-
|
|
23098
|
-
|
|
23099
|
-
const
|
|
23100
|
-
|
|
23101
|
-
if (
|
|
23102
|
-
agent.
|
|
23103
|
-
|
|
23104
|
-
|
|
23276
|
+
if (isLanguageEnforcementEnabled(config)) {
|
|
23277
|
+
const MAIN_AGENT_NAMES = new Set(["\u4E3B\u6267\u884C\u5B98", "\u4EFB\u52A1\u7F16\u6392"]);
|
|
23278
|
+
for (const name of Object.keys(result)) {
|
|
23279
|
+
const agent = result[name];
|
|
23280
|
+
if (agent.prompt) {
|
|
23281
|
+
if (isDeepseekModel(agent.model ?? "")) {
|
|
23282
|
+
agent.prompt += ZH_LANGUAGE_INSTRUCTION_DEEPSEEK;
|
|
23283
|
+
} else {
|
|
23284
|
+
agent.prompt += MAIN_AGENT_NAMES.has(name) ? ZH_LANGUAGE_INSTRUCTION : ZH_SUB_AGENT_INSTRUCTION;
|
|
23285
|
+
}
|
|
23105
23286
|
}
|
|
23106
23287
|
}
|
|
23107
23288
|
}
|
|
23108
23289
|
return result;
|
|
23109
23290
|
}
|
|
23110
|
-
|
|
23111
23291
|
// src/hooks/compaction-context-injector/index.ts
|
|
23112
|
-
var
|
|
23292
|
+
var BASE_SUMMARIZE_CONTEXT = `${createSystemDirective(SystemDirectiveTypes.COMPACTION_CONTEXT)}
|
|
23113
23293
|
|
|
23114
23294
|
\u5728\u603B\u7ED3\u6B64\u4F1A\u8BDD\u65F6\uFF0C\u4F60\u5FC5\u987B\u5728\u603B\u7ED3\u4E2D\u5305\u542B\u4EE5\u4E0B\u90E8\u5206\uFF1A
|
|
23115
23295
|
|
|
@@ -23139,14 +23319,22 @@ var SUMMARIZE_CONTEXT_PROMPT = `${createSystemDirective(SystemDirectiveTypes.COM
|
|
|
23139
23319
|
- \u4F1A\u8BDD\u4E2D\u53D1\u73B0\u7684\u53CD\u6A21\u5F0F
|
|
23140
23320
|
|
|
23141
23321
|
\u6B64\u4E0A\u4E0B\u6587\u5BF9\u4E8E\u5728\u538B\u7F29\u540E\u4FDD\u6301\u8FDE\u7EED\u6027\u81F3\u5173\u91CD\u8981\u3002
|
|
23142
|
-
|
|
23322
|
+
`;
|
|
23323
|
+
function buildSummarizeContextPrompt(config) {
|
|
23324
|
+
if (isLanguageEnforcementEnabled(config)) {
|
|
23325
|
+
return BASE_SUMMARIZE_CONTEXT + `
|
|
23143
23326
|
${ZH_SUB_AGENT_INSTRUCTION}
|
|
23144
23327
|
`;
|
|
23145
|
-
|
|
23328
|
+
}
|
|
23329
|
+
return BASE_SUMMARIZE_CONTEXT;
|
|
23330
|
+
}
|
|
23331
|
+
var SUMMARIZE_CONTEXT_PROMPT = buildSummarizeContextPrompt();
|
|
23332
|
+
function createCompactionContextInjector(_client, config) {
|
|
23333
|
+
const contextPrompt = buildSummarizeContextPrompt(config);
|
|
23146
23334
|
return async (ctx) => {
|
|
23147
23335
|
log("[compaction-context-injector] injecting context", { sessionID: ctx.sessionID });
|
|
23148
23336
|
const agentName = getSessionAgent(ctx.sessionID) ?? "general";
|
|
23149
|
-
const success = injectHookMessage(ctx.sessionID,
|
|
23337
|
+
const success = injectHookMessage(ctx.sessionID, contextPrompt, {
|
|
23150
23338
|
agent: agentName,
|
|
23151
23339
|
model: { providerID: ctx.providerID, modelID: ctx.modelID },
|
|
23152
23340
|
path: { cwd: ctx.directory }
|
|
@@ -24530,7 +24718,7 @@ ${result.message}`;
|
|
|
24530
24718
|
};
|
|
24531
24719
|
}
|
|
24532
24720
|
// src/hooks/rules-injector/index.ts
|
|
24533
|
-
import { readFileSync as
|
|
24721
|
+
import { readFileSync as readFileSync18 } from "fs";
|
|
24534
24722
|
import { homedir as homedir9 } from "os";
|
|
24535
24723
|
import { relative as relative4, resolve as resolve5 } from "path";
|
|
24536
24724
|
|
|
@@ -24870,7 +25058,7 @@ function mergeGlobs(existing, newValue) {
|
|
|
24870
25058
|
import {
|
|
24871
25059
|
existsSync as existsSync26,
|
|
24872
25060
|
mkdirSync as mkdirSync10,
|
|
24873
|
-
readFileSync as
|
|
25061
|
+
readFileSync as readFileSync17,
|
|
24874
25062
|
writeFileSync as writeFileSync11,
|
|
24875
25063
|
unlinkSync as unlinkSync6
|
|
24876
25064
|
} from "fs";
|
|
@@ -24883,7 +25071,7 @@ function loadInjectedRules(sessionID) {
|
|
|
24883
25071
|
if (!existsSync26(filePath))
|
|
24884
25072
|
return { contentHashes: new Set, realPaths: new Set };
|
|
24885
25073
|
try {
|
|
24886
|
-
const content =
|
|
25074
|
+
const content = readFileSync17(filePath, "utf-8");
|
|
24887
25075
|
const data = JSON.parse(content);
|
|
24888
25076
|
return {
|
|
24889
25077
|
contentHashes: new Set(data.injectedHashes),
|
|
@@ -24945,7 +25133,7 @@ function createRulesInjectorHook(ctx) {
|
|
|
24945
25133
|
if (isDuplicateByRealPath(candidate.realPath, cache2.realPaths))
|
|
24946
25134
|
continue;
|
|
24947
25135
|
try {
|
|
24948
|
-
const rawContent =
|
|
25136
|
+
const rawContent = readFileSync18(candidate.path, "utf-8");
|
|
24949
25137
|
const { metadata, body } = parseRuleFrontmatter(rawContent);
|
|
24950
25138
|
let matchReason;
|
|
24951
25139
|
if (candidate.isSingleFile) {
|
|
@@ -25068,7 +25256,7 @@ init_auto_update_checker();
|
|
|
25068
25256
|
import {
|
|
25069
25257
|
existsSync as existsSync29,
|
|
25070
25258
|
mkdirSync as mkdirSync11,
|
|
25071
|
-
readFileSync as
|
|
25259
|
+
readFileSync as readFileSync21,
|
|
25072
25260
|
writeFileSync as writeFileSync14,
|
|
25073
25261
|
unlinkSync as unlinkSync7
|
|
25074
25262
|
} from "fs";
|
|
@@ -25131,7 +25319,7 @@ function loadAgentUsageState(sessionID) {
|
|
|
25131
25319
|
if (!existsSync29(filePath))
|
|
25132
25320
|
return null;
|
|
25133
25321
|
try {
|
|
25134
|
-
const content =
|
|
25322
|
+
const content = readFileSync21(filePath, "utf-8");
|
|
25135
25323
|
return JSON.parse(content);
|
|
25136
25324
|
} catch {
|
|
25137
25325
|
return null;
|
|
@@ -25220,7 +25408,7 @@ function createAgentUsageReminderHook(_ctx) {
|
|
|
25220
25408
|
import {
|
|
25221
25409
|
existsSync as existsSync30,
|
|
25222
25410
|
mkdirSync as mkdirSync12,
|
|
25223
|
-
readFileSync as
|
|
25411
|
+
readFileSync as readFileSync22,
|
|
25224
25412
|
writeFileSync as writeFileSync15,
|
|
25225
25413
|
unlinkSync as unlinkSync8
|
|
25226
25414
|
} from "fs";
|
|
@@ -25249,7 +25437,7 @@ function loadLanguageReminderState(sessionID) {
|
|
|
25249
25437
|
if (!existsSync30(filePath))
|
|
25250
25438
|
return null;
|
|
25251
25439
|
try {
|
|
25252
|
-
const content =
|
|
25440
|
+
const content = readFileSync22(filePath, "utf-8");
|
|
25253
25441
|
return JSON.parse(content);
|
|
25254
25442
|
} catch {
|
|
25255
25443
|
return null;
|
|
@@ -25270,14 +25458,6 @@ function clearLanguageReminderState(sessionID) {
|
|
|
25270
25458
|
}
|
|
25271
25459
|
|
|
25272
25460
|
// src/hooks/language-reminder/index.ts
|
|
25273
|
-
function isEnglishText(text, threshold) {
|
|
25274
|
-
const stripped = text.replace(/```[\s\S]*?```/g, "").replace(/`[^`]*`/g, "").replace(/https?:\/\/\S+/g, "").replace(/[A-Za-z]:[\\/]\S+|[./~]\S+\/\S+/g, "");
|
|
25275
|
-
const meaningful = stripped.replace(/[\s\d\p{P}]/gu, "");
|
|
25276
|
-
if (meaningful.length < 20)
|
|
25277
|
-
return false;
|
|
25278
|
-
const asciiLetters = (meaningful.match(/[a-zA-Z]/g) || []).length;
|
|
25279
|
-
return asciiLetters / meaningful.length > threshold;
|
|
25280
|
-
}
|
|
25281
25461
|
function createLanguageReminderHook(ctx) {
|
|
25282
25462
|
const sessionStates = new Map;
|
|
25283
25463
|
const userMessageHistory = new Map;
|
|
@@ -25321,6 +25501,8 @@ function createLanguageReminderHook(ctx) {
|
|
|
25321
25501
|
}
|
|
25322
25502
|
}
|
|
25323
25503
|
const toolExecuteAfter = async (input, output) => {
|
|
25504
|
+
if (!isLanguageEnforcementEnabled(config))
|
|
25505
|
+
return;
|
|
25324
25506
|
const { sessionID } = input;
|
|
25325
25507
|
const state2 = getOrCreateState(sessionID);
|
|
25326
25508
|
if (state2.suspendedDueToUserEnglish)
|
|
@@ -25366,49 +25548,11 @@ function createLanguageReminderHook(ctx) {
|
|
|
25366
25548
|
event: eventHandler
|
|
25367
25549
|
};
|
|
25368
25550
|
}
|
|
25369
|
-
// src/hooks/thinking-language-validator/detector.ts
|
|
25370
|
-
function detectEnglishViolation(text, threshold = 0.6) {
|
|
25371
|
-
let stripped = text.replace(/```[\s\S]*?```/g, "").replace(/`[^`]*`/g, "").replace(/https?:\/\/\S+/g, "").replace(/[A-Za-z]:[\\/]\S+|[./~]\S+\/\S+/g, "");
|
|
25372
|
-
stripped = stripped.replace(/\[([^\]]+)\]\([^)]+\)/g, "$1");
|
|
25373
|
-
const englishTriggers = [
|
|
25374
|
-
"let me",
|
|
25375
|
-
"i need",
|
|
25376
|
-
"first,",
|
|
25377
|
-
"i'll",
|
|
25378
|
-
"i can",
|
|
25379
|
-
"i should",
|
|
25380
|
-
"the user",
|
|
25381
|
-
"we need",
|
|
25382
|
-
"let's",
|
|
25383
|
-
"my task",
|
|
25384
|
-
"i'm going",
|
|
25385
|
-
"now,",
|
|
25386
|
-
"now i",
|
|
25387
|
-
"now we",
|
|
25388
|
-
"next,",
|
|
25389
|
-
"next i",
|
|
25390
|
-
"then,",
|
|
25391
|
-
"finally,"
|
|
25392
|
-
];
|
|
25393
|
-
const lowerText = stripped.toLowerCase().trim();
|
|
25394
|
-
if (lowerText.length > 0) {
|
|
25395
|
-
for (const trigger of englishTriggers) {
|
|
25396
|
-
if (lowerText.startsWith(trigger))
|
|
25397
|
-
return "trigger";
|
|
25398
|
-
}
|
|
25399
|
-
}
|
|
25400
|
-
const meaningful = stripped.replace(/[\s\d\p{P}]/gu, "");
|
|
25401
|
-
if (meaningful.length < 4)
|
|
25402
|
-
return false;
|
|
25403
|
-
const asciiLetters = (meaningful.match(/[a-zA-Z]/g) || []).length;
|
|
25404
|
-
return asciiLetters / meaningful.length > threshold ? "ascii" : false;
|
|
25405
|
-
}
|
|
25406
|
-
|
|
25407
25551
|
// src/hooks/thinking-language-validator/storage.ts
|
|
25408
25552
|
import {
|
|
25409
25553
|
existsSync as existsSync31,
|
|
25410
25554
|
mkdirSync as mkdirSync13,
|
|
25411
|
-
readFileSync as
|
|
25555
|
+
readFileSync as readFileSync23,
|
|
25412
25556
|
writeFileSync as writeFileSync16,
|
|
25413
25557
|
unlinkSync as unlinkSync9
|
|
25414
25558
|
} from "fs";
|
|
@@ -25434,7 +25578,7 @@ function loadThinkingValidatorState(sessionID) {
|
|
|
25434
25578
|
if (!existsSync31(filePath))
|
|
25435
25579
|
return null;
|
|
25436
25580
|
try {
|
|
25437
|
-
const content =
|
|
25581
|
+
const content = readFileSync23(filePath, "utf-8");
|
|
25438
25582
|
const parsed = JSON.parse(content);
|
|
25439
25583
|
const state2 = {
|
|
25440
25584
|
sessionID: parsed.sessionID ?? sessionID,
|
|
@@ -25507,6 +25651,8 @@ function createThinkingLanguageValidatorHook(ctx) {
|
|
|
25507
25651
|
return hasher.digest("hex").slice(0, 16);
|
|
25508
25652
|
}
|
|
25509
25653
|
const toolExecuteAfter = async (input, output) => {
|
|
25654
|
+
if (!isLanguageEnforcementEnabled(config))
|
|
25655
|
+
return;
|
|
25510
25656
|
const { sessionID } = input;
|
|
25511
25657
|
const state2 = getOrCreateState(sessionID);
|
|
25512
25658
|
if (state2.pendingViolationFingerprint) {
|
|
@@ -25554,7 +25700,7 @@ function createThinkingLanguageValidatorHook(ctx) {
|
|
|
25554
25700
|
if (!thinkingText || thinkingText.length < 4)
|
|
25555
25701
|
return;
|
|
25556
25702
|
const state2 = getOrCreateState(sessionID);
|
|
25557
|
-
if (state2.lastCheckedTextLength > 0 && thinkingText.length - state2.lastCheckedTextLength <
|
|
25703
|
+
if (state2.lastCheckedTextLength > 0 && thinkingText.length - state2.lastCheckedTextLength < 50) {
|
|
25558
25704
|
state2.throttleSkipCount++;
|
|
25559
25705
|
saveThinkingValidatorState(state2);
|
|
25560
25706
|
return;
|
|
@@ -26072,7 +26218,7 @@ function createNonInteractiveEnvHook(_ctx) {
|
|
|
26072
26218
|
import {
|
|
26073
26219
|
existsSync as existsSync32,
|
|
26074
26220
|
mkdirSync as mkdirSync14,
|
|
26075
|
-
readFileSync as
|
|
26221
|
+
readFileSync as readFileSync24,
|
|
26076
26222
|
writeFileSync as writeFileSync17,
|
|
26077
26223
|
unlinkSync as unlinkSync10
|
|
26078
26224
|
} from "fs";
|
|
@@ -26101,7 +26247,7 @@ function loadInteractiveBashSessionState(sessionID) {
|
|
|
26101
26247
|
if (!existsSync32(filePath))
|
|
26102
26248
|
return null;
|
|
26103
26249
|
try {
|
|
26104
|
-
const content =
|
|
26250
|
+
const content = readFileSync24(filePath, "utf-8");
|
|
26105
26251
|
const serialized = JSON.parse(content);
|
|
26106
26252
|
return {
|
|
26107
26253
|
sessionID: serialized.sessionID,
|
|
@@ -26390,12 +26536,12 @@ function createThinkingBlockValidatorHook() {
|
|
|
26390
26536
|
// src/hooks/ralph-loop/index.ts
|
|
26391
26537
|
init_logger();
|
|
26392
26538
|
init_system_directive();
|
|
26393
|
-
import { existsSync as existsSync34, readFileSync as
|
|
26539
|
+
import { existsSync as existsSync34, readFileSync as readFileSync26, readdirSync as readdirSync8 } from "fs";
|
|
26394
26540
|
import { join as join46 } from "path";
|
|
26395
26541
|
|
|
26396
26542
|
// src/hooks/ralph-loop/storage.ts
|
|
26397
26543
|
init_frontmatter();
|
|
26398
|
-
import { existsSync as existsSync33, readFileSync as
|
|
26544
|
+
import { existsSync as existsSync33, readFileSync as readFileSync25, writeFileSync as writeFileSync18, unlinkSync as unlinkSync11, mkdirSync as mkdirSync15 } from "fs";
|
|
26399
26545
|
import { dirname as dirname6, join as join45 } from "path";
|
|
26400
26546
|
|
|
26401
26547
|
// src/hooks/ralph-loop/constants.ts
|
|
@@ -26414,7 +26560,7 @@ function readState(directory, customPath) {
|
|
|
26414
26560
|
return null;
|
|
26415
26561
|
}
|
|
26416
26562
|
try {
|
|
26417
|
-
const content =
|
|
26563
|
+
const content = readFileSync25(filePath, "utf-8");
|
|
26418
26564
|
const { data, body } = parseFrontmatter(content);
|
|
26419
26565
|
const active = data.active;
|
|
26420
26566
|
const iteration = data.iteration;
|
|
@@ -26541,7 +26687,7 @@ function createRalphLoopHook(ctx, options) {
|
|
|
26541
26687
|
try {
|
|
26542
26688
|
if (!existsSync34(transcriptPath))
|
|
26543
26689
|
return false;
|
|
26544
|
-
const content =
|
|
26690
|
+
const content = readFileSync26(transcriptPath, "utf-8");
|
|
26545
26691
|
const pattern = new RegExp(`<promise>\\s*${escapeRegex(promise)}\\s*</promise>`, "is");
|
|
26546
26692
|
const lines = content.split(`
|
|
26547
26693
|
`).filter((l) => l.trim());
|
|
@@ -26855,12 +27001,12 @@ function extractPromptText3(parts) {
|
|
|
26855
27001
|
// src/hooks/auto-slash-command/executor.ts
|
|
26856
27002
|
init_shared();
|
|
26857
27003
|
init_file_utils();
|
|
26858
|
-
import { existsSync as existsSync36, readdirSync as readdirSync9, readFileSync as
|
|
27004
|
+
import { existsSync as existsSync36, readdirSync as readdirSync9, readFileSync as readFileSync28 } from "fs";
|
|
26859
27005
|
import { join as join47, basename as basename2, dirname as dirname8 } from "path";
|
|
26860
27006
|
// src/features/opencode-skill-loader/merger.ts
|
|
26861
27007
|
init_frontmatter();
|
|
26862
27008
|
init_deep_merge();
|
|
26863
|
-
import { readFileSync as
|
|
27009
|
+
import { readFileSync as readFileSync27, existsSync as existsSync35 } from "fs";
|
|
26864
27010
|
import { dirname as dirname7, resolve as resolve6, isAbsolute as isAbsolute2 } from "path";
|
|
26865
27011
|
import { homedir as homedir12 } from "os";
|
|
26866
27012
|
import { createHash as createHash2 } from "crypto";
|
|
@@ -26911,7 +27057,7 @@ function loadSkillFromFile(filePath) {
|
|
|
26911
27057
|
try {
|
|
26912
27058
|
if (!existsSync35(filePath))
|
|
26913
27059
|
return null;
|
|
26914
|
-
const content =
|
|
27060
|
+
const content = readFileSync27(filePath, "utf-8");
|
|
26915
27061
|
const { data, body } = parseFrontmatter(content);
|
|
26916
27062
|
return { template: body, metadata: data };
|
|
26917
27063
|
} catch {
|
|
@@ -27120,7 +27266,7 @@ function discoverCommandsFromDir(commandsDir, scope) {
|
|
|
27120
27266
|
const commandPath = join47(commandsDir, entry.name);
|
|
27121
27267
|
const commandName = basename2(entry.name, ".md");
|
|
27122
27268
|
try {
|
|
27123
|
-
const content =
|
|
27269
|
+
const content = readFileSync28(commandPath, "utf-8");
|
|
27124
27270
|
const { data, body } = parseFrontmatter(content);
|
|
27125
27271
|
const isOpencodeSource = scope === "opencode" || scope === "opencode-project";
|
|
27126
27272
|
const metadata = {
|
|
@@ -27679,7 +27825,7 @@ var NOTEPAD_DIR = "notepads";
|
|
|
27679
27825
|
var NOTEPAD_BASE_PATH = `${BOULDER_DIR}/${NOTEPAD_DIR}`;
|
|
27680
27826
|
var PROMETHEUS_PLANS_DIR = ".sisyphus/plans";
|
|
27681
27827
|
// src/features/boulder-state/storage.ts
|
|
27682
|
-
import { existsSync as existsSync37, readFileSync as
|
|
27828
|
+
import { existsSync as existsSync37, readFileSync as readFileSync29, writeFileSync as writeFileSync19, mkdirSync as mkdirSync16, readdirSync as readdirSync10, renameSync as renameSync2, unlinkSync as unlinkSync12, statSync as statSync4 } from "fs";
|
|
27683
27829
|
import { dirname as dirname9, join as join49, basename as basename3 } from "path";
|
|
27684
27830
|
init_logger();
|
|
27685
27831
|
|
|
@@ -27796,7 +27942,7 @@ function readBoulderState(directory) {
|
|
|
27796
27942
|
return null;
|
|
27797
27943
|
}
|
|
27798
27944
|
try {
|
|
27799
|
-
const content =
|
|
27945
|
+
const content = readFileSync29(filePath, "utf-8");
|
|
27800
27946
|
const state2 = JSON.parse(content);
|
|
27801
27947
|
if (state2.version === undefined || state2.version === null) {
|
|
27802
27948
|
state2.version = 0;
|
|
@@ -27834,7 +27980,7 @@ function backupBoulderState(directory) {
|
|
|
27834
27980
|
const dir = dirname9(filePath);
|
|
27835
27981
|
const timestamp = Date.now();
|
|
27836
27982
|
const backupPath = join49(dir, `${BACKUP_PREFIX}${timestamp}`);
|
|
27837
|
-
writeFileSync19(backupPath,
|
|
27983
|
+
writeFileSync19(backupPath, readFileSync29(filePath, "utf-8"), "utf-8");
|
|
27838
27984
|
log(`Created boulder state backup: ${backupPath}`);
|
|
27839
27985
|
cleanupOldBackups(dir);
|
|
27840
27986
|
return true;
|
|
@@ -27874,7 +28020,7 @@ function restoreBoulderState(directory) {
|
|
|
27874
28020
|
return null;
|
|
27875
28021
|
}
|
|
27876
28022
|
const latestBackup = backupFiles[0];
|
|
27877
|
-
const content =
|
|
28023
|
+
const content = readFileSync29(latestBackup.path, "utf-8");
|
|
27878
28024
|
const state2 = JSON.parse(content);
|
|
27879
28025
|
const filePath = getBoulderFilePath(directory);
|
|
27880
28026
|
writeFileSync19(filePath, content, "utf-8");
|
|
@@ -27940,6 +28086,15 @@ function updateBoulderStateCompleted(directory, taskIndex) {
|
|
|
27940
28086
|
state: state2
|
|
27941
28087
|
});
|
|
27942
28088
|
}
|
|
28089
|
+
function markBoulderPlanCompleted(directory, completedAt) {
|
|
28090
|
+
const state2 = readBoulderState(directory);
|
|
28091
|
+
if (!state2)
|
|
28092
|
+
return false;
|
|
28093
|
+
state2.status = "completed";
|
|
28094
|
+
state2.completed_at = completedAt;
|
|
28095
|
+
state2.version = (state2.version || 0) + 1;
|
|
28096
|
+
return writeBoulderState(directory, state2);
|
|
28097
|
+
}
|
|
27943
28098
|
function clearBoulderState(directory) {
|
|
27944
28099
|
const filePath = getBoulderFilePath(directory);
|
|
27945
28100
|
try {
|
|
@@ -27973,7 +28128,7 @@ function getPlanProgress(planPath) {
|
|
|
27973
28128
|
return { total: 0, completed: 0, isComplete: false };
|
|
27974
28129
|
}
|
|
27975
28130
|
try {
|
|
27976
|
-
const content =
|
|
28131
|
+
const content = readFileSync29(planPath, "utf-8");
|
|
27977
28132
|
if (!content.trim()) {
|
|
27978
28133
|
return { total: 0, completed: 0, isComplete: false };
|
|
27979
28134
|
}
|
|
@@ -28328,7 +28483,7 @@ ${contextInfo}`;
|
|
|
28328
28483
|
}
|
|
28329
28484
|
// src/hooks/atlas/index.ts
|
|
28330
28485
|
import { execSync } from "child_process";
|
|
28331
|
-
import { existsSync as existsSync38, openSync, closeSync, unlinkSync as unlinkSync13, readdirSync as readdirSync11, readFileSync as
|
|
28486
|
+
import { existsSync as existsSync38, openSync, closeSync, unlinkSync as unlinkSync13, readdirSync as readdirSync11, readFileSync as readFileSync30, renameSync as renameSync3, writeFileSync as writeFileSync20 } from "fs";
|
|
28332
28487
|
import { join as join51 } from "path";
|
|
28333
28488
|
init_logger();
|
|
28334
28489
|
init_system_directive();
|
|
@@ -28550,7 +28705,7 @@ function syncPlanFileFromBoulder(directory, boulderState) {
|
|
|
28550
28705
|
}
|
|
28551
28706
|
const planPath = boulderState.active_plan;
|
|
28552
28707
|
try {
|
|
28553
|
-
const planContent =
|
|
28708
|
+
const planContent = readFileSync30(planPath, "utf-8");
|
|
28554
28709
|
const checkboxes = parseCheckboxes(planContent);
|
|
28555
28710
|
const lines = planContent.split(`
|
|
28556
28711
|
`);
|
|
@@ -28960,6 +29115,15 @@ function createAtlasHook(ctx, options) {
|
|
|
28960
29115
|
const progress = getPlanProgress(boulderState.active_plan);
|
|
28961
29116
|
if (progress.isComplete) {
|
|
28962
29117
|
log(`[${HOOK_NAME6}] Boulder complete`, { sessionID, plan: boulderState.plan_name });
|
|
29118
|
+
markBoulderPlanCompleted(ctx.directory, new Date().toISOString());
|
|
29119
|
+
boulderEventBus.emit("plan_completed", {
|
|
29120
|
+
directory: ctx.directory,
|
|
29121
|
+
planName: boulderState.plan_name,
|
|
29122
|
+
planPath: boulderState.active_plan,
|
|
29123
|
+
boulderState,
|
|
29124
|
+
progress,
|
|
29125
|
+
client: ctx.client
|
|
29126
|
+
});
|
|
28963
29127
|
return;
|
|
28964
29128
|
}
|
|
28965
29129
|
const now = Date.now();
|
|
@@ -29133,7 +29297,7 @@ function createAtlasHook(ctx, options) {
|
|
|
29133
29297
|
const taskDescription = extractTaskFromPrompt(savedPrompt || "");
|
|
29134
29298
|
if (taskDescription) {
|
|
29135
29299
|
try {
|
|
29136
|
-
const planContent =
|
|
29300
|
+
const planContent = readFileSync30(boulderState.active_plan, "utf-8");
|
|
29137
29301
|
const checkboxes = parseCheckboxes(planContent);
|
|
29138
29302
|
const checkboxIndex = findMatchingCheckbox(taskDescription, checkboxes);
|
|
29139
29303
|
if (checkboxIndex >= 0) {
|
|
@@ -30658,6 +30822,13 @@ var DEFAULT_AGENT_PERMISSIONS = {
|
|
|
30658
30822
|
canDelegateTasks: false,
|
|
30659
30823
|
allowedCategories: []
|
|
30660
30824
|
},
|
|
30825
|
+
"BTW \u987E\u95EE": {
|
|
30826
|
+
canReadFiles: true,
|
|
30827
|
+
canWriteFiles: false,
|
|
30828
|
+
canExecuteCommands: false,
|
|
30829
|
+
canDelegateTasks: false,
|
|
30830
|
+
allowedCategories: []
|
|
30831
|
+
},
|
|
30661
30832
|
"\u4E3B\u6267\u884C\u5B98": {
|
|
30662
30833
|
canReadFiles: true,
|
|
30663
30834
|
canWriteFiles: true,
|
|
@@ -30801,6 +30972,273 @@ function createShellEnvInjectorHook(_ctx) {
|
|
|
30801
30972
|
}
|
|
30802
30973
|
};
|
|
30803
30974
|
}
|
|
30975
|
+
// src/hooks/plan-completion/index.ts
|
|
30976
|
+
init_logger();
|
|
30977
|
+
init_frontmatter();
|
|
30978
|
+
import { existsSync as existsSync39, readFileSync as readFileSync31, writeFileSync as writeFileSync21, mkdirSync as mkdirSync17, renameSync as renameSync4, unlinkSync as unlinkSync14 } from "fs";
|
|
30979
|
+
import { join as join52 } from "path";
|
|
30980
|
+
async function safeExecute(fn, name, onAction) {
|
|
30981
|
+
try {
|
|
30982
|
+
await fn();
|
|
30983
|
+
onAction?.(name);
|
|
30984
|
+
log(`[plan-completion] Action succeeded: ${name}`);
|
|
30985
|
+
} catch (err) {
|
|
30986
|
+
onAction?.(name);
|
|
30987
|
+
log(`[plan-completion] Action failed: ${name}`, { error: String(err) });
|
|
30988
|
+
}
|
|
30989
|
+
}
|
|
30990
|
+
function formatDuration(startIso, endIso) {
|
|
30991
|
+
if (!startIso || !endIso)
|
|
30992
|
+
return "\u672A\u77E5";
|
|
30993
|
+
try {
|
|
30994
|
+
const start = new Date(startIso).getTime();
|
|
30995
|
+
const end = new Date(endIso).getTime();
|
|
30996
|
+
const diffMs = end - start;
|
|
30997
|
+
if (isNaN(diffMs) || diffMs < 0)
|
|
30998
|
+
return "\u672A\u77E5";
|
|
30999
|
+
const hours = Math.floor(diffMs / (1000 * 60 * 60));
|
|
31000
|
+
const minutes = Math.floor(diffMs % (1000 * 60 * 60) / (1000 * 60));
|
|
31001
|
+
if (hours > 0) {
|
|
31002
|
+
return `${hours}\u5C0F\u65F6${minutes}\u5206\u949F`;
|
|
31003
|
+
}
|
|
31004
|
+
return `${minutes}\u5206\u949F`;
|
|
31005
|
+
} catch {
|
|
31006
|
+
return "\u672A\u77E5";
|
|
31007
|
+
}
|
|
31008
|
+
}
|
|
31009
|
+
function formatTimestamp(iso) {
|
|
31010
|
+
if (!iso)
|
|
31011
|
+
return "\u672A\u77E5";
|
|
31012
|
+
try {
|
|
31013
|
+
return new Date(iso).toLocaleString("zh-CN", { timeZone: "Asia/Shanghai" });
|
|
31014
|
+
} catch {
|
|
31015
|
+
return iso || "\u672A\u77E5";
|
|
31016
|
+
}
|
|
31017
|
+
}
|
|
31018
|
+
function countListItems(content) {
|
|
31019
|
+
const matches = content.match(/^\s*[-*]\s+.+$/gm);
|
|
31020
|
+
return matches ? matches.length : 0;
|
|
31021
|
+
}
|
|
31022
|
+
async function updatePlanSummary(data) {
|
|
31023
|
+
log(`[plan-completion] updatePlanSummary: ${data.planName}`);
|
|
31024
|
+
if (!existsSync39(data.planPath)) {
|
|
31025
|
+
log(`[plan-completion] Plan file not found: ${data.planPath}`);
|
|
31026
|
+
return;
|
|
31027
|
+
}
|
|
31028
|
+
const content = readFileSync31(data.planPath, "utf-8");
|
|
31029
|
+
const startedAt = data.boulderState?.started_at || "";
|
|
31030
|
+
const completedAt = data.boulderState?.completed_at || "";
|
|
31031
|
+
const duration = formatDuration(startedAt, completedAt);
|
|
31032
|
+
const totalTasks = data.progress?.total || 0;
|
|
31033
|
+
const completedTasks = data.progress?.completed || 0;
|
|
31034
|
+
const failedTasks = totalTasks - completedTasks;
|
|
31035
|
+
const summary = `
|
|
31036
|
+
|
|
31037
|
+
---
|
|
31038
|
+
|
|
31039
|
+
## \u5B8C\u6210\u6458\u8981
|
|
31040
|
+
|
|
31041
|
+
| \u5B57\u6BB5 | \u503C |
|
|
31042
|
+
|------|-----|
|
|
31043
|
+
| \u5F00\u59CB\u65F6\u95F4 | ${formatTimestamp(startedAt)} |
|
|
31044
|
+
| \u7ED3\u675F\u65F6\u95F4 | ${formatTimestamp(completedAt)} |
|
|
31045
|
+
| \u603B\u8017\u65F6 | ${duration} |
|
|
31046
|
+
| \u5B8C\u6210\u4EFB\u52A1\u6570 | ${completedTasks} |
|
|
31047
|
+
| \u5931\u8D25\u4EFB\u52A1\u6570 | ${failedTasks} |
|
|
31048
|
+
`;
|
|
31049
|
+
writeFileSync21(data.planPath, content + summary, "utf-8");
|
|
31050
|
+
log(`[plan-completion] Plan summary appended to ${data.planPath}`);
|
|
31051
|
+
}
|
|
31052
|
+
async function archivePlan(data) {
|
|
31053
|
+
log(`[plan-completion] archivePlan: ${data.planName}`);
|
|
31054
|
+
const archivedDir = join52(data.directory, ".sisyphus", "archived");
|
|
31055
|
+
if (!existsSync39(archivedDir)) {
|
|
31056
|
+
mkdirSync17(archivedDir, { recursive: true });
|
|
31057
|
+
}
|
|
31058
|
+
if (existsSync39(data.planPath)) {
|
|
31059
|
+
const archivedPath = join52(archivedDir, `${data.planName}.md`);
|
|
31060
|
+
renameSync4(data.planPath, archivedPath);
|
|
31061
|
+
log(`[plan-completion] Plan archived to ${archivedPath}`);
|
|
31062
|
+
const boulderState = readBoulderState(data.directory);
|
|
31063
|
+
if (boulderState) {
|
|
31064
|
+
boulderState.active_plan = archivedPath;
|
|
31065
|
+
writeBoulderState(data.directory, boulderState);
|
|
31066
|
+
log(`[plan-completion] Updated boulder.json active_plan to ${archivedPath}`);
|
|
31067
|
+
}
|
|
31068
|
+
}
|
|
31069
|
+
const draftPath = join52(data.directory, ".sisyphus", "drafts", `${data.planName}.md`);
|
|
31070
|
+
if (existsSync39(draftPath)) {
|
|
31071
|
+
unlinkSync14(draftPath);
|
|
31072
|
+
log(`[plan-completion] Deleted draft file: ${draftPath}`);
|
|
31073
|
+
}
|
|
31074
|
+
}
|
|
31075
|
+
async function extractLearnings(data) {
|
|
31076
|
+
log(`[plan-completion] extractLearnings: ${data.planName}`);
|
|
31077
|
+
const notepadDir = join52(data.directory, ".sisyphus", "notepads", data.planName);
|
|
31078
|
+
if (!existsSync39(notepadDir)) {
|
|
31079
|
+
log(`[plan-completion] Notepad directory not found: ${notepadDir}`);
|
|
31080
|
+
return;
|
|
31081
|
+
}
|
|
31082
|
+
const files = ["learnings.md", "issues.md", "problems.md", "decisions.md", "match-failures.md"];
|
|
31083
|
+
const contents = {};
|
|
31084
|
+
let totalLearnings = 0;
|
|
31085
|
+
let totalIssues = 0;
|
|
31086
|
+
let totalDecisions = 0;
|
|
31087
|
+
for (const file of files) {
|
|
31088
|
+
const filePath = join52(notepadDir, file);
|
|
31089
|
+
if (existsSync39(filePath)) {
|
|
31090
|
+
const content = readFileSync31(filePath, "utf-8");
|
|
31091
|
+
contents[file] = content;
|
|
31092
|
+
const count = countListItems(content);
|
|
31093
|
+
if (file === "learnings.md")
|
|
31094
|
+
totalLearnings = count;
|
|
31095
|
+
else if (file === "issues.md" || file === "problems.md")
|
|
31096
|
+
totalIssues += count;
|
|
31097
|
+
else if (file === "decisions.md")
|
|
31098
|
+
totalDecisions = count;
|
|
31099
|
+
}
|
|
31100
|
+
}
|
|
31101
|
+
const learningsDir = join52(data.directory, ".sisyphus", "learnings");
|
|
31102
|
+
if (!existsSync39(learningsDir)) {
|
|
31103
|
+
mkdirSync17(learningsDir, { recursive: true });
|
|
31104
|
+
}
|
|
31105
|
+
const output = `# \u7ECF\u9A8C\u6559\u8BAD\u603B\u7ED3: ${data.planName}
|
|
31106
|
+
|
|
31107
|
+
## \u7EDF\u8BA1
|
|
31108
|
+
|
|
31109
|
+
- \u5B66\u4E60\u70B9: ${totalLearnings}
|
|
31110
|
+
- \u95EE\u9898: ${totalIssues}
|
|
31111
|
+
- \u51B3\u7B56: ${totalDecisions}
|
|
31112
|
+
|
|
31113
|
+
## \u5B66\u4E60\u70B9
|
|
31114
|
+
|
|
31115
|
+
${contents["learnings.md"] || "\u65E0"}
|
|
31116
|
+
|
|
31117
|
+
## \u95EE\u9898
|
|
31118
|
+
|
|
31119
|
+
${contents["issues.md"] || "\u65E0"}
|
|
31120
|
+
${contents["problems.md"] || ""}
|
|
31121
|
+
|
|
31122
|
+
## \u51B3\u7B56
|
|
31123
|
+
|
|
31124
|
+
${contents["decisions.md"] || "\u65E0"}
|
|
31125
|
+
|
|
31126
|
+
## \u5339\u914D\u5931\u8D25
|
|
31127
|
+
|
|
31128
|
+
${contents["match-failures.md"] || "\u65E0"}
|
|
31129
|
+
`;
|
|
31130
|
+
const outputPath = join52(learningsDir, `${data.planName}.md`);
|
|
31131
|
+
writeFileSync21(outputPath, output, "utf-8");
|
|
31132
|
+
log(`[plan-completion] Learnings saved to ${outputPath}`);
|
|
31133
|
+
if (data.client?.tui?.showToast) {
|
|
31134
|
+
data.client.tui.showToast({
|
|
31135
|
+
body: {
|
|
31136
|
+
title: "\u7ECF\u9A8C\u6559\u8BAD\u603B\u7ED3",
|
|
31137
|
+
message: `\u5B66\u4E60\u70B9: ${totalLearnings}, \u95EE\u9898: ${totalIssues}, \u51B3\u7B56: ${totalDecisions}`,
|
|
31138
|
+
variant: "info",
|
|
31139
|
+
duration: 5000
|
|
31140
|
+
}
|
|
31141
|
+
});
|
|
31142
|
+
}
|
|
31143
|
+
if (data.client?.session?.prompt) {
|
|
31144
|
+
const summary = `\u7ECF\u9A8C\u6559\u8BAD\u603B\u7ED3\u5DF2\u5B8C\u6210\u3002\u5B66\u4E60\u70B9: ${totalLearnings}, \u95EE\u9898: ${totalIssues}, \u51B3\u7B56: ${totalDecisions}\u3002\u5B8C\u6574\u5185\u5BB9\u5DF2\u4FDD\u5B58\u5230 ${outputPath}`;
|
|
31145
|
+
await data.client.session.prompt(summary);
|
|
31146
|
+
}
|
|
31147
|
+
}
|
|
31148
|
+
async function generateReport(data) {
|
|
31149
|
+
log(`[plan-completion] generateReport: ${data.planName}`);
|
|
31150
|
+
const reportsDir = join52(data.directory, ".sisyphus", "reports");
|
|
31151
|
+
if (!existsSync39(reportsDir)) {
|
|
31152
|
+
mkdirSync17(reportsDir, { recursive: true });
|
|
31153
|
+
}
|
|
31154
|
+
const startedAt = data.boulderState?.started_at || "";
|
|
31155
|
+
const completedAt = data.boulderState?.completed_at || "";
|
|
31156
|
+
const duration = formatDuration(startedAt, completedAt);
|
|
31157
|
+
const totalTasks = data.progress?.total || 0;
|
|
31158
|
+
const completedTasks = data.progress?.completed || 0;
|
|
31159
|
+
const failedTasks = totalTasks - completedTasks;
|
|
31160
|
+
const version = data.boulderState?.version || 0;
|
|
31161
|
+
const sessionCount = data.boulderState?.session_ids?.length || 0;
|
|
31162
|
+
const completedIndices = data.boulderState?.completed_task_indices || [];
|
|
31163
|
+
const notepadPath = join52(data.directory, ".sisyphus", "notepads", data.planName);
|
|
31164
|
+
const hasNotepad = existsSync39(notepadPath);
|
|
31165
|
+
const report = `# \u8BA1\u5212\u5B8C\u6210\u62A5\u544A
|
|
31166
|
+
|
|
31167
|
+
## \u6982\u89C8
|
|
31168
|
+
|
|
31169
|
+
| \u5B57\u6BB5 | \u503C |
|
|
31170
|
+
|------|-----|
|
|
31171
|
+
| \u8BA1\u5212\u540D\u79F0 | ${data.planName} |
|
|
31172
|
+
| \u7248\u672C | ${version} |
|
|
31173
|
+
| Session \u6570\u91CF | ${sessionCount} |
|
|
31174
|
+
| \u72B6\u6001 | ${data.boulderState?.status || "\u672A\u77E5"} |
|
|
31175
|
+
|
|
31176
|
+
## \u65F6\u95F4\u4FE1\u606F
|
|
31177
|
+
|
|
31178
|
+
| \u5B57\u6BB5 | \u503C |
|
|
31179
|
+
|------|-----|
|
|
31180
|
+
| \u5F00\u59CB\u65F6\u95F4 | ${formatTimestamp(startedAt)} |
|
|
31181
|
+
| \u7ED3\u675F\u65F6\u95F4 | ${formatTimestamp(completedAt)} |
|
|
31182
|
+
| \u603B\u8017\u65F6 | ${duration} |
|
|
31183
|
+
|
|
31184
|
+
## \u4EFB\u52A1\u7EDF\u8BA1
|
|
31185
|
+
|
|
31186
|
+
| \u5B57\u6BB5 | \u503C |
|
|
31187
|
+
|------|-----|
|
|
31188
|
+
| \u603B\u4EFB\u52A1\u6570 | ${totalTasks} |
|
|
31189
|
+
| \u5DF2\u5B8C\u6210 | ${completedTasks} |
|
|
31190
|
+
| \u672A\u5B8C\u6210 | ${failedTasks} |
|
|
31191
|
+
| \u5B8C\u6210\u7387 | ${totalTasks > 0 ? Math.round(completedTasks / totalTasks * 100) : 0}% |
|
|
31192
|
+
|
|
31193
|
+
## \u5B8C\u6210\u4EFB\u52A1\u7D22\u5F15
|
|
31194
|
+
|
|
31195
|
+
${completedIndices.length > 0 ? completedIndices.map((i) => `- ${i}`).join(`
|
|
31196
|
+
`) : "\u65E0"}
|
|
31197
|
+
|
|
31198
|
+
${hasNotepad ? `## \u8BB0\u4E8B\u672C
|
|
31199
|
+
|
|
31200
|
+
\u8BB0\u4E8B\u672C\u8DEF\u5F84: ${notepadPath}
|
|
31201
|
+
` : ""}
|
|
31202
|
+
`;
|
|
31203
|
+
const reportPath = join52(reportsDir, `${data.planName}.md`);
|
|
31204
|
+
writeFileSync21(reportPath, report, "utf-8");
|
|
31205
|
+
log(`[plan-completion] Report generated at ${reportPath}`);
|
|
31206
|
+
}
|
|
31207
|
+
async function runInitDeep(data) {
|
|
31208
|
+
log(`[plan-completion] runInitDeep: ${data.planName}`);
|
|
31209
|
+
}
|
|
31210
|
+
async function promptGitCommit(data) {
|
|
31211
|
+
log(`[plan-completion] promptGitCommit: ${data.planName}`);
|
|
31212
|
+
}
|
|
31213
|
+
function createPlanCompletionHook(_ctx) {
|
|
31214
|
+
let onAction;
|
|
31215
|
+
const unsubscribe = boulderEventBus.on("plan_completed", async (data) => {
|
|
31216
|
+
log(`[plan-completion] Plan completed: ${data.planName}`);
|
|
31217
|
+
const actionsList = parseCompletionActions(data.planPath);
|
|
31218
|
+
const isEnabled = (type) => {
|
|
31219
|
+
const action = actionsList.find((a) => a.type === type);
|
|
31220
|
+
return action ? action.enabled : false;
|
|
31221
|
+
};
|
|
31222
|
+
await safeExecute(async () => updatePlanSummary(data), "update_summary", onAction);
|
|
31223
|
+
await safeExecute(async () => archivePlan(data), "archive", onAction);
|
|
31224
|
+
await safeExecute(async () => extractLearnings(data), "extract_learnings", onAction);
|
|
31225
|
+
await safeExecute(async () => generateReport(data), "generate_report", onAction);
|
|
31226
|
+
if (isEnabled("init_deep")) {
|
|
31227
|
+
await safeExecute(async () => runInitDeep(data), "init_deep", onAction);
|
|
31228
|
+
}
|
|
31229
|
+
if (isEnabled("git_commit")) {
|
|
31230
|
+
await safeExecute(async () => promptGitCommit(data), "git_commit", onAction);
|
|
31231
|
+
}
|
|
31232
|
+
});
|
|
31233
|
+
return {
|
|
31234
|
+
cleanup: () => {
|
|
31235
|
+
unsubscribe();
|
|
31236
|
+
},
|
|
31237
|
+
setOnActionCallback: (cb) => {
|
|
31238
|
+
onAction = cb;
|
|
31239
|
+
}
|
|
31240
|
+
};
|
|
31241
|
+
}
|
|
30804
31242
|
// src/features/context-injector/collector.ts
|
|
30805
31243
|
var PRIORITY_ORDER = {
|
|
30806
31244
|
critical: 0,
|
|
@@ -30974,8 +31412,8 @@ function createFirstMessageVariantGate() {
|
|
|
30974
31412
|
}
|
|
30975
31413
|
// src/features/claude-code-mcp-loader/loader.ts
|
|
30976
31414
|
init_shared();
|
|
30977
|
-
import { existsSync as
|
|
30978
|
-
import { join as
|
|
31415
|
+
import { existsSync as existsSync40, readFileSync as readFileSync32 } from "fs";
|
|
31416
|
+
import { join as join53 } from "path";
|
|
30979
31417
|
|
|
30980
31418
|
// src/features/claude-code-mcp-loader/env-expander.ts
|
|
30981
31419
|
function expandEnvVars(value) {
|
|
@@ -31045,13 +31483,13 @@ function getMcpConfigPaths() {
|
|
|
31045
31483
|
const claudeConfigDir = getClaudeConfigDir();
|
|
31046
31484
|
const cwd2 = process.cwd();
|
|
31047
31485
|
return [
|
|
31048
|
-
{ path:
|
|
31049
|
-
{ path:
|
|
31050
|
-
{ path:
|
|
31486
|
+
{ path: join53(claudeConfigDir, ".mcp.json"), scope: "user" },
|
|
31487
|
+
{ path: join53(cwd2, ".mcp.json"), scope: "project" },
|
|
31488
|
+
{ path: join53(cwd2, ".claude", ".mcp.json"), scope: "local" }
|
|
31051
31489
|
];
|
|
31052
31490
|
}
|
|
31053
31491
|
async function loadMcpConfigFile(filePath) {
|
|
31054
|
-
if (!
|
|
31492
|
+
if (!existsSync40(filePath)) {
|
|
31055
31493
|
return null;
|
|
31056
31494
|
}
|
|
31057
31495
|
try {
|
|
@@ -31066,10 +31504,10 @@ function getSystemMcpServerNames() {
|
|
|
31066
31504
|
const names = new Set;
|
|
31067
31505
|
const paths = getMcpConfigPaths();
|
|
31068
31506
|
for (const { path: path7 } of paths) {
|
|
31069
|
-
if (!
|
|
31507
|
+
if (!existsSync40(path7))
|
|
31070
31508
|
continue;
|
|
31071
31509
|
try {
|
|
31072
|
-
const content =
|
|
31510
|
+
const content = readFileSync32(path7, "utf-8");
|
|
31073
31511
|
const config = JSON.parse(content);
|
|
31074
31512
|
if (!config?.mcpServers)
|
|
31075
31513
|
continue;
|
|
@@ -31120,27 +31558,27 @@ async function loadMcpConfigs() {
|
|
|
31120
31558
|
return { servers, loadedServers };
|
|
31121
31559
|
}
|
|
31122
31560
|
// src/features/claude-code-session-state/recovery.ts
|
|
31123
|
-
import { existsSync as
|
|
31124
|
-
import { join as
|
|
31561
|
+
import { existsSync as existsSync41, readdirSync as readdirSync13 } from "fs";
|
|
31562
|
+
import { join as join54 } from "path";
|
|
31125
31563
|
init_logger();
|
|
31126
31564
|
function recoverSessionAgents() {
|
|
31127
31565
|
let recoveredCount = 0;
|
|
31128
31566
|
try {
|
|
31129
|
-
if (!
|
|
31567
|
+
if (!existsSync41(MESSAGE_STORAGE)) {
|
|
31130
31568
|
log("[recovery] MESSAGE_STORAGE directory does not exist", { path: MESSAGE_STORAGE });
|
|
31131
31569
|
return 0;
|
|
31132
31570
|
}
|
|
31133
|
-
const entries =
|
|
31571
|
+
const entries = readdirSync13(MESSAGE_STORAGE, { withFileTypes: true });
|
|
31134
31572
|
for (const entry of entries) {
|
|
31135
31573
|
if (!entry.isDirectory())
|
|
31136
31574
|
continue;
|
|
31137
|
-
const projectDir =
|
|
31575
|
+
const projectDir = join54(MESSAGE_STORAGE, entry.name);
|
|
31138
31576
|
try {
|
|
31139
|
-
const sessionDirs =
|
|
31577
|
+
const sessionDirs = readdirSync13(projectDir, { withFileTypes: true });
|
|
31140
31578
|
for (const sessionEntry of sessionDirs) {
|
|
31141
31579
|
if (!sessionEntry.isDirectory())
|
|
31142
31580
|
continue;
|
|
31143
|
-
const sessionDir =
|
|
31581
|
+
const sessionDir = join54(projectDir, sessionEntry.name);
|
|
31144
31582
|
const sessionID = sessionEntry.name;
|
|
31145
31583
|
try {
|
|
31146
31584
|
const msg = findNearestAssistantMessage(sessionDir);
|
|
@@ -31566,14 +32004,14 @@ var EXT_TO_LANG = {
|
|
|
31566
32004
|
".gql": "graphql"
|
|
31567
32005
|
};
|
|
31568
32006
|
// src/tools/lsp/config.ts
|
|
31569
|
-
import { existsSync as
|
|
31570
|
-
import { join as
|
|
32007
|
+
import { existsSync as existsSync42, readFileSync as readFileSync33 } from "fs";
|
|
32008
|
+
import { join as join55 } from "path";
|
|
31571
32009
|
init_shared();
|
|
31572
32010
|
function loadJsonFile(path7) {
|
|
31573
|
-
if (!
|
|
32011
|
+
if (!existsSync42(path7))
|
|
31574
32012
|
return null;
|
|
31575
32013
|
try {
|
|
31576
|
-
return JSON.parse(
|
|
32014
|
+
return JSON.parse(readFileSync33(path7, "utf-8"));
|
|
31577
32015
|
} catch {
|
|
31578
32016
|
return null;
|
|
31579
32017
|
}
|
|
@@ -31582,9 +32020,9 @@ function getConfigPaths3() {
|
|
|
31582
32020
|
const cwd2 = process.cwd();
|
|
31583
32021
|
const configDir = getOpenCodeConfigDir({ binary: "opencode" });
|
|
31584
32022
|
return {
|
|
31585
|
-
project:
|
|
31586
|
-
user:
|
|
31587
|
-
opencode:
|
|
32023
|
+
project: join55(cwd2, ".opencode", "oh-my-opencode.json"),
|
|
32024
|
+
user: join55(configDir, "oh-my-opencode.json"),
|
|
32025
|
+
opencode: join55(configDir, "opencode.json")
|
|
31588
32026
|
};
|
|
31589
32027
|
}
|
|
31590
32028
|
function loadAllConfigs() {
|
|
@@ -31697,7 +32135,7 @@ function isServerInstalled(command) {
|
|
|
31697
32135
|
return false;
|
|
31698
32136
|
const cmd = command[0];
|
|
31699
32137
|
if (cmd.includes("/") || cmd.includes("\\")) {
|
|
31700
|
-
if (
|
|
32138
|
+
if (existsSync42(cmd))
|
|
31701
32139
|
return true;
|
|
31702
32140
|
}
|
|
31703
32141
|
const isWindows2 = process.platform === "win32";
|
|
@@ -31719,23 +32157,23 @@ function isServerInstalled(command) {
|
|
|
31719
32157
|
const paths = pathEnv.split(pathSeparator);
|
|
31720
32158
|
for (const p of paths) {
|
|
31721
32159
|
for (const suffix of exts) {
|
|
31722
|
-
if (
|
|
32160
|
+
if (existsSync42(join55(p, cmd + suffix))) {
|
|
31723
32161
|
return true;
|
|
31724
32162
|
}
|
|
31725
32163
|
}
|
|
31726
32164
|
}
|
|
31727
32165
|
const cwd2 = process.cwd();
|
|
31728
32166
|
const configDir = getOpenCodeConfigDir({ binary: "opencode" });
|
|
31729
|
-
const dataDir =
|
|
32167
|
+
const dataDir = join55(getDataDir(), "opencode");
|
|
31730
32168
|
const additionalBases = [
|
|
31731
|
-
|
|
31732
|
-
|
|
31733
|
-
|
|
31734
|
-
|
|
32169
|
+
join55(cwd2, "node_modules", ".bin"),
|
|
32170
|
+
join55(configDir, "bin"),
|
|
32171
|
+
join55(configDir, "node_modules", ".bin"),
|
|
32172
|
+
join55(dataDir, "bin")
|
|
31735
32173
|
];
|
|
31736
32174
|
for (const base of additionalBases) {
|
|
31737
32175
|
for (const suffix of exts) {
|
|
31738
|
-
if (
|
|
32176
|
+
if (existsSync42(join55(base, cmd + suffix))) {
|
|
31739
32177
|
return true;
|
|
31740
32178
|
}
|
|
31741
32179
|
}
|
|
@@ -31747,7 +32185,7 @@ function isServerInstalled(command) {
|
|
|
31747
32185
|
}
|
|
31748
32186
|
// src/tools/lsp/client.ts
|
|
31749
32187
|
var {spawn: spawn6 } = globalThis.Bun;
|
|
31750
|
-
import { readFileSync as
|
|
32188
|
+
import { readFileSync as readFileSync34 } from "fs";
|
|
31751
32189
|
import { extname, resolve as resolve8 } from "path";
|
|
31752
32190
|
import { pathToFileURL } from "url";
|
|
31753
32191
|
class LSPServerManager {
|
|
@@ -32198,7 +32636,7 @@ ${msg}`);
|
|
|
32198
32636
|
const absPath = resolve8(filePath);
|
|
32199
32637
|
if (this.openedFiles.has(absPath))
|
|
32200
32638
|
return;
|
|
32201
|
-
const text =
|
|
32639
|
+
const text = readFileSync34(absPath, "utf-8");
|
|
32202
32640
|
const ext = extname(absPath);
|
|
32203
32641
|
const languageId = getLanguageId(ext);
|
|
32204
32642
|
this.notify("textDocument/didOpen", {
|
|
@@ -32288,17 +32726,17 @@ ${msg}`);
|
|
|
32288
32726
|
// src/tools/lsp/utils.ts
|
|
32289
32727
|
import { extname as extname2, resolve as resolve9 } from "path";
|
|
32290
32728
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
32291
|
-
import { existsSync as
|
|
32729
|
+
import { existsSync as existsSync43, readFileSync as readFileSync35, writeFileSync as writeFileSync22 } from "fs";
|
|
32292
32730
|
function findWorkspaceRoot(filePath) {
|
|
32293
32731
|
let dir = resolve9(filePath);
|
|
32294
|
-
if (!
|
|
32732
|
+
if (!existsSync43(dir) || !__require("fs").statSync(dir).isDirectory()) {
|
|
32295
32733
|
dir = __require("path").dirname(dir);
|
|
32296
32734
|
}
|
|
32297
32735
|
const markers = [".git", "package.json", "pyproject.toml", "Cargo.toml", "go.mod", "pom.xml", "build.gradle"];
|
|
32298
32736
|
let prevDir = "";
|
|
32299
32737
|
while (dir !== prevDir) {
|
|
32300
32738
|
for (const marker of markers) {
|
|
32301
|
-
if (
|
|
32739
|
+
if (existsSync43(__require("path").join(dir, marker))) {
|
|
32302
32740
|
return dir;
|
|
32303
32741
|
}
|
|
32304
32742
|
}
|
|
@@ -32453,7 +32891,7 @@ function formatPrepareRenameResult(result) {
|
|
|
32453
32891
|
}
|
|
32454
32892
|
function applyTextEditsToFile(filePath, edits) {
|
|
32455
32893
|
try {
|
|
32456
|
-
let content =
|
|
32894
|
+
let content = readFileSync35(filePath, "utf-8");
|
|
32457
32895
|
const lines = content.split(`
|
|
32458
32896
|
`);
|
|
32459
32897
|
const sortedEdits = [...edits].sort((a, b) => {
|
|
@@ -32478,7 +32916,7 @@ function applyTextEditsToFile(filePath, edits) {
|
|
|
32478
32916
|
`));
|
|
32479
32917
|
}
|
|
32480
32918
|
}
|
|
32481
|
-
|
|
32919
|
+
writeFileSync22(filePath, lines.join(`
|
|
32482
32920
|
`), "utf-8");
|
|
32483
32921
|
return { success: true, editCount: edits.length };
|
|
32484
32922
|
} catch (err) {
|
|
@@ -32509,7 +32947,7 @@ function applyWorkspaceEdit(edit) {
|
|
|
32509
32947
|
if (change.kind === "create") {
|
|
32510
32948
|
try {
|
|
32511
32949
|
const filePath = uriToPath(change.uri);
|
|
32512
|
-
|
|
32950
|
+
writeFileSync22(filePath, "", "utf-8");
|
|
32513
32951
|
result.filesModified.push(filePath);
|
|
32514
32952
|
} catch (err) {
|
|
32515
32953
|
result.success = false;
|
|
@@ -32519,8 +32957,8 @@ function applyWorkspaceEdit(edit) {
|
|
|
32519
32957
|
try {
|
|
32520
32958
|
const oldPath = uriToPath(change.oldUri);
|
|
32521
32959
|
const newPath = uriToPath(change.newUri);
|
|
32522
|
-
const content =
|
|
32523
|
-
|
|
32960
|
+
const content = readFileSync35(oldPath, "utf-8");
|
|
32961
|
+
writeFileSync22(newPath, content, "utf-8");
|
|
32524
32962
|
__require("fs").unlinkSync(oldPath);
|
|
32525
32963
|
result.filesModified.push(newPath);
|
|
32526
32964
|
} catch (err) {
|
|
@@ -45099,13 +45537,13 @@ var lsp_rename = tool({
|
|
|
45099
45537
|
});
|
|
45100
45538
|
// src/tools/ast-grep/constants.ts
|
|
45101
45539
|
import { createRequire as createRequire4 } from "module";
|
|
45102
|
-
import { dirname as
|
|
45103
|
-
import { existsSync as
|
|
45540
|
+
import { dirname as dirname11, join as join57 } from "path";
|
|
45541
|
+
import { existsSync as existsSync45, statSync as statSync5 } from "fs";
|
|
45104
45542
|
|
|
45105
45543
|
// src/tools/ast-grep/downloader.ts
|
|
45106
45544
|
init_shared();
|
|
45107
|
-
import { existsSync as
|
|
45108
|
-
import { join as
|
|
45545
|
+
import { existsSync as existsSync44, mkdirSync as mkdirSync18, chmodSync as chmodSync2, unlinkSync as unlinkSync15 } from "fs";
|
|
45546
|
+
import { join as join56 } from "path";
|
|
45109
45547
|
import { homedir as homedir13 } from "os";
|
|
45110
45548
|
import { createRequire as createRequire3 } from "module";
|
|
45111
45549
|
var REPO2 = "ast-grep/ast-grep";
|
|
@@ -45131,19 +45569,19 @@ var PLATFORM_MAP2 = {
|
|
|
45131
45569
|
function getCacheDir3() {
|
|
45132
45570
|
if (process.platform === "win32") {
|
|
45133
45571
|
const localAppData = process.env.LOCALAPPDATA || process.env.APPDATA;
|
|
45134
|
-
const base2 = localAppData ||
|
|
45135
|
-
return
|
|
45572
|
+
const base2 = localAppData || join56(homedir13(), "AppData", "Local");
|
|
45573
|
+
return join56(base2, "oh-my-opencode", "bin");
|
|
45136
45574
|
}
|
|
45137
45575
|
const xdgCache = process.env.XDG_CACHE_HOME;
|
|
45138
|
-
const base = xdgCache ||
|
|
45139
|
-
return
|
|
45576
|
+
const base = xdgCache || join56(homedir13(), ".cache");
|
|
45577
|
+
return join56(base, "oh-my-opencode", "bin");
|
|
45140
45578
|
}
|
|
45141
45579
|
function getBinaryName3() {
|
|
45142
45580
|
return process.platform === "win32" ? "sg.exe" : "sg";
|
|
45143
45581
|
}
|
|
45144
45582
|
function getCachedBinaryPath2() {
|
|
45145
|
-
const binaryPath =
|
|
45146
|
-
return
|
|
45583
|
+
const binaryPath = join56(getCacheDir3(), getBinaryName3());
|
|
45584
|
+
return existsSync44(binaryPath) ? binaryPath : null;
|
|
45147
45585
|
}
|
|
45148
45586
|
async function downloadAstGrep(version2 = DEFAULT_VERSION) {
|
|
45149
45587
|
const platformKey = `${process.platform}-${process.arch}`;
|
|
@@ -45154,8 +45592,8 @@ async function downloadAstGrep(version2 = DEFAULT_VERSION) {
|
|
|
45154
45592
|
}
|
|
45155
45593
|
const cacheDir = getCacheDir3();
|
|
45156
45594
|
const binaryName = getBinaryName3();
|
|
45157
|
-
const binaryPath =
|
|
45158
|
-
if (
|
|
45595
|
+
const binaryPath = join56(cacheDir, binaryName);
|
|
45596
|
+
if (existsSync44(binaryPath)) {
|
|
45159
45597
|
return binaryPath;
|
|
45160
45598
|
}
|
|
45161
45599
|
const { arch, os: os6 } = platformInfo;
|
|
@@ -45163,21 +45601,21 @@ async function downloadAstGrep(version2 = DEFAULT_VERSION) {
|
|
|
45163
45601
|
const downloadUrl = `https://github.com/${REPO2}/releases/download/${version2}/${assetName}`;
|
|
45164
45602
|
console.log(`[oh-my-opencode] Downloading ast-grep binary...`);
|
|
45165
45603
|
try {
|
|
45166
|
-
if (!
|
|
45167
|
-
|
|
45604
|
+
if (!existsSync44(cacheDir)) {
|
|
45605
|
+
mkdirSync18(cacheDir, { recursive: true });
|
|
45168
45606
|
}
|
|
45169
45607
|
const response = await fetch(downloadUrl, { redirect: "follow" });
|
|
45170
45608
|
if (!response.ok) {
|
|
45171
45609
|
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
45172
45610
|
}
|
|
45173
|
-
const archivePath =
|
|
45611
|
+
const archivePath = join56(cacheDir, assetName);
|
|
45174
45612
|
const arrayBuffer = await response.arrayBuffer();
|
|
45175
45613
|
await Bun.write(archivePath, arrayBuffer);
|
|
45176
45614
|
await extractZip(archivePath, cacheDir);
|
|
45177
|
-
if (
|
|
45178
|
-
|
|
45615
|
+
if (existsSync44(archivePath)) {
|
|
45616
|
+
unlinkSync15(archivePath);
|
|
45179
45617
|
}
|
|
45180
|
-
if (process.platform !== "win32" &&
|
|
45618
|
+
if (process.platform !== "win32" && existsSync44(binaryPath)) {
|
|
45181
45619
|
chmodSync2(binaryPath, 493);
|
|
45182
45620
|
}
|
|
45183
45621
|
console.log(`[oh-my-opencode] ast-grep binary ready.`);
|
|
@@ -45227,9 +45665,9 @@ function findSgCliPathSync() {
|
|
|
45227
45665
|
try {
|
|
45228
45666
|
const require2 = createRequire4(import.meta.url);
|
|
45229
45667
|
const cliPkgPath = require2.resolve("@ast-grep/cli/package.json");
|
|
45230
|
-
const cliDir =
|
|
45231
|
-
const sgPath =
|
|
45232
|
-
if (
|
|
45668
|
+
const cliDir = dirname11(cliPkgPath);
|
|
45669
|
+
const sgPath = join57(cliDir, binaryName);
|
|
45670
|
+
if (existsSync45(sgPath) && isValidBinary(sgPath)) {
|
|
45233
45671
|
return sgPath;
|
|
45234
45672
|
}
|
|
45235
45673
|
} catch {}
|
|
@@ -45238,10 +45676,10 @@ function findSgCliPathSync() {
|
|
|
45238
45676
|
try {
|
|
45239
45677
|
const require2 = createRequire4(import.meta.url);
|
|
45240
45678
|
const pkgPath = require2.resolve(`${platformPkg}/package.json`);
|
|
45241
|
-
const pkgDir =
|
|
45679
|
+
const pkgDir = dirname11(pkgPath);
|
|
45242
45680
|
const astGrepName = process.platform === "win32" ? "ast-grep.exe" : "ast-grep";
|
|
45243
|
-
const binaryPath =
|
|
45244
|
-
if (
|
|
45681
|
+
const binaryPath = join57(pkgDir, astGrepName);
|
|
45682
|
+
if (existsSync45(binaryPath) && isValidBinary(binaryPath)) {
|
|
45245
45683
|
return binaryPath;
|
|
45246
45684
|
}
|
|
45247
45685
|
} catch {}
|
|
@@ -45249,7 +45687,7 @@ function findSgCliPathSync() {
|
|
|
45249
45687
|
if (process.platform === "darwin") {
|
|
45250
45688
|
const homebrewPaths = ["/opt/homebrew/bin/sg", "/usr/local/bin/sg"];
|
|
45251
45689
|
for (const path7 of homebrewPaths) {
|
|
45252
|
-
if (
|
|
45690
|
+
if (existsSync45(path7) && isValidBinary(path7)) {
|
|
45253
45691
|
return path7;
|
|
45254
45692
|
}
|
|
45255
45693
|
}
|
|
@@ -45304,11 +45742,11 @@ var DEFAULT_MAX_MATCHES = 500;
|
|
|
45304
45742
|
|
|
45305
45743
|
// src/tools/ast-grep/cli.ts
|
|
45306
45744
|
var {spawn: spawn7 } = globalThis.Bun;
|
|
45307
|
-
import { existsSync as
|
|
45745
|
+
import { existsSync as existsSync46 } from "fs";
|
|
45308
45746
|
var resolvedCliPath3 = null;
|
|
45309
45747
|
var initPromise2 = null;
|
|
45310
45748
|
async function getAstGrepPath() {
|
|
45311
|
-
if (resolvedCliPath3 !== null &&
|
|
45749
|
+
if (resolvedCliPath3 !== null && existsSync46(resolvedCliPath3)) {
|
|
45312
45750
|
return resolvedCliPath3;
|
|
45313
45751
|
}
|
|
45314
45752
|
if (initPromise2) {
|
|
@@ -45316,7 +45754,7 @@ async function getAstGrepPath() {
|
|
|
45316
45754
|
}
|
|
45317
45755
|
initPromise2 = (async () => {
|
|
45318
45756
|
const syncPath = findSgCliPathSync();
|
|
45319
|
-
if (syncPath &&
|
|
45757
|
+
if (syncPath && existsSync46(syncPath)) {
|
|
45320
45758
|
resolvedCliPath3 = syncPath;
|
|
45321
45759
|
setSgCliPath(syncPath);
|
|
45322
45760
|
return syncPath;
|
|
@@ -45350,7 +45788,7 @@ async function runSg(options) {
|
|
|
45350
45788
|
const paths = options.paths && options.paths.length > 0 ? options.paths : ["."];
|
|
45351
45789
|
args.push(...paths);
|
|
45352
45790
|
let cliPath = getSgCliPath();
|
|
45353
|
-
if (!
|
|
45791
|
+
if (!existsSync46(cliPath) && cliPath !== "sg") {
|
|
45354
45792
|
const downloadedPath = await getAstGrepPath();
|
|
45355
45793
|
if (downloadedPath) {
|
|
45356
45794
|
cliPath = downloadedPath;
|
|
@@ -45614,21 +46052,21 @@ var ast_grep_replace = tool({
|
|
|
45614
46052
|
var {spawn: spawn9 } = globalThis.Bun;
|
|
45615
46053
|
|
|
45616
46054
|
// src/tools/grep/constants.ts
|
|
45617
|
-
import { existsSync as
|
|
45618
|
-
import { join as
|
|
46055
|
+
import { existsSync as existsSync48 } from "fs";
|
|
46056
|
+
import { join as join59, dirname as dirname12 } from "path";
|
|
45619
46057
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
45620
46058
|
|
|
45621
46059
|
// src/tools/grep/downloader.ts
|
|
45622
46060
|
init_shared();
|
|
45623
|
-
import { existsSync as
|
|
45624
|
-
import { join as
|
|
46061
|
+
import { existsSync as existsSync47, mkdirSync as mkdirSync19, chmodSync as chmodSync3, unlinkSync as unlinkSync16, readdirSync as readdirSync14 } from "fs";
|
|
46062
|
+
import { join as join58 } from "path";
|
|
45625
46063
|
var {spawn: spawn8 } = globalThis.Bun;
|
|
45626
46064
|
function findFileRecursive(dir, filename) {
|
|
45627
46065
|
try {
|
|
45628
|
-
const entries =
|
|
46066
|
+
const entries = readdirSync14(dir, { withFileTypes: true, recursive: true });
|
|
45629
46067
|
for (const entry of entries) {
|
|
45630
46068
|
if (entry.isFile() && entry.name === filename) {
|
|
45631
|
-
return
|
|
46069
|
+
return join58(entry.parentPath ?? dir, entry.name);
|
|
45632
46070
|
}
|
|
45633
46071
|
}
|
|
45634
46072
|
} catch {
|
|
@@ -45649,11 +46087,11 @@ function getPlatformKey() {
|
|
|
45649
46087
|
}
|
|
45650
46088
|
function getInstallDir() {
|
|
45651
46089
|
const homeDir = process.env.HOME || process.env.USERPROFILE || ".";
|
|
45652
|
-
return
|
|
46090
|
+
return join58(homeDir, ".cache", "oh-my-opencode", "bin");
|
|
45653
46091
|
}
|
|
45654
46092
|
function getRgPath() {
|
|
45655
46093
|
const isWindows2 = process.platform === "win32";
|
|
45656
|
-
return
|
|
46094
|
+
return join58(getInstallDir(), isWindows2 ? "rg.exe" : "rg");
|
|
45657
46095
|
}
|
|
45658
46096
|
async function downloadFile(url2, destPath) {
|
|
45659
46097
|
const response = await fetch(url2);
|
|
@@ -45687,10 +46125,10 @@ async function extractZip2(archivePath, destDir) {
|
|
|
45687
46125
|
const binaryName = process.platform === "win32" ? "rg.exe" : "rg";
|
|
45688
46126
|
const foundPath = findFileRecursive(destDir, binaryName);
|
|
45689
46127
|
if (foundPath) {
|
|
45690
|
-
const destPath =
|
|
46128
|
+
const destPath = join58(destDir, binaryName);
|
|
45691
46129
|
if (foundPath !== destPath) {
|
|
45692
|
-
const { renameSync:
|
|
45693
|
-
|
|
46130
|
+
const { renameSync: renameSync5 } = await import("fs");
|
|
46131
|
+
renameSync5(foundPath, destPath);
|
|
45694
46132
|
}
|
|
45695
46133
|
}
|
|
45696
46134
|
}
|
|
@@ -45702,13 +46140,13 @@ async function downloadAndInstallRipgrep() {
|
|
|
45702
46140
|
}
|
|
45703
46141
|
const installDir = getInstallDir();
|
|
45704
46142
|
const rgPath = getRgPath();
|
|
45705
|
-
if (
|
|
46143
|
+
if (existsSync47(rgPath)) {
|
|
45706
46144
|
return rgPath;
|
|
45707
46145
|
}
|
|
45708
|
-
|
|
46146
|
+
mkdirSync19(installDir, { recursive: true });
|
|
45709
46147
|
const filename = `ripgrep-${RG_VERSION}-${config3.platform}.${config3.extension}`;
|
|
45710
46148
|
const url2 = `https://github.com/BurntSushi/ripgrep/releases/download/${RG_VERSION}/${filename}`;
|
|
45711
|
-
const archivePath =
|
|
46149
|
+
const archivePath = join58(installDir, filename);
|
|
45712
46150
|
try {
|
|
45713
46151
|
await downloadFile(url2, archivePath);
|
|
45714
46152
|
if (config3.extension === "tar.gz") {
|
|
@@ -45719,21 +46157,21 @@ async function downloadAndInstallRipgrep() {
|
|
|
45719
46157
|
if (process.platform !== "win32") {
|
|
45720
46158
|
chmodSync3(rgPath, 493);
|
|
45721
46159
|
}
|
|
45722
|
-
if (!
|
|
46160
|
+
if (!existsSync47(rgPath)) {
|
|
45723
46161
|
throw new Error("\u63D0\u53D6\u540E\u672A\u627E\u5230 ripgrep \u4E8C\u8FDB\u5236\u6587\u4EF6");
|
|
45724
46162
|
}
|
|
45725
46163
|
return rgPath;
|
|
45726
46164
|
} finally {
|
|
45727
|
-
if (
|
|
46165
|
+
if (existsSync47(archivePath)) {
|
|
45728
46166
|
try {
|
|
45729
|
-
|
|
46167
|
+
unlinkSync16(archivePath);
|
|
45730
46168
|
} catch {}
|
|
45731
46169
|
}
|
|
45732
46170
|
}
|
|
45733
46171
|
}
|
|
45734
46172
|
function getInstalledRipgrepPath() {
|
|
45735
46173
|
const rgPath = getRgPath();
|
|
45736
|
-
return
|
|
46174
|
+
return existsSync47(rgPath) ? rgPath : null;
|
|
45737
46175
|
}
|
|
45738
46176
|
|
|
45739
46177
|
// src/tools/grep/constants.ts
|
|
@@ -45757,7 +46195,7 @@ function findExecutable(name) {
|
|
|
45757
46195
|
continue;
|
|
45758
46196
|
}
|
|
45759
46197
|
}
|
|
45760
|
-
if (
|
|
46198
|
+
if (existsSync48(trimmed)) {
|
|
45761
46199
|
return trimmed;
|
|
45762
46200
|
}
|
|
45763
46201
|
}
|
|
@@ -45768,18 +46206,18 @@ function findExecutable(name) {
|
|
|
45768
46206
|
}
|
|
45769
46207
|
function getOpenCodeBundledRg() {
|
|
45770
46208
|
const execPath = process.execPath;
|
|
45771
|
-
const execDir =
|
|
46209
|
+
const execDir = dirname12(execPath);
|
|
45772
46210
|
const isWindows2 = process.platform === "win32";
|
|
45773
46211
|
const rgName = isWindows2 ? "rg.exe" : "rg";
|
|
45774
46212
|
const candidates = [
|
|
45775
|
-
|
|
45776
|
-
|
|
45777
|
-
|
|
45778
|
-
|
|
45779
|
-
|
|
46213
|
+
join59(getDataDir(), "opencode", "bin", rgName),
|
|
46214
|
+
join59(execDir, rgName),
|
|
46215
|
+
join59(execDir, "bin", rgName),
|
|
46216
|
+
join59(execDir, "..", "bin", rgName),
|
|
46217
|
+
join59(execDir, "..", "libexec", rgName)
|
|
45780
46218
|
];
|
|
45781
46219
|
for (const candidate of candidates) {
|
|
45782
|
-
if (
|
|
46220
|
+
if (existsSync48(candidate)) {
|
|
45783
46221
|
return candidate;
|
|
45784
46222
|
}
|
|
45785
46223
|
}
|
|
@@ -46241,8 +46679,8 @@ var glob = tool({
|
|
|
46241
46679
|
init_shared();
|
|
46242
46680
|
init_file_utils();
|
|
46243
46681
|
init_shared();
|
|
46244
|
-
import { existsSync as
|
|
46245
|
-
import { join as
|
|
46682
|
+
import { existsSync as existsSync49, readdirSync as readdirSync15, readFileSync as readFileSync36 } from "fs";
|
|
46683
|
+
import { join as join60, basename as basename4, dirname as dirname13 } from "path";
|
|
46246
46684
|
// src/features/builtin-commands/templates/init-deep.ts
|
|
46247
46685
|
var INIT_DEEP_TEMPLATE = `# /init-deep
|
|
46248
46686
|
|
|
@@ -47282,6 +47720,21 @@ var START_WORK_TEMPLATE = `\u4F60\u6B63\u5728\u5F00\u59CB\u4E00\u4E2A \u4E3B\u62
|
|
|
47282
47720
|
- \u5728\u59D4\u6D3E\u4EFB\u4F55\u4EFB\u52A1\u4E4B\u524D\uFF0C\u8BFB\u53D6\u5B8C\u6574\u7684\u8BA1\u5212\u6587\u4EF6
|
|
47283
47721
|
- \u9075\u5FAA \u4EFB\u52A1\u7F16\u6392-\u4E3B\u6267\u884C\u5B98 \u7684\u59D4\u6D3E\u534F\u8BAE\uFF087 \u8282\u683C\u5F0F\uFF09`;
|
|
47284
47722
|
|
|
47723
|
+
// src/features/builtin-commands/templates/btw.ts
|
|
47724
|
+
var BTW_TEMPLATE = `# /btw \u547D\u4EE4 \u2014 \u6781\u5EA6\u7CBE\u7B80\u4FA7\u8FB9\u63D0\u95EE
|
|
47725
|
+
|
|
47726
|
+
\u4F60\u6536\u5230\u4E86\u4E00\u4E2A\u4FA7\u8FB9\u95EE\u9898\u3002\u8BF7\u4EE5\u5355\u6B21\u54CD\u5E94\u56DE\u7B54\uFF0C\u4E0D\u8981\u53D1\u8D77\u540E\u7EED\u8FFD\u95EE\u3002
|
|
47727
|
+
|
|
47728
|
+
## \u7EA6\u675F
|
|
47729
|
+
- \u76F4\u63A5\u56DE\u7B54\u95EE\u9898\uFF0C\u4E0D\u8981\u6DFB\u52A0\u4E0A\u4E0B\u6587\u65E0\u5173\u7684\u5185\u5BB9
|
|
47730
|
+
- \u56DE\u7B54\u63A7\u5236\u5728 100 \u5B57\u4EE5\u5185\uFF0C1-3 \u53E5\u8BDD
|
|
47731
|
+
- \u53EA\u8F93\u51FA\u7B54\u6848\u672C\u8EAB\uFF0C\u4E0D\u8981\u8F93\u51FA\u601D\u8003\u8FC7\u7A0B\u6216\u5206\u6790
|
|
47732
|
+
- \u4E0D\u8981\u53D1\u8D77\u540E\u7EED\u5BF9\u8BDD
|
|
47733
|
+
- \u4F7F\u7528\u4E2D\u6587\u56DE\u590D
|
|
47734
|
+
|
|
47735
|
+
## \u7528\u6237\u95EE\u9898
|
|
47736
|
+
$ARGUMENTS`;
|
|
47737
|
+
|
|
47285
47738
|
// src/features/builtin-commands/commands.ts
|
|
47286
47739
|
var BUILTIN_COMMAND_DEFINITIONS = {
|
|
47287
47740
|
"init-deep": {
|
|
@@ -47346,6 +47799,17 @@ Timestamp: $TIMESTAMP
|
|
|
47346
47799
|
$ARGUMENTS
|
|
47347
47800
|
</user-request>`,
|
|
47348
47801
|
argumentHint: "[plan-name]"
|
|
47802
|
+
},
|
|
47803
|
+
btw: {
|
|
47804
|
+
description: "(builtin) \u6781\u5EA6\u7CBE\u7B80\u4FA7\u8FB9\u63D0\u95EE \u2014 \u5F02\u6B65\u6267\u884C\uFF0C\u4E0D\u963B\u585E\u4E3B\u5BF9\u8BDD",
|
|
47805
|
+
template: `<command-instruction>
|
|
47806
|
+
${BTW_TEMPLATE}
|
|
47807
|
+
</command-instruction>
|
|
47808
|
+
|
|
47809
|
+
<user-request>
|
|
47810
|
+
$ARGUMENTS
|
|
47811
|
+
</user-request>`,
|
|
47812
|
+
argumentHint: "<\u4F60\u7684\u95EE\u9898>"
|
|
47349
47813
|
}
|
|
47350
47814
|
};
|
|
47351
47815
|
function loadBuiltinCommands(disabledCommands) {
|
|
@@ -47361,18 +47825,18 @@ function loadBuiltinCommands(disabledCommands) {
|
|
|
47361
47825
|
}
|
|
47362
47826
|
// src/tools/slashcommand/tools.ts
|
|
47363
47827
|
function discoverCommandsFromDir2(commandsDir, scope) {
|
|
47364
|
-
if (!
|
|
47828
|
+
if (!existsSync49(commandsDir)) {
|
|
47365
47829
|
return [];
|
|
47366
47830
|
}
|
|
47367
|
-
const entries =
|
|
47831
|
+
const entries = readdirSync15(commandsDir, { withFileTypes: true });
|
|
47368
47832
|
const commands2 = [];
|
|
47369
47833
|
for (const entry of entries) {
|
|
47370
47834
|
if (!isMarkdownFile(entry))
|
|
47371
47835
|
continue;
|
|
47372
|
-
const commandPath =
|
|
47836
|
+
const commandPath = join60(commandsDir, entry.name);
|
|
47373
47837
|
const commandName = basename4(entry.name, ".md");
|
|
47374
47838
|
try {
|
|
47375
|
-
const content =
|
|
47839
|
+
const content = readFileSync36(commandPath, "utf-8");
|
|
47376
47840
|
const { data, body } = parseFrontmatter(content);
|
|
47377
47841
|
const isOpencodeSource = scope === "opencode" || scope === "opencode-project";
|
|
47378
47842
|
const metadata = {
|
|
@@ -47396,17 +47860,17 @@ function discoverCommandsFromDir2(commandsDir, scope) {
|
|
|
47396
47860
|
}
|
|
47397
47861
|
return commands2;
|
|
47398
47862
|
}
|
|
47399
|
-
function discoverCommandsSync() {
|
|
47863
|
+
function discoverCommandsSync(disabledCommands) {
|
|
47400
47864
|
const configDir = getOpenCodeConfigDir({ binary: "opencode" });
|
|
47401
|
-
const userCommandsDir =
|
|
47402
|
-
const projectCommandsDir =
|
|
47403
|
-
const opencodeGlobalDir =
|
|
47404
|
-
const opencodeProjectDir =
|
|
47865
|
+
const userCommandsDir = join60(getClaudeConfigDir(), "commands");
|
|
47866
|
+
const projectCommandsDir = join60(process.cwd(), ".claude", "commands");
|
|
47867
|
+
const opencodeGlobalDir = join60(configDir, "command");
|
|
47868
|
+
const opencodeProjectDir = join60(process.cwd(), ".opencode", "command");
|
|
47405
47869
|
const userCommands = discoverCommandsFromDir2(userCommandsDir, "user");
|
|
47406
47870
|
const opencodeGlobalCommands = discoverCommandsFromDir2(opencodeGlobalDir, "opencode");
|
|
47407
47871
|
const projectCommands = discoverCommandsFromDir2(projectCommandsDir, "project");
|
|
47408
47872
|
const opencodeProjectCommands = discoverCommandsFromDir2(opencodeProjectDir, "opencode-project");
|
|
47409
|
-
const builtinCommandsMap = loadBuiltinCommands();
|
|
47873
|
+
const builtinCommandsMap = loadBuiltinCommands(disabledCommands);
|
|
47410
47874
|
const builtinCommands = Object.values(builtinCommandsMap).map((cmd) => ({
|
|
47411
47875
|
name: cmd.name,
|
|
47412
47876
|
metadata: {
|
|
@@ -47439,6 +47903,28 @@ function skillToCommandInfo2(skill) {
|
|
|
47439
47903
|
lazyContentLoader: skill.lazyContent
|
|
47440
47904
|
};
|
|
47441
47905
|
}
|
|
47906
|
+
var COMMANDS_TO_SANITIZE = new Set(["btw"]);
|
|
47907
|
+
var CONSTRAINT_PATTERNS = [
|
|
47908
|
+
"\u4E0D\u8981\u53D1\u8D77\u540E\u7EED\u5BF9\u8BDD",
|
|
47909
|
+
"\u56DE\u7B54\u63A7\u5236\u5728",
|
|
47910
|
+
"\u4F60\u6536\u5230\u4E86\u4E00\u4E2A\u4FA7\u8FB9\u95EE\u9898",
|
|
47911
|
+
"\u53EA\u8F93\u51FA\u7B54\u6848\u672C\u8EAB",
|
|
47912
|
+
"\u4E0D\u8981\u8F93\u51FA\u601D\u8003\u8FC7\u7A0B"
|
|
47913
|
+
];
|
|
47914
|
+
function sanitizeCommandContent(content, commandName) {
|
|
47915
|
+
if (!COMMANDS_TO_SANITIZE.has(commandName.toLowerCase())) {
|
|
47916
|
+
return content;
|
|
47917
|
+
}
|
|
47918
|
+
let cleaned = content.replace(/<\/?command-instruction>/g, "").replace(/<\/?user-request>/g, "").replace(/<\/?user-task>/g, "").replace(/<\/?session-context>/g, "").replace(/\$ARGUMENTS/g, "");
|
|
47919
|
+
const lines = cleaned.split(`
|
|
47920
|
+
`);
|
|
47921
|
+
cleaned = lines.filter((line) => {
|
|
47922
|
+
const trimmed = line.trim().replace(/^-\s*/, "");
|
|
47923
|
+
return !CONSTRAINT_PATTERNS.some((pattern) => trimmed.startsWith(pattern));
|
|
47924
|
+
}).join(`
|
|
47925
|
+
`);
|
|
47926
|
+
return cleaned.trim();
|
|
47927
|
+
}
|
|
47442
47928
|
async function formatLoadedCommand(cmd) {
|
|
47443
47929
|
const sections = [];
|
|
47444
47930
|
sections.push(`# /${cmd.name} Command
|
|
@@ -47473,10 +47959,11 @@ async function formatLoadedCommand(cmd) {
|
|
|
47473
47959
|
if (!content && cmd.lazyContentLoader) {
|
|
47474
47960
|
content = await cmd.lazyContentLoader.load();
|
|
47475
47961
|
}
|
|
47476
|
-
const commandDir = cmd.path ?
|
|
47962
|
+
const commandDir = cmd.path ? dirname13(cmd.path) : process.cwd();
|
|
47477
47963
|
const withFileRefs = await resolveFileReferencesInText(content, commandDir);
|
|
47478
47964
|
const resolvedContent = await resolveCommandsInText(withFileRefs);
|
|
47479
|
-
|
|
47965
|
+
const sanitized = sanitizeCommandContent(resolvedContent, cmd.name);
|
|
47966
|
+
sections.push(sanitized.trim());
|
|
47480
47967
|
return sections.join(`
|
|
47481
47968
|
`);
|
|
47482
47969
|
}
|
|
@@ -47578,13 +48065,13 @@ var slashcommand = createSlashcommandTool();
|
|
|
47578
48065
|
// src/tools/session-manager/constants.ts
|
|
47579
48066
|
init_data_path();
|
|
47580
48067
|
init_shared();
|
|
47581
|
-
import { join as
|
|
48068
|
+
import { join as join61 } from "path";
|
|
47582
48069
|
var OPENCODE_STORAGE11 = getOpenCodeStorageDir();
|
|
47583
|
-
var MESSAGE_STORAGE4 =
|
|
47584
|
-
var PART_STORAGE4 =
|
|
47585
|
-
var SESSION_STORAGE =
|
|
47586
|
-
var TODO_DIR2 =
|
|
47587
|
-
var TRANSCRIPT_DIR2 =
|
|
48070
|
+
var MESSAGE_STORAGE4 = join61(OPENCODE_STORAGE11, "message");
|
|
48071
|
+
var PART_STORAGE4 = join61(OPENCODE_STORAGE11, "part");
|
|
48072
|
+
var SESSION_STORAGE = join61(OPENCODE_STORAGE11, "session");
|
|
48073
|
+
var TODO_DIR2 = join61(getClaudeConfigDir(), "todos");
|
|
48074
|
+
var TRANSCRIPT_DIR2 = join61(getClaudeConfigDir(), "transcripts");
|
|
47588
48075
|
var SESSION_LIST_DESCRIPTION = `\u5217\u51FA\u6240\u6709 OpenCode session\uFF0C\u652F\u6301\u53EF\u9009\u8FC7\u6EE4\u3002
|
|
47589
48076
|
|
|
47590
48077
|
\u8FD4\u56DE\u53EF\u7528\u7684 session ID \u5217\u8868\uFF0C\u5305\u542B\u6D88\u606F\u6570\u91CF\u3001\u65E5\u671F\u8303\u56F4\u548C\u4F7F\u7528\u8FC7\u7684 agents \u7B49\u5143\u6570\u636E\u3002
|
|
@@ -47657,11 +48144,11 @@ Has Todos: Yes (12 items, 8 completed)
|
|
|
47657
48144
|
Has Transcript: Yes (234 entries)`;
|
|
47658
48145
|
|
|
47659
48146
|
// src/tools/session-manager/storage.ts
|
|
47660
|
-
import { existsSync as
|
|
48147
|
+
import { existsSync as existsSync50, readdirSync as readdirSync16 } from "fs";
|
|
47661
48148
|
import { readdir, readFile } from "fs/promises";
|
|
47662
|
-
import { join as
|
|
48149
|
+
import { join as join62 } from "path";
|
|
47663
48150
|
async function getMainSessions(options) {
|
|
47664
|
-
if (!
|
|
48151
|
+
if (!existsSync50(SESSION_STORAGE))
|
|
47665
48152
|
return [];
|
|
47666
48153
|
const sessions = [];
|
|
47667
48154
|
try {
|
|
@@ -47669,13 +48156,13 @@ async function getMainSessions(options) {
|
|
|
47669
48156
|
for (const projectDir of projectDirs) {
|
|
47670
48157
|
if (!projectDir.isDirectory())
|
|
47671
48158
|
continue;
|
|
47672
|
-
const projectPath =
|
|
48159
|
+
const projectPath = join62(SESSION_STORAGE, projectDir.name);
|
|
47673
48160
|
const sessionFiles = await readdir(projectPath);
|
|
47674
48161
|
for (const file2 of sessionFiles) {
|
|
47675
48162
|
if (!file2.endsWith(".json"))
|
|
47676
48163
|
continue;
|
|
47677
48164
|
try {
|
|
47678
|
-
const content = await readFile(
|
|
48165
|
+
const content = await readFile(join62(projectPath, file2), "utf-8");
|
|
47679
48166
|
const meta = JSON.parse(content);
|
|
47680
48167
|
if (meta.parentID)
|
|
47681
48168
|
continue;
|
|
@@ -47693,7 +48180,7 @@ async function getMainSessions(options) {
|
|
|
47693
48180
|
return sessions.sort((a, b) => b.time.updated - a.time.updated);
|
|
47694
48181
|
}
|
|
47695
48182
|
async function getAllSessions() {
|
|
47696
|
-
if (!
|
|
48183
|
+
if (!existsSync50(MESSAGE_STORAGE4))
|
|
47697
48184
|
return [];
|
|
47698
48185
|
const sessions = [];
|
|
47699
48186
|
async function scanDirectory(dir) {
|
|
@@ -47701,7 +48188,7 @@ async function getAllSessions() {
|
|
|
47701
48188
|
const entries = await readdir(dir, { withFileTypes: true });
|
|
47702
48189
|
for (const entry of entries) {
|
|
47703
48190
|
if (entry.isDirectory()) {
|
|
47704
|
-
const sessionPath =
|
|
48191
|
+
const sessionPath = join62(dir, entry.name);
|
|
47705
48192
|
const files = await readdir(sessionPath);
|
|
47706
48193
|
if (files.some((f) => f.endsWith(".json"))) {
|
|
47707
48194
|
sessions.push(entry.name);
|
|
@@ -47718,16 +48205,16 @@ async function getAllSessions() {
|
|
|
47718
48205
|
return [...new Set(sessions)];
|
|
47719
48206
|
}
|
|
47720
48207
|
function getMessageDir6(sessionID) {
|
|
47721
|
-
if (!
|
|
48208
|
+
if (!existsSync50(MESSAGE_STORAGE4))
|
|
47722
48209
|
return "";
|
|
47723
|
-
const directPath =
|
|
47724
|
-
if (
|
|
48210
|
+
const directPath = join62(MESSAGE_STORAGE4, sessionID);
|
|
48211
|
+
if (existsSync50(directPath)) {
|
|
47725
48212
|
return directPath;
|
|
47726
48213
|
}
|
|
47727
48214
|
try {
|
|
47728
|
-
for (const dir of
|
|
47729
|
-
const sessionPath =
|
|
47730
|
-
if (
|
|
48215
|
+
for (const dir of readdirSync16(MESSAGE_STORAGE4)) {
|
|
48216
|
+
const sessionPath = join62(MESSAGE_STORAGE4, dir, sessionID);
|
|
48217
|
+
if (existsSync50(sessionPath)) {
|
|
47731
48218
|
return sessionPath;
|
|
47732
48219
|
}
|
|
47733
48220
|
}
|
|
@@ -47741,7 +48228,7 @@ function sessionExists(sessionID) {
|
|
|
47741
48228
|
}
|
|
47742
48229
|
async function readSessionMessages(sessionID) {
|
|
47743
48230
|
const messageDir = getMessageDir6(sessionID);
|
|
47744
|
-
if (!messageDir || !
|
|
48231
|
+
if (!messageDir || !existsSync50(messageDir))
|
|
47745
48232
|
return [];
|
|
47746
48233
|
const messages = [];
|
|
47747
48234
|
try {
|
|
@@ -47750,7 +48237,7 @@ async function readSessionMessages(sessionID) {
|
|
|
47750
48237
|
if (!file2.endsWith(".json"))
|
|
47751
48238
|
continue;
|
|
47752
48239
|
try {
|
|
47753
|
-
const content = await readFile(
|
|
48240
|
+
const content = await readFile(join62(messageDir, file2), "utf-8");
|
|
47754
48241
|
const meta = JSON.parse(content);
|
|
47755
48242
|
const parts = await readParts2(meta.id);
|
|
47756
48243
|
messages.push({
|
|
@@ -47776,8 +48263,8 @@ async function readSessionMessages(sessionID) {
|
|
|
47776
48263
|
});
|
|
47777
48264
|
}
|
|
47778
48265
|
async function readParts2(messageID) {
|
|
47779
|
-
const partDir =
|
|
47780
|
-
if (!
|
|
48266
|
+
const partDir = join62(PART_STORAGE4, messageID);
|
|
48267
|
+
if (!existsSync50(partDir))
|
|
47781
48268
|
return [];
|
|
47782
48269
|
const parts = [];
|
|
47783
48270
|
try {
|
|
@@ -47786,7 +48273,7 @@ async function readParts2(messageID) {
|
|
|
47786
48273
|
if (!file2.endsWith(".json"))
|
|
47787
48274
|
continue;
|
|
47788
48275
|
try {
|
|
47789
|
-
const content = await readFile(
|
|
48276
|
+
const content = await readFile(join62(partDir, file2), "utf-8");
|
|
47790
48277
|
parts.push(JSON.parse(content));
|
|
47791
48278
|
} catch {
|
|
47792
48279
|
continue;
|
|
@@ -47798,14 +48285,14 @@ async function readParts2(messageID) {
|
|
|
47798
48285
|
return parts.sort((a, b) => a.id.localeCompare(b.id));
|
|
47799
48286
|
}
|
|
47800
48287
|
async function readSessionTodos(sessionID) {
|
|
47801
|
-
if (!
|
|
48288
|
+
if (!existsSync50(TODO_DIR2))
|
|
47802
48289
|
return [];
|
|
47803
48290
|
try {
|
|
47804
48291
|
const allFiles = await readdir(TODO_DIR2);
|
|
47805
48292
|
const todoFiles = allFiles.filter((f) => f.includes(sessionID) && f.endsWith(".json"));
|
|
47806
48293
|
for (const file2 of todoFiles) {
|
|
47807
48294
|
try {
|
|
47808
|
-
const content = await readFile(
|
|
48295
|
+
const content = await readFile(join62(TODO_DIR2, file2), "utf-8");
|
|
47809
48296
|
const data = JSON.parse(content);
|
|
47810
48297
|
if (Array.isArray(data)) {
|
|
47811
48298
|
return data.map((item) => ({
|
|
@@ -47825,10 +48312,10 @@ async function readSessionTodos(sessionID) {
|
|
|
47825
48312
|
return [];
|
|
47826
48313
|
}
|
|
47827
48314
|
async function readSessionTranscript(sessionID) {
|
|
47828
|
-
if (!
|
|
48315
|
+
if (!existsSync50(TRANSCRIPT_DIR2))
|
|
47829
48316
|
return 0;
|
|
47830
|
-
const transcriptFile =
|
|
47831
|
-
if (!
|
|
48317
|
+
const transcriptFile = join62(TRANSCRIPT_DIR2, `${sessionID}.jsonl`);
|
|
48318
|
+
if (!existsSync50(transcriptFile))
|
|
47832
48319
|
return 0;
|
|
47833
48320
|
try {
|
|
47834
48321
|
const content = await readFile(transcriptFile, "utf-8");
|
|
@@ -48324,7 +48811,7 @@ var TOOL_DESCRIPTION_PREFIX2 = `\u52A0\u8F7D skill \u4EE5\u83B7\u53D6\u7279\u5B9
|
|
|
48324
48811
|
Skills \u63D0\u4F9B\u4E13\u4E1A\u77E5\u8BC6\u548C\u5206\u6B65\u6307\u5BFC\u3002
|
|
48325
48812
|
\u5F53\u4EFB\u52A1\u4E0E\u53EF\u7528 skill \u7684\u63CF\u8FF0\u76F8\u5339\u914D\u65F6\u4F7F\u7528\u6B64\u5DE5\u5177\u3002`;
|
|
48326
48813
|
// src/tools/skill/tools.ts
|
|
48327
|
-
import { dirname as
|
|
48814
|
+
import { dirname as dirname14 } from "path";
|
|
48328
48815
|
function loadedSkillToInfo(skill) {
|
|
48329
48816
|
return {
|
|
48330
48817
|
name: skill.name,
|
|
@@ -48478,7 +48965,7 @@ function createSkillTool(options = {}) {
|
|
|
48478
48965
|
if (args.name === "git-master") {
|
|
48479
48966
|
body = injectGitMasterConfig(body, options.gitMasterConfig);
|
|
48480
48967
|
}
|
|
48481
|
-
const dir = skill.path ?
|
|
48968
|
+
const dir = skill.path ? dirname14(skill.path) : skill.resolvedPath || process.cwd();
|
|
48482
48969
|
const output = [
|
|
48483
48970
|
`## Skill: ${skill.name}`,
|
|
48484
48971
|
"",
|
|
@@ -49035,20 +49522,20 @@ var CALL_OMO_AGENT_DESCRIPTION = `\u542F\u52A8\u6DF1\u5EA6\u63A2\u7D22/\u77E5\u8
|
|
|
49035
49522
|
|
|
49036
49523
|
\u4F20\u5165 \`session_id=<id>\` \u53EF\u7EE7\u7EED\u4E4B\u524D\u7684 agent\uFF0C\u4FDD\u7559\u5B8C\u6574\u4E0A\u4E0B\u6587\u3002Prompts \u5FC5\u987B\u4E3A\u4E2D\u6587\u3002\u4F7F\u7528 \`background_output\` \u83B7\u53D6\u5F02\u6B65\u7ED3\u679C\u3002`;
|
|
49037
49524
|
// src/tools/call-omo-agent/tools.ts
|
|
49038
|
-
import { existsSync as
|
|
49039
|
-
import { join as
|
|
49525
|
+
import { existsSync as existsSync51, readdirSync as readdirSync17 } from "fs";
|
|
49526
|
+
import { join as join63 } from "path";
|
|
49040
49527
|
init_shared();
|
|
49041
49528
|
init_agent_display_names();
|
|
49042
49529
|
init_session_cursor();
|
|
49043
49530
|
function getMessageDir7(sessionID) {
|
|
49044
|
-
if (!
|
|
49531
|
+
if (!existsSync51(MESSAGE_STORAGE))
|
|
49045
49532
|
return null;
|
|
49046
|
-
const directPath =
|
|
49047
|
-
if (
|
|
49533
|
+
const directPath = join63(MESSAGE_STORAGE, sessionID);
|
|
49534
|
+
if (existsSync51(directPath))
|
|
49048
49535
|
return directPath;
|
|
49049
|
-
for (const dir of
|
|
49050
|
-
const sessionPath =
|
|
49051
|
-
if (
|
|
49536
|
+
for (const dir of readdirSync17(MESSAGE_STORAGE)) {
|
|
49537
|
+
const sessionPath = join63(MESSAGE_STORAGE, dir, sessionID);
|
|
49538
|
+
if (existsSync51(sessionPath))
|
|
49052
49539
|
return sessionPath;
|
|
49053
49540
|
}
|
|
49054
49541
|
return null;
|
|
@@ -49474,8 +49961,8 @@ function createLookAt(ctx) {
|
|
|
49474
49961
|
}
|
|
49475
49962
|
// src/tools/delegate-task/tools.ts
|
|
49476
49963
|
init_constants();
|
|
49477
|
-
import { existsSync as
|
|
49478
|
-
import { join as
|
|
49964
|
+
import { existsSync as existsSync52, readdirSync as readdirSync18 } from "fs";
|
|
49965
|
+
import { join as join64 } from "path";
|
|
49479
49966
|
|
|
49480
49967
|
// src/features/task-toast-manager/manager.ts
|
|
49481
49968
|
class TaskToastManager {
|
|
@@ -49681,14 +50168,14 @@ function parseFallbackModelEntries(entries) {
|
|
|
49681
50168
|
});
|
|
49682
50169
|
}
|
|
49683
50170
|
function getMessageDir8(sessionID) {
|
|
49684
|
-
if (!
|
|
50171
|
+
if (!existsSync52(MESSAGE_STORAGE))
|
|
49685
50172
|
return null;
|
|
49686
|
-
const directPath =
|
|
49687
|
-
if (
|
|
50173
|
+
const directPath = join64(MESSAGE_STORAGE, sessionID);
|
|
50174
|
+
if (existsSync52(directPath))
|
|
49688
50175
|
return directPath;
|
|
49689
|
-
for (const dir of
|
|
49690
|
-
const sessionPath =
|
|
49691
|
-
if (
|
|
50176
|
+
for (const dir of readdirSync18(MESSAGE_STORAGE)) {
|
|
50177
|
+
const sessionPath = join64(MESSAGE_STORAGE, dir, sessionID);
|
|
50178
|
+
if (existsSync52(sessionPath))
|
|
49692
50179
|
return sessionPath;
|
|
49693
50180
|
}
|
|
49694
50181
|
return null;
|
|
@@ -49757,13 +50244,15 @@ function resolveCategoryConfig(categoryName, options) {
|
|
|
49757
50244
|
return { config: config3, promptAppend, model };
|
|
49758
50245
|
}
|
|
49759
50246
|
function buildSystemContent(input) {
|
|
49760
|
-
const { skillContent, categoryPromptAppend } = input;
|
|
50247
|
+
const { skillContent, categoryPromptAppend, config: config3 } = input;
|
|
49761
50248
|
const parts = [];
|
|
49762
50249
|
if (skillContent)
|
|
49763
50250
|
parts.push(skillContent);
|
|
49764
50251
|
if (categoryPromptAppend)
|
|
49765
50252
|
parts.push(categoryPromptAppend);
|
|
49766
|
-
|
|
50253
|
+
if (isLanguageEnforcementEnabled(config3)) {
|
|
50254
|
+
parts.push(ZH_SUB_AGENT_INSTRUCTION);
|
|
50255
|
+
}
|
|
49767
50256
|
return parts.join(`
|
|
49768
50257
|
|
|
49769
50258
|
`);
|
|
@@ -49804,7 +50293,7 @@ async function pollTaskCompletion(client2, sessionID, maxWaitMs = 120000, pollIn
|
|
|
49804
50293
|
return "\u4EFB\u52A1\u8D85\u65F6";
|
|
49805
50294
|
}
|
|
49806
50295
|
function createDelegateTask(options) {
|
|
49807
|
-
const { manager, client: client2, directory, userCategories, gitMasterConfig, sisyphusJuniorModel, runtimeFallbackConfig, agentFallbackModels } = options;
|
|
50296
|
+
const { manager, client: client2, directory, userCategories, gitMasterConfig, sisyphusJuniorModel, runtimeFallbackConfig, agentFallbackModels, languageEnforcementConfig } = options;
|
|
49808
50297
|
const allCategories = { ...DEFAULT_CATEGORIES, ...userCategories };
|
|
49809
50298
|
const getConfiguredFallbackModels = (agent, category) => {
|
|
49810
50299
|
const chineseAgent = agent ? resolveAgentName(agent) : undefined;
|
|
@@ -50145,7 +50634,7 @@ ${textContent || "(\u65E0\u6587\u672C\u8F93\u51FA)"}
|
|
|
50145
50634
|
}
|
|
50146
50635
|
}
|
|
50147
50636
|
agentToUse = resolveAgentName(agentToUse);
|
|
50148
|
-
const systemContent = buildSystemContent({ skillContent, categoryPromptAppend });
|
|
50637
|
+
const systemContent = buildSystemContent({ skillContent, categoryPromptAppend, config: languageEnforcementConfig });
|
|
50149
50638
|
const effectiveRunInBackground = runInBackground || isUnstableAgent;
|
|
50150
50639
|
if (effectiveRunInBackground) {
|
|
50151
50640
|
try {
|
|
@@ -50443,6 +50932,84 @@ ${classification.shouldFallback ? "\uD83D\uDCA1 \u6B64\u9519\u8BEF\u7B26\u5408 r
|
|
|
50443
50932
|
const textParts = lastMessage?.parts?.filter((p) => p.type === "text" || p.type === "reasoning") ?? [];
|
|
50444
50933
|
const textContent = textParts.map((p) => p.text ?? "").filter(Boolean).join(`
|
|
50445
50934
|
`);
|
|
50935
|
+
let displayContent = textContent;
|
|
50936
|
+
const pluginConfig = toolContext.pluginConfig;
|
|
50937
|
+
if (isLanguageEnforcementEnabled(pluginConfig) && textContent) {
|
|
50938
|
+
const codeBlockMatches = textContent.match(/```[\s\S]*?```/g) || [];
|
|
50939
|
+
const codeBlockRatio = codeBlockMatches.reduce((sum, b) => sum + b.length, 0) / textContent.length;
|
|
50940
|
+
const isValidJson = (() => {
|
|
50941
|
+
try {
|
|
50942
|
+
JSON.parse(textContent);
|
|
50943
|
+
return true;
|
|
50944
|
+
} catch {
|
|
50945
|
+
return false;
|
|
50946
|
+
}
|
|
50947
|
+
})();
|
|
50948
|
+
const shouldSkip = codeBlockRatio > 0.7 || isValidJson || textContent.length > 50 * 1024;
|
|
50949
|
+
if (!shouldSkip) {
|
|
50950
|
+
const violation = detectEnglishViolation(textContent, 0.6);
|
|
50951
|
+
if (violation) {
|
|
50952
|
+
try {
|
|
50953
|
+
await client2.session.prompt({
|
|
50954
|
+
path: { id: sessionID },
|
|
50955
|
+
body: {
|
|
50956
|
+
agent: agentToUse,
|
|
50957
|
+
system: systemContent,
|
|
50958
|
+
tools: { task: false, delegate_task: false, call_omo_agent: true },
|
|
50959
|
+
parts: [{ type: "text", text: args.prompt + `
|
|
50960
|
+
|
|
50961
|
+
[SYSTEM: \u8BF7\u52A1\u5FC5\u4F7F\u7528\u4E2D\u6587\u56DE\u5E94\u3002\u4E0A\u6B21\u56DE\u5E94\u68C0\u6D4B\u5230\u82F1\u6587\u601D\u8003\u75D5\u8FF9\u3002]` }],
|
|
50962
|
+
...categoryModel ? { model: categoryModel } : {}
|
|
50963
|
+
}
|
|
50964
|
+
});
|
|
50965
|
+
const retryPollStart = Date.now();
|
|
50966
|
+
const RETRY_MAX_POLL_MS = 10 * 60 * 1000;
|
|
50967
|
+
const RETRY_STABILITY_MS = 5000;
|
|
50968
|
+
const RETRY_STABILITY_POLLS = 3;
|
|
50969
|
+
let retryLastMsgCount = 0;
|
|
50970
|
+
let retryStablePolls = 0;
|
|
50971
|
+
while (Date.now() - retryPollStart < RETRY_MAX_POLL_MS) {
|
|
50972
|
+
if (ctx.abort?.aborted)
|
|
50973
|
+
break;
|
|
50974
|
+
await sleep(500);
|
|
50975
|
+
const retryStatusResult = await client2.session.status();
|
|
50976
|
+
const retryAllStatuses = retryStatusResult.data ?? {};
|
|
50977
|
+
if (retryAllStatuses[sessionID]?.type !== "idle") {
|
|
50978
|
+
retryStablePolls = 0;
|
|
50979
|
+
retryLastMsgCount = 0;
|
|
50980
|
+
continue;
|
|
50981
|
+
}
|
|
50982
|
+
if (Date.now() - retryPollStart < RETRY_STABILITY_MS)
|
|
50983
|
+
continue;
|
|
50984
|
+
const retryMsgsResult = await client2.session.messages({ path: { id: sessionID } });
|
|
50985
|
+
const retryMsgs = retryMsgsResult.data ?? retryMsgsResult;
|
|
50986
|
+
if (retryMsgs.length === retryLastMsgCount) {
|
|
50987
|
+
retryStablePolls++;
|
|
50988
|
+
if (retryStablePolls >= RETRY_STABILITY_POLLS)
|
|
50989
|
+
break;
|
|
50990
|
+
} else {
|
|
50991
|
+
retryStablePolls = 0;
|
|
50992
|
+
retryLastMsgCount = retryMsgs.length;
|
|
50993
|
+
}
|
|
50994
|
+
}
|
|
50995
|
+
const retryMessagesResult = await client2.session.messages({ path: { id: sessionID } });
|
|
50996
|
+
if (!retryMessagesResult.error) {
|
|
50997
|
+
const retryMessages = retryMessagesResult.data ?? retryMessagesResult;
|
|
50998
|
+
const retryAssistantMsgs = retryMessages.filter((m) => m.info?.role === "assistant").sort((a, b) => (b.info?.time?.created ?? 0) - (a.info?.time?.created ?? 0));
|
|
50999
|
+
const retryLastMsg = retryAssistantMsgs[0];
|
|
51000
|
+
if (retryLastMsg) {
|
|
51001
|
+
const retryTextParts = retryLastMsg.parts?.filter((p) => p.type === "text" || p.type === "reasoning") ?? [];
|
|
51002
|
+
const retryTextContent = retryTextParts.map((p) => p.text ?? "").filter(Boolean).join(`
|
|
51003
|
+
`);
|
|
51004
|
+
if (retryTextContent) {
|
|
51005
|
+
displayContent = retryTextContent;
|
|
51006
|
+
}
|
|
51007
|
+
}
|
|
51008
|
+
}
|
|
51009
|
+
} catch {}
|
|
51010
|
+
}
|
|
51011
|
+
}
|
|
51012
|
+
}
|
|
50446
51013
|
const duration3 = PerfTimer.formatDuration(startTime);
|
|
50447
51014
|
if (toastManager) {
|
|
50448
51015
|
toastManager.removeTask(taskId);
|
|
@@ -50455,7 +51022,7 @@ ${classification.shouldFallback ? "\uD83D\uDCA1 \u6B64\u9519\u8BEF\u7B26\u5408 r
|
|
|
50455
51022
|
|
|
50456
51023
|
---
|
|
50457
51024
|
|
|
50458
|
-
${
|
|
51025
|
+
${displayContent || "(\u65E0\u6587\u672C\u8F93\u51FA)"}
|
|
50459
51026
|
|
|
50460
51027
|
---
|
|
50461
51028
|
\u7EE7\u7EED\u6B64 session\uFF1Asession_id="${sessionID}"`;
|
|
@@ -50481,6 +51048,44 @@ ${classification.shouldFallback ? "\uD83D\uDCA1 \u6B64\u9519\u8BEF\u7B26\u5408 r
|
|
|
50481
51048
|
|
|
50482
51049
|
// src/tools/delegate-task/index.ts
|
|
50483
51050
|
init_constants();
|
|
51051
|
+
// src/tools/btw/constants.ts
|
|
51052
|
+
var BTW_TOOL_DESCRIPTION = `
|
|
51053
|
+
\u5411 BTW \u987E\u95EE\uFF08\u53EA\u8BFB\u8F7B\u91CF Agent\uFF09\u63D0\u51FA\u4E00\u4E2A\u5FEB\u901F\u95EE\u9898\u3002
|
|
51054
|
+
\u5F02\u6B65\u6267\u884C\uFF0C\u4E0D\u963B\u585E\u4E3B\u5BF9\u8BDD\u2014\u2014\u5B8C\u6210\u540E\u901A\u8FC7\u7CFB\u7EDF\u901A\u77E5\u81EA\u52A8\u544A\u77E5\u3002
|
|
51055
|
+
\u9002\u7528\u4E8E\u4EE3\u7801\u5206\u6790\u3001\u6982\u5FF5\u6F84\u6E05\u3001\u6A21\u5F0F\u5EFA\u8BAE\u7B49\u8F7B\u91CF\u67E5\u8BE2\u3002
|
|
51056
|
+
BTW \u987E\u95EE\u65E0\u5199\u6743\u9650\uFF0C\u4E0D\u53EF\u4FEE\u6539\u6587\u4EF6\u6216\u6267\u884C\u547D\u4EE4\u3002
|
|
51057
|
+
`.trim();
|
|
51058
|
+
|
|
51059
|
+
// src/tools/btw/tools.ts
|
|
51060
|
+
function createBtwTool(ctx, backgroundManager) {
|
|
51061
|
+
return tool({
|
|
51062
|
+
description: BTW_TOOL_DESCRIPTION,
|
|
51063
|
+
args: {
|
|
51064
|
+
question: tool.schema.string().describe("\u8981\u8BE2\u95EE BTW \u987E\u95EE\u7684\u95EE\u9898")
|
|
51065
|
+
},
|
|
51066
|
+
async execute(args, toolContext) {
|
|
51067
|
+
const parentSessionID = toolContext.sessionID;
|
|
51068
|
+
const parentSession = await ctx.client.session.get({
|
|
51069
|
+
path: { id: parentSessionID }
|
|
51070
|
+
});
|
|
51071
|
+
const parentDirectory = parentSession?.data?.directory ?? ctx.directory;
|
|
51072
|
+
const btwPrompt = `\u4F60\u662F\u4E00\u4E2A\u8F7B\u91CF\u53EA\u8BFB\u987E\u95EE\uFF08BTW \u987E\u95EE\uFF09\u3002
|
|
51073
|
+
\u8BF7\u6781\u5EA6\u7CBE\u7B80\u5730\u56DE\u7B54\u4EE5\u4E0B\u95EE\u9898\uFF0C\u63A7\u5236\u5728 100 \u5B57\u4EE5\u5185\uFF0C1-3 \u53E5\u8BDD\u3002
|
|
51074
|
+
\u53EA\u8F93\u51FA\u7B54\u6848\uFF0C\u4E0D\u8981\u8F93\u51FA reasoning \u6216\u601D\u8003\u8FC7\u7A0B\u3002
|
|
51075
|
+
|
|
51076
|
+
\u95EE\u9898\uFF1A${args.question}`;
|
|
51077
|
+
const task = await backgroundManager.launch({
|
|
51078
|
+
description: `BTW: ${args.question.substring(0, 50)}`,
|
|
51079
|
+
prompt: btwPrompt,
|
|
51080
|
+
agent: "BTW \u987E\u95EE",
|
|
51081
|
+
parentSessionID,
|
|
51082
|
+
parentMessageID: toolContext.messageID
|
|
51083
|
+
});
|
|
51084
|
+
return `> **BTW**\uFF1A\u6B63\u5728\u67E5\u8BE2\u300C${args.question.substring(0, 30)}${args.question.length > 30 ? "..." : ""}\u300D
|
|
51085
|
+
\u5B8C\u6210\u540E\u5C06\u901A\u8FC7\u7CFB\u7EDF\u901A\u77E5\u81EA\u52A8\u544A\u77E5\u3002\u53EF\u7528 \`background_output("${task.id}")\` \u67E5\u770B\u7ED3\u679C\u3002`;
|
|
51086
|
+
}
|
|
51087
|
+
});
|
|
51088
|
+
}
|
|
50484
51089
|
// src/tools/index.ts
|
|
50485
51090
|
function createBackgroundTools(manager, client2) {
|
|
50486
51091
|
return {
|
|
@@ -50666,8 +51271,8 @@ class PerformanceAggregator {
|
|
|
50666
51271
|
}
|
|
50667
51272
|
|
|
50668
51273
|
// src/features/background-agent/manager.ts
|
|
50669
|
-
import { existsSync as
|
|
50670
|
-
import { join as
|
|
51274
|
+
import { existsSync as existsSync53, readdirSync as readdirSync19 } from "fs";
|
|
51275
|
+
import { join as join65 } from "path";
|
|
50671
51276
|
var TASK_TTL_MS = 30 * 60 * 1000;
|
|
50672
51277
|
var MIN_STABILITY_TIME_MS = 10 * 1000;
|
|
50673
51278
|
var DEFAULT_STALE_TIMEOUT_MS = 120000;
|
|
@@ -51841,14 +52446,14 @@ function registerProcessSignal(signal, handler, exitAfter) {
|
|
|
51841
52446
|
return listener;
|
|
51842
52447
|
}
|
|
51843
52448
|
function getMessageDir9(sessionID) {
|
|
51844
|
-
if (!
|
|
52449
|
+
if (!existsSync53(MESSAGE_STORAGE))
|
|
51845
52450
|
return null;
|
|
51846
|
-
const directPath =
|
|
51847
|
-
if (
|
|
52451
|
+
const directPath = join65(MESSAGE_STORAGE, sessionID);
|
|
52452
|
+
if (existsSync53(directPath))
|
|
51848
52453
|
return directPath;
|
|
51849
|
-
for (const dir of
|
|
51850
|
-
const sessionPath =
|
|
51851
|
-
if (
|
|
52454
|
+
for (const dir of readdirSync19(MESSAGE_STORAGE)) {
|
|
52455
|
+
const sessionPath = join65(MESSAGE_STORAGE, dir, sessionID);
|
|
52456
|
+
if (existsSync53(sessionPath))
|
|
51852
52457
|
return sessionPath;
|
|
51853
52458
|
}
|
|
51854
52459
|
return null;
|
|
@@ -70522,7 +71127,8 @@ var BuiltinAgentNameSchema = exports_external2.enum([
|
|
|
70522
71127
|
"\u5A92\u4F53\u89E3\u6790",
|
|
70523
71128
|
"\u9884\u5BA1\u987E\u95EE",
|
|
70524
71129
|
"\u8BA1\u5212\u5BA1\u67E5",
|
|
70525
|
-
"\u4EFB\u52A1\u7F16\u6392"
|
|
71130
|
+
"\u4EFB\u52A1\u7F16\u6392",
|
|
71131
|
+
"BTW \u987E\u95EE"
|
|
70526
71132
|
]);
|
|
70527
71133
|
var BuiltinSkillNameSchema = exports_external2.enum([
|
|
70528
71134
|
"playwright",
|
|
@@ -70542,7 +71148,8 @@ var OverridableAgentNameSchema = exports_external2.enum([
|
|
|
70542
71148
|
"\u77E5\u8BC6\u5178\u85CF",
|
|
70543
71149
|
"\u6DF1\u5EA6\u63A2\u7D22",
|
|
70544
71150
|
"\u5A92\u4F53\u89E3\u6790",
|
|
70545
|
-
"\u4EFB\u52A1\u7F16\u6392"
|
|
71151
|
+
"\u4EFB\u52A1\u7F16\u6392",
|
|
71152
|
+
"BTW \u987E\u95EE"
|
|
70546
71153
|
]);
|
|
70547
71154
|
var HookNameSchema = exports_external2.enum([
|
|
70548
71155
|
"todo-continuation-enforcer",
|
|
@@ -70583,11 +71190,13 @@ var HookNameSchema = exports_external2.enum([
|
|
|
70583
71190
|
"tool-definition-optimizer",
|
|
70584
71191
|
"permission-ask-bridge",
|
|
70585
71192
|
"shell-env-injector",
|
|
70586
|
-
"dispose-coordinator"
|
|
71193
|
+
"dispose-coordinator",
|
|
71194
|
+
"plan-completion"
|
|
70587
71195
|
]);
|
|
70588
71196
|
var BuiltinCommandNameSchema = exports_external2.enum([
|
|
70589
71197
|
"init-deep",
|
|
70590
|
-
"start-work"
|
|
71198
|
+
"start-work",
|
|
71199
|
+
"btw"
|
|
70591
71200
|
]);
|
|
70592
71201
|
var ProviderModelStringSchema = exports_external2.string().refine((value) => {
|
|
70593
71202
|
const separatorIndex = value.indexOf("/");
|
|
@@ -70636,7 +71245,8 @@ var AgentOverridesSchema = exports_external2.object({
|
|
|
70636
71245
|
"\u77E5\u8BC6\u5178\u85CF": AgentOverrideConfigSchema.optional(),
|
|
70637
71246
|
"\u6DF1\u5EA6\u63A2\u7D22": AgentOverrideConfigSchema.optional(),
|
|
70638
71247
|
"\u5A92\u4F53\u89E3\u6790": AgentOverrideConfigSchema.optional(),
|
|
70639
|
-
"\u4EFB\u52A1\u7F16\u6392": AgentOverrideConfigSchema.optional()
|
|
71248
|
+
"\u4EFB\u52A1\u7F16\u6392": AgentOverrideConfigSchema.optional(),
|
|
71249
|
+
"BTW \u987E\u95EE": AgentOverrideConfigSchema.optional()
|
|
70640
71250
|
});
|
|
70641
71251
|
var ClaudeCodeConfigSchema = exports_external2.object({
|
|
70642
71252
|
mcp: exports_external2.boolean().optional(),
|
|
@@ -71068,7 +71678,7 @@ init_file_utils();
|
|
|
71068
71678
|
init_shared();
|
|
71069
71679
|
init_logger();
|
|
71070
71680
|
import { promises as fs11 } from "fs";
|
|
71071
|
-
import { join as
|
|
71681
|
+
import { join as join67, basename as basename6 } from "path";
|
|
71072
71682
|
async function loadCommandsFromDir(commandsDir, scope, visited = new Set, prefix = "") {
|
|
71073
71683
|
try {
|
|
71074
71684
|
await fs11.access(commandsDir);
|
|
@@ -71098,7 +71708,7 @@ async function loadCommandsFromDir(commandsDir, scope, visited = new Set, prefix
|
|
|
71098
71708
|
if (entry.isDirectory()) {
|
|
71099
71709
|
if (entry.name.startsWith("."))
|
|
71100
71710
|
continue;
|
|
71101
|
-
const subDirPath =
|
|
71711
|
+
const subDirPath = join67(commandsDir, entry.name);
|
|
71102
71712
|
const subPrefix = prefix ? `${prefix}:${entry.name}` : entry.name;
|
|
71103
71713
|
const subCommands = await loadCommandsFromDir(subDirPath, scope, visited, subPrefix);
|
|
71104
71714
|
commands2.push(...subCommands);
|
|
@@ -71106,7 +71716,7 @@ async function loadCommandsFromDir(commandsDir, scope, visited = new Set, prefix
|
|
|
71106
71716
|
}
|
|
71107
71717
|
if (!isMarkdownFile(entry))
|
|
71108
71718
|
continue;
|
|
71109
|
-
const commandPath =
|
|
71719
|
+
const commandPath = join67(commandsDir, entry.name);
|
|
71110
71720
|
const baseCommandName = basename6(entry.name, ".md");
|
|
71111
71721
|
const commandName = prefix ? `${prefix}:${baseCommandName}` : baseCommandName;
|
|
71112
71722
|
try {
|
|
@@ -71153,23 +71763,23 @@ function commandsToRecord(commands2) {
|
|
|
71153
71763
|
return result;
|
|
71154
71764
|
}
|
|
71155
71765
|
async function loadUserCommands() {
|
|
71156
|
-
const userCommandsDir =
|
|
71766
|
+
const userCommandsDir = join67(getClaudeConfigDir(), "commands");
|
|
71157
71767
|
const commands2 = await loadCommandsFromDir(userCommandsDir, "user");
|
|
71158
71768
|
return commandsToRecord(commands2);
|
|
71159
71769
|
}
|
|
71160
71770
|
async function loadProjectCommands() {
|
|
71161
|
-
const projectCommandsDir =
|
|
71771
|
+
const projectCommandsDir = join67(process.cwd(), ".claude", "commands");
|
|
71162
71772
|
const commands2 = await loadCommandsFromDir(projectCommandsDir, "project");
|
|
71163
71773
|
return commandsToRecord(commands2);
|
|
71164
71774
|
}
|
|
71165
71775
|
async function loadOpencodeGlobalCommands() {
|
|
71166
71776
|
const configDir = getOpenCodeConfigDir({ binary: "opencode" });
|
|
71167
|
-
const opencodeCommandsDir =
|
|
71777
|
+
const opencodeCommandsDir = join67(configDir, "command");
|
|
71168
71778
|
const commands2 = await loadCommandsFromDir(opencodeCommandsDir, "opencode");
|
|
71169
71779
|
return commandsToRecord(commands2);
|
|
71170
71780
|
}
|
|
71171
71781
|
async function loadOpencodeProjectCommands() {
|
|
71172
|
-
const opencodeProjectDir =
|
|
71782
|
+
const opencodeProjectDir = join67(process.cwd(), ".opencode", "command");
|
|
71173
71783
|
const commands2 = await loadCommandsFromDir(opencodeProjectDir, "opencode-project");
|
|
71174
71784
|
return commandsToRecord(commands2);
|
|
71175
71785
|
}
|
|
@@ -71177,8 +71787,8 @@ async function loadOpencodeProjectCommands() {
|
|
|
71177
71787
|
init_frontmatter();
|
|
71178
71788
|
init_file_utils();
|
|
71179
71789
|
init_shared();
|
|
71180
|
-
import { existsSync as
|
|
71181
|
-
import { join as
|
|
71790
|
+
import { existsSync as existsSync55, readdirSync as readdirSync20, readFileSync as readFileSync38 } from "fs";
|
|
71791
|
+
import { join as join68, basename as basename7 } from "path";
|
|
71182
71792
|
function parseToolsConfig(toolsStr) {
|
|
71183
71793
|
if (!toolsStr)
|
|
71184
71794
|
return;
|
|
@@ -71191,25 +71801,25 @@ function parseToolsConfig(toolsStr) {
|
|
|
71191
71801
|
}
|
|
71192
71802
|
return result;
|
|
71193
71803
|
}
|
|
71194
|
-
function loadAgentsFromDir(agentsDir, scope) {
|
|
71195
|
-
if (!
|
|
71804
|
+
function loadAgentsFromDir(agentsDir, scope, leConfig) {
|
|
71805
|
+
if (!existsSync55(agentsDir)) {
|
|
71196
71806
|
return [];
|
|
71197
71807
|
}
|
|
71198
|
-
const entries =
|
|
71808
|
+
const entries = readdirSync20(agentsDir, { withFileTypes: true });
|
|
71199
71809
|
const agents = [];
|
|
71200
71810
|
for (const entry of entries) {
|
|
71201
71811
|
if (!isMarkdownFile(entry))
|
|
71202
71812
|
continue;
|
|
71203
|
-
const agentPath =
|
|
71813
|
+
const agentPath = join68(agentsDir, entry.name);
|
|
71204
71814
|
const agentName = basename7(entry.name, ".md");
|
|
71205
71815
|
try {
|
|
71206
|
-
const content =
|
|
71816
|
+
const content = readFileSync38(agentPath, "utf-8");
|
|
71207
71817
|
const { data, body } = parseFrontmatter(content);
|
|
71208
71818
|
const name = data.name || agentName;
|
|
71209
71819
|
const originalDescription = data.description || "";
|
|
71210
71820
|
const formattedDescription = `(${scope}) ${originalDescription}`;
|
|
71211
71821
|
const trimmedBody = body.trim();
|
|
71212
|
-
const promptWithLang = trimmedBody.includes("<Language_Instruction>") ? trimmedBody : trimmedBody + ZH_SUB_AGENT_INSTRUCTION;
|
|
71822
|
+
const promptWithLang = trimmedBody.includes("<Language_Instruction>") || !isLanguageEnforcementEnabled(leConfig) ? trimmedBody : trimmedBody + ZH_SUB_AGENT_INSTRUCTION;
|
|
71213
71823
|
const config4 = {
|
|
71214
71824
|
description: formattedDescription,
|
|
71215
71825
|
mode: "subagent",
|
|
@@ -71231,18 +71841,18 @@ function loadAgentsFromDir(agentsDir, scope) {
|
|
|
71231
71841
|
}
|
|
71232
71842
|
return agents;
|
|
71233
71843
|
}
|
|
71234
|
-
function loadUserAgents() {
|
|
71235
|
-
const userAgentsDir =
|
|
71236
|
-
const agents = loadAgentsFromDir(userAgentsDir, "user");
|
|
71844
|
+
function loadUserAgents(leConfig) {
|
|
71845
|
+
const userAgentsDir = join68(getClaudeConfigDir(), "agents");
|
|
71846
|
+
const agents = loadAgentsFromDir(userAgentsDir, "user", leConfig);
|
|
71237
71847
|
const result = {};
|
|
71238
71848
|
for (const agent of agents) {
|
|
71239
71849
|
result[agent.name] = agent.config;
|
|
71240
71850
|
}
|
|
71241
71851
|
return result;
|
|
71242
71852
|
}
|
|
71243
|
-
function loadProjectAgents() {
|
|
71244
|
-
const projectAgentsDir =
|
|
71245
|
-
const agents = loadAgentsFromDir(projectAgentsDir, "project");
|
|
71853
|
+
function loadProjectAgents(leConfig) {
|
|
71854
|
+
const projectAgentsDir = join68(process.cwd(), ".claude", "agents");
|
|
71855
|
+
const agents = loadAgentsFromDir(projectAgentsDir, "project", leConfig);
|
|
71246
71856
|
const result = {};
|
|
71247
71857
|
for (const agent of agents) {
|
|
71248
71858
|
result[agent.name] = agent.config;
|
|
@@ -71253,18 +71863,18 @@ function loadProjectAgents() {
|
|
|
71253
71863
|
init_frontmatter();
|
|
71254
71864
|
init_file_utils();
|
|
71255
71865
|
init_logger();
|
|
71256
|
-
import { existsSync as
|
|
71866
|
+
import { existsSync as existsSync56, readdirSync as readdirSync21, readFileSync as readFileSync39 } from "fs";
|
|
71257
71867
|
import { homedir as homedir14 } from "os";
|
|
71258
|
-
import { join as
|
|
71868
|
+
import { join as join69, basename as basename8 } from "path";
|
|
71259
71869
|
var CLAUDE_PLUGIN_ROOT_VAR = "${CLAUDE_PLUGIN_ROOT}";
|
|
71260
71870
|
function getPluginsBaseDir() {
|
|
71261
71871
|
if (process.env.CLAUDE_PLUGINS_HOME) {
|
|
71262
71872
|
return process.env.CLAUDE_PLUGINS_HOME;
|
|
71263
71873
|
}
|
|
71264
|
-
return
|
|
71874
|
+
return join69(homedir14(), ".claude", "plugins");
|
|
71265
71875
|
}
|
|
71266
71876
|
function getInstalledPluginsPath() {
|
|
71267
|
-
return
|
|
71877
|
+
return join69(getPluginsBaseDir(), "installed_plugins.json");
|
|
71268
71878
|
}
|
|
71269
71879
|
function resolvePluginPath(path8, pluginRoot) {
|
|
71270
71880
|
return path8.replace(CLAUDE_PLUGIN_ROOT_VAR, pluginRoot);
|
|
@@ -71289,11 +71899,11 @@ function resolvePluginPaths(obj, pluginRoot) {
|
|
|
71289
71899
|
}
|
|
71290
71900
|
function loadInstalledPlugins() {
|
|
71291
71901
|
const dbPath = getInstalledPluginsPath();
|
|
71292
|
-
if (!
|
|
71902
|
+
if (!existsSync56(dbPath)) {
|
|
71293
71903
|
return null;
|
|
71294
71904
|
}
|
|
71295
71905
|
try {
|
|
71296
|
-
const content =
|
|
71906
|
+
const content = readFileSync39(dbPath, "utf-8");
|
|
71297
71907
|
return JSON.parse(content);
|
|
71298
71908
|
} catch (error95) {
|
|
71299
71909
|
log("Failed to load installed plugins database", error95);
|
|
@@ -71304,15 +71914,15 @@ function getClaudeSettingsPath() {
|
|
|
71304
71914
|
if (process.env.CLAUDE_SETTINGS_PATH) {
|
|
71305
71915
|
return process.env.CLAUDE_SETTINGS_PATH;
|
|
71306
71916
|
}
|
|
71307
|
-
return
|
|
71917
|
+
return join69(homedir14(), ".claude", "settings.json");
|
|
71308
71918
|
}
|
|
71309
71919
|
function loadClaudeSettings() {
|
|
71310
71920
|
const settingsPath = getClaudeSettingsPath();
|
|
71311
|
-
if (!
|
|
71921
|
+
if (!existsSync56(settingsPath)) {
|
|
71312
71922
|
return null;
|
|
71313
71923
|
}
|
|
71314
71924
|
try {
|
|
71315
|
-
const content =
|
|
71925
|
+
const content = readFileSync39(settingsPath, "utf-8");
|
|
71316
71926
|
return JSON.parse(content);
|
|
71317
71927
|
} catch (error95) {
|
|
71318
71928
|
log("Failed to load Claude settings", error95);
|
|
@@ -71320,12 +71930,12 @@ function loadClaudeSettings() {
|
|
|
71320
71930
|
}
|
|
71321
71931
|
}
|
|
71322
71932
|
function loadPluginManifest(installPath) {
|
|
71323
|
-
const manifestPath =
|
|
71324
|
-
if (!
|
|
71933
|
+
const manifestPath = join69(installPath, ".claude-plugin", "plugin.json");
|
|
71934
|
+
if (!existsSync56(manifestPath)) {
|
|
71325
71935
|
return null;
|
|
71326
71936
|
}
|
|
71327
71937
|
try {
|
|
71328
|
-
const content =
|
|
71938
|
+
const content = readFileSync39(manifestPath, "utf-8");
|
|
71329
71939
|
return JSON.parse(content);
|
|
71330
71940
|
} catch (error95) {
|
|
71331
71941
|
log(`Failed to load plugin manifest from ${manifestPath}`, error95);
|
|
@@ -71372,7 +71982,7 @@ function discoverInstalledPlugins(options) {
|
|
|
71372
71982
|
continue;
|
|
71373
71983
|
}
|
|
71374
71984
|
const { installPath, scope, version: version3 } = installation;
|
|
71375
|
-
if (!
|
|
71985
|
+
if (!existsSync56(installPath)) {
|
|
71376
71986
|
errors5.push({
|
|
71377
71987
|
pluginKey,
|
|
71378
71988
|
installPath,
|
|
@@ -71390,21 +72000,21 @@ function discoverInstalledPlugins(options) {
|
|
|
71390
72000
|
pluginKey,
|
|
71391
72001
|
manifest: manifest ?? undefined
|
|
71392
72002
|
};
|
|
71393
|
-
if (
|
|
71394
|
-
loadedPlugin.commandsDir =
|
|
72003
|
+
if (existsSync56(join69(installPath, "commands"))) {
|
|
72004
|
+
loadedPlugin.commandsDir = join69(installPath, "commands");
|
|
71395
72005
|
}
|
|
71396
|
-
if (
|
|
71397
|
-
loadedPlugin.agentsDir =
|
|
72006
|
+
if (existsSync56(join69(installPath, "agents"))) {
|
|
72007
|
+
loadedPlugin.agentsDir = join69(installPath, "agents");
|
|
71398
72008
|
}
|
|
71399
|
-
if (
|
|
71400
|
-
loadedPlugin.skillsDir =
|
|
72009
|
+
if (existsSync56(join69(installPath, "skills"))) {
|
|
72010
|
+
loadedPlugin.skillsDir = join69(installPath, "skills");
|
|
71401
72011
|
}
|
|
71402
|
-
const hooksPath =
|
|
71403
|
-
if (
|
|
72012
|
+
const hooksPath = join69(installPath, "hooks", "hooks.json");
|
|
72013
|
+
if (existsSync56(hooksPath)) {
|
|
71404
72014
|
loadedPlugin.hooksPath = hooksPath;
|
|
71405
72015
|
}
|
|
71406
|
-
const mcpPath =
|
|
71407
|
-
if (
|
|
72016
|
+
const mcpPath = join69(installPath, ".mcp.json");
|
|
72017
|
+
if (existsSync56(mcpPath)) {
|
|
71408
72018
|
loadedPlugin.mcpPath = mcpPath;
|
|
71409
72019
|
}
|
|
71410
72020
|
plugins.push(loadedPlugin);
|
|
@@ -71415,17 +72025,17 @@ function discoverInstalledPlugins(options) {
|
|
|
71415
72025
|
function loadPluginCommands(plugins) {
|
|
71416
72026
|
const commands2 = {};
|
|
71417
72027
|
for (const plugin of plugins) {
|
|
71418
|
-
if (!plugin.commandsDir || !
|
|
72028
|
+
if (!plugin.commandsDir || !existsSync56(plugin.commandsDir))
|
|
71419
72029
|
continue;
|
|
71420
|
-
const entries =
|
|
72030
|
+
const entries = readdirSync21(plugin.commandsDir, { withFileTypes: true });
|
|
71421
72031
|
for (const entry of entries) {
|
|
71422
72032
|
if (!isMarkdownFile(entry))
|
|
71423
72033
|
continue;
|
|
71424
|
-
const commandPath =
|
|
72034
|
+
const commandPath = join69(plugin.commandsDir, entry.name);
|
|
71425
72035
|
const commandName = basename8(entry.name, ".md");
|
|
71426
72036
|
const namespacedName = `${plugin.name}:${commandName}`;
|
|
71427
72037
|
try {
|
|
71428
|
-
const content =
|
|
72038
|
+
const content = readFileSync39(commandPath, "utf-8");
|
|
71429
72039
|
const { data, body } = parseFrontmatter(content);
|
|
71430
72040
|
const wrappedTemplate = `<command-instruction>
|
|
71431
72041
|
${body.trim()}
|
|
@@ -71457,21 +72067,21 @@ $ARGUMENTS
|
|
|
71457
72067
|
function loadPluginSkillsAsCommands(plugins) {
|
|
71458
72068
|
const skills = {};
|
|
71459
72069
|
for (const plugin of plugins) {
|
|
71460
|
-
if (!plugin.skillsDir || !
|
|
72070
|
+
if (!plugin.skillsDir || !existsSync56(plugin.skillsDir))
|
|
71461
72071
|
continue;
|
|
71462
|
-
const entries =
|
|
72072
|
+
const entries = readdirSync21(plugin.skillsDir, { withFileTypes: true });
|
|
71463
72073
|
for (const entry of entries) {
|
|
71464
72074
|
if (entry.name.startsWith("."))
|
|
71465
72075
|
continue;
|
|
71466
|
-
const skillPath =
|
|
72076
|
+
const skillPath = join69(plugin.skillsDir, entry.name);
|
|
71467
72077
|
if (!entry.isDirectory() && !entry.isSymbolicLink())
|
|
71468
72078
|
continue;
|
|
71469
72079
|
const resolvedPath = resolveSymlink(skillPath);
|
|
71470
|
-
const skillMdPath =
|
|
71471
|
-
if (!
|
|
72080
|
+
const skillMdPath = join69(resolvedPath, "SKILL.md");
|
|
72081
|
+
if (!existsSync56(skillMdPath))
|
|
71472
72082
|
continue;
|
|
71473
72083
|
try {
|
|
71474
|
-
const content =
|
|
72084
|
+
const content = readFileSync39(skillMdPath, "utf-8");
|
|
71475
72085
|
const { data, body } = parseFrontmatter(content);
|
|
71476
72086
|
const skillName = data.name || entry.name;
|
|
71477
72087
|
const namespacedName = `${plugin.name}:${skillName}`;
|
|
@@ -71518,17 +72128,17 @@ function parseToolsConfig2(toolsStr) {
|
|
|
71518
72128
|
function loadPluginAgents(plugins) {
|
|
71519
72129
|
const agents = {};
|
|
71520
72130
|
for (const plugin of plugins) {
|
|
71521
|
-
if (!plugin.agentsDir || !
|
|
72131
|
+
if (!plugin.agentsDir || !existsSync56(plugin.agentsDir))
|
|
71522
72132
|
continue;
|
|
71523
|
-
const entries =
|
|
72133
|
+
const entries = readdirSync21(plugin.agentsDir, { withFileTypes: true });
|
|
71524
72134
|
for (const entry of entries) {
|
|
71525
72135
|
if (!isMarkdownFile(entry))
|
|
71526
72136
|
continue;
|
|
71527
|
-
const agentPath =
|
|
72137
|
+
const agentPath = join69(plugin.agentsDir, entry.name);
|
|
71528
72138
|
const agentName = basename8(entry.name, ".md");
|
|
71529
72139
|
const namespacedName = `${plugin.name}:${agentName}`;
|
|
71530
72140
|
try {
|
|
71531
|
-
const content =
|
|
72141
|
+
const content = readFileSync39(agentPath, "utf-8");
|
|
71532
72142
|
const { data, body } = parseFrontmatter(content);
|
|
71533
72143
|
const name = data.name || agentName;
|
|
71534
72144
|
const originalDescription = data.description || "";
|
|
@@ -71554,7 +72164,7 @@ function loadPluginAgents(plugins) {
|
|
|
71554
72164
|
async function loadPluginMcpServers(plugins) {
|
|
71555
72165
|
const servers = {};
|
|
71556
72166
|
for (const plugin of plugins) {
|
|
71557
|
-
if (!plugin.mcpPath || !
|
|
72167
|
+
if (!plugin.mcpPath || !existsSync56(plugin.mcpPath))
|
|
71558
72168
|
continue;
|
|
71559
72169
|
try {
|
|
71560
72170
|
const content = await Bun.file(plugin.mcpPath).text();
|
|
@@ -71586,10 +72196,10 @@ async function loadPluginMcpServers(plugins) {
|
|
|
71586
72196
|
function loadPluginHooksConfigs(plugins) {
|
|
71587
72197
|
const configs = [];
|
|
71588
72198
|
for (const plugin of plugins) {
|
|
71589
|
-
if (!plugin.hooksPath || !
|
|
72199
|
+
if (!plugin.hooksPath || !existsSync56(plugin.hooksPath))
|
|
71590
72200
|
continue;
|
|
71591
72201
|
try {
|
|
71592
|
-
const content =
|
|
72202
|
+
const content = readFileSync39(plugin.hooksPath, "utf-8");
|
|
71593
72203
|
let config4 = JSON.parse(content);
|
|
71594
72204
|
config4 = resolvePluginPaths(config4, plugin.installPath);
|
|
71595
72205
|
configs.push(config4);
|
|
@@ -72951,9 +73561,9 @@ function createConfigHandler(deps) {
|
|
|
72951
73561
|
...discoveredOpencodeGlobalSkills,
|
|
72952
73562
|
...discoveredUserSkills
|
|
72953
73563
|
];
|
|
72954
|
-
const builtinAgents = await createBuiltinAgents(migratedDisabledAgents, pluginConfig.agents, ctx.directory, config4.model, pluginConfig.categories, pluginConfig.git_master, allDiscoveredSkills, ctx.client);
|
|
72955
|
-
const userAgents = pluginConfig.claude_code?.agents ?? true ? loadUserAgents() : {};
|
|
72956
|
-
const projectAgents = pluginConfig.claude_code?.agents ?? true ? loadProjectAgents() : {};
|
|
73564
|
+
const builtinAgents = await createBuiltinAgents(migratedDisabledAgents, pluginConfig.agents, ctx.directory, config4.model, pluginConfig.categories, pluginConfig.git_master, allDiscoveredSkills, ctx.client, pluginConfig);
|
|
73565
|
+
const userAgents = pluginConfig.claude_code?.agents ?? true ? loadUserAgents(pluginConfig) : {};
|
|
73566
|
+
const projectAgents = pluginConfig.claude_code?.agents ?? true ? loadProjectAgents(pluginConfig) : {};
|
|
72957
73567
|
const rawPluginAgents = pluginComponents.agents;
|
|
72958
73568
|
const pluginAgents = Object.fromEntries(Object.entries(rawPluginAgents).map(([k, v]) => [
|
|
72959
73569
|
k,
|
|
@@ -73004,21 +73614,27 @@ function createConfigHandler(deps) {
|
|
|
73004
73614
|
};
|
|
73005
73615
|
agentConfig["\u6218\u7565\u53C2\u8C0B"] = prometheusOverride ? { ...prometheusBase, ...prometheusOverride } : prometheusBase;
|
|
73006
73616
|
}
|
|
73007
|
-
|
|
73008
|
-
|
|
73009
|
-
if (
|
|
73010
|
-
prometheusAgent.
|
|
73011
|
-
|
|
73012
|
-
|
|
73617
|
+
if (isLanguageEnforcementEnabled(pluginConfig)) {
|
|
73618
|
+
const prometheusAgent = agentConfig["\u6218\u7565\u53C2\u8C0B"];
|
|
73619
|
+
if (prometheusAgent?.prompt && !prometheusAgent.prompt.includes("<Language_Instruction>")) {
|
|
73620
|
+
if (isDeepseekModel(prometheusAgent.model ?? "")) {
|
|
73621
|
+
prometheusAgent.prompt += ZH_LANGUAGE_INSTRUCTION_DEEPSEEK;
|
|
73622
|
+
} else {
|
|
73623
|
+
prometheusAgent.prompt += ZH_LANGUAGE_INSTRUCTION;
|
|
73624
|
+
}
|
|
73013
73625
|
}
|
|
73014
73626
|
}
|
|
73015
|
-
|
|
73016
|
-
|
|
73017
|
-
juniorAgent.prompt
|
|
73627
|
+
if (isLanguageEnforcementEnabled(pluginConfig)) {
|
|
73628
|
+
const juniorAgent = agentConfig["\u6267\u884C\u52A9\u7406"];
|
|
73629
|
+
if (juniorAgent?.prompt && !juniorAgent.prompt.includes("<Language_Instruction>")) {
|
|
73630
|
+
juniorAgent.prompt += ZH_SUB_AGENT_INSTRUCTION;
|
|
73631
|
+
}
|
|
73018
73632
|
}
|
|
73019
|
-
|
|
73020
|
-
|
|
73021
|
-
openCodeBuilderAgent.prompt
|
|
73633
|
+
if (isLanguageEnforcementEnabled(pluginConfig)) {
|
|
73634
|
+
const openCodeBuilderAgent = agentConfig["OpenCode-Builder"];
|
|
73635
|
+
if (openCodeBuilderAgent?.prompt && !openCodeBuilderAgent.prompt.includes("<Language_Instruction>")) {
|
|
73636
|
+
openCodeBuilderAgent.prompt += ZH_SUB_AGENT_INSTRUCTION;
|
|
73637
|
+
}
|
|
73022
73638
|
}
|
|
73023
73639
|
const filteredConfigAgents = configAgent ? Object.fromEntries(Object.entries(configAgent).filter(([key]) => {
|
|
73024
73640
|
if (key === "build")
|
|
@@ -73273,7 +73889,7 @@ var OhMyOpenCodePlugin = async (ctx) => {
|
|
|
73273
73889
|
const anthropicContextWindowLimitRecovery = isHookEnabled("anthropic-context-window-limit-recovery") ? createAnthropicContextWindowLimitRecoveryHook(ctx, {
|
|
73274
73890
|
experimental: pluginConfig.experimental
|
|
73275
73891
|
}) : null;
|
|
73276
|
-
const compactionContextInjector = isHookEnabled("compaction-context-injector") ? createCompactionContextInjector(ctx.client) : undefined;
|
|
73892
|
+
const compactionContextInjector = isHookEnabled("compaction-context-injector") ? createCompactionContextInjector(ctx.client, pluginConfig) : undefined;
|
|
73277
73893
|
const rulesInjector = isHookEnabled("rules-injector") ? createRulesInjectorHook(ctx) : null;
|
|
73278
73894
|
const autoUpdateChecker = isHookEnabled("auto-update-checker") ? createAutoUpdateCheckerHook(ctx, {
|
|
73279
73895
|
showStartupToast: isHookEnabled("startup-toast"),
|
|
@@ -73283,8 +73899,8 @@ var OhMyOpenCodePlugin = async (ctx) => {
|
|
|
73283
73899
|
const keywordDetector = isHookEnabled("keyword-detector") ? createKeywordDetectorHook(ctx, contextCollector) : null;
|
|
73284
73900
|
const contextInjectorMessagesTransform = createContextInjectorMessagesTransformHook(contextCollector);
|
|
73285
73901
|
const agentUsageReminder = isHookEnabled("agent-usage-reminder") ? createAgentUsageReminderHook(ctx) : null;
|
|
73286
|
-
const languageReminder = isHookEnabled("language-reminder") ? createLanguageReminderHook(ctx) : null;
|
|
73287
|
-
const thinkingLanguageValidator = isHookEnabled("thinking-language-validator") ? createThinkingLanguageValidatorHook(ctx) : null;
|
|
73902
|
+
const languageReminder = isHookEnabled("language-reminder") && isLanguageEnforcementEnabled(pluginConfig) ? createLanguageReminderHook(ctx) : null;
|
|
73903
|
+
const thinkingLanguageValidator = isHookEnabled("thinking-language-validator") && isLanguageEnforcementEnabled(pluginConfig) ? createThinkingLanguageValidatorHook(ctx) : null;
|
|
73288
73904
|
const nonInteractiveEnv = isHookEnabled("non-interactive-env") ? createNonInteractiveEnvHook(ctx) : null;
|
|
73289
73905
|
const interactiveBashSession = isHookEnabled("interactive-bash-session") ? createInteractiveBashSessionHook(ctx) : null;
|
|
73290
73906
|
const thinkingBlockValidator = isHookEnabled("thinking-block-validator") ? createThinkingBlockValidatorHook() : null;
|
|
@@ -73336,6 +73952,7 @@ var OhMyOpenCodePlugin = async (ctx) => {
|
|
|
73336
73952
|
const toolDefOptimizer = isHookEnabled("tool-definition-optimizer") ? createToolDefinitionOptimizerHook(ctx) : null;
|
|
73337
73953
|
const permissionAskBridge = isHookEnabled("permission-ask-bridge") ? createPermissionAskBridgeHook(ctx) : null;
|
|
73338
73954
|
const shellEnvInjector = isHookEnabled("shell-env-injector") ? createShellEnvInjectorHook(ctx) : null;
|
|
73955
|
+
const planCompletionHook = isHookEnabled("plan-completion") ? createPlanCompletionHook(ctx) : null;
|
|
73339
73956
|
initTaskToastManager(ctx.client);
|
|
73340
73957
|
const todoContinuationEnforcer = isHookEnabled("todo-continuation-enforcer") ? createTodoContinuationEnforcer(ctx, { backgroundManager, ralphLoopHook: ralphLoop ?? undefined }) : null;
|
|
73341
73958
|
if (sessionRecovery && todoContinuationEnforcer) {
|
|
@@ -73345,6 +73962,7 @@ var OhMyOpenCodePlugin = async (ctx) => {
|
|
|
73345
73962
|
const backgroundNotificationHook = isHookEnabled("background-notification") ? createBackgroundNotificationHook(backgroundManager) : null;
|
|
73346
73963
|
const backgroundTools = createBackgroundTools(backgroundManager, ctx.client);
|
|
73347
73964
|
const callOmoAgent = createCallOmoAgent(ctx, backgroundManager);
|
|
73965
|
+
const btwTool = createBtwTool(ctx, backgroundManager);
|
|
73348
73966
|
const isMultimodalLookerEnabled = !includesCaseInsensitive(pluginConfig.disabled_agents ?? [], "multimodal-looker");
|
|
73349
73967
|
const lookAt = isMultimodalLookerEnabled ? createLookAt(ctx) : null;
|
|
73350
73968
|
const delegateTask = createDelegateTask({
|
|
@@ -73391,7 +74009,7 @@ var OhMyOpenCodePlugin = async (ctx) => {
|
|
|
73391
74009
|
getLoadedSkills: () => mergedSkills,
|
|
73392
74010
|
getSessionID: getSessionIDForMcp
|
|
73393
74011
|
});
|
|
73394
|
-
const commands2 = discoverCommandsSync();
|
|
74012
|
+
const commands2 = discoverCommandsSync(["btw"]);
|
|
73395
74013
|
const slashcommandTool = createSlashcommandTool({
|
|
73396
74014
|
commands: commands2,
|
|
73397
74015
|
skills: mergedSkills
|
|
@@ -73430,6 +74048,7 @@ var OhMyOpenCodePlugin = async (ctx) => {
|
|
|
73430
74048
|
call_omo_agent: callOmoAgent,
|
|
73431
74049
|
...lookAt ? { look_at: lookAt } : {},
|
|
73432
74050
|
delegate_task: delegateTask,
|
|
74051
|
+
btw: btwTool,
|
|
73433
74052
|
skill: skillTool,
|
|
73434
74053
|
skill_mcp: skillMcpTool,
|
|
73435
74054
|
slashcommand: slashcommandTool,
|
|
@@ -73761,7 +74380,7 @@ var OhMyOpenCodePlugin = async (ctx) => {
|
|
|
73761
74380
|
- \u5F53\u524D Agent: ${agentName}
|
|
73762
74381
|
- \u89D2\u8272\u7EA6\u675F: ${roleDesc}
|
|
73763
74382
|
- \u5728\u538B\u7F29\u540E\u7684\u6458\u8981\u4E2D\u660E\u786E\u4FDD\u7559\u6B64 Agent \u7684\u8EAB\u4EFD\u548C\u89D2\u8272\u7EA6\u675F`);
|
|
73764
|
-
output.context.push(
|
|
74383
|
+
output.context.push(buildSummarizeContextPrompt(pluginConfig));
|
|
73765
74384
|
},
|
|
73766
74385
|
dispose: disposeCoordinator?.dispose
|
|
73767
74386
|
};
|