@skj1724/oh-my-opencode 3.19.4 → 3.19.5
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/bin/oh-my-opencode.js +39 -32
- package/dist/cli/index.js +21 -2
- package/dist/config/schema.d.ts +30 -0
- package/dist/features/background-agent/manager.d.ts +3 -0
- package/dist/features/hook-message-injector/injector.d.ts +0 -6
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/perf-profiler/index.d.ts +2 -0
- package/dist/hooks/perf-profiler/index.test.d.ts +1 -0
- package/dist/hooks/perf-profiler/types.d.ts +42 -0
- package/dist/hooks/think-mode/index.d.ts +26 -2
- package/dist/hooks/think-mode/types.d.ts +14 -12
- package/dist/index.js +1173 -737
- package/dist/shared/fileio-monitor.d.ts +10 -0
- package/dist/shared/fileio-monitor.test.d.ts +1 -0
- package/dist/shared/index.d.ts +2 -0
- package/dist/shared/perf-tracer.d.ts +73 -0
- package/dist/shared/perf-tracer.test.d.ts +1 -0
- package/dist/tools/perf-profiler/client-patch.d.ts +2 -0
- package/package.json +1 -1
- package/postinstall.mjs +20 -0
package/dist/index.js
CHANGED
|
@@ -46,6 +46,84 @@ var __export = (target, all) => {
|
|
|
46
46
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
47
47
|
var __require = import.meta.require;
|
|
48
48
|
|
|
49
|
+
// src/shared/fileio-monitor.ts
|
|
50
|
+
import { readdirSync, readFileSync, writeFileSync, existsSync } from "fs";
|
|
51
|
+
import { relative } from "path";
|
|
52
|
+
import { cwd } from "process";
|
|
53
|
+
function summarize(path) {
|
|
54
|
+
let result;
|
|
55
|
+
try {
|
|
56
|
+
result = relative(cwd(), path);
|
|
57
|
+
} catch {
|
|
58
|
+
result = path;
|
|
59
|
+
}
|
|
60
|
+
if (result.length > MAX_PATH_LENGTH) {
|
|
61
|
+
return result.slice(0, MAX_PATH_LENGTH - 3) + "...";
|
|
62
|
+
}
|
|
63
|
+
return result;
|
|
64
|
+
}
|
|
65
|
+
function setFileIOMonitor(monitor) {
|
|
66
|
+
globalMonitor = monitor;
|
|
67
|
+
}
|
|
68
|
+
function getFileIOMonitor() {
|
|
69
|
+
return globalMonitor;
|
|
70
|
+
}
|
|
71
|
+
function createFileIOMonitor(tracer) {
|
|
72
|
+
return {
|
|
73
|
+
readdirSync(path) {
|
|
74
|
+
if (!tracer.isEnabled()) {
|
|
75
|
+
return readdirSync(path);
|
|
76
|
+
}
|
|
77
|
+
const start = performance.now();
|
|
78
|
+
try {
|
|
79
|
+
return readdirSync(path);
|
|
80
|
+
} finally {
|
|
81
|
+
const durationMs = performance.now() - start;
|
|
82
|
+
tracer.recordFileIO("readdirSync", summarize(path), durationMs);
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
readFileSync(path, options) {
|
|
86
|
+
if (!tracer.isEnabled()) {
|
|
87
|
+
return readFileSync(path, options);
|
|
88
|
+
}
|
|
89
|
+
const start = performance.now();
|
|
90
|
+
try {
|
|
91
|
+
return readFileSync(path, options);
|
|
92
|
+
} finally {
|
|
93
|
+
const durationMs = performance.now() - start;
|
|
94
|
+
tracer.recordFileIO("readFileSync", summarize(path), durationMs);
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
writeFileSync(path, data, options) {
|
|
98
|
+
if (!tracer.isEnabled()) {
|
|
99
|
+
writeFileSync(path, data, options);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
const start = performance.now();
|
|
103
|
+
try {
|
|
104
|
+
writeFileSync(path, data, options);
|
|
105
|
+
} finally {
|
|
106
|
+
const durationMs = performance.now() - start;
|
|
107
|
+
tracer.recordFileIO("writeFileSync", summarize(path), durationMs);
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
existsSync(path) {
|
|
111
|
+
if (!tracer.isEnabled()) {
|
|
112
|
+
return existsSync(path);
|
|
113
|
+
}
|
|
114
|
+
const start = performance.now();
|
|
115
|
+
try {
|
|
116
|
+
return existsSync(path);
|
|
117
|
+
} finally {
|
|
118
|
+
const durationMs = performance.now() - start;
|
|
119
|
+
tracer.recordFileIO("existsSync", summarize(path), durationMs);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
var MAX_PATH_LENGTH = 120, globalMonitor = null;
|
|
125
|
+
var init_fileio_monitor = () => {};
|
|
126
|
+
|
|
49
127
|
// src/shared/data-path.ts
|
|
50
128
|
import * as path from "path";
|
|
51
129
|
import * as os from "os";
|
|
@@ -2767,17 +2845,17 @@ var init_frontmatter = __esm(() => {
|
|
|
2767
2845
|
import { spawn as spawn2 } from "child_process";
|
|
2768
2846
|
import { exec } from "child_process";
|
|
2769
2847
|
import { promisify } from "util";
|
|
2770
|
-
import { existsSync as
|
|
2848
|
+
import { existsSync as existsSync5 } from "fs";
|
|
2771
2849
|
import { homedir as homedir2 } from "os";
|
|
2772
2850
|
function getHomeDir() {
|
|
2773
2851
|
return process.env.HOME || process.env.USERPROFILE || homedir2();
|
|
2774
2852
|
}
|
|
2775
2853
|
function findShellPath(defaultPaths, customPath) {
|
|
2776
|
-
if (customPath &&
|
|
2854
|
+
if (customPath && existsSync5(customPath)) {
|
|
2777
2855
|
return customPath;
|
|
2778
2856
|
}
|
|
2779
2857
|
for (const path3 of defaultPaths) {
|
|
2780
|
-
if (
|
|
2858
|
+
if (existsSync5(path3)) {
|
|
2781
2859
|
return path3;
|
|
2782
2860
|
}
|
|
2783
2861
|
}
|
|
@@ -2789,9 +2867,9 @@ function findZshPath(customZshPath) {
|
|
|
2789
2867
|
function findBashPath() {
|
|
2790
2868
|
return findShellPath(DEFAULT_BASH_PATHS);
|
|
2791
2869
|
}
|
|
2792
|
-
async function executeHookCommand(command, stdin,
|
|
2870
|
+
async function executeHookCommand(command, stdin, cwd2, options) {
|
|
2793
2871
|
const home = getHomeDir();
|
|
2794
|
-
let expandedCommand = command.replace(/^~(?=\/|$)/g, home).replace(/\s~(?=\/)/g, ` ${home}`).replace(/\$CLAUDE_PROJECT_DIR/g,
|
|
2872
|
+
let expandedCommand = command.replace(/^~(?=\/|$)/g, home).replace(/\s~(?=\/)/g, ` ${home}`).replace(/\$CLAUDE_PROJECT_DIR/g, cwd2).replace(/\$\{CLAUDE_PROJECT_DIR\}/g, cwd2);
|
|
2795
2873
|
let finalCommand = expandedCommand;
|
|
2796
2874
|
if (options?.forceZsh) {
|
|
2797
2875
|
const zshPath = findZshPath(options.zshPath);
|
|
@@ -2807,9 +2885,9 @@ async function executeHookCommand(command, stdin, cwd, options) {
|
|
|
2807
2885
|
}
|
|
2808
2886
|
return new Promise((resolve) => {
|
|
2809
2887
|
const proc = spawn2(finalCommand, {
|
|
2810
|
-
cwd,
|
|
2888
|
+
cwd: cwd2,
|
|
2811
2889
|
shell: true,
|
|
2812
|
-
env: { ...process.env, HOME: home, CLAUDE_PROJECT_DIR:
|
|
2890
|
+
env: { ...process.env, HOME: home, CLAUDE_PROJECT_DIR: cwd2 }
|
|
2813
2891
|
});
|
|
2814
2892
|
let stdout = "";
|
|
2815
2893
|
let stderr = "";
|
|
@@ -2912,7 +2990,7 @@ var init_command_executor = __esm(() => {
|
|
|
2912
2990
|
});
|
|
2913
2991
|
|
|
2914
2992
|
// src/shared/file-reference-resolver.ts
|
|
2915
|
-
import { existsSync as
|
|
2993
|
+
import { existsSync as existsSync6, readFileSync as readFileSync4, statSync } from "fs";
|
|
2916
2994
|
import { join as join8, isAbsolute } from "path";
|
|
2917
2995
|
function findFileReferences(text) {
|
|
2918
2996
|
const matches = [];
|
|
@@ -2928,24 +3006,24 @@ function findFileReferences(text) {
|
|
|
2928
3006
|
}
|
|
2929
3007
|
return matches;
|
|
2930
3008
|
}
|
|
2931
|
-
function resolveFilePath(filePath,
|
|
3009
|
+
function resolveFilePath(filePath, cwd2) {
|
|
2932
3010
|
if (isAbsolute(filePath)) {
|
|
2933
3011
|
return filePath;
|
|
2934
3012
|
}
|
|
2935
|
-
return join8(
|
|
3013
|
+
return join8(cwd2, filePath);
|
|
2936
3014
|
}
|
|
2937
3015
|
function readFileContent(resolvedPath) {
|
|
2938
|
-
if (!
|
|
3016
|
+
if (!existsSync6(resolvedPath)) {
|
|
2939
3017
|
return `[file not found: ${resolvedPath}]`;
|
|
2940
3018
|
}
|
|
2941
3019
|
const stat = statSync(resolvedPath);
|
|
2942
3020
|
if (stat.isDirectory()) {
|
|
2943
3021
|
return `[cannot read directory: ${resolvedPath}]`;
|
|
2944
3022
|
}
|
|
2945
|
-
const content =
|
|
3023
|
+
const content = readFileSync4(resolvedPath, "utf-8");
|
|
2946
3024
|
return content;
|
|
2947
3025
|
}
|
|
2948
|
-
async function resolveFileReferencesInText(text,
|
|
3026
|
+
async function resolveFileReferencesInText(text, cwd2 = process.cwd(), depth = 0, maxDepth = 3) {
|
|
2949
3027
|
if (depth >= maxDepth) {
|
|
2950
3028
|
return text;
|
|
2951
3029
|
}
|
|
@@ -2955,7 +3033,7 @@ async function resolveFileReferencesInText(text, cwd = process.cwd(), depth = 0,
|
|
|
2955
3033
|
}
|
|
2956
3034
|
const replacements = new Map;
|
|
2957
3035
|
for (const match of matches) {
|
|
2958
|
-
const resolvedPath = resolveFilePath(match.filePath,
|
|
3036
|
+
const resolvedPath = resolveFilePath(match.filePath, cwd2);
|
|
2959
3037
|
const content = readFileContent(resolvedPath);
|
|
2960
3038
|
replacements.set(match.fullMatch, content);
|
|
2961
3039
|
}
|
|
@@ -2964,7 +3042,7 @@ async function resolveFileReferencesInText(text, cwd = process.cwd(), depth = 0,
|
|
|
2964
3042
|
resolved = resolved.split(pattern).join(replacement);
|
|
2965
3043
|
}
|
|
2966
3044
|
if (findFileReferences(resolved).length > 0 && depth + 1 < maxDepth) {
|
|
2967
|
-
return resolveFileReferencesInText(resolved,
|
|
3045
|
+
return resolveFileReferencesInText(resolved, cwd2, depth + 1, maxDepth);
|
|
2968
3046
|
}
|
|
2969
3047
|
return resolved;
|
|
2970
3048
|
}
|
|
@@ -4138,7 +4216,7 @@ var init_main = __esm(() => {
|
|
|
4138
4216
|
});
|
|
4139
4217
|
|
|
4140
4218
|
// src/shared/jsonc-parser.ts
|
|
4141
|
-
import { existsSync as
|
|
4219
|
+
import { existsSync as existsSync7, readFileSync as readFileSync5 } from "fs";
|
|
4142
4220
|
function parseJsonc(content) {
|
|
4143
4221
|
const errors = [];
|
|
4144
4222
|
const result = parse2(content, errors, {
|
|
@@ -4169,10 +4247,10 @@ function parseJsoncSafe(content) {
|
|
|
4169
4247
|
function detectConfigFile(basePath) {
|
|
4170
4248
|
const jsoncPath = `${basePath}.jsonc`;
|
|
4171
4249
|
const jsonPath = `${basePath}.json`;
|
|
4172
|
-
if (
|
|
4250
|
+
if (existsSync7(jsoncPath)) {
|
|
4173
4251
|
return { format: "jsonc", path: jsoncPath };
|
|
4174
4252
|
}
|
|
4175
|
-
if (
|
|
4253
|
+
if (existsSync7(jsonPath)) {
|
|
4176
4254
|
return { format: "json", path: jsonPath };
|
|
4177
4255
|
}
|
|
4178
4256
|
return { format: "none", path: jsonPath };
|
|
@@ -4318,7 +4396,7 @@ var init_migration = __esm(() => {
|
|
|
4318
4396
|
});
|
|
4319
4397
|
|
|
4320
4398
|
// src/shared/opencode-config-dir.ts
|
|
4321
|
-
import { existsSync as
|
|
4399
|
+
import { existsSync as existsSync8 } from "fs";
|
|
4322
4400
|
import { homedir as homedir4 } from "os";
|
|
4323
4401
|
import { join as join10, resolve as resolve2 } from "path";
|
|
4324
4402
|
function isDevBuild(version) {
|
|
@@ -4350,13 +4428,13 @@ function getCliConfigDir() {
|
|
|
4350
4428
|
if (process.platform === "win32") {
|
|
4351
4429
|
const crossPlatformDir = join10(homedir4(), ".config", "opencode");
|
|
4352
4430
|
const crossPlatformConfig = join10(crossPlatformDir, "opencode.json");
|
|
4353
|
-
if (
|
|
4431
|
+
if (existsSync8(crossPlatformConfig)) {
|
|
4354
4432
|
return crossPlatformDir;
|
|
4355
4433
|
}
|
|
4356
4434
|
const appData = process.env.APPDATA || join10(homedir4(), "AppData", "Roaming");
|
|
4357
4435
|
const appdataDir = join10(appData, "opencode");
|
|
4358
4436
|
const appdataConfig = join10(appdataDir, "opencode.json");
|
|
4359
|
-
if (
|
|
4437
|
+
if (existsSync8(appdataConfig)) {
|
|
4360
4438
|
return appdataDir;
|
|
4361
4439
|
}
|
|
4362
4440
|
return crossPlatformDir;
|
|
@@ -4375,7 +4453,7 @@ function getOpenCodeConfigDir(options) {
|
|
|
4375
4453
|
const legacyDir = getCliConfigDir();
|
|
4376
4454
|
const legacyConfig = join10(legacyDir, "opencode.json");
|
|
4377
4455
|
const legacyConfigC = join10(legacyDir, "opencode.jsonc");
|
|
4378
|
-
if (
|
|
4456
|
+
if (existsSync8(legacyConfig) || existsSync8(legacyConfigC)) {
|
|
4379
4457
|
return legacyDir;
|
|
4380
4458
|
}
|
|
4381
4459
|
}
|
|
@@ -4853,7 +4931,7 @@ var init_model_requirements = __esm(() => {
|
|
|
4853
4931
|
});
|
|
4854
4932
|
|
|
4855
4933
|
// src/shared/model-availability.ts
|
|
4856
|
-
import { existsSync as
|
|
4934
|
+
import { existsSync as existsSync10, readFileSync as readFileSync7 } from "fs";
|
|
4857
4935
|
import { homedir as homedir6 } from "os";
|
|
4858
4936
|
import { join as join12 } from "path";
|
|
4859
4937
|
function normalizeModelName(name) {
|
|
@@ -4908,12 +4986,12 @@ async function fetchAvailableModels(_client) {
|
|
|
4908
4986
|
const modelSet = new Set;
|
|
4909
4987
|
const cacheFile = join12(getOpenCodeCacheDir(), "models.json");
|
|
4910
4988
|
log("[fetchAvailableModels] reading cache file", { cacheFile });
|
|
4911
|
-
if (!
|
|
4989
|
+
if (!existsSync10(cacheFile)) {
|
|
4912
4990
|
log("[fetchAvailableModels] cache file not found, returning empty set");
|
|
4913
4991
|
return modelSet;
|
|
4914
4992
|
}
|
|
4915
4993
|
try {
|
|
4916
|
-
const content =
|
|
4994
|
+
const content = readFileSync7(cacheFile, "utf-8");
|
|
4917
4995
|
const data = JSON.parse(content);
|
|
4918
4996
|
const providerIds = Object.keys(data);
|
|
4919
4997
|
log("[fetchAvailableModels] providers found", { count: providerIds.length, providers: providerIds.slice(0, 10) });
|
|
@@ -4936,7 +5014,7 @@ async function fetchAvailableModels(_client) {
|
|
|
4936
5014
|
}
|
|
4937
5015
|
function isModelCacheAvailable() {
|
|
4938
5016
|
const cacheFile = join12(getOpenCodeCacheDir(), "models.json");
|
|
4939
|
-
return
|
|
5017
|
+
return existsSync10(cacheFile);
|
|
4940
5018
|
}
|
|
4941
5019
|
var cachedModels = null;
|
|
4942
5020
|
var init_model_availability = __esm(() => {
|
|
@@ -5033,6 +5111,136 @@ class PerfTimer {
|
|
|
5033
5111
|
}
|
|
5034
5112
|
}
|
|
5035
5113
|
|
|
5114
|
+
// src/shared/perf-tracer.ts
|
|
5115
|
+
import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync3, existsSync as existsSync11 } from "fs";
|
|
5116
|
+
import { tmpdir as tmpdir2 } from "os";
|
|
5117
|
+
import { join as join13 } from "path";
|
|
5118
|
+
|
|
5119
|
+
class PerfTracer {
|
|
5120
|
+
buffer = [];
|
|
5121
|
+
enabled;
|
|
5122
|
+
outputDir;
|
|
5123
|
+
slowThreshold;
|
|
5124
|
+
eventCount = 0;
|
|
5125
|
+
memorySnapshotInterval;
|
|
5126
|
+
constructor(config) {
|
|
5127
|
+
this.enabled = config.enabled;
|
|
5128
|
+
this.outputDir = config.outputDir ?? join13(tmpdir2(), "oh-my-opencode-perf");
|
|
5129
|
+
this.slowThreshold = config.slowThreshold ?? 100;
|
|
5130
|
+
this.memorySnapshotInterval = config.memorySnapshotInterval ?? 5;
|
|
5131
|
+
}
|
|
5132
|
+
isEnabled() {
|
|
5133
|
+
return this.enabled;
|
|
5134
|
+
}
|
|
5135
|
+
isSlowHook(durationMs) {
|
|
5136
|
+
return durationMs > this.slowThreshold;
|
|
5137
|
+
}
|
|
5138
|
+
recordHook(pipeline, hook, durationMs, sessionID, tool, error) {
|
|
5139
|
+
if (!this.enabled)
|
|
5140
|
+
return;
|
|
5141
|
+
const span = {
|
|
5142
|
+
t: new Date().toISOString(),
|
|
5143
|
+
type: "hook",
|
|
5144
|
+
pipeline,
|
|
5145
|
+
hook,
|
|
5146
|
+
durationMs,
|
|
5147
|
+
sessionID
|
|
5148
|
+
};
|
|
5149
|
+
if (tool !== undefined)
|
|
5150
|
+
span.tool = tool;
|
|
5151
|
+
if (error !== undefined)
|
|
5152
|
+
span.error = error;
|
|
5153
|
+
this.buffer.push(span);
|
|
5154
|
+
}
|
|
5155
|
+
recordPipeline(name, totalDurationMs, hookCount, sessionID) {
|
|
5156
|
+
if (!this.enabled)
|
|
5157
|
+
return;
|
|
5158
|
+
this.buffer.push({
|
|
5159
|
+
t: new Date().toISOString(),
|
|
5160
|
+
type: "pipeline",
|
|
5161
|
+
name,
|
|
5162
|
+
totalDurationMs,
|
|
5163
|
+
hookCount,
|
|
5164
|
+
sessionID
|
|
5165
|
+
});
|
|
5166
|
+
}
|
|
5167
|
+
recordApiCall(method, durationMs, sessionID, messageCount, error) {
|
|
5168
|
+
if (!this.enabled)
|
|
5169
|
+
return;
|
|
5170
|
+
const span = {
|
|
5171
|
+
t: new Date().toISOString(),
|
|
5172
|
+
type: "api",
|
|
5173
|
+
method,
|
|
5174
|
+
durationMs,
|
|
5175
|
+
sessionID
|
|
5176
|
+
};
|
|
5177
|
+
if (messageCount !== undefined)
|
|
5178
|
+
span.messageCount = messageCount;
|
|
5179
|
+
if (error !== undefined)
|
|
5180
|
+
span.error = error;
|
|
5181
|
+
this.buffer.push(span);
|
|
5182
|
+
}
|
|
5183
|
+
recordFileIO(operation, path4, durationMs, fileCount) {
|
|
5184
|
+
if (!this.enabled)
|
|
5185
|
+
return;
|
|
5186
|
+
const span = {
|
|
5187
|
+
t: new Date().toISOString(),
|
|
5188
|
+
type: "fileio",
|
|
5189
|
+
operation,
|
|
5190
|
+
path: path4,
|
|
5191
|
+
durationMs
|
|
5192
|
+
};
|
|
5193
|
+
if (fileCount !== undefined)
|
|
5194
|
+
span.fileCount = fileCount;
|
|
5195
|
+
this.buffer.push(span);
|
|
5196
|
+
}
|
|
5197
|
+
recordPolling(durationMs, taskCount, sessionCount) {
|
|
5198
|
+
if (!this.enabled)
|
|
5199
|
+
return;
|
|
5200
|
+
this.buffer.push({
|
|
5201
|
+
t: new Date().toISOString(),
|
|
5202
|
+
type: "polling",
|
|
5203
|
+
durationMs,
|
|
5204
|
+
taskCount,
|
|
5205
|
+
sessionCount
|
|
5206
|
+
});
|
|
5207
|
+
}
|
|
5208
|
+
snapshotMemory(trigger, mapSizes) {
|
|
5209
|
+
if (!this.enabled)
|
|
5210
|
+
return;
|
|
5211
|
+
this.eventCount++;
|
|
5212
|
+
if (this.eventCount % this.memorySnapshotInterval !== 0)
|
|
5213
|
+
return;
|
|
5214
|
+
this.buffer.push({
|
|
5215
|
+
t: new Date().toISOString(),
|
|
5216
|
+
type: "memory",
|
|
5217
|
+
trigger,
|
|
5218
|
+
mapSizes
|
|
5219
|
+
});
|
|
5220
|
+
}
|
|
5221
|
+
flush() {
|
|
5222
|
+
if (this.buffer.length === 0)
|
|
5223
|
+
return;
|
|
5224
|
+
if (!existsSync11(this.outputDir)) {
|
|
5225
|
+
mkdirSync3(this.outputDir, { recursive: true });
|
|
5226
|
+
}
|
|
5227
|
+
const date = new Date().toISOString().slice(0, 10);
|
|
5228
|
+
const filePath = join13(this.outputDir, `${date}.jsonl`);
|
|
5229
|
+
let output = "";
|
|
5230
|
+
for (const span of this.buffer) {
|
|
5231
|
+
output += JSON.stringify(span) + `
|
|
5232
|
+
`;
|
|
5233
|
+
}
|
|
5234
|
+
appendFileSync2(filePath, output);
|
|
5235
|
+
this.buffer = [];
|
|
5236
|
+
}
|
|
5237
|
+
reset() {
|
|
5238
|
+
this.buffer = [];
|
|
5239
|
+
this.eventCount = 0;
|
|
5240
|
+
}
|
|
5241
|
+
}
|
|
5242
|
+
var init_perf_tracer = () => {};
|
|
5243
|
+
|
|
5036
5244
|
// src/shared/index.ts
|
|
5037
5245
|
var init_shared = __esm(() => {
|
|
5038
5246
|
init_frontmatter();
|
|
@@ -5060,6 +5268,8 @@ var init_shared = __esm(() => {
|
|
|
5060
5268
|
init_model_requirements();
|
|
5061
5269
|
init_model_resolver();
|
|
5062
5270
|
init_model_availability();
|
|
5271
|
+
init_perf_tracer();
|
|
5272
|
+
init_fileio_monitor();
|
|
5063
5273
|
});
|
|
5064
5274
|
|
|
5065
5275
|
// node_modules/picomatch/lib/constants.js
|
|
@@ -10944,49 +11154,49 @@ var require_fast_uri = __commonJS((exports, module) => {
|
|
|
10944
11154
|
schemelessOptions.skipEscape = true;
|
|
10945
11155
|
return serialize(resolved, schemelessOptions);
|
|
10946
11156
|
}
|
|
10947
|
-
function resolveComponent(base,
|
|
11157
|
+
function resolveComponent(base, relative6, options, skipNormalization) {
|
|
10948
11158
|
const target = {};
|
|
10949
11159
|
if (!skipNormalization) {
|
|
10950
11160
|
base = parse11(serialize(base, options), options);
|
|
10951
|
-
|
|
11161
|
+
relative6 = parse11(serialize(relative6, options), options);
|
|
10952
11162
|
}
|
|
10953
11163
|
options = options || {};
|
|
10954
|
-
if (!options.tolerant &&
|
|
10955
|
-
target.scheme =
|
|
10956
|
-
target.userinfo =
|
|
10957
|
-
target.host =
|
|
10958
|
-
target.port =
|
|
10959
|
-
target.path = removeDotSegments(
|
|
10960
|
-
target.query =
|
|
11164
|
+
if (!options.tolerant && relative6.scheme) {
|
|
11165
|
+
target.scheme = relative6.scheme;
|
|
11166
|
+
target.userinfo = relative6.userinfo;
|
|
11167
|
+
target.host = relative6.host;
|
|
11168
|
+
target.port = relative6.port;
|
|
11169
|
+
target.path = removeDotSegments(relative6.path || "");
|
|
11170
|
+
target.query = relative6.query;
|
|
10961
11171
|
} else {
|
|
10962
|
-
if (
|
|
10963
|
-
target.userinfo =
|
|
10964
|
-
target.host =
|
|
10965
|
-
target.port =
|
|
10966
|
-
target.path = removeDotSegments(
|
|
10967
|
-
target.query =
|
|
11172
|
+
if (relative6.userinfo !== undefined || relative6.host !== undefined || relative6.port !== undefined) {
|
|
11173
|
+
target.userinfo = relative6.userinfo;
|
|
11174
|
+
target.host = relative6.host;
|
|
11175
|
+
target.port = relative6.port;
|
|
11176
|
+
target.path = removeDotSegments(relative6.path || "");
|
|
11177
|
+
target.query = relative6.query;
|
|
10968
11178
|
} else {
|
|
10969
|
-
if (!
|
|
11179
|
+
if (!relative6.path) {
|
|
10970
11180
|
target.path = base.path;
|
|
10971
|
-
if (
|
|
10972
|
-
target.query =
|
|
11181
|
+
if (relative6.query !== undefined) {
|
|
11182
|
+
target.query = relative6.query;
|
|
10973
11183
|
} else {
|
|
10974
11184
|
target.query = base.query;
|
|
10975
11185
|
}
|
|
10976
11186
|
} else {
|
|
10977
|
-
if (
|
|
10978
|
-
target.path = removeDotSegments(
|
|
11187
|
+
if (relative6.path[0] === "/") {
|
|
11188
|
+
target.path = removeDotSegments(relative6.path);
|
|
10979
11189
|
} else {
|
|
10980
11190
|
if ((base.userinfo !== undefined || base.host !== undefined || base.port !== undefined) && !base.path) {
|
|
10981
|
-
target.path = "/" +
|
|
11191
|
+
target.path = "/" + relative6.path;
|
|
10982
11192
|
} else if (!base.path) {
|
|
10983
|
-
target.path =
|
|
11193
|
+
target.path = relative6.path;
|
|
10984
11194
|
} else {
|
|
10985
|
-
target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) +
|
|
11195
|
+
target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) + relative6.path;
|
|
10986
11196
|
}
|
|
10987
11197
|
target.path = removeDotSegments(target.path);
|
|
10988
11198
|
}
|
|
10989
|
-
target.query =
|
|
11199
|
+
target.query = relative6.query;
|
|
10990
11200
|
}
|
|
10991
11201
|
target.userinfo = base.userinfo;
|
|
10992
11202
|
target.host = base.host;
|
|
@@ -10994,7 +11204,7 @@ var require_fast_uri = __commonJS((exports, module) => {
|
|
|
10994
11204
|
}
|
|
10995
11205
|
target.scheme = base.scheme;
|
|
10996
11206
|
}
|
|
10997
|
-
target.fragment =
|
|
11207
|
+
target.fragment = relative6.fragment;
|
|
10998
11208
|
return target;
|
|
10999
11209
|
}
|
|
11000
11210
|
function equal(uriA, uriB, options) {
|
|
@@ -14201,7 +14411,7 @@ var require_resolveCommand = __commonJS((exports, module) => {
|
|
|
14201
14411
|
var getPathKey = require_path_key();
|
|
14202
14412
|
function resolveCommandAttempt(parsed, withoutPathExt) {
|
|
14203
14413
|
const env = parsed.options.env || process.env;
|
|
14204
|
-
const
|
|
14414
|
+
const cwd2 = process.cwd();
|
|
14205
14415
|
const hasCustomCwd = parsed.options.cwd != null;
|
|
14206
14416
|
const shouldSwitchCwd = hasCustomCwd && process.chdir !== undefined && !process.chdir.disabled;
|
|
14207
14417
|
if (shouldSwitchCwd) {
|
|
@@ -14217,7 +14427,7 @@ var require_resolveCommand = __commonJS((exports, module) => {
|
|
|
14217
14427
|
});
|
|
14218
14428
|
} catch (e) {} finally {
|
|
14219
14429
|
if (shouldSwitchCwd) {
|
|
14220
|
-
process.chdir(
|
|
14430
|
+
process.chdir(cwd2);
|
|
14221
14431
|
}
|
|
14222
14432
|
}
|
|
14223
14433
|
if (resolved) {
|
|
@@ -14424,7 +14634,7 @@ var require_cross_spawn = __commonJS((exports, module) => {
|
|
|
14424
14634
|
});
|
|
14425
14635
|
|
|
14426
14636
|
// src/hooks/todo-continuation-enforcer.ts
|
|
14427
|
-
import { existsSync as
|
|
14637
|
+
import { existsSync as existsSync3, readdirSync as readdirSync3 } from "fs";
|
|
14428
14638
|
import { join as join5 } from "path";
|
|
14429
14639
|
|
|
14430
14640
|
// src/features/claude-code-session-state/state.ts
|
|
@@ -14452,7 +14662,8 @@ function clearSessionAgent(sessionID) {
|
|
|
14452
14662
|
sessionAgentMap.delete(sessionID);
|
|
14453
14663
|
}
|
|
14454
14664
|
// src/features/hook-message-injector/injector.ts
|
|
14455
|
-
|
|
14665
|
+
init_fileio_monitor();
|
|
14666
|
+
import { existsSync as existsSync2, mkdirSync, readFileSync as readFileSync2, readdirSync as readdirSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
14456
14667
|
import { join as join3 } from "path";
|
|
14457
14668
|
|
|
14458
14669
|
// src/features/hook-message-injector/constants.ts
|
|
@@ -14464,11 +14675,12 @@ var PART_STORAGE = join2(OPENCODE_STORAGE, "part");
|
|
|
14464
14675
|
|
|
14465
14676
|
// src/features/hook-message-injector/injector.ts
|
|
14466
14677
|
function findNearestMessageWithFields(messageDir) {
|
|
14678
|
+
const monitor = getFileIOMonitor();
|
|
14467
14679
|
try {
|
|
14468
|
-
const files = readdirSync(messageDir).filter((f) => f.endsWith(".json")).sort().reverse();
|
|
14680
|
+
const files = (monitor?.readdirSync(messageDir) ?? readdirSync2(messageDir)).filter((f) => f.endsWith(".json")).sort().reverse();
|
|
14469
14681
|
for (const file of files) {
|
|
14470
14682
|
try {
|
|
14471
|
-
const content = readFileSync(join3(messageDir, file), "utf-8");
|
|
14683
|
+
const content = monitor?.readFileSync(join3(messageDir, file), "utf-8") ?? readFileSync2(join3(messageDir, file), "utf-8");
|
|
14472
14684
|
const msg = JSON.parse(content);
|
|
14473
14685
|
if (msg.agent && msg.model?.providerID && msg.model?.modelID) {
|
|
14474
14686
|
return msg;
|
|
@@ -14479,7 +14691,7 @@ function findNearestMessageWithFields(messageDir) {
|
|
|
14479
14691
|
}
|
|
14480
14692
|
for (const file of files) {
|
|
14481
14693
|
try {
|
|
14482
|
-
const content = readFileSync(join3(messageDir, file), "utf-8");
|
|
14694
|
+
const content = monitor?.readFileSync(join3(messageDir, file), "utf-8") ?? readFileSync2(join3(messageDir, file), "utf-8");
|
|
14483
14695
|
const msg = JSON.parse(content);
|
|
14484
14696
|
if (msg.agent || msg.model?.providerID && msg.model?.modelID) {
|
|
14485
14697
|
return msg;
|
|
@@ -14494,11 +14706,12 @@ function findNearestMessageWithFields(messageDir) {
|
|
|
14494
14706
|
return null;
|
|
14495
14707
|
}
|
|
14496
14708
|
function findFirstMessageWithAgent(messageDir) {
|
|
14709
|
+
const monitor = getFileIOMonitor();
|
|
14497
14710
|
try {
|
|
14498
|
-
const files = readdirSync(messageDir).filter((f) => f.endsWith(".json")).sort();
|
|
14711
|
+
const files = (monitor?.readdirSync(messageDir) ?? readdirSync2(messageDir)).filter((f) => f.endsWith(".json")).sort();
|
|
14499
14712
|
for (const file of files) {
|
|
14500
14713
|
try {
|
|
14501
|
-
const content = readFileSync(join3(messageDir, file), "utf-8");
|
|
14714
|
+
const content = monitor?.readFileSync(join3(messageDir, file), "utf-8") ?? readFileSync2(join3(messageDir, file), "utf-8");
|
|
14502
14715
|
const msg = JSON.parse(content);
|
|
14503
14716
|
if (msg.agent) {
|
|
14504
14717
|
return msg.agent;
|
|
@@ -14523,20 +14736,24 @@ function generatePartId() {
|
|
|
14523
14736
|
return `prt_${timestamp}${random}`;
|
|
14524
14737
|
}
|
|
14525
14738
|
function getOrCreateMessageDir(sessionID) {
|
|
14526
|
-
|
|
14527
|
-
|
|
14739
|
+
const monitor = getFileIOMonitor();
|
|
14740
|
+
const _exists = (p) => monitor?.existsSync(p) ?? existsSync2(p);
|
|
14741
|
+
const _mkdir = (p, opts) => monitor ? undefined : mkdirSync(p, opts);
|
|
14742
|
+
const _readdir = (p) => monitor?.readdirSync(p) ?? readdirSync2(p);
|
|
14743
|
+
if (!_exists(MESSAGE_STORAGE)) {
|
|
14744
|
+
_mkdir(MESSAGE_STORAGE, { recursive: true });
|
|
14528
14745
|
}
|
|
14529
14746
|
const directPath = join3(MESSAGE_STORAGE, sessionID);
|
|
14530
|
-
if (
|
|
14747
|
+
if (_exists(directPath)) {
|
|
14531
14748
|
return directPath;
|
|
14532
14749
|
}
|
|
14533
|
-
for (const dir of
|
|
14750
|
+
for (const dir of _readdir(MESSAGE_STORAGE)) {
|
|
14534
14751
|
const sessionPath = join3(MESSAGE_STORAGE, dir, sessionID);
|
|
14535
|
-
if (
|
|
14752
|
+
if (_exists(sessionPath)) {
|
|
14536
14753
|
return sessionPath;
|
|
14537
14754
|
}
|
|
14538
14755
|
}
|
|
14539
|
-
|
|
14756
|
+
_mkdir(directPath, { recursive: true });
|
|
14540
14757
|
return directPath;
|
|
14541
14758
|
}
|
|
14542
14759
|
function injectHookMessage(sessionID, hookContent, originalMessage) {
|
|
@@ -14585,12 +14802,22 @@ function injectHookMessage(sessionID, hookContent, originalMessage) {
|
|
|
14585
14802
|
sessionID
|
|
14586
14803
|
};
|
|
14587
14804
|
try {
|
|
14588
|
-
|
|
14805
|
+
const monitor = getFileIOMonitor();
|
|
14806
|
+
if (monitor) {
|
|
14807
|
+
monitor.writeFileSync(join3(messageDir, `${messageID}.json`), JSON.stringify(messageMeta, null, 2));
|
|
14808
|
+
} else {
|
|
14809
|
+
writeFileSync2(join3(messageDir, `${messageID}.json`), JSON.stringify(messageMeta, null, 2));
|
|
14810
|
+
}
|
|
14589
14811
|
const partDir = join3(PART_STORAGE, messageID);
|
|
14590
|
-
|
|
14812
|
+
const _exists = (p) => monitor?.existsSync(p) ?? existsSync2(p);
|
|
14813
|
+
if (!_exists(partDir)) {
|
|
14591
14814
|
mkdirSync(partDir, { recursive: true });
|
|
14592
14815
|
}
|
|
14593
|
-
|
|
14816
|
+
if (monitor) {
|
|
14817
|
+
monitor.writeFileSync(join3(partDir, `${partID}.json`), JSON.stringify(textPart, null, 2));
|
|
14818
|
+
} else {
|
|
14819
|
+
writeFileSync2(join3(partDir, `${partID}.json`), JSON.stringify(textPart, null, 2));
|
|
14820
|
+
}
|
|
14594
14821
|
return true;
|
|
14595
14822
|
} catch {
|
|
14596
14823
|
return false;
|
|
@@ -14612,14 +14839,14 @@ var COUNTDOWN_SECONDS = 2;
|
|
|
14612
14839
|
var TOAST_DURATION_MS = 900;
|
|
14613
14840
|
var COUNTDOWN_GRACE_PERIOD_MS = 500;
|
|
14614
14841
|
function getMessageDir(sessionID) {
|
|
14615
|
-
if (!
|
|
14842
|
+
if (!existsSync3(MESSAGE_STORAGE))
|
|
14616
14843
|
return null;
|
|
14617
14844
|
const directPath = join5(MESSAGE_STORAGE, sessionID);
|
|
14618
|
-
if (
|
|
14845
|
+
if (existsSync3(directPath))
|
|
14619
14846
|
return directPath;
|
|
14620
|
-
for (const dir of
|
|
14847
|
+
for (const dir of readdirSync3(MESSAGE_STORAGE)) {
|
|
14621
14848
|
const sessionPath = join5(MESSAGE_STORAGE, dir, sessionID);
|
|
14622
|
-
if (
|
|
14849
|
+
if (existsSync3(sessionPath))
|
|
14623
14850
|
return sessionPath;
|
|
14624
14851
|
}
|
|
14625
14852
|
return null;
|
|
@@ -15397,7 +15624,7 @@ function createSessionNotification(ctx, config = {}) {
|
|
|
15397
15624
|
};
|
|
15398
15625
|
}
|
|
15399
15626
|
// src/hooks/session-recovery/storage.ts
|
|
15400
|
-
import { existsSync as
|
|
15627
|
+
import { existsSync as existsSync4, mkdirSync as mkdirSync2, readdirSync as readdirSync4, readFileSync as readFileSync3, unlinkSync, writeFileSync as writeFileSync3 } from "fs";
|
|
15401
15628
|
import { join as join7 } from "path";
|
|
15402
15629
|
|
|
15403
15630
|
// src/hooks/session-recovery/constants.ts
|
|
@@ -15418,15 +15645,15 @@ function generatePartId2() {
|
|
|
15418
15645
|
return `prt_${timestamp}${random}`;
|
|
15419
15646
|
}
|
|
15420
15647
|
function getMessageDir2(sessionID) {
|
|
15421
|
-
if (!
|
|
15648
|
+
if (!existsSync4(MESSAGE_STORAGE2))
|
|
15422
15649
|
return "";
|
|
15423
15650
|
const directPath = join7(MESSAGE_STORAGE2, sessionID);
|
|
15424
|
-
if (
|
|
15651
|
+
if (existsSync4(directPath)) {
|
|
15425
15652
|
return directPath;
|
|
15426
15653
|
}
|
|
15427
|
-
for (const dir of
|
|
15654
|
+
for (const dir of readdirSync4(MESSAGE_STORAGE2)) {
|
|
15428
15655
|
const sessionPath = join7(MESSAGE_STORAGE2, dir, sessionID);
|
|
15429
|
-
if (
|
|
15656
|
+
if (existsSync4(sessionPath)) {
|
|
15430
15657
|
return sessionPath;
|
|
15431
15658
|
}
|
|
15432
15659
|
}
|
|
@@ -15434,14 +15661,14 @@ function getMessageDir2(sessionID) {
|
|
|
15434
15661
|
}
|
|
15435
15662
|
function readMessages(sessionID) {
|
|
15436
15663
|
const messageDir = getMessageDir2(sessionID);
|
|
15437
|
-
if (!messageDir || !
|
|
15664
|
+
if (!messageDir || !existsSync4(messageDir))
|
|
15438
15665
|
return [];
|
|
15439
15666
|
const messages = [];
|
|
15440
|
-
for (const file of
|
|
15667
|
+
for (const file of readdirSync4(messageDir)) {
|
|
15441
15668
|
if (!file.endsWith(".json"))
|
|
15442
15669
|
continue;
|
|
15443
15670
|
try {
|
|
15444
|
-
const content =
|
|
15671
|
+
const content = readFileSync3(join7(messageDir, file), "utf-8");
|
|
15445
15672
|
messages.push(JSON.parse(content));
|
|
15446
15673
|
} catch {
|
|
15447
15674
|
continue;
|
|
@@ -15457,14 +15684,14 @@ function readMessages(sessionID) {
|
|
|
15457
15684
|
}
|
|
15458
15685
|
function readParts(messageID) {
|
|
15459
15686
|
const partDir = join7(PART_STORAGE2, messageID);
|
|
15460
|
-
if (!
|
|
15687
|
+
if (!existsSync4(partDir))
|
|
15461
15688
|
return [];
|
|
15462
15689
|
const parts = [];
|
|
15463
|
-
for (const file of
|
|
15690
|
+
for (const file of readdirSync4(partDir)) {
|
|
15464
15691
|
if (!file.endsWith(".json"))
|
|
15465
15692
|
continue;
|
|
15466
15693
|
try {
|
|
15467
|
-
const content =
|
|
15694
|
+
const content = readFileSync3(join7(partDir, file), "utf-8");
|
|
15468
15695
|
parts.push(JSON.parse(content));
|
|
15469
15696
|
} catch {
|
|
15470
15697
|
continue;
|
|
@@ -15495,7 +15722,7 @@ function messageHasContent(messageID) {
|
|
|
15495
15722
|
}
|
|
15496
15723
|
function injectTextPart(sessionID, messageID, text) {
|
|
15497
15724
|
const partDir = join7(PART_STORAGE2, messageID);
|
|
15498
|
-
if (!
|
|
15725
|
+
if (!existsSync4(partDir)) {
|
|
15499
15726
|
mkdirSync2(partDir, { recursive: true });
|
|
15500
15727
|
}
|
|
15501
15728
|
const partId = generatePartId2();
|
|
@@ -15508,7 +15735,7 @@ function injectTextPart(sessionID, messageID, text) {
|
|
|
15508
15735
|
synthetic: true
|
|
15509
15736
|
};
|
|
15510
15737
|
try {
|
|
15511
|
-
|
|
15738
|
+
writeFileSync3(join7(partDir, `${partId}.json`), JSON.stringify(part, null, 2));
|
|
15512
15739
|
return true;
|
|
15513
15740
|
} catch {
|
|
15514
15741
|
return false;
|
|
@@ -15604,7 +15831,7 @@ function findLastThinkingContent(sessionID, beforeMessageID) {
|
|
|
15604
15831
|
}
|
|
15605
15832
|
function prependThinkingPart(sessionID, messageID) {
|
|
15606
15833
|
const partDir = join7(PART_STORAGE2, messageID);
|
|
15607
|
-
if (!
|
|
15834
|
+
if (!existsSync4(partDir)) {
|
|
15608
15835
|
mkdirSync2(partDir, { recursive: true });
|
|
15609
15836
|
}
|
|
15610
15837
|
const previousThinking = findLastThinkingContent(sessionID, messageID);
|
|
@@ -15614,11 +15841,11 @@ function prependThinkingPart(sessionID, messageID) {
|
|
|
15614
15841
|
sessionID,
|
|
15615
15842
|
messageID,
|
|
15616
15843
|
type: "thinking",
|
|
15617
|
-
thinking: previousThinking || "[
|
|
15844
|
+
thinking: previousThinking || "[\u63A5\u7EED\u4E4B\u524D\u7684\u63A8\u7406]",
|
|
15618
15845
|
synthetic: true
|
|
15619
15846
|
};
|
|
15620
15847
|
try {
|
|
15621
|
-
|
|
15848
|
+
writeFileSync3(join7(partDir, `${partId}.json`), JSON.stringify(part, null, 2));
|
|
15622
15849
|
return true;
|
|
15623
15850
|
} catch {
|
|
15624
15851
|
return false;
|
|
@@ -15626,15 +15853,15 @@ function prependThinkingPart(sessionID, messageID) {
|
|
|
15626
15853
|
}
|
|
15627
15854
|
function stripThinkingParts(messageID) {
|
|
15628
15855
|
const partDir = join7(PART_STORAGE2, messageID);
|
|
15629
|
-
if (!
|
|
15856
|
+
if (!existsSync4(partDir))
|
|
15630
15857
|
return false;
|
|
15631
15858
|
let anyRemoved = false;
|
|
15632
|
-
for (const file of
|
|
15859
|
+
for (const file of readdirSync4(partDir)) {
|
|
15633
15860
|
if (!file.endsWith(".json"))
|
|
15634
15861
|
continue;
|
|
15635
15862
|
try {
|
|
15636
15863
|
const filePath = join7(partDir, file);
|
|
15637
|
-
const content =
|
|
15864
|
+
const content = readFileSync3(filePath, "utf-8");
|
|
15638
15865
|
const part = JSON.parse(content);
|
|
15639
15866
|
if (THINKING_TYPES.has(part.type)) {
|
|
15640
15867
|
unlinkSync(filePath);
|
|
@@ -15648,22 +15875,22 @@ function stripThinkingParts(messageID) {
|
|
|
15648
15875
|
}
|
|
15649
15876
|
function replaceEmptyTextParts(messageID, replacementText) {
|
|
15650
15877
|
const partDir = join7(PART_STORAGE2, messageID);
|
|
15651
|
-
if (!
|
|
15878
|
+
if (!existsSync4(partDir))
|
|
15652
15879
|
return false;
|
|
15653
15880
|
let anyReplaced = false;
|
|
15654
|
-
for (const file of
|
|
15881
|
+
for (const file of readdirSync4(partDir)) {
|
|
15655
15882
|
if (!file.endsWith(".json"))
|
|
15656
15883
|
continue;
|
|
15657
15884
|
try {
|
|
15658
15885
|
const filePath = join7(partDir, file);
|
|
15659
|
-
const content =
|
|
15886
|
+
const content = readFileSync3(filePath, "utf-8");
|
|
15660
15887
|
const part = JSON.parse(content);
|
|
15661
15888
|
if (part.type === "text") {
|
|
15662
15889
|
const textPart = part;
|
|
15663
15890
|
if (!textPart.text?.trim()) {
|
|
15664
15891
|
textPart.text = replacementText;
|
|
15665
15892
|
textPart.synthetic = true;
|
|
15666
|
-
|
|
15893
|
+
writeFileSync3(filePath, JSON.stringify(textPart, null, 2));
|
|
15667
15894
|
anyReplaced = true;
|
|
15668
15895
|
}
|
|
15669
15896
|
}
|
|
@@ -15932,25 +16159,25 @@ function createSessionRecoveryHook(ctx, options) {
|
|
|
15932
16159
|
// src/hooks/comment-checker/cli.ts
|
|
15933
16160
|
var {spawn: spawn5 } = globalThis.Bun;
|
|
15934
16161
|
import { createRequire as createRequire2 } from "module";
|
|
15935
|
-
import { dirname, join as
|
|
15936
|
-
import { existsSync as
|
|
16162
|
+
import { dirname, join as join15 } from "path";
|
|
16163
|
+
import { existsSync as existsSync13 } from "fs";
|
|
15937
16164
|
import * as fs5 from "fs";
|
|
15938
|
-
import { tmpdir as
|
|
16165
|
+
import { tmpdir as tmpdir4 } from "os";
|
|
15939
16166
|
|
|
15940
16167
|
// src/hooks/comment-checker/downloader.ts
|
|
15941
16168
|
init_shared();
|
|
15942
16169
|
var {spawn: spawn4 } = globalThis.Bun;
|
|
15943
|
-
import { existsSync as
|
|
15944
|
-
import { join as
|
|
15945
|
-
import { homedir as homedir7, tmpdir as
|
|
16170
|
+
import { existsSync as existsSync12, mkdirSync as mkdirSync4, chmodSync, unlinkSync as unlinkSync2, appendFileSync as appendFileSync3 } from "fs";
|
|
16171
|
+
import { join as join14 } from "path";
|
|
16172
|
+
import { homedir as homedir7, tmpdir as tmpdir3 } from "os";
|
|
15946
16173
|
import { createRequire } from "module";
|
|
15947
16174
|
var DEBUG = process.env.COMMENT_CHECKER_DEBUG === "1";
|
|
15948
|
-
var DEBUG_FILE =
|
|
16175
|
+
var DEBUG_FILE = join14(tmpdir3(), "comment-checker-debug.log");
|
|
15949
16176
|
function debugLog(...args) {
|
|
15950
16177
|
if (DEBUG) {
|
|
15951
16178
|
const msg = `[${new Date().toISOString()}] [comment-checker:downloader] ${args.map((a) => typeof a === "object" ? JSON.stringify(a, null, 2) : String(a)).join(" ")}
|
|
15952
16179
|
`;
|
|
15953
|
-
|
|
16180
|
+
appendFileSync3(DEBUG_FILE, msg);
|
|
15954
16181
|
}
|
|
15955
16182
|
}
|
|
15956
16183
|
var REPO = "code-yeongyu/go-claude-code-comment-checker";
|
|
@@ -15964,19 +16191,19 @@ var PLATFORM_MAP = {
|
|
|
15964
16191
|
function getCacheDir() {
|
|
15965
16192
|
if (process.platform === "win32") {
|
|
15966
16193
|
const localAppData = process.env.LOCALAPPDATA || process.env.APPDATA;
|
|
15967
|
-
const base2 = localAppData ||
|
|
15968
|
-
return
|
|
16194
|
+
const base2 = localAppData || join14(homedir7(), "AppData", "Local");
|
|
16195
|
+
return join14(base2, "oh-my-opencode", "bin");
|
|
15969
16196
|
}
|
|
15970
16197
|
const xdgCache = process.env.XDG_CACHE_HOME;
|
|
15971
|
-
const base = xdgCache ||
|
|
15972
|
-
return
|
|
16198
|
+
const base = xdgCache || join14(homedir7(), ".cache");
|
|
16199
|
+
return join14(base, "oh-my-opencode", "bin");
|
|
15973
16200
|
}
|
|
15974
16201
|
function getBinaryName() {
|
|
15975
16202
|
return process.platform === "win32" ? "comment-checker.exe" : "comment-checker";
|
|
15976
16203
|
}
|
|
15977
16204
|
function getCachedBinaryPath() {
|
|
15978
|
-
const binaryPath =
|
|
15979
|
-
return
|
|
16205
|
+
const binaryPath = join14(getCacheDir(), getBinaryName());
|
|
16206
|
+
return existsSync12(binaryPath) ? binaryPath : null;
|
|
15980
16207
|
}
|
|
15981
16208
|
function getPackageVersion() {
|
|
15982
16209
|
try {
|
|
@@ -16008,8 +16235,8 @@ async function downloadCommentChecker() {
|
|
|
16008
16235
|
}
|
|
16009
16236
|
const cacheDir = getCacheDir();
|
|
16010
16237
|
const binaryName = getBinaryName();
|
|
16011
|
-
const binaryPath =
|
|
16012
|
-
if (
|
|
16238
|
+
const binaryPath = join14(cacheDir, binaryName);
|
|
16239
|
+
if (existsSync12(binaryPath)) {
|
|
16013
16240
|
debugLog("Binary already cached at:", binaryPath);
|
|
16014
16241
|
return binaryPath;
|
|
16015
16242
|
}
|
|
@@ -16020,14 +16247,14 @@ async function downloadCommentChecker() {
|
|
|
16020
16247
|
debugLog(`Downloading from: ${downloadUrl}`);
|
|
16021
16248
|
console.log(`[oh-my-opencode] Downloading comment-checker binary...`);
|
|
16022
16249
|
try {
|
|
16023
|
-
if (!
|
|
16024
|
-
|
|
16250
|
+
if (!existsSync12(cacheDir)) {
|
|
16251
|
+
mkdirSync4(cacheDir, { recursive: true });
|
|
16025
16252
|
}
|
|
16026
16253
|
const response = await fetch(downloadUrl, { redirect: "follow" });
|
|
16027
16254
|
if (!response.ok) {
|
|
16028
16255
|
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
16029
16256
|
}
|
|
16030
|
-
const archivePath =
|
|
16257
|
+
const archivePath = join14(cacheDir, assetName);
|
|
16031
16258
|
const arrayBuffer = await response.arrayBuffer();
|
|
16032
16259
|
await Bun.write(archivePath, arrayBuffer);
|
|
16033
16260
|
debugLog(`Downloaded archive to: ${archivePath}`);
|
|
@@ -16036,10 +16263,10 @@ async function downloadCommentChecker() {
|
|
|
16036
16263
|
} else {
|
|
16037
16264
|
await extractZip(archivePath, cacheDir);
|
|
16038
16265
|
}
|
|
16039
|
-
if (
|
|
16266
|
+
if (existsSync12(archivePath)) {
|
|
16040
16267
|
unlinkSync2(archivePath);
|
|
16041
16268
|
}
|
|
16042
|
-
if (process.platform !== "win32" &&
|
|
16269
|
+
if (process.platform !== "win32" && existsSync12(binaryPath)) {
|
|
16043
16270
|
chmodSync(binaryPath, 493);
|
|
16044
16271
|
}
|
|
16045
16272
|
debugLog(`Successfully downloaded binary to: ${binaryPath}`);
|
|
@@ -16063,7 +16290,7 @@ async function ensureCommentCheckerBinary() {
|
|
|
16063
16290
|
|
|
16064
16291
|
// src/hooks/comment-checker/cli.ts
|
|
16065
16292
|
var DEBUG2 = process.env.COMMENT_CHECKER_DEBUG === "1";
|
|
16066
|
-
var DEBUG_FILE2 =
|
|
16293
|
+
var DEBUG_FILE2 = join15(tmpdir4(), "comment-checker-debug.log");
|
|
16067
16294
|
function debugLog2(...args) {
|
|
16068
16295
|
if (DEBUG2) {
|
|
16069
16296
|
const msg = `[${new Date().toISOString()}] [comment-checker:cli] ${args.map((a) => typeof a === "object" ? JSON.stringify(a, null, 2) : String(a)).join(" ")}
|
|
@@ -16089,8 +16316,8 @@ function findCommentCheckerPathSync() {
|
|
|
16089
16316
|
const require2 = createRequire2(import.meta.url);
|
|
16090
16317
|
const cliPkgPath = require2.resolve("@code-yeongyu/comment-checker/package.json");
|
|
16091
16318
|
const cliDir = dirname(cliPkgPath);
|
|
16092
|
-
const binaryPath =
|
|
16093
|
-
if (
|
|
16319
|
+
const binaryPath = join15(cliDir, "bin", binaryName);
|
|
16320
|
+
if (existsSync13(binaryPath)) {
|
|
16094
16321
|
debugLog2("found binary in main package:", binaryPath);
|
|
16095
16322
|
return binaryPath;
|
|
16096
16323
|
}
|
|
@@ -16111,7 +16338,7 @@ async function getCommentCheckerPath() {
|
|
|
16111
16338
|
}
|
|
16112
16339
|
initPromise = (async () => {
|
|
16113
16340
|
const syncPath = findCommentCheckerPathSync();
|
|
16114
|
-
if (syncPath &&
|
|
16341
|
+
if (syncPath && existsSync13(syncPath)) {
|
|
16115
16342
|
resolvedCliPath = syncPath;
|
|
16116
16343
|
debugLog2("using sync-resolved path:", syncPath);
|
|
16117
16344
|
return syncPath;
|
|
@@ -16147,7 +16374,7 @@ async function runCommentChecker(input, cliPath, customPrompt) {
|
|
|
16147
16374
|
debugLog2("comment-checker binary not found");
|
|
16148
16375
|
return { hasComments: false, message: "" };
|
|
16149
16376
|
}
|
|
16150
|
-
if (!
|
|
16377
|
+
if (!existsSync13(binaryPath)) {
|
|
16151
16378
|
debugLog2("comment-checker binary does not exist:", binaryPath);
|
|
16152
16379
|
return { hasComments: false, message: "" };
|
|
16153
16380
|
}
|
|
@@ -16185,11 +16412,11 @@ async function runCommentChecker(input, cliPath, customPrompt) {
|
|
|
16185
16412
|
|
|
16186
16413
|
// src/hooks/comment-checker/index.ts
|
|
16187
16414
|
import * as fs6 from "fs";
|
|
16188
|
-
import { existsSync as
|
|
16189
|
-
import { tmpdir as
|
|
16190
|
-
import { join as
|
|
16415
|
+
import { existsSync as existsSync14 } from "fs";
|
|
16416
|
+
import { tmpdir as tmpdir5 } from "os";
|
|
16417
|
+
import { join as join16 } from "path";
|
|
16191
16418
|
var DEBUG3 = process.env.COMMENT_CHECKER_DEBUG === "1";
|
|
16192
|
-
var DEBUG_FILE3 =
|
|
16419
|
+
var DEBUG_FILE3 = join16(tmpdir5(), "comment-checker-debug.log");
|
|
16193
16420
|
function debugLog3(...args) {
|
|
16194
16421
|
if (DEBUG3) {
|
|
16195
16422
|
const msg = `[${new Date().toISOString()}] [comment-checker:hook] ${args.map((a) => typeof a === "object" ? JSON.stringify(a, null, 2) : String(a)).join(" ")}
|
|
@@ -16269,7 +16496,7 @@ function createCommentCheckerHooks(config) {
|
|
|
16269
16496
|
}
|
|
16270
16497
|
try {
|
|
16271
16498
|
const cliPath = await cliPathPromise;
|
|
16272
|
-
if (!cliPath || !
|
|
16499
|
+
if (!cliPath || !existsSync14(cliPath)) {
|
|
16273
16500
|
debugLog3("CLI not available, skipping comment check");
|
|
16274
16501
|
return;
|
|
16275
16502
|
}
|
|
@@ -16349,36 +16576,36 @@ function createToolOutputTruncatorHook(ctx, options) {
|
|
|
16349
16576
|
};
|
|
16350
16577
|
}
|
|
16351
16578
|
// src/hooks/directory-agents-injector/index.ts
|
|
16352
|
-
import { existsSync as
|
|
16353
|
-
import { dirname as dirname2, join as
|
|
16579
|
+
import { existsSync as existsSync16, readFileSync as readFileSync9 } from "fs";
|
|
16580
|
+
import { dirname as dirname2, join as join19, resolve as resolve3 } from "path";
|
|
16354
16581
|
|
|
16355
16582
|
// src/hooks/directory-agents-injector/storage.ts
|
|
16356
16583
|
import {
|
|
16357
|
-
existsSync as
|
|
16358
|
-
mkdirSync as
|
|
16359
|
-
readFileSync as
|
|
16360
|
-
writeFileSync as
|
|
16584
|
+
existsSync as existsSync15,
|
|
16585
|
+
mkdirSync as mkdirSync5,
|
|
16586
|
+
readFileSync as readFileSync8,
|
|
16587
|
+
writeFileSync as writeFileSync5,
|
|
16361
16588
|
unlinkSync as unlinkSync3
|
|
16362
16589
|
} from "fs";
|
|
16363
|
-
import { join as
|
|
16590
|
+
import { join as join18 } from "path";
|
|
16364
16591
|
|
|
16365
16592
|
// src/hooks/directory-agents-injector/constants.ts
|
|
16366
16593
|
init_data_path();
|
|
16367
|
-
import { join as
|
|
16594
|
+
import { join as join17 } from "path";
|
|
16368
16595
|
var OPENCODE_STORAGE3 = getOpenCodeStorageDir();
|
|
16369
|
-
var AGENTS_INJECTOR_STORAGE =
|
|
16596
|
+
var AGENTS_INJECTOR_STORAGE = join17(OPENCODE_STORAGE3, "directory-agents");
|
|
16370
16597
|
var AGENTS_FILENAME = "AGENTS.md";
|
|
16371
16598
|
|
|
16372
16599
|
// src/hooks/directory-agents-injector/storage.ts
|
|
16373
16600
|
function getStoragePath(sessionID) {
|
|
16374
|
-
return
|
|
16601
|
+
return join18(AGENTS_INJECTOR_STORAGE, `${sessionID}.json`);
|
|
16375
16602
|
}
|
|
16376
16603
|
function loadInjectedPaths(sessionID) {
|
|
16377
16604
|
const filePath = getStoragePath(sessionID);
|
|
16378
|
-
if (!
|
|
16605
|
+
if (!existsSync15(filePath))
|
|
16379
16606
|
return new Set;
|
|
16380
16607
|
try {
|
|
16381
|
-
const content =
|
|
16608
|
+
const content = readFileSync8(filePath, "utf-8");
|
|
16382
16609
|
const data = JSON.parse(content);
|
|
16383
16610
|
return new Set(data.injectedPaths);
|
|
16384
16611
|
} catch {
|
|
@@ -16386,19 +16613,19 @@ function loadInjectedPaths(sessionID) {
|
|
|
16386
16613
|
}
|
|
16387
16614
|
}
|
|
16388
16615
|
function saveInjectedPaths(sessionID, paths) {
|
|
16389
|
-
if (!
|
|
16390
|
-
|
|
16616
|
+
if (!existsSync15(AGENTS_INJECTOR_STORAGE)) {
|
|
16617
|
+
mkdirSync5(AGENTS_INJECTOR_STORAGE, { recursive: true });
|
|
16391
16618
|
}
|
|
16392
16619
|
const data = {
|
|
16393
16620
|
sessionID,
|
|
16394
16621
|
injectedPaths: [...paths],
|
|
16395
16622
|
updatedAt: Date.now()
|
|
16396
16623
|
};
|
|
16397
|
-
|
|
16624
|
+
writeFileSync5(getStoragePath(sessionID), JSON.stringify(data, null, 2));
|
|
16398
16625
|
}
|
|
16399
16626
|
function clearInjectedPaths(sessionID) {
|
|
16400
16627
|
const filePath = getStoragePath(sessionID);
|
|
16401
|
-
if (
|
|
16628
|
+
if (existsSync15(filePath)) {
|
|
16402
16629
|
unlinkSync3(filePath);
|
|
16403
16630
|
}
|
|
16404
16631
|
}
|
|
@@ -16428,8 +16655,8 @@ function createDirectoryAgentsInjectorHook(ctx) {
|
|
|
16428
16655
|
while (true) {
|
|
16429
16656
|
const isRootDir = current === ctx.directory;
|
|
16430
16657
|
if (!isRootDir) {
|
|
16431
|
-
const agentsPath =
|
|
16432
|
-
if (
|
|
16658
|
+
const agentsPath = join19(current, AGENTS_FILENAME);
|
|
16659
|
+
if (existsSync16(agentsPath)) {
|
|
16433
16660
|
found.push(agentsPath);
|
|
16434
16661
|
}
|
|
16435
16662
|
}
|
|
@@ -16456,7 +16683,7 @@ function createDirectoryAgentsInjectorHook(ctx) {
|
|
|
16456
16683
|
if (cache.has(agentsDir))
|
|
16457
16684
|
continue;
|
|
16458
16685
|
try {
|
|
16459
|
-
const content =
|
|
16686
|
+
const content = readFileSync9(agentsPath, "utf-8");
|
|
16460
16687
|
const { result, truncated } = await truncator.truncate(sessionID, content);
|
|
16461
16688
|
const truncationNotice = truncated ? `
|
|
16462
16689
|
|
|
@@ -16526,36 +16753,36 @@ ${result}${truncationNotice}`;
|
|
|
16526
16753
|
};
|
|
16527
16754
|
}
|
|
16528
16755
|
// src/hooks/directory-readme-injector/index.ts
|
|
16529
|
-
import { existsSync as
|
|
16530
|
-
import { dirname as dirname3, join as
|
|
16756
|
+
import { existsSync as existsSync18, readFileSync as readFileSync11 } from "fs";
|
|
16757
|
+
import { dirname as dirname3, join as join22, resolve as resolve4 } from "path";
|
|
16531
16758
|
|
|
16532
16759
|
// src/hooks/directory-readme-injector/storage.ts
|
|
16533
16760
|
import {
|
|
16534
|
-
existsSync as
|
|
16535
|
-
mkdirSync as
|
|
16536
|
-
readFileSync as
|
|
16537
|
-
writeFileSync as
|
|
16761
|
+
existsSync as existsSync17,
|
|
16762
|
+
mkdirSync as mkdirSync6,
|
|
16763
|
+
readFileSync as readFileSync10,
|
|
16764
|
+
writeFileSync as writeFileSync6,
|
|
16538
16765
|
unlinkSync as unlinkSync4
|
|
16539
16766
|
} from "fs";
|
|
16540
|
-
import { join as
|
|
16767
|
+
import { join as join21 } from "path";
|
|
16541
16768
|
|
|
16542
16769
|
// src/hooks/directory-readme-injector/constants.ts
|
|
16543
16770
|
init_data_path();
|
|
16544
|
-
import { join as
|
|
16771
|
+
import { join as join20 } from "path";
|
|
16545
16772
|
var OPENCODE_STORAGE4 = getOpenCodeStorageDir();
|
|
16546
|
-
var README_INJECTOR_STORAGE =
|
|
16773
|
+
var README_INJECTOR_STORAGE = join20(OPENCODE_STORAGE4, "directory-readme");
|
|
16547
16774
|
var README_FILENAME = "README.md";
|
|
16548
16775
|
|
|
16549
16776
|
// src/hooks/directory-readme-injector/storage.ts
|
|
16550
16777
|
function getStoragePath2(sessionID) {
|
|
16551
|
-
return
|
|
16778
|
+
return join21(README_INJECTOR_STORAGE, `${sessionID}.json`);
|
|
16552
16779
|
}
|
|
16553
16780
|
function loadInjectedPaths2(sessionID) {
|
|
16554
16781
|
const filePath = getStoragePath2(sessionID);
|
|
16555
|
-
if (!
|
|
16782
|
+
if (!existsSync17(filePath))
|
|
16556
16783
|
return new Set;
|
|
16557
16784
|
try {
|
|
16558
|
-
const content =
|
|
16785
|
+
const content = readFileSync10(filePath, "utf-8");
|
|
16559
16786
|
const data = JSON.parse(content);
|
|
16560
16787
|
return new Set(data.injectedPaths);
|
|
16561
16788
|
} catch {
|
|
@@ -16563,19 +16790,19 @@ function loadInjectedPaths2(sessionID) {
|
|
|
16563
16790
|
}
|
|
16564
16791
|
}
|
|
16565
16792
|
function saveInjectedPaths2(sessionID, paths) {
|
|
16566
|
-
if (!
|
|
16567
|
-
|
|
16793
|
+
if (!existsSync17(README_INJECTOR_STORAGE)) {
|
|
16794
|
+
mkdirSync6(README_INJECTOR_STORAGE, { recursive: true });
|
|
16568
16795
|
}
|
|
16569
16796
|
const data = {
|
|
16570
16797
|
sessionID,
|
|
16571
16798
|
injectedPaths: [...paths],
|
|
16572
16799
|
updatedAt: Date.now()
|
|
16573
16800
|
};
|
|
16574
|
-
|
|
16801
|
+
writeFileSync6(getStoragePath2(sessionID), JSON.stringify(data, null, 2));
|
|
16575
16802
|
}
|
|
16576
16803
|
function clearInjectedPaths2(sessionID) {
|
|
16577
16804
|
const filePath = getStoragePath2(sessionID);
|
|
16578
|
-
if (
|
|
16805
|
+
if (existsSync17(filePath)) {
|
|
16579
16806
|
unlinkSync4(filePath);
|
|
16580
16807
|
}
|
|
16581
16808
|
}
|
|
@@ -16603,8 +16830,8 @@ function createDirectoryReadmeInjectorHook(ctx) {
|
|
|
16603
16830
|
const found = [];
|
|
16604
16831
|
let current = startDir;
|
|
16605
16832
|
while (true) {
|
|
16606
|
-
const readmePath =
|
|
16607
|
-
if (
|
|
16833
|
+
const readmePath = join22(current, README_FILENAME);
|
|
16834
|
+
if (existsSync18(readmePath)) {
|
|
16608
16835
|
found.push(readmePath);
|
|
16609
16836
|
}
|
|
16610
16837
|
if (current === ctx.directory)
|
|
@@ -16630,7 +16857,7 @@ function createDirectoryReadmeInjectorHook(ctx) {
|
|
|
16630
16857
|
if (cache.has(readmeDir))
|
|
16631
16858
|
continue;
|
|
16632
16859
|
try {
|
|
16633
|
-
const content =
|
|
16860
|
+
const content = readFileSync11(readmePath, "utf-8");
|
|
16634
16861
|
const { result, truncated } = await truncator.truncate(sessionID, content);
|
|
16635
16862
|
const truncationNotice = truncated ? `
|
|
16636
16863
|
|
|
@@ -16914,22 +17141,22 @@ var TRUNCATE_CONFIG = {
|
|
|
16914
17141
|
|
|
16915
17142
|
// src/hooks/anthropic-context-window-limit-recovery/storage.ts
|
|
16916
17143
|
init_data_path();
|
|
16917
|
-
import { existsSync as
|
|
16918
|
-
import { join as
|
|
17144
|
+
import { existsSync as existsSync19, readdirSync as readdirSync5, readFileSync as readFileSync12, writeFileSync as writeFileSync7 } from "fs";
|
|
17145
|
+
import { join as join23 } from "path";
|
|
16919
17146
|
var OPENCODE_STORAGE5 = getOpenCodeStorageDir();
|
|
16920
|
-
var MESSAGE_STORAGE3 =
|
|
16921
|
-
var PART_STORAGE3 =
|
|
17147
|
+
var MESSAGE_STORAGE3 = join23(OPENCODE_STORAGE5, "message");
|
|
17148
|
+
var PART_STORAGE3 = join23(OPENCODE_STORAGE5, "part");
|
|
16922
17149
|
var TRUNCATION_MESSAGE = "[TOOL RESULT TRUNCATED - Context limit exceeded. Original output was too large and has been truncated to recover the session. Please re-run this tool if you need the full output.]";
|
|
16923
17150
|
function getMessageDir3(sessionID) {
|
|
16924
|
-
if (!
|
|
17151
|
+
if (!existsSync19(MESSAGE_STORAGE3))
|
|
16925
17152
|
return "";
|
|
16926
|
-
const directPath =
|
|
16927
|
-
if (
|
|
17153
|
+
const directPath = join23(MESSAGE_STORAGE3, sessionID);
|
|
17154
|
+
if (existsSync19(directPath)) {
|
|
16928
17155
|
return directPath;
|
|
16929
17156
|
}
|
|
16930
|
-
for (const dir of
|
|
16931
|
-
const sessionPath =
|
|
16932
|
-
if (
|
|
17157
|
+
for (const dir of readdirSync5(MESSAGE_STORAGE3)) {
|
|
17158
|
+
const sessionPath = join23(MESSAGE_STORAGE3, dir, sessionID);
|
|
17159
|
+
if (existsSync19(sessionPath)) {
|
|
16933
17160
|
return sessionPath;
|
|
16934
17161
|
}
|
|
16935
17162
|
}
|
|
@@ -16937,10 +17164,10 @@ function getMessageDir3(sessionID) {
|
|
|
16937
17164
|
}
|
|
16938
17165
|
function getMessageIds(sessionID) {
|
|
16939
17166
|
const messageDir = getMessageDir3(sessionID);
|
|
16940
|
-
if (!messageDir || !
|
|
17167
|
+
if (!messageDir || !existsSync19(messageDir))
|
|
16941
17168
|
return [];
|
|
16942
17169
|
const messageIds = [];
|
|
16943
|
-
for (const file of
|
|
17170
|
+
for (const file of readdirSync5(messageDir)) {
|
|
16944
17171
|
if (!file.endsWith(".json"))
|
|
16945
17172
|
continue;
|
|
16946
17173
|
const messageId = file.replace(".json", "");
|
|
@@ -16952,15 +17179,15 @@ function findToolResultsBySize(sessionID) {
|
|
|
16952
17179
|
const messageIds = getMessageIds(sessionID);
|
|
16953
17180
|
const results = [];
|
|
16954
17181
|
for (const messageID of messageIds) {
|
|
16955
|
-
const partDir =
|
|
16956
|
-
if (!
|
|
17182
|
+
const partDir = join23(PART_STORAGE3, messageID);
|
|
17183
|
+
if (!existsSync19(partDir))
|
|
16957
17184
|
continue;
|
|
16958
|
-
for (const file of
|
|
17185
|
+
for (const file of readdirSync5(partDir)) {
|
|
16959
17186
|
if (!file.endsWith(".json"))
|
|
16960
17187
|
continue;
|
|
16961
17188
|
try {
|
|
16962
|
-
const partPath =
|
|
16963
|
-
const content =
|
|
17189
|
+
const partPath = join23(partDir, file);
|
|
17190
|
+
const content = readFileSync12(partPath, "utf-8");
|
|
16964
17191
|
const part = JSON.parse(content);
|
|
16965
17192
|
if (part.type === "tool" && part.state?.output && !part.truncated) {
|
|
16966
17193
|
results.push({
|
|
@@ -16980,7 +17207,7 @@ function findToolResultsBySize(sessionID) {
|
|
|
16980
17207
|
}
|
|
16981
17208
|
function truncateToolResult(partPath) {
|
|
16982
17209
|
try {
|
|
16983
|
-
const content =
|
|
17210
|
+
const content = readFileSync12(partPath, "utf-8");
|
|
16984
17211
|
const part = JSON.parse(content);
|
|
16985
17212
|
if (!part.state?.output) {
|
|
16986
17213
|
return { success: false };
|
|
@@ -16994,7 +17221,7 @@ function truncateToolResult(partPath) {
|
|
|
16994
17221
|
part.state.time = { start: Date.now() };
|
|
16995
17222
|
}
|
|
16996
17223
|
part.state.time.compacted = Date.now();
|
|
16997
|
-
|
|
17224
|
+
writeFileSync7(partPath, JSON.stringify(part, null, 2));
|
|
16998
17225
|
return { success: true, toolName, originalSize };
|
|
16999
17226
|
} catch {
|
|
17000
17227
|
return { success: false };
|
|
@@ -17494,15 +17721,29 @@ function createCompactionContextInjector() {
|
|
|
17494
17721
|
}
|
|
17495
17722
|
// src/hooks/think-mode/detector.ts
|
|
17496
17723
|
var ENGLISH_PATTERNS = [/\bultrathink\b/i, /\bthink\b/i];
|
|
17497
|
-
var
|
|
17724
|
+
var CHINESE_KEYWORDS = [
|
|
17725
|
+
"\u601D\u8003",
|
|
17726
|
+
"\u8003\u8651",
|
|
17727
|
+
"\u8003\u616E",
|
|
17728
|
+
"\u6DF1\u5165\u601D\u8003",
|
|
17729
|
+
"\u4ED4\u7EC6\u60F3\u60F3",
|
|
17730
|
+
"\u4ED4\u7EC6\u601D\u8003",
|
|
17731
|
+
"\u8BA4\u771F\u601D\u8003",
|
|
17732
|
+
"\u597D\u597D\u60F3\u60F3",
|
|
17733
|
+
"\u597D\u597D\u8003\u8651",
|
|
17734
|
+
"\u7422\u78E8",
|
|
17735
|
+
"\u5206\u6790\u4E00\u4E0B",
|
|
17736
|
+
"\u53CD\u601D",
|
|
17737
|
+
"\u63A8\u6572",
|
|
17738
|
+
"\u659F\u914C",
|
|
17739
|
+
"\u6DF1\u601D\u719F\u8651",
|
|
17740
|
+
"\u60F3\u4E00\u60F3"
|
|
17741
|
+
];
|
|
17742
|
+
var OTHER_MULTILINGUAL_KEYWORDS = [
|
|
17498
17743
|
"\uC0DD\uAC01",
|
|
17499
17744
|
"\uACE0\uBBFC",
|
|
17500
17745
|
"\uAC80\uD1A0",
|
|
17501
17746
|
"\uC81C\uB300\uB85C",
|
|
17502
|
-
"\u601D\u8003",
|
|
17503
|
-
"\u8003\u8651",
|
|
17504
|
-
"\u8003\u616E",
|
|
17505
|
-
"\u601D\u8003",
|
|
17506
17747
|
"\u8003\u3048",
|
|
17507
17748
|
"\u719F\u8003",
|
|
17508
17749
|
"\u0938\u094B\u091A",
|
|
@@ -17580,8 +17821,9 @@ var MULTILINGUAL_KEYWORDS = [
|
|
|
17580
17821
|
"fikir",
|
|
17581
17822
|
"berfikir"
|
|
17582
17823
|
];
|
|
17583
|
-
var
|
|
17584
|
-
var
|
|
17824
|
+
var CHINESE_PATTERNS = CHINESE_KEYWORDS.map((kw) => new RegExp(kw, "i"));
|
|
17825
|
+
var MULTILINGUAL_PATTERNS = OTHER_MULTILINGUAL_KEYWORDS.map((kw) => new RegExp(kw, "i"));
|
|
17826
|
+
var THINK_PATTERNS = [...ENGLISH_PATTERNS, ...CHINESE_PATTERNS, ...MULTILINGUAL_PATTERNS];
|
|
17585
17827
|
var CODE_BLOCK_PATTERN = /```[\s\S]*?```/g;
|
|
17586
17828
|
var INLINE_CODE_PATTERN = /`[^`]+`/g;
|
|
17587
17829
|
function removeCodeBlocks(text) {
|
|
@@ -17729,53 +17971,55 @@ init_shared();
|
|
|
17729
17971
|
var thinkModeState = new Map;
|
|
17730
17972
|
function createThinkModeHook() {
|
|
17731
17973
|
return {
|
|
17732
|
-
"chat.params": async (
|
|
17733
|
-
const promptText = extractPromptText(
|
|
17974
|
+
"chat.params": async (input, output) => {
|
|
17975
|
+
const promptText = extractPromptText(input.message.parts ?? []);
|
|
17734
17976
|
const state2 = {
|
|
17735
17977
|
requested: false,
|
|
17736
17978
|
modelSwitched: false,
|
|
17737
17979
|
thinkingConfigInjected: false
|
|
17738
17980
|
};
|
|
17739
17981
|
if (!detectThinkKeyword(promptText)) {
|
|
17740
|
-
thinkModeState.set(sessionID, state2);
|
|
17982
|
+
thinkModeState.set(input.sessionID, state2);
|
|
17741
17983
|
return;
|
|
17742
17984
|
}
|
|
17743
17985
|
state2.requested = true;
|
|
17744
|
-
const
|
|
17745
|
-
|
|
17746
|
-
|
|
17986
|
+
const modelID = input.model.id;
|
|
17987
|
+
const providerID = input.model.providerID;
|
|
17988
|
+
if (!modelID) {
|
|
17989
|
+
thinkModeState.set(input.sessionID, state2);
|
|
17747
17990
|
return;
|
|
17748
17991
|
}
|
|
17749
|
-
state2.providerID =
|
|
17750
|
-
state2.modelID =
|
|
17751
|
-
if (isAlreadyHighVariant(
|
|
17752
|
-
thinkModeState.set(sessionID, state2);
|
|
17992
|
+
state2.providerID = providerID;
|
|
17993
|
+
state2.modelID = modelID;
|
|
17994
|
+
if (isAlreadyHighVariant(modelID)) {
|
|
17995
|
+
thinkModeState.set(input.sessionID, state2);
|
|
17753
17996
|
return;
|
|
17754
17997
|
}
|
|
17755
|
-
const highVariant = getHighVariant(
|
|
17756
|
-
const thinkingConfig = getThinkingConfig(
|
|
17998
|
+
const highVariant = getHighVariant(modelID);
|
|
17999
|
+
const thinkingConfig = getThinkingConfig(providerID, modelID);
|
|
17757
18000
|
if (highVariant) {
|
|
17758
|
-
|
|
17759
|
-
providerID: currentModel.providerID,
|
|
17760
|
-
modelID: highVariant
|
|
17761
|
-
};
|
|
18001
|
+
input.model.id = highVariant;
|
|
17762
18002
|
state2.modelSwitched = true;
|
|
17763
18003
|
log("Think mode: model switched to high variant", {
|
|
17764
|
-
sessionID,
|
|
17765
|
-
from:
|
|
18004
|
+
sessionID: input.sessionID,
|
|
18005
|
+
from: modelID,
|
|
17766
18006
|
to: highVariant
|
|
17767
18007
|
});
|
|
17768
18008
|
}
|
|
17769
18009
|
if (thinkingConfig) {
|
|
17770
|
-
|
|
18010
|
+
const { maxTokens, ...thinkingOptions } = thinkingConfig;
|
|
18011
|
+
if (typeof maxTokens === "number") {
|
|
18012
|
+
output.maxOutputTokens = maxTokens;
|
|
18013
|
+
}
|
|
18014
|
+
Object.assign(output.options, thinkingOptions);
|
|
17771
18015
|
state2.thinkingConfigInjected = true;
|
|
17772
18016
|
log("Think mode: thinking config injected", {
|
|
17773
|
-
sessionID,
|
|
17774
|
-
provider:
|
|
18017
|
+
sessionID: input.sessionID,
|
|
18018
|
+
provider: providerID,
|
|
17775
18019
|
config: thinkingConfig
|
|
17776
18020
|
});
|
|
17777
18021
|
}
|
|
17778
|
-
thinkModeState.set(sessionID, state2);
|
|
18022
|
+
thinkModeState.set(input.sessionID, state2);
|
|
17779
18023
|
},
|
|
17780
18024
|
event: async ({ event }) => {
|
|
17781
18025
|
if (event.type === "session.deleted") {
|
|
@@ -17789,8 +18033,8 @@ function createThinkModeHook() {
|
|
|
17789
18033
|
}
|
|
17790
18034
|
// src/hooks/claude-code-hooks/config.ts
|
|
17791
18035
|
init_shared();
|
|
17792
|
-
import { join as
|
|
17793
|
-
import { existsSync as
|
|
18036
|
+
import { join as join24 } from "path";
|
|
18037
|
+
import { existsSync as existsSync20 } from "fs";
|
|
17794
18038
|
function normalizeHookMatcher(raw) {
|
|
17795
18039
|
return {
|
|
17796
18040
|
matcher: raw.matcher ?? raw.pattern ?? "*",
|
|
@@ -17816,11 +18060,11 @@ function normalizeHooksConfig(raw) {
|
|
|
17816
18060
|
function getClaudeSettingsPaths(customPath) {
|
|
17817
18061
|
const claudeConfigDir = getClaudeConfigDir();
|
|
17818
18062
|
const paths = [
|
|
17819
|
-
|
|
17820
|
-
|
|
17821
|
-
|
|
18063
|
+
join24(claudeConfigDir, "settings.json"),
|
|
18064
|
+
join24(process.cwd(), ".claude", "settings.json"),
|
|
18065
|
+
join24(process.cwd(), ".claude", "settings.local.json")
|
|
17822
18066
|
];
|
|
17823
|
-
if (customPath &&
|
|
18067
|
+
if (customPath && existsSync20(customPath)) {
|
|
17824
18068
|
paths.unshift(customPath);
|
|
17825
18069
|
}
|
|
17826
18070
|
return paths;
|
|
@@ -17845,7 +18089,7 @@ async function loadClaudeHooksConfig(customSettingsPath) {
|
|
|
17845
18089
|
const paths = getClaudeSettingsPaths(customSettingsPath);
|
|
17846
18090
|
let mergedConfig = {};
|
|
17847
18091
|
for (const settingsPath of paths) {
|
|
17848
|
-
if (
|
|
18092
|
+
if (existsSync20(settingsPath)) {
|
|
17849
18093
|
try {
|
|
17850
18094
|
const content = await Bun.file(settingsPath).text();
|
|
17851
18095
|
const settings = JSON.parse(content);
|
|
@@ -17864,14 +18108,14 @@ async function loadClaudeHooksConfig(customSettingsPath) {
|
|
|
17864
18108
|
// src/hooks/claude-code-hooks/config-loader.ts
|
|
17865
18109
|
init_logger();
|
|
17866
18110
|
init_shared();
|
|
17867
|
-
import { existsSync as
|
|
17868
|
-
import { join as
|
|
17869
|
-
var USER_CONFIG_PATH =
|
|
18111
|
+
import { existsSync as existsSync21 } from "fs";
|
|
18112
|
+
import { join as join25 } from "path";
|
|
18113
|
+
var USER_CONFIG_PATH = join25(getOpenCodeConfigDir({ binary: "opencode" }), "opencode-cc-plugin.json");
|
|
17870
18114
|
function getProjectConfigPath() {
|
|
17871
|
-
return
|
|
18115
|
+
return join25(process.cwd(), ".opencode", "opencode-cc-plugin.json");
|
|
17872
18116
|
}
|
|
17873
18117
|
async function loadConfigFromPath(path4) {
|
|
17874
|
-
if (!
|
|
18118
|
+
if (!existsSync21(path4)) {
|
|
17875
18119
|
return null;
|
|
17876
18120
|
}
|
|
17877
18121
|
try {
|
|
@@ -18059,17 +18303,17 @@ init_shared();
|
|
|
18059
18303
|
// src/hooks/claude-code-hooks/transcript.ts
|
|
18060
18304
|
init_tool_name();
|
|
18061
18305
|
init_shared();
|
|
18062
|
-
import { join as
|
|
18063
|
-
import { mkdirSync as
|
|
18064
|
-
import { tmpdir as
|
|
18306
|
+
import { join as join26 } from "path";
|
|
18307
|
+
import { mkdirSync as mkdirSync7, appendFileSync as appendFileSync6, existsSync as existsSync22, writeFileSync as writeFileSync8, unlinkSync as unlinkSync5 } from "fs";
|
|
18308
|
+
import { tmpdir as tmpdir6 } from "os";
|
|
18065
18309
|
import { randomUUID } from "crypto";
|
|
18066
|
-
var TRANSCRIPT_DIR =
|
|
18310
|
+
var TRANSCRIPT_DIR = join26(getClaudeConfigDir(), "transcripts");
|
|
18067
18311
|
function getTranscriptPath(sessionId) {
|
|
18068
|
-
return
|
|
18312
|
+
return join26(TRANSCRIPT_DIR, `${sessionId}.jsonl`);
|
|
18069
18313
|
}
|
|
18070
18314
|
function ensureTranscriptDir() {
|
|
18071
|
-
if (!
|
|
18072
|
-
|
|
18315
|
+
if (!existsSync22(TRANSCRIPT_DIR)) {
|
|
18316
|
+
mkdirSync7(TRANSCRIPT_DIR, { recursive: true });
|
|
18073
18317
|
}
|
|
18074
18318
|
}
|
|
18075
18319
|
function appendTranscriptEntry(sessionId, entry) {
|
|
@@ -18077,7 +18321,7 @@ function appendTranscriptEntry(sessionId, entry) {
|
|
|
18077
18321
|
const path4 = getTranscriptPath(sessionId);
|
|
18078
18322
|
const line = JSON.stringify(entry) + `
|
|
18079
18323
|
`;
|
|
18080
|
-
|
|
18324
|
+
appendFileSync6(path4, line);
|
|
18081
18325
|
}
|
|
18082
18326
|
function recordToolUse(sessionId, toolName, toolInput) {
|
|
18083
18327
|
appendTranscriptEntry(sessionId, {
|
|
@@ -18155,8 +18399,8 @@ async function buildTranscriptFromSession(client, sessionId, directory, currentT
|
|
|
18155
18399
|
}
|
|
18156
18400
|
};
|
|
18157
18401
|
entries.push(JSON.stringify(currentEntry));
|
|
18158
|
-
const tempPath =
|
|
18159
|
-
|
|
18402
|
+
const tempPath = join26(tmpdir6(), `opencode-transcript-${sessionId}-${randomUUID()}.jsonl`);
|
|
18403
|
+
writeFileSync8(tempPath, entries.join(`
|
|
18160
18404
|
`) + `
|
|
18161
18405
|
`);
|
|
18162
18406
|
return tempPath;
|
|
@@ -18175,8 +18419,8 @@ async function buildTranscriptFromSession(client, sessionId, directory, currentT
|
|
|
18175
18419
|
]
|
|
18176
18420
|
}
|
|
18177
18421
|
};
|
|
18178
|
-
const tempPath =
|
|
18179
|
-
|
|
18422
|
+
const tempPath = join26(tmpdir6(), `opencode-transcript-${sessionId}-${randomUUID()}.jsonl`);
|
|
18423
|
+
writeFileSync8(tempPath, JSON.stringify(currentEntry) + `
|
|
18180
18424
|
`);
|
|
18181
18425
|
return tempPath;
|
|
18182
18426
|
} catch {
|
|
@@ -18391,11 +18635,11 @@ ${USER_PROMPT_SUBMIT_TAG_CLOSE}`);
|
|
|
18391
18635
|
init_shared();
|
|
18392
18636
|
|
|
18393
18637
|
// src/hooks/claude-code-hooks/todo.ts
|
|
18394
|
-
import { join as
|
|
18638
|
+
import { join as join27 } from "path";
|
|
18395
18639
|
init_shared();
|
|
18396
|
-
var TODO_DIR =
|
|
18640
|
+
var TODO_DIR = join27(getClaudeConfigDir(), "todos");
|
|
18397
18641
|
function getTodoPath(sessionId) {
|
|
18398
|
-
return
|
|
18642
|
+
return join27(TODO_DIR, `${sessionId}-agent-${sessionId}.json`);
|
|
18399
18643
|
}
|
|
18400
18644
|
|
|
18401
18645
|
// src/hooks/claude-code-hooks/stop.ts
|
|
@@ -18837,24 +19081,24 @@ ${result.message}`;
|
|
|
18837
19081
|
};
|
|
18838
19082
|
}
|
|
18839
19083
|
// src/hooks/rules-injector/index.ts
|
|
18840
|
-
import { readFileSync as
|
|
19084
|
+
import { readFileSync as readFileSync14 } from "fs";
|
|
18841
19085
|
import { homedir as homedir8 } from "os";
|
|
18842
|
-
import { relative as
|
|
19086
|
+
import { relative as relative4, resolve as resolve5 } from "path";
|
|
18843
19087
|
|
|
18844
19088
|
// src/hooks/rules-injector/finder.ts
|
|
18845
19089
|
import {
|
|
18846
|
-
existsSync as
|
|
18847
|
-
readdirSync as
|
|
19090
|
+
existsSync as existsSync23,
|
|
19091
|
+
readdirSync as readdirSync6,
|
|
18848
19092
|
realpathSync,
|
|
18849
19093
|
statSync as statSync2
|
|
18850
19094
|
} from "fs";
|
|
18851
|
-
import { dirname as dirname4, join as
|
|
19095
|
+
import { dirname as dirname4, join as join29, relative as relative2 } from "path";
|
|
18852
19096
|
|
|
18853
19097
|
// src/hooks/rules-injector/constants.ts
|
|
18854
19098
|
init_data_path();
|
|
18855
|
-
import { join as
|
|
19099
|
+
import { join as join28 } from "path";
|
|
18856
19100
|
var OPENCODE_STORAGE6 = getOpenCodeStorageDir();
|
|
18857
|
-
var RULES_INJECTOR_STORAGE =
|
|
19101
|
+
var RULES_INJECTOR_STORAGE = join28(OPENCODE_STORAGE6, "rules-injector");
|
|
18858
19102
|
var PROJECT_MARKERS = [
|
|
18859
19103
|
".git",
|
|
18860
19104
|
"pyproject.toml",
|
|
@@ -18895,8 +19139,8 @@ function findProjectRoot(startPath) {
|
|
|
18895
19139
|
}
|
|
18896
19140
|
while (true) {
|
|
18897
19141
|
for (const marker of PROJECT_MARKERS) {
|
|
18898
|
-
const markerPath =
|
|
18899
|
-
if (
|
|
19142
|
+
const markerPath = join29(current, marker);
|
|
19143
|
+
if (existsSync23(markerPath)) {
|
|
18900
19144
|
return current;
|
|
18901
19145
|
}
|
|
18902
19146
|
}
|
|
@@ -18908,12 +19152,12 @@ function findProjectRoot(startPath) {
|
|
|
18908
19152
|
}
|
|
18909
19153
|
}
|
|
18910
19154
|
function findRuleFilesRecursive(dir, results) {
|
|
18911
|
-
if (!
|
|
19155
|
+
if (!existsSync23(dir))
|
|
18912
19156
|
return;
|
|
18913
19157
|
try {
|
|
18914
|
-
const entries =
|
|
19158
|
+
const entries = readdirSync6(dir, { withFileTypes: true });
|
|
18915
19159
|
for (const entry of entries) {
|
|
18916
|
-
const fullPath =
|
|
19160
|
+
const fullPath = join29(dir, entry.name);
|
|
18917
19161
|
if (entry.isDirectory()) {
|
|
18918
19162
|
findRuleFilesRecursive(fullPath, results);
|
|
18919
19163
|
} else if (entry.isFile()) {
|
|
@@ -18938,7 +19182,7 @@ function findRuleFiles(projectRoot, homeDir, currentFile) {
|
|
|
18938
19182
|
let distance = 0;
|
|
18939
19183
|
while (true) {
|
|
18940
19184
|
for (const [parent, subdir] of PROJECT_RULE_SUBDIRS) {
|
|
18941
|
-
const ruleDir =
|
|
19185
|
+
const ruleDir = join29(currentDir, parent, subdir);
|
|
18942
19186
|
const files = [];
|
|
18943
19187
|
findRuleFilesRecursive(ruleDir, files);
|
|
18944
19188
|
for (const filePath of files) {
|
|
@@ -18964,8 +19208,8 @@ function findRuleFiles(projectRoot, homeDir, currentFile) {
|
|
|
18964
19208
|
}
|
|
18965
19209
|
if (projectRoot) {
|
|
18966
19210
|
for (const ruleFile of PROJECT_RULE_FILES) {
|
|
18967
|
-
const filePath =
|
|
18968
|
-
if (
|
|
19211
|
+
const filePath = join29(projectRoot, ruleFile);
|
|
19212
|
+
if (existsSync23(filePath)) {
|
|
18969
19213
|
try {
|
|
18970
19214
|
const stat = statSync2(filePath);
|
|
18971
19215
|
if (stat.isFile()) {
|
|
@@ -18985,7 +19229,7 @@ function findRuleFiles(projectRoot, homeDir, currentFile) {
|
|
|
18985
19229
|
}
|
|
18986
19230
|
}
|
|
18987
19231
|
}
|
|
18988
|
-
const userRuleDir =
|
|
19232
|
+
const userRuleDir = join29(homeDir, USER_RULE_DIR);
|
|
18989
19233
|
const userFiles = [];
|
|
18990
19234
|
findRuleFilesRecursive(userRuleDir, userFiles);
|
|
18991
19235
|
for (const filePath of userFiles) {
|
|
@@ -19012,7 +19256,7 @@ function findRuleFiles(projectRoot, homeDir, currentFile) {
|
|
|
19012
19256
|
// src/hooks/rules-injector/matcher.ts
|
|
19013
19257
|
var import_picomatch = __toESM(require_picomatch2(), 1);
|
|
19014
19258
|
import { createHash } from "crypto";
|
|
19015
|
-
import { relative as
|
|
19259
|
+
import { relative as relative3 } from "path";
|
|
19016
19260
|
function shouldApplyRule(metadata, currentFilePath, projectRoot) {
|
|
19017
19261
|
if (metadata.alwaysApply === true) {
|
|
19018
19262
|
return { applies: true, reason: "alwaysApply" };
|
|
@@ -19025,7 +19269,7 @@ function shouldApplyRule(metadata, currentFilePath, projectRoot) {
|
|
|
19025
19269
|
if (patterns.length === 0) {
|
|
19026
19270
|
return { applies: false };
|
|
19027
19271
|
}
|
|
19028
|
-
const relativePath = projectRoot ?
|
|
19272
|
+
const relativePath = projectRoot ? relative3(projectRoot, currentFilePath) : currentFilePath;
|
|
19029
19273
|
for (const pattern of patterns) {
|
|
19030
19274
|
if (import_picomatch.default.isMatch(relativePath, pattern, { dot: true, bash: true })) {
|
|
19031
19275
|
return { applies: true, reason: `glob: ${pattern}` };
|
|
@@ -19174,22 +19418,22 @@ function mergeGlobs(existing, newValue) {
|
|
|
19174
19418
|
|
|
19175
19419
|
// src/hooks/rules-injector/storage.ts
|
|
19176
19420
|
import {
|
|
19177
|
-
existsSync as
|
|
19178
|
-
mkdirSync as
|
|
19179
|
-
readFileSync as
|
|
19180
|
-
writeFileSync as
|
|
19421
|
+
existsSync as existsSync24,
|
|
19422
|
+
mkdirSync as mkdirSync8,
|
|
19423
|
+
readFileSync as readFileSync13,
|
|
19424
|
+
writeFileSync as writeFileSync9,
|
|
19181
19425
|
unlinkSync as unlinkSync6
|
|
19182
19426
|
} from "fs";
|
|
19183
|
-
import { join as
|
|
19427
|
+
import { join as join30 } from "path";
|
|
19184
19428
|
function getStoragePath3(sessionID) {
|
|
19185
|
-
return
|
|
19429
|
+
return join30(RULES_INJECTOR_STORAGE, `${sessionID}.json`);
|
|
19186
19430
|
}
|
|
19187
19431
|
function loadInjectedRules(sessionID) {
|
|
19188
19432
|
const filePath = getStoragePath3(sessionID);
|
|
19189
|
-
if (!
|
|
19433
|
+
if (!existsSync24(filePath))
|
|
19190
19434
|
return { contentHashes: new Set, realPaths: new Set };
|
|
19191
19435
|
try {
|
|
19192
|
-
const content =
|
|
19436
|
+
const content = readFileSync13(filePath, "utf-8");
|
|
19193
19437
|
const data = JSON.parse(content);
|
|
19194
19438
|
return {
|
|
19195
19439
|
contentHashes: new Set(data.injectedHashes),
|
|
@@ -19200,8 +19444,8 @@ function loadInjectedRules(sessionID) {
|
|
|
19200
19444
|
}
|
|
19201
19445
|
}
|
|
19202
19446
|
function saveInjectedRules(sessionID, data) {
|
|
19203
|
-
if (!
|
|
19204
|
-
|
|
19447
|
+
if (!existsSync24(RULES_INJECTOR_STORAGE)) {
|
|
19448
|
+
mkdirSync8(RULES_INJECTOR_STORAGE, { recursive: true });
|
|
19205
19449
|
}
|
|
19206
19450
|
const storageData = {
|
|
19207
19451
|
sessionID,
|
|
@@ -19209,11 +19453,11 @@ function saveInjectedRules(sessionID, data) {
|
|
|
19209
19453
|
injectedRealPaths: [...data.realPaths],
|
|
19210
19454
|
updatedAt: Date.now()
|
|
19211
19455
|
};
|
|
19212
|
-
|
|
19456
|
+
writeFileSync9(getStoragePath3(sessionID), JSON.stringify(storageData, null, 2));
|
|
19213
19457
|
}
|
|
19214
19458
|
function clearInjectedRules(sessionID) {
|
|
19215
19459
|
const filePath = getStoragePath3(sessionID);
|
|
19216
|
-
if (
|
|
19460
|
+
if (existsSync24(filePath)) {
|
|
19217
19461
|
unlinkSync6(filePath);
|
|
19218
19462
|
}
|
|
19219
19463
|
}
|
|
@@ -19251,7 +19495,7 @@ function createRulesInjectorHook(ctx) {
|
|
|
19251
19495
|
if (isDuplicateByRealPath(candidate.realPath, cache2.realPaths))
|
|
19252
19496
|
continue;
|
|
19253
19497
|
try {
|
|
19254
|
-
const rawContent =
|
|
19498
|
+
const rawContent = readFileSync14(candidate.path, "utf-8");
|
|
19255
19499
|
const { metadata, body } = parseRuleFrontmatter(rawContent);
|
|
19256
19500
|
let matchReason;
|
|
19257
19501
|
if (candidate.isSingleFile) {
|
|
@@ -19265,7 +19509,7 @@ function createRulesInjectorHook(ctx) {
|
|
|
19265
19509
|
const contentHash = createContentHash(body);
|
|
19266
19510
|
if (isDuplicateByContentHash(contentHash, cache2.contentHashes))
|
|
19267
19511
|
continue;
|
|
19268
|
-
const relativePath = projectRoot ?
|
|
19512
|
+
const relativePath = projectRoot ? relative4(projectRoot, candidate.path) : candidate.path;
|
|
19269
19513
|
toInject.push({
|
|
19270
19514
|
relativePath,
|
|
19271
19515
|
matchReason,
|
|
@@ -19369,19 +19613,19 @@ init_auto_update_checker();
|
|
|
19369
19613
|
|
|
19370
19614
|
// src/hooks/agent-usage-reminder/storage.ts
|
|
19371
19615
|
import {
|
|
19372
|
-
existsSync as
|
|
19373
|
-
mkdirSync as
|
|
19374
|
-
readFileSync as
|
|
19375
|
-
writeFileSync as
|
|
19616
|
+
existsSync as existsSync27,
|
|
19617
|
+
mkdirSync as mkdirSync9,
|
|
19618
|
+
readFileSync as readFileSync17,
|
|
19619
|
+
writeFileSync as writeFileSync12,
|
|
19376
19620
|
unlinkSync as unlinkSync7
|
|
19377
19621
|
} from "fs";
|
|
19378
|
-
import { join as
|
|
19622
|
+
import { join as join35 } from "path";
|
|
19379
19623
|
|
|
19380
19624
|
// src/hooks/agent-usage-reminder/constants.ts
|
|
19381
19625
|
init_data_path();
|
|
19382
|
-
import { join as
|
|
19626
|
+
import { join as join34 } from "path";
|
|
19383
19627
|
var OPENCODE_STORAGE7 = getOpenCodeStorageDir();
|
|
19384
|
-
var AGENT_USAGE_REMINDER_STORAGE =
|
|
19628
|
+
var AGENT_USAGE_REMINDER_STORAGE = join34(OPENCODE_STORAGE7, "agent-usage-reminder");
|
|
19385
19629
|
var TARGET_TOOLS = new Set([
|
|
19386
19630
|
"grep",
|
|
19387
19631
|
"safe_grep",
|
|
@@ -19427,29 +19671,29 @@ delegate_task(agent="librarian", prompt="\u67E5\u627E Z \u7684\u6587\u6863")
|
|
|
19427
19671
|
|
|
19428
19672
|
// src/hooks/agent-usage-reminder/storage.ts
|
|
19429
19673
|
function getStoragePath4(sessionID) {
|
|
19430
|
-
return
|
|
19674
|
+
return join35(AGENT_USAGE_REMINDER_STORAGE, `${sessionID}.json`);
|
|
19431
19675
|
}
|
|
19432
19676
|
function loadAgentUsageState(sessionID) {
|
|
19433
19677
|
const filePath = getStoragePath4(sessionID);
|
|
19434
|
-
if (!
|
|
19678
|
+
if (!existsSync27(filePath))
|
|
19435
19679
|
return null;
|
|
19436
19680
|
try {
|
|
19437
|
-
const content =
|
|
19681
|
+
const content = readFileSync17(filePath, "utf-8");
|
|
19438
19682
|
return JSON.parse(content);
|
|
19439
19683
|
} catch {
|
|
19440
19684
|
return null;
|
|
19441
19685
|
}
|
|
19442
19686
|
}
|
|
19443
19687
|
function saveAgentUsageState(state2) {
|
|
19444
|
-
if (!
|
|
19445
|
-
|
|
19688
|
+
if (!existsSync27(AGENT_USAGE_REMINDER_STORAGE)) {
|
|
19689
|
+
mkdirSync9(AGENT_USAGE_REMINDER_STORAGE, { recursive: true });
|
|
19446
19690
|
}
|
|
19447
19691
|
const filePath = getStoragePath4(state2.sessionID);
|
|
19448
|
-
|
|
19692
|
+
writeFileSync12(filePath, JSON.stringify(state2, null, 2));
|
|
19449
19693
|
}
|
|
19450
19694
|
function clearAgentUsageState(sessionID) {
|
|
19451
19695
|
const filePath = getStoragePath4(sessionID);
|
|
19452
|
-
if (
|
|
19696
|
+
if (existsSync27(filePath)) {
|
|
19453
19697
|
unlinkSync7(filePath);
|
|
19454
19698
|
}
|
|
19455
19699
|
}
|
|
@@ -20032,19 +20276,19 @@ function createNonInteractiveEnvHook(_ctx) {
|
|
|
20032
20276
|
}
|
|
20033
20277
|
// src/hooks/interactive-bash-session/storage.ts
|
|
20034
20278
|
import {
|
|
20035
|
-
existsSync as
|
|
20036
|
-
mkdirSync as
|
|
20037
|
-
readFileSync as
|
|
20038
|
-
writeFileSync as
|
|
20279
|
+
existsSync as existsSync28,
|
|
20280
|
+
mkdirSync as mkdirSync10,
|
|
20281
|
+
readFileSync as readFileSync18,
|
|
20282
|
+
writeFileSync as writeFileSync13,
|
|
20039
20283
|
unlinkSync as unlinkSync8
|
|
20040
20284
|
} from "fs";
|
|
20041
|
-
import { join as
|
|
20285
|
+
import { join as join37 } from "path";
|
|
20042
20286
|
|
|
20043
20287
|
// src/hooks/interactive-bash-session/constants.ts
|
|
20044
20288
|
init_data_path();
|
|
20045
|
-
import { join as
|
|
20289
|
+
import { join as join36 } from "path";
|
|
20046
20290
|
var OPENCODE_STORAGE8 = getOpenCodeStorageDir();
|
|
20047
|
-
var INTERACTIVE_BASH_SESSION_STORAGE =
|
|
20291
|
+
var INTERACTIVE_BASH_SESSION_STORAGE = join36(OPENCODE_STORAGE8, "interactive-bash-session");
|
|
20048
20292
|
var OMO_SESSION_PREFIX = "omo-";
|
|
20049
20293
|
function buildSessionReminderMessage(sessions) {
|
|
20050
20294
|
if (sessions.length === 0)
|
|
@@ -20056,14 +20300,14 @@ function buildSessionReminderMessage(sessions) {
|
|
|
20056
20300
|
|
|
20057
20301
|
// src/hooks/interactive-bash-session/storage.ts
|
|
20058
20302
|
function getStoragePath5(sessionID) {
|
|
20059
|
-
return
|
|
20303
|
+
return join37(INTERACTIVE_BASH_SESSION_STORAGE, `${sessionID}.json`);
|
|
20060
20304
|
}
|
|
20061
20305
|
function loadInteractiveBashSessionState(sessionID) {
|
|
20062
20306
|
const filePath = getStoragePath5(sessionID);
|
|
20063
|
-
if (!
|
|
20307
|
+
if (!existsSync28(filePath))
|
|
20064
20308
|
return null;
|
|
20065
20309
|
try {
|
|
20066
|
-
const content =
|
|
20310
|
+
const content = readFileSync18(filePath, "utf-8");
|
|
20067
20311
|
const serialized = JSON.parse(content);
|
|
20068
20312
|
return {
|
|
20069
20313
|
sessionID: serialized.sessionID,
|
|
@@ -20075,8 +20319,8 @@ function loadInteractiveBashSessionState(sessionID) {
|
|
|
20075
20319
|
}
|
|
20076
20320
|
}
|
|
20077
20321
|
function saveInteractiveBashSessionState(state2) {
|
|
20078
|
-
if (!
|
|
20079
|
-
|
|
20322
|
+
if (!existsSync28(INTERACTIVE_BASH_SESSION_STORAGE)) {
|
|
20323
|
+
mkdirSync10(INTERACTIVE_BASH_SESSION_STORAGE, { recursive: true });
|
|
20080
20324
|
}
|
|
20081
20325
|
const filePath = getStoragePath5(state2.sessionID);
|
|
20082
20326
|
const serialized = {
|
|
@@ -20084,11 +20328,11 @@ function saveInteractiveBashSessionState(state2) {
|
|
|
20084
20328
|
tmuxSessions: Array.from(state2.tmuxSessions),
|
|
20085
20329
|
updatedAt: state2.updatedAt
|
|
20086
20330
|
};
|
|
20087
|
-
|
|
20331
|
+
writeFileSync13(filePath, JSON.stringify(serialized, null, 2));
|
|
20088
20332
|
}
|
|
20089
20333
|
function clearInteractiveBashSessionState(sessionID) {
|
|
20090
20334
|
const filePath = getStoragePath5(sessionID);
|
|
20091
|
-
if (
|
|
20335
|
+
if (existsSync28(filePath)) {
|
|
20092
20336
|
unlinkSync8(filePath);
|
|
20093
20337
|
}
|
|
20094
20338
|
}
|
|
@@ -20342,7 +20586,7 @@ function createThinkingBlockValidatorHook() {
|
|
|
20342
20586
|
continue;
|
|
20343
20587
|
if (hasContentParts(msg.parts) && !startsWithThinkingBlock(msg.parts)) {
|
|
20344
20588
|
const previousThinking = findPreviousThinkingContent(messages, i2);
|
|
20345
|
-
const thinkingContent = previousThinking || "[
|
|
20589
|
+
const thinkingContent = previousThinking || "[\u63A5\u7EED\u4E4B\u524D\u7684\u63A8\u7406]";
|
|
20346
20590
|
prependThinkingBlock(msg, thinkingContent);
|
|
20347
20591
|
}
|
|
20348
20592
|
}
|
|
@@ -20352,13 +20596,13 @@ function createThinkingBlockValidatorHook() {
|
|
|
20352
20596
|
// src/hooks/ralph-loop/index.ts
|
|
20353
20597
|
init_logger();
|
|
20354
20598
|
init_system_directive();
|
|
20355
|
-
import { existsSync as
|
|
20356
|
-
import { join as
|
|
20599
|
+
import { existsSync as existsSync30, readFileSync as readFileSync20, readdirSync as readdirSync7 } from "fs";
|
|
20600
|
+
import { join as join39 } from "path";
|
|
20357
20601
|
|
|
20358
20602
|
// src/hooks/ralph-loop/storage.ts
|
|
20359
20603
|
init_frontmatter();
|
|
20360
|
-
import { existsSync as
|
|
20361
|
-
import { dirname as dirname6, join as
|
|
20604
|
+
import { existsSync as existsSync29, readFileSync as readFileSync19, writeFileSync as writeFileSync14, unlinkSync as unlinkSync9, mkdirSync as mkdirSync11 } from "fs";
|
|
20605
|
+
import { dirname as dirname6, join as join38 } from "path";
|
|
20362
20606
|
|
|
20363
20607
|
// src/hooks/ralph-loop/constants.ts
|
|
20364
20608
|
var HOOK_NAME3 = "ralph-loop";
|
|
@@ -20368,15 +20612,15 @@ var DEFAULT_COMPLETION_PROMISE = "DONE";
|
|
|
20368
20612
|
|
|
20369
20613
|
// src/hooks/ralph-loop/storage.ts
|
|
20370
20614
|
function getStateFilePath(directory, customPath) {
|
|
20371
|
-
return customPath ?
|
|
20615
|
+
return customPath ? join38(directory, customPath) : join38(directory, DEFAULT_STATE_FILE);
|
|
20372
20616
|
}
|
|
20373
20617
|
function readState(directory, customPath) {
|
|
20374
20618
|
const filePath = getStateFilePath(directory, customPath);
|
|
20375
|
-
if (!
|
|
20619
|
+
if (!existsSync29(filePath)) {
|
|
20376
20620
|
return null;
|
|
20377
20621
|
}
|
|
20378
20622
|
try {
|
|
20379
|
-
const content =
|
|
20623
|
+
const content = readFileSync19(filePath, "utf-8");
|
|
20380
20624
|
const { data, body } = parseFrontmatter(content);
|
|
20381
20625
|
const active = data.active;
|
|
20382
20626
|
const iteration = data.iteration;
|
|
@@ -20410,8 +20654,8 @@ function writeState(directory, state2, customPath) {
|
|
|
20410
20654
|
const filePath = getStateFilePath(directory, customPath);
|
|
20411
20655
|
try {
|
|
20412
20656
|
const dir = dirname6(filePath);
|
|
20413
|
-
if (!
|
|
20414
|
-
|
|
20657
|
+
if (!existsSync29(dir)) {
|
|
20658
|
+
mkdirSync11(dir, { recursive: true });
|
|
20415
20659
|
}
|
|
20416
20660
|
const sessionIdLine = state2.session_id ? `session_id: "${state2.session_id}"
|
|
20417
20661
|
` : "";
|
|
@@ -20426,7 +20670,7 @@ started_at: "${state2.started_at}"
|
|
|
20426
20670
|
${sessionIdLine}${ultraworkLine}---
|
|
20427
20671
|
${state2.prompt}
|
|
20428
20672
|
`;
|
|
20429
|
-
|
|
20673
|
+
writeFileSync14(filePath, content, "utf-8");
|
|
20430
20674
|
return true;
|
|
20431
20675
|
} catch {
|
|
20432
20676
|
return false;
|
|
@@ -20435,7 +20679,7 @@ ${state2.prompt}
|
|
|
20435
20679
|
function clearState(directory, customPath) {
|
|
20436
20680
|
const filePath = getStateFilePath(directory, customPath);
|
|
20437
20681
|
try {
|
|
20438
|
-
if (
|
|
20682
|
+
if (existsSync29(filePath)) {
|
|
20439
20683
|
unlinkSync9(filePath);
|
|
20440
20684
|
}
|
|
20441
20685
|
return true;
|
|
@@ -20456,14 +20700,14 @@ function incrementIteration(directory, customPath) {
|
|
|
20456
20700
|
|
|
20457
20701
|
// src/hooks/ralph-loop/index.ts
|
|
20458
20702
|
function getMessageDir4(sessionID) {
|
|
20459
|
-
if (!
|
|
20703
|
+
if (!existsSync30(MESSAGE_STORAGE))
|
|
20460
20704
|
return null;
|
|
20461
|
-
const directPath =
|
|
20462
|
-
if (
|
|
20705
|
+
const directPath = join39(MESSAGE_STORAGE, sessionID);
|
|
20706
|
+
if (existsSync30(directPath))
|
|
20463
20707
|
return directPath;
|
|
20464
|
-
for (const dir of
|
|
20465
|
-
const sessionPath =
|
|
20466
|
-
if (
|
|
20708
|
+
for (const dir of readdirSync7(MESSAGE_STORAGE)) {
|
|
20709
|
+
const sessionPath = join39(MESSAGE_STORAGE, dir, sessionID);
|
|
20710
|
+
if (existsSync30(sessionPath))
|
|
20467
20711
|
return sessionPath;
|
|
20468
20712
|
}
|
|
20469
20713
|
return null;
|
|
@@ -20500,9 +20744,9 @@ function createRalphLoopHook(ctx, options) {
|
|
|
20500
20744
|
if (!transcriptPath)
|
|
20501
20745
|
return false;
|
|
20502
20746
|
try {
|
|
20503
|
-
if (!
|
|
20747
|
+
if (!existsSync30(transcriptPath))
|
|
20504
20748
|
return false;
|
|
20505
|
-
const content =
|
|
20749
|
+
const content = readFileSync20(transcriptPath, "utf-8");
|
|
20506
20750
|
const pattern = new RegExp(`<promise>\\s*${escapeRegex(promise)}\\s*</promise>`, "is");
|
|
20507
20751
|
const lines = content.split(`
|
|
20508
20752
|
`).filter((l) => l.trim());
|
|
@@ -20816,8 +21060,8 @@ function extractPromptText3(parts) {
|
|
|
20816
21060
|
// src/hooks/auto-slash-command/executor.ts
|
|
20817
21061
|
init_shared();
|
|
20818
21062
|
init_file_utils();
|
|
20819
|
-
import { existsSync as
|
|
20820
|
-
import { join as
|
|
21063
|
+
import { existsSync as existsSync32, readdirSync as readdirSync8, readFileSync as readFileSync23 } from "fs";
|
|
21064
|
+
import { join as join41, basename as basename2, dirname as dirname8 } from "path";
|
|
20821
21065
|
// src/features/opencode-skill-loader/loader.ts
|
|
20822
21066
|
init_js_yaml();
|
|
20823
21067
|
init_frontmatter();
|
|
@@ -20825,7 +21069,7 @@ init_file_utils();
|
|
|
20825
21069
|
init_shared();
|
|
20826
21070
|
init_opencode_config_dir();
|
|
20827
21071
|
import { promises as fs9 } from "fs";
|
|
20828
|
-
import { join as
|
|
21072
|
+
import { join as join40, basename } from "path";
|
|
20829
21073
|
function parseSkillMcpConfigFromFrontmatter(content) {
|
|
20830
21074
|
const frontmatterMatch = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
20831
21075
|
if (!frontmatterMatch)
|
|
@@ -20841,7 +21085,7 @@ function parseSkillMcpConfigFromFrontmatter(content) {
|
|
|
20841
21085
|
return;
|
|
20842
21086
|
}
|
|
20843
21087
|
async function loadMcpJsonFromDir(skillDir) {
|
|
20844
|
-
const mcpJsonPath =
|
|
21088
|
+
const mcpJsonPath = join40(skillDir, "mcp.json");
|
|
20845
21089
|
try {
|
|
20846
21090
|
const content = await fs9.readFile(mcpJsonPath, "utf-8");
|
|
20847
21091
|
const parsed = JSON.parse(content);
|
|
@@ -20922,11 +21166,11 @@ async function loadSkillsFromDir(skillsDir, scope) {
|
|
|
20922
21166
|
for (const entry of entries) {
|
|
20923
21167
|
if (entry.name.startsWith("."))
|
|
20924
21168
|
continue;
|
|
20925
|
-
const entryPath =
|
|
21169
|
+
const entryPath = join40(skillsDir, entry.name);
|
|
20926
21170
|
if (entry.isDirectory() || entry.isSymbolicLink()) {
|
|
20927
21171
|
const resolvedPath = await resolveSymlinkAsync(entryPath);
|
|
20928
21172
|
const dirName = entry.name;
|
|
20929
|
-
const skillMdPath =
|
|
21173
|
+
const skillMdPath = join40(resolvedPath, "SKILL.md");
|
|
20930
21174
|
try {
|
|
20931
21175
|
await fs9.access(skillMdPath);
|
|
20932
21176
|
const skill = await loadSkillFromPath(skillMdPath, resolvedPath, dirName, scope);
|
|
@@ -20934,7 +21178,7 @@ async function loadSkillsFromDir(skillsDir, scope) {
|
|
|
20934
21178
|
skills.push(skill);
|
|
20935
21179
|
continue;
|
|
20936
21180
|
} catch {}
|
|
20937
|
-
const namedSkillMdPath =
|
|
21181
|
+
const namedSkillMdPath = join40(resolvedPath, `${dirName}.md`);
|
|
20938
21182
|
try {
|
|
20939
21183
|
await fs9.access(namedSkillMdPath);
|
|
20940
21184
|
const skill = await loadSkillFromPath(namedSkillMdPath, resolvedPath, dirName, scope);
|
|
@@ -20962,23 +21206,23 @@ function skillsToRecord(skills) {
|
|
|
20962
21206
|
return result;
|
|
20963
21207
|
}
|
|
20964
21208
|
async function loadUserSkills() {
|
|
20965
|
-
const userSkillsDir =
|
|
21209
|
+
const userSkillsDir = join40(getClaudeConfigDir(), "skills");
|
|
20966
21210
|
const skills = await loadSkillsFromDir(userSkillsDir, "user");
|
|
20967
21211
|
return skillsToRecord(skills);
|
|
20968
21212
|
}
|
|
20969
21213
|
async function loadProjectSkills() {
|
|
20970
|
-
const projectSkillsDir =
|
|
21214
|
+
const projectSkillsDir = join40(process.cwd(), ".claude", "skills");
|
|
20971
21215
|
const skills = await loadSkillsFromDir(projectSkillsDir, "project");
|
|
20972
21216
|
return skillsToRecord(skills);
|
|
20973
21217
|
}
|
|
20974
21218
|
async function loadOpencodeGlobalSkills() {
|
|
20975
21219
|
const configDir = getOpenCodeConfigDir({ binary: "opencode" });
|
|
20976
|
-
const opencodeSkillsDir =
|
|
21220
|
+
const opencodeSkillsDir = join40(configDir, "skills");
|
|
20977
21221
|
const skills = await loadSkillsFromDir(opencodeSkillsDir, "opencode");
|
|
20978
21222
|
return skillsToRecord(skills);
|
|
20979
21223
|
}
|
|
20980
21224
|
async function loadOpencodeProjectSkills() {
|
|
20981
|
-
const opencodeProjectDir =
|
|
21225
|
+
const opencodeProjectDir = join40(process.cwd(), ".opencode", "skills");
|
|
20982
21226
|
const skills = await loadSkillsFromDir(opencodeProjectDir, "opencode-project");
|
|
20983
21227
|
return skillsToRecord(skills);
|
|
20984
21228
|
}
|
|
@@ -21007,26 +21251,26 @@ async function discoverSkills(options = {}) {
|
|
|
21007
21251
|
return [...opencodeProjectSkills, ...projectSkills, ...opencodeGlobalSkills, ...userSkills];
|
|
21008
21252
|
}
|
|
21009
21253
|
async function discoverUserClaudeSkills() {
|
|
21010
|
-
const userSkillsDir =
|
|
21254
|
+
const userSkillsDir = join40(getClaudeConfigDir(), "skills");
|
|
21011
21255
|
return loadSkillsFromDir(userSkillsDir, "user");
|
|
21012
21256
|
}
|
|
21013
21257
|
async function discoverProjectClaudeSkills() {
|
|
21014
|
-
const projectSkillsDir =
|
|
21258
|
+
const projectSkillsDir = join40(process.cwd(), ".claude", "skills");
|
|
21015
21259
|
return loadSkillsFromDir(projectSkillsDir, "project");
|
|
21016
21260
|
}
|
|
21017
21261
|
async function discoverOpencodeGlobalSkills() {
|
|
21018
21262
|
const configDir = getOpenCodeConfigDir({ binary: "opencode" });
|
|
21019
|
-
const opencodeSkillsDir =
|
|
21263
|
+
const opencodeSkillsDir = join40(configDir, "skills");
|
|
21020
21264
|
return loadSkillsFromDir(opencodeSkillsDir, "opencode");
|
|
21021
21265
|
}
|
|
21022
21266
|
async function discoverOpencodeProjectSkills() {
|
|
21023
|
-
const opencodeProjectDir =
|
|
21267
|
+
const opencodeProjectDir = join40(process.cwd(), ".opencode", "skills");
|
|
21024
21268
|
return loadSkillsFromDir(opencodeProjectDir, "opencode-project");
|
|
21025
21269
|
}
|
|
21026
21270
|
// src/features/opencode-skill-loader/merger.ts
|
|
21027
21271
|
init_frontmatter();
|
|
21028
21272
|
init_deep_merge();
|
|
21029
|
-
import { readFileSync as
|
|
21273
|
+
import { readFileSync as readFileSync21, existsSync as existsSync31 } from "fs";
|
|
21030
21274
|
import { dirname as dirname7, resolve as resolve6, isAbsolute as isAbsolute2 } from "path";
|
|
21031
21275
|
import { homedir as homedir11 } from "os";
|
|
21032
21276
|
var SCOPE_PRIORITY = {
|
|
@@ -21074,9 +21318,9 @@ function resolveFilePath2(from, configDir) {
|
|
|
21074
21318
|
}
|
|
21075
21319
|
function loadSkillFromFile(filePath) {
|
|
21076
21320
|
try {
|
|
21077
|
-
if (!
|
|
21321
|
+
if (!existsSync31(filePath))
|
|
21078
21322
|
return null;
|
|
21079
|
-
const content =
|
|
21323
|
+
const content = readFileSync21(filePath, "utf-8");
|
|
21080
21324
|
const { data, body } = parseFrontmatter(content);
|
|
21081
21325
|
return { template: body, metadata: data };
|
|
21082
21326
|
} catch {
|
|
@@ -22423,7 +22667,7 @@ function createBuiltinSkills() {
|
|
|
22423
22667
|
|
|
22424
22668
|
// src/features/opencode-skill-loader/skill-content.ts
|
|
22425
22669
|
init_frontmatter();
|
|
22426
|
-
import { readFileSync as
|
|
22670
|
+
import { readFileSync as readFileSync22 } from "fs";
|
|
22427
22671
|
var cachedSkills = null;
|
|
22428
22672
|
async function getAllSkills() {
|
|
22429
22673
|
if (cachedSkills)
|
|
@@ -22456,7 +22700,7 @@ async function getAllSkills() {
|
|
|
22456
22700
|
}
|
|
22457
22701
|
async function extractSkillTemplate(skill) {
|
|
22458
22702
|
if (skill.path) {
|
|
22459
|
-
const content =
|
|
22703
|
+
const content = readFileSync22(skill.path, "utf-8");
|
|
22460
22704
|
const { body } = parseFrontmatter(content);
|
|
22461
22705
|
return body.trim();
|
|
22462
22706
|
}
|
|
@@ -22558,18 +22802,18 @@ async function resolveMultipleSkillsAsync(skillNames, options) {
|
|
|
22558
22802
|
}
|
|
22559
22803
|
// src/hooks/auto-slash-command/executor.ts
|
|
22560
22804
|
function discoverCommandsFromDir(commandsDir, scope) {
|
|
22561
|
-
if (!
|
|
22805
|
+
if (!existsSync32(commandsDir)) {
|
|
22562
22806
|
return [];
|
|
22563
22807
|
}
|
|
22564
|
-
const entries =
|
|
22808
|
+
const entries = readdirSync8(commandsDir, { withFileTypes: true });
|
|
22565
22809
|
const commands = [];
|
|
22566
22810
|
for (const entry of entries) {
|
|
22567
22811
|
if (!isMarkdownFile(entry))
|
|
22568
22812
|
continue;
|
|
22569
|
-
const commandPath =
|
|
22813
|
+
const commandPath = join41(commandsDir, entry.name);
|
|
22570
22814
|
const commandName = basename2(entry.name, ".md");
|
|
22571
22815
|
try {
|
|
22572
|
-
const content =
|
|
22816
|
+
const content = readFileSync23(commandPath, "utf-8");
|
|
22573
22817
|
const { data, body } = parseFrontmatter(content);
|
|
22574
22818
|
const isOpencodeSource = scope === "opencode" || scope === "opencode-project";
|
|
22575
22819
|
const metadata = {
|
|
@@ -22612,10 +22856,10 @@ function skillToCommandInfo(skill) {
|
|
|
22612
22856
|
}
|
|
22613
22857
|
async function discoverAllCommands(options) {
|
|
22614
22858
|
const configDir = getOpenCodeConfigDir({ binary: "opencode" });
|
|
22615
|
-
const userCommandsDir =
|
|
22616
|
-
const projectCommandsDir =
|
|
22617
|
-
const opencodeGlobalDir =
|
|
22618
|
-
const opencodeProjectDir =
|
|
22859
|
+
const userCommandsDir = join41(getClaudeConfigDir(), "commands");
|
|
22860
|
+
const projectCommandsDir = join41(process.cwd(), ".claude", "commands");
|
|
22861
|
+
const opencodeGlobalDir = join41(configDir, "command");
|
|
22862
|
+
const opencodeProjectDir = join41(process.cwd(), ".opencode", "command");
|
|
22619
22863
|
const userCommands = discoverCommandsFromDir(userCommandsDir, "user");
|
|
22620
22864
|
const opencodeGlobalCommands = discoverCommandsFromDir(opencodeGlobalDir, "opencode");
|
|
22621
22865
|
const projectCommands = discoverCommandsFromDir(projectCommandsDir, "project");
|
|
@@ -22785,8 +23029,8 @@ ${EDIT_ERROR_REMINDER}`;
|
|
|
22785
23029
|
};
|
|
22786
23030
|
}
|
|
22787
23031
|
// src/hooks/prometheus-md-only/index.ts
|
|
22788
|
-
import { existsSync as
|
|
22789
|
-
import { join as
|
|
23032
|
+
import { existsSync as existsSync33, readdirSync as readdirSync9 } from "fs";
|
|
23033
|
+
import { join as join42, resolve as resolve7, relative as relative5, isAbsolute as isAbsolute3 } from "path";
|
|
22790
23034
|
|
|
22791
23035
|
// src/hooks/prometheus-md-only/constants.ts
|
|
22792
23036
|
init_system_directive();
|
|
@@ -22891,7 +23135,7 @@ init_logger();
|
|
|
22891
23135
|
init_system_directive();
|
|
22892
23136
|
function isAllowedFile(filePath, workspaceRoot) {
|
|
22893
23137
|
const resolved = resolve7(workspaceRoot, filePath);
|
|
22894
|
-
const rel =
|
|
23138
|
+
const rel = relative5(workspaceRoot, resolved);
|
|
22895
23139
|
if (rel.startsWith("..") || isAbsolute3(rel)) {
|
|
22896
23140
|
return false;
|
|
22897
23141
|
}
|
|
@@ -22905,14 +23149,14 @@ function isAllowedFile(filePath, workspaceRoot) {
|
|
|
22905
23149
|
return true;
|
|
22906
23150
|
}
|
|
22907
23151
|
function getMessageDir5(sessionID) {
|
|
22908
|
-
if (!
|
|
23152
|
+
if (!existsSync33(MESSAGE_STORAGE))
|
|
22909
23153
|
return null;
|
|
22910
|
-
const directPath =
|
|
22911
|
-
if (
|
|
23154
|
+
const directPath = join42(MESSAGE_STORAGE, sessionID);
|
|
23155
|
+
if (existsSync33(directPath))
|
|
22912
23156
|
return directPath;
|
|
22913
|
-
for (const dir of
|
|
22914
|
-
const sessionPath =
|
|
22915
|
-
if (
|
|
23157
|
+
for (const dir of readdirSync9(MESSAGE_STORAGE)) {
|
|
23158
|
+
const sessionPath = join42(MESSAGE_STORAGE, dir, sessionID);
|
|
23159
|
+
if (existsSync33(sessionPath))
|
|
22916
23160
|
return sessionPath;
|
|
22917
23161
|
}
|
|
22918
23162
|
return null;
|
|
@@ -23026,18 +23270,18 @@ var NOTEPAD_DIR = "notepads";
|
|
|
23026
23270
|
var NOTEPAD_BASE_PATH = `${BOULDER_DIR}/${NOTEPAD_DIR}`;
|
|
23027
23271
|
var PROMETHEUS_PLANS_DIR = ".sisyphus/plans";
|
|
23028
23272
|
// src/features/boulder-state/storage.ts
|
|
23029
|
-
import { existsSync as
|
|
23030
|
-
import { dirname as dirname9, join as
|
|
23273
|
+
import { existsSync as existsSync34, readFileSync as readFileSync24, writeFileSync as writeFileSync15, mkdirSync as mkdirSync12, readdirSync as readdirSync10 } from "fs";
|
|
23274
|
+
import { dirname as dirname9, join as join43, basename as basename3 } from "path";
|
|
23031
23275
|
function getBoulderFilePath(directory) {
|
|
23032
|
-
return
|
|
23276
|
+
return join43(directory, BOULDER_DIR, BOULDER_FILE);
|
|
23033
23277
|
}
|
|
23034
23278
|
function readBoulderState(directory) {
|
|
23035
23279
|
const filePath = getBoulderFilePath(directory);
|
|
23036
|
-
if (!
|
|
23280
|
+
if (!existsSync34(filePath)) {
|
|
23037
23281
|
return null;
|
|
23038
23282
|
}
|
|
23039
23283
|
try {
|
|
23040
|
-
const content =
|
|
23284
|
+
const content = readFileSync24(filePath, "utf-8");
|
|
23041
23285
|
return JSON.parse(content);
|
|
23042
23286
|
} catch {
|
|
23043
23287
|
return null;
|
|
@@ -23047,10 +23291,10 @@ function writeBoulderState(directory, state2) {
|
|
|
23047
23291
|
const filePath = getBoulderFilePath(directory);
|
|
23048
23292
|
try {
|
|
23049
23293
|
const dir = dirname9(filePath);
|
|
23050
|
-
if (!
|
|
23051
|
-
|
|
23294
|
+
if (!existsSync34(dir)) {
|
|
23295
|
+
mkdirSync12(dir, { recursive: true });
|
|
23052
23296
|
}
|
|
23053
|
-
|
|
23297
|
+
writeFileSync15(filePath, JSON.stringify(state2, null, 2), "utf-8");
|
|
23054
23298
|
return true;
|
|
23055
23299
|
} catch {
|
|
23056
23300
|
return false;
|
|
@@ -23071,7 +23315,7 @@ function appendSessionId(directory, sessionId) {
|
|
|
23071
23315
|
function clearBoulderState(directory) {
|
|
23072
23316
|
const filePath = getBoulderFilePath(directory);
|
|
23073
23317
|
try {
|
|
23074
|
-
if (
|
|
23318
|
+
if (existsSync34(filePath)) {
|
|
23075
23319
|
const { unlinkSync: unlinkSync10 } = __require("fs");
|
|
23076
23320
|
unlinkSync10(filePath);
|
|
23077
23321
|
}
|
|
@@ -23081,13 +23325,13 @@ function clearBoulderState(directory) {
|
|
|
23081
23325
|
}
|
|
23082
23326
|
}
|
|
23083
23327
|
function findPrometheusPlans(directory) {
|
|
23084
|
-
const plansDir =
|
|
23085
|
-
if (!
|
|
23328
|
+
const plansDir = join43(directory, PROMETHEUS_PLANS_DIR);
|
|
23329
|
+
if (!existsSync34(plansDir)) {
|
|
23086
23330
|
return [];
|
|
23087
23331
|
}
|
|
23088
23332
|
try {
|
|
23089
|
-
const files =
|
|
23090
|
-
return files.filter((f) => f.endsWith(".md")).map((f) =>
|
|
23333
|
+
const files = readdirSync10(plansDir);
|
|
23334
|
+
return files.filter((f) => f.endsWith(".md")).map((f) => join43(plansDir, f)).sort((a, b) => {
|
|
23091
23335
|
const aStat = __require("fs").statSync(a);
|
|
23092
23336
|
const bStat = __require("fs").statSync(b);
|
|
23093
23337
|
return bStat.mtimeMs - aStat.mtimeMs;
|
|
@@ -23097,11 +23341,11 @@ function findPrometheusPlans(directory) {
|
|
|
23097
23341
|
}
|
|
23098
23342
|
}
|
|
23099
23343
|
function getPlanProgress(planPath) {
|
|
23100
|
-
if (!
|
|
23344
|
+
if (!existsSync34(planPath)) {
|
|
23101
23345
|
return { total: 0, completed: 0, isComplete: true };
|
|
23102
23346
|
}
|
|
23103
23347
|
try {
|
|
23104
|
-
const content =
|
|
23348
|
+
const content = readFileSync24(planPath, "utf-8");
|
|
23105
23349
|
const uncheckedMatches = content.match(/^[-*]\s*\[\s*\]/gm) || [];
|
|
23106
23350
|
const checkedMatches = content.match(/^[-*]\s*\[[xX]\]/gm) || [];
|
|
23107
23351
|
const total = uncheckedMatches.length + checkedMatches.length;
|
|
@@ -23318,8 +23562,8 @@ ${contextInfo}`;
|
|
|
23318
23562
|
}
|
|
23319
23563
|
// src/hooks/atlas/index.ts
|
|
23320
23564
|
import { execSync } from "child_process";
|
|
23321
|
-
import { existsSync as
|
|
23322
|
-
import { join as
|
|
23565
|
+
import { existsSync as existsSync35, readdirSync as readdirSync11 } from "fs";
|
|
23566
|
+
import { join as join44 } from "path";
|
|
23323
23567
|
init_logger();
|
|
23324
23568
|
init_system_directive();
|
|
23325
23569
|
var HOOK_NAME6 = "atlas";
|
|
@@ -23648,14 +23892,14 @@ function formatFileChanges(stats, notepadPath) {
|
|
|
23648
23892
|
`);
|
|
23649
23893
|
}
|
|
23650
23894
|
function getMessageDir6(sessionID) {
|
|
23651
|
-
if (!
|
|
23895
|
+
if (!existsSync35(MESSAGE_STORAGE))
|
|
23652
23896
|
return null;
|
|
23653
|
-
const directPath =
|
|
23654
|
-
if (
|
|
23897
|
+
const directPath = join44(MESSAGE_STORAGE, sessionID);
|
|
23898
|
+
if (existsSync35(directPath))
|
|
23655
23899
|
return directPath;
|
|
23656
|
-
for (const dir of
|
|
23657
|
-
const sessionPath =
|
|
23658
|
-
if (
|
|
23900
|
+
for (const dir of readdirSync11(MESSAGE_STORAGE)) {
|
|
23901
|
+
const sessionPath = join44(MESSAGE_STORAGE, dir, sessionID);
|
|
23902
|
+
if (existsSync35(sessionPath))
|
|
23659
23903
|
return sessionPath;
|
|
23660
23904
|
}
|
|
23661
23905
|
return null;
|
|
@@ -24109,6 +24353,28 @@ function createQuestionLabelTruncatorHook() {
|
|
|
24109
24353
|
}
|
|
24110
24354
|
};
|
|
24111
24355
|
}
|
|
24356
|
+
// src/hooks/perf-profiler/index.ts
|
|
24357
|
+
function createPerfProfilerHook(options) {
|
|
24358
|
+
return {
|
|
24359
|
+
event: async (input) => {
|
|
24360
|
+
if (input.event.type === "message.part.updated")
|
|
24361
|
+
return;
|
|
24362
|
+
const tracer = options.tracer;
|
|
24363
|
+
if (!tracer.isEnabled())
|
|
24364
|
+
return;
|
|
24365
|
+
const mapSizes = {};
|
|
24366
|
+
for (const [name, fn] of Object.entries(options.memoryProbes ?? {})) {
|
|
24367
|
+
try {
|
|
24368
|
+
mapSizes[name] = fn();
|
|
24369
|
+
} catch {}
|
|
24370
|
+
}
|
|
24371
|
+
tracer.snapshotMemory(input.event.type, mapSizes);
|
|
24372
|
+
},
|
|
24373
|
+
"tool.execute.before": async () => {},
|
|
24374
|
+
"tool.execute.after": async () => {},
|
|
24375
|
+
"chat.message": async () => {}
|
|
24376
|
+
};
|
|
24377
|
+
}
|
|
24112
24378
|
// src/features/context-injector/collector.ts
|
|
24113
24379
|
var PRIORITY_ORDER = {
|
|
24114
24380
|
critical: 0,
|
|
@@ -24282,8 +24548,8 @@ function createFirstMessageVariantGate() {
|
|
|
24282
24548
|
}
|
|
24283
24549
|
// src/features/claude-code-mcp-loader/loader.ts
|
|
24284
24550
|
init_shared();
|
|
24285
|
-
import { existsSync as
|
|
24286
|
-
import { join as
|
|
24551
|
+
import { existsSync as existsSync36, readFileSync as readFileSync25 } from "fs";
|
|
24552
|
+
import { join as join45 } from "path";
|
|
24287
24553
|
|
|
24288
24554
|
// src/features/claude-code-mcp-loader/env-expander.ts
|
|
24289
24555
|
function expandEnvVars(value) {
|
|
@@ -24351,15 +24617,15 @@ function transformMcpServer(name, server) {
|
|
|
24351
24617
|
init_logger();
|
|
24352
24618
|
function getMcpConfigPaths() {
|
|
24353
24619
|
const claudeConfigDir = getClaudeConfigDir();
|
|
24354
|
-
const
|
|
24620
|
+
const cwd2 = process.cwd();
|
|
24355
24621
|
return [
|
|
24356
|
-
{ path:
|
|
24357
|
-
{ path:
|
|
24358
|
-
{ path:
|
|
24622
|
+
{ path: join45(claudeConfigDir, ".mcp.json"), scope: "user" },
|
|
24623
|
+
{ path: join45(cwd2, ".mcp.json"), scope: "project" },
|
|
24624
|
+
{ path: join45(cwd2, ".claude", ".mcp.json"), scope: "local" }
|
|
24359
24625
|
];
|
|
24360
24626
|
}
|
|
24361
24627
|
async function loadMcpConfigFile(filePath) {
|
|
24362
|
-
if (!
|
|
24628
|
+
if (!existsSync36(filePath)) {
|
|
24363
24629
|
return null;
|
|
24364
24630
|
}
|
|
24365
24631
|
try {
|
|
@@ -24374,10 +24640,10 @@ function getSystemMcpServerNames() {
|
|
|
24374
24640
|
const names = new Set;
|
|
24375
24641
|
const paths = getMcpConfigPaths();
|
|
24376
24642
|
for (const { path: path7 } of paths) {
|
|
24377
|
-
if (!
|
|
24643
|
+
if (!existsSync36(path7))
|
|
24378
24644
|
continue;
|
|
24379
24645
|
try {
|
|
24380
|
-
const content =
|
|
24646
|
+
const content = readFileSync25(path7, "utf-8");
|
|
24381
24647
|
const config = JSON.parse(content);
|
|
24382
24648
|
if (!config?.mcpServers)
|
|
24383
24649
|
continue;
|
|
@@ -24820,25 +25086,25 @@ var EXT_TO_LANG = {
|
|
|
24820
25086
|
".gql": "graphql"
|
|
24821
25087
|
};
|
|
24822
25088
|
// src/tools/lsp/config.ts
|
|
24823
|
-
import { existsSync as
|
|
24824
|
-
import { join as
|
|
25089
|
+
import { existsSync as existsSync37, readFileSync as readFileSync26 } from "fs";
|
|
25090
|
+
import { join as join46 } from "path";
|
|
24825
25091
|
init_shared();
|
|
24826
25092
|
function loadJsonFile(path7) {
|
|
24827
|
-
if (!
|
|
25093
|
+
if (!existsSync37(path7))
|
|
24828
25094
|
return null;
|
|
24829
25095
|
try {
|
|
24830
|
-
return JSON.parse(
|
|
25096
|
+
return JSON.parse(readFileSync26(path7, "utf-8"));
|
|
24831
25097
|
} catch {
|
|
24832
25098
|
return null;
|
|
24833
25099
|
}
|
|
24834
25100
|
}
|
|
24835
25101
|
function getConfigPaths3() {
|
|
24836
|
-
const
|
|
25102
|
+
const cwd2 = process.cwd();
|
|
24837
25103
|
const configDir = getOpenCodeConfigDir({ binary: "opencode" });
|
|
24838
25104
|
return {
|
|
24839
|
-
project:
|
|
24840
|
-
user:
|
|
24841
|
-
opencode:
|
|
25105
|
+
project: join46(cwd2, ".opencode", "oh-my-opencode.json"),
|
|
25106
|
+
user: join46(configDir, "oh-my-opencode.json"),
|
|
25107
|
+
opencode: join46(configDir, "opencode.json")
|
|
24842
25108
|
};
|
|
24843
25109
|
}
|
|
24844
25110
|
function loadAllConfigs() {
|
|
@@ -24951,7 +25217,7 @@ function isServerInstalled(command) {
|
|
|
24951
25217
|
return false;
|
|
24952
25218
|
const cmd = command[0];
|
|
24953
25219
|
if (cmd.includes("/") || cmd.includes("\\")) {
|
|
24954
|
-
if (
|
|
25220
|
+
if (existsSync37(cmd))
|
|
24955
25221
|
return true;
|
|
24956
25222
|
}
|
|
24957
25223
|
const isWindows2 = process.platform === "win32";
|
|
@@ -24973,23 +25239,23 @@ function isServerInstalled(command) {
|
|
|
24973
25239
|
const paths = pathEnv.split(pathSeparator);
|
|
24974
25240
|
for (const p of paths) {
|
|
24975
25241
|
for (const suffix of exts) {
|
|
24976
|
-
if (
|
|
25242
|
+
if (existsSync37(join46(p, cmd + suffix))) {
|
|
24977
25243
|
return true;
|
|
24978
25244
|
}
|
|
24979
25245
|
}
|
|
24980
25246
|
}
|
|
24981
|
-
const
|
|
25247
|
+
const cwd2 = process.cwd();
|
|
24982
25248
|
const configDir = getOpenCodeConfigDir({ binary: "opencode" });
|
|
24983
|
-
const dataDir =
|
|
25249
|
+
const dataDir = join46(getDataDir(), "opencode");
|
|
24984
25250
|
const additionalBases = [
|
|
24985
|
-
|
|
24986
|
-
|
|
24987
|
-
|
|
24988
|
-
|
|
25251
|
+
join46(cwd2, "node_modules", ".bin"),
|
|
25252
|
+
join46(configDir, "bin"),
|
|
25253
|
+
join46(configDir, "node_modules", ".bin"),
|
|
25254
|
+
join46(dataDir, "bin")
|
|
24989
25255
|
];
|
|
24990
25256
|
for (const base of additionalBases) {
|
|
24991
25257
|
for (const suffix of exts) {
|
|
24992
|
-
if (
|
|
25258
|
+
if (existsSync37(join46(base, cmd + suffix))) {
|
|
24993
25259
|
return true;
|
|
24994
25260
|
}
|
|
24995
25261
|
}
|
|
@@ -25001,7 +25267,7 @@ function isServerInstalled(command) {
|
|
|
25001
25267
|
}
|
|
25002
25268
|
// src/tools/lsp/client.ts
|
|
25003
25269
|
var {spawn: spawn6 } = globalThis.Bun;
|
|
25004
|
-
import { readFileSync as
|
|
25270
|
+
import { readFileSync as readFileSync27 } from "fs";
|
|
25005
25271
|
import { extname, resolve as resolve8 } from "path";
|
|
25006
25272
|
import { pathToFileURL } from "url";
|
|
25007
25273
|
class LSPServerManager {
|
|
@@ -25451,7 +25717,7 @@ ${msg}`);
|
|
|
25451
25717
|
const absPath = resolve8(filePath);
|
|
25452
25718
|
if (this.openedFiles.has(absPath))
|
|
25453
25719
|
return;
|
|
25454
|
-
const text =
|
|
25720
|
+
const text = readFileSync27(absPath, "utf-8");
|
|
25455
25721
|
const ext = extname(absPath);
|
|
25456
25722
|
const languageId = getLanguageId(ext);
|
|
25457
25723
|
this.notify("textDocument/didOpen", {
|
|
@@ -25541,17 +25807,17 @@ ${msg}`);
|
|
|
25541
25807
|
// src/tools/lsp/utils.ts
|
|
25542
25808
|
import { extname as extname2, resolve as resolve9 } from "path";
|
|
25543
25809
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
25544
|
-
import { existsSync as
|
|
25810
|
+
import { existsSync as existsSync38, readFileSync as readFileSync28, writeFileSync as writeFileSync16 } from "fs";
|
|
25545
25811
|
function findWorkspaceRoot(filePath) {
|
|
25546
25812
|
let dir = resolve9(filePath);
|
|
25547
|
-
if (!
|
|
25813
|
+
if (!existsSync38(dir) || !__require("fs").statSync(dir).isDirectory()) {
|
|
25548
25814
|
dir = __require("path").dirname(dir);
|
|
25549
25815
|
}
|
|
25550
25816
|
const markers = [".git", "package.json", "pyproject.toml", "Cargo.toml", "go.mod", "pom.xml", "build.gradle"];
|
|
25551
25817
|
let prevDir = "";
|
|
25552
25818
|
while (dir !== prevDir) {
|
|
25553
25819
|
for (const marker of markers) {
|
|
25554
|
-
if (
|
|
25820
|
+
if (existsSync38(__require("path").join(dir, marker))) {
|
|
25555
25821
|
return dir;
|
|
25556
25822
|
}
|
|
25557
25823
|
}
|
|
@@ -25706,7 +25972,7 @@ function formatPrepareRenameResult(result) {
|
|
|
25706
25972
|
}
|
|
25707
25973
|
function applyTextEditsToFile(filePath, edits) {
|
|
25708
25974
|
try {
|
|
25709
|
-
let content =
|
|
25975
|
+
let content = readFileSync28(filePath, "utf-8");
|
|
25710
25976
|
const lines = content.split(`
|
|
25711
25977
|
`);
|
|
25712
25978
|
const sortedEdits = [...edits].sort((a, b) => {
|
|
@@ -25731,7 +25997,7 @@ function applyTextEditsToFile(filePath, edits) {
|
|
|
25731
25997
|
`));
|
|
25732
25998
|
}
|
|
25733
25999
|
}
|
|
25734
|
-
|
|
26000
|
+
writeFileSync16(filePath, lines.join(`
|
|
25735
26001
|
`), "utf-8");
|
|
25736
26002
|
return { success: true, editCount: edits.length };
|
|
25737
26003
|
} catch (err) {
|
|
@@ -25762,7 +26028,7 @@ function applyWorkspaceEdit(edit) {
|
|
|
25762
26028
|
if (change.kind === "create") {
|
|
25763
26029
|
try {
|
|
25764
26030
|
const filePath = uriToPath(change.uri);
|
|
25765
|
-
|
|
26031
|
+
writeFileSync16(filePath, "", "utf-8");
|
|
25766
26032
|
result.filesModified.push(filePath);
|
|
25767
26033
|
} catch (err) {
|
|
25768
26034
|
result.success = false;
|
|
@@ -25772,8 +26038,8 @@ function applyWorkspaceEdit(edit) {
|
|
|
25772
26038
|
try {
|
|
25773
26039
|
const oldPath = uriToPath(change.oldUri);
|
|
25774
26040
|
const newPath = uriToPath(change.newUri);
|
|
25775
|
-
const content =
|
|
25776
|
-
|
|
26041
|
+
const content = readFileSync28(oldPath, "utf-8");
|
|
26042
|
+
writeFileSync16(newPath, content, "utf-8");
|
|
25777
26043
|
__require("fs").unlinkSync(oldPath);
|
|
25778
26044
|
result.filesModified.push(newPath);
|
|
25779
26045
|
} catch (err) {
|
|
@@ -38352,13 +38618,13 @@ var lsp_rename = tool({
|
|
|
38352
38618
|
});
|
|
38353
38619
|
// src/tools/ast-grep/constants.ts
|
|
38354
38620
|
import { createRequire as createRequire4 } from "module";
|
|
38355
|
-
import { dirname as dirname10, join as
|
|
38356
|
-
import { existsSync as
|
|
38621
|
+
import { dirname as dirname10, join as join48 } from "path";
|
|
38622
|
+
import { existsSync as existsSync40, statSync as statSync4 } from "fs";
|
|
38357
38623
|
|
|
38358
38624
|
// src/tools/ast-grep/downloader.ts
|
|
38359
38625
|
init_shared();
|
|
38360
|
-
import { existsSync as
|
|
38361
|
-
import { join as
|
|
38626
|
+
import { existsSync as existsSync39, mkdirSync as mkdirSync13, chmodSync as chmodSync2, unlinkSync as unlinkSync10 } from "fs";
|
|
38627
|
+
import { join as join47 } from "path";
|
|
38362
38628
|
import { homedir as homedir12 } from "os";
|
|
38363
38629
|
import { createRequire as createRequire3 } from "module";
|
|
38364
38630
|
var REPO2 = "ast-grep/ast-grep";
|
|
@@ -38384,19 +38650,19 @@ var PLATFORM_MAP2 = {
|
|
|
38384
38650
|
function getCacheDir3() {
|
|
38385
38651
|
if (process.platform === "win32") {
|
|
38386
38652
|
const localAppData = process.env.LOCALAPPDATA || process.env.APPDATA;
|
|
38387
|
-
const base2 = localAppData ||
|
|
38388
|
-
return
|
|
38653
|
+
const base2 = localAppData || join47(homedir12(), "AppData", "Local");
|
|
38654
|
+
return join47(base2, "oh-my-opencode", "bin");
|
|
38389
38655
|
}
|
|
38390
38656
|
const xdgCache = process.env.XDG_CACHE_HOME;
|
|
38391
|
-
const base = xdgCache ||
|
|
38392
|
-
return
|
|
38657
|
+
const base = xdgCache || join47(homedir12(), ".cache");
|
|
38658
|
+
return join47(base, "oh-my-opencode", "bin");
|
|
38393
38659
|
}
|
|
38394
38660
|
function getBinaryName3() {
|
|
38395
38661
|
return process.platform === "win32" ? "sg.exe" : "sg";
|
|
38396
38662
|
}
|
|
38397
38663
|
function getCachedBinaryPath2() {
|
|
38398
|
-
const binaryPath =
|
|
38399
|
-
return
|
|
38664
|
+
const binaryPath = join47(getCacheDir3(), getBinaryName3());
|
|
38665
|
+
return existsSync39(binaryPath) ? binaryPath : null;
|
|
38400
38666
|
}
|
|
38401
38667
|
async function downloadAstGrep(version2 = DEFAULT_VERSION) {
|
|
38402
38668
|
const platformKey = `${process.platform}-${process.arch}`;
|
|
@@ -38407,8 +38673,8 @@ async function downloadAstGrep(version2 = DEFAULT_VERSION) {
|
|
|
38407
38673
|
}
|
|
38408
38674
|
const cacheDir = getCacheDir3();
|
|
38409
38675
|
const binaryName = getBinaryName3();
|
|
38410
|
-
const binaryPath =
|
|
38411
|
-
if (
|
|
38676
|
+
const binaryPath = join47(cacheDir, binaryName);
|
|
38677
|
+
if (existsSync39(binaryPath)) {
|
|
38412
38678
|
return binaryPath;
|
|
38413
38679
|
}
|
|
38414
38680
|
const { arch, os: os6 } = platformInfo;
|
|
@@ -38416,21 +38682,21 @@ async function downloadAstGrep(version2 = DEFAULT_VERSION) {
|
|
|
38416
38682
|
const downloadUrl = `https://github.com/${REPO2}/releases/download/${version2}/${assetName}`;
|
|
38417
38683
|
console.log(`[oh-my-opencode] Downloading ast-grep binary...`);
|
|
38418
38684
|
try {
|
|
38419
|
-
if (!
|
|
38420
|
-
|
|
38685
|
+
if (!existsSync39(cacheDir)) {
|
|
38686
|
+
mkdirSync13(cacheDir, { recursive: true });
|
|
38421
38687
|
}
|
|
38422
38688
|
const response = await fetch(downloadUrl, { redirect: "follow" });
|
|
38423
38689
|
if (!response.ok) {
|
|
38424
38690
|
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
38425
38691
|
}
|
|
38426
|
-
const archivePath =
|
|
38692
|
+
const archivePath = join47(cacheDir, assetName);
|
|
38427
38693
|
const arrayBuffer = await response.arrayBuffer();
|
|
38428
38694
|
await Bun.write(archivePath, arrayBuffer);
|
|
38429
38695
|
await extractZip(archivePath, cacheDir);
|
|
38430
|
-
if (
|
|
38696
|
+
if (existsSync39(archivePath)) {
|
|
38431
38697
|
unlinkSync10(archivePath);
|
|
38432
38698
|
}
|
|
38433
|
-
if (process.platform !== "win32" &&
|
|
38699
|
+
if (process.platform !== "win32" && existsSync39(binaryPath)) {
|
|
38434
38700
|
chmodSync2(binaryPath, 493);
|
|
38435
38701
|
}
|
|
38436
38702
|
console.log(`[oh-my-opencode] ast-grep binary ready.`);
|
|
@@ -38481,8 +38747,8 @@ function findSgCliPathSync() {
|
|
|
38481
38747
|
const require2 = createRequire4(import.meta.url);
|
|
38482
38748
|
const cliPkgPath = require2.resolve("@ast-grep/cli/package.json");
|
|
38483
38749
|
const cliDir = dirname10(cliPkgPath);
|
|
38484
|
-
const sgPath =
|
|
38485
|
-
if (
|
|
38750
|
+
const sgPath = join48(cliDir, binaryName);
|
|
38751
|
+
if (existsSync40(sgPath) && isValidBinary(sgPath)) {
|
|
38486
38752
|
return sgPath;
|
|
38487
38753
|
}
|
|
38488
38754
|
} catch {}
|
|
@@ -38493,8 +38759,8 @@ function findSgCliPathSync() {
|
|
|
38493
38759
|
const pkgPath = require2.resolve(`${platformPkg}/package.json`);
|
|
38494
38760
|
const pkgDir = dirname10(pkgPath);
|
|
38495
38761
|
const astGrepName = process.platform === "win32" ? "ast-grep.exe" : "ast-grep";
|
|
38496
|
-
const binaryPath =
|
|
38497
|
-
if (
|
|
38762
|
+
const binaryPath = join48(pkgDir, astGrepName);
|
|
38763
|
+
if (existsSync40(binaryPath) && isValidBinary(binaryPath)) {
|
|
38498
38764
|
return binaryPath;
|
|
38499
38765
|
}
|
|
38500
38766
|
} catch {}
|
|
@@ -38502,7 +38768,7 @@ function findSgCliPathSync() {
|
|
|
38502
38768
|
if (process.platform === "darwin") {
|
|
38503
38769
|
const homebrewPaths = ["/opt/homebrew/bin/sg", "/usr/local/bin/sg"];
|
|
38504
38770
|
for (const path7 of homebrewPaths) {
|
|
38505
|
-
if (
|
|
38771
|
+
if (existsSync40(path7) && isValidBinary(path7)) {
|
|
38506
38772
|
return path7;
|
|
38507
38773
|
}
|
|
38508
38774
|
}
|
|
@@ -38557,11 +38823,11 @@ var DEFAULT_MAX_MATCHES = 500;
|
|
|
38557
38823
|
|
|
38558
38824
|
// src/tools/ast-grep/cli.ts
|
|
38559
38825
|
var {spawn: spawn7 } = globalThis.Bun;
|
|
38560
|
-
import { existsSync as
|
|
38826
|
+
import { existsSync as existsSync41 } from "fs";
|
|
38561
38827
|
var resolvedCliPath3 = null;
|
|
38562
38828
|
var initPromise2 = null;
|
|
38563
38829
|
async function getAstGrepPath() {
|
|
38564
|
-
if (resolvedCliPath3 !== null &&
|
|
38830
|
+
if (resolvedCliPath3 !== null && existsSync41(resolvedCliPath3)) {
|
|
38565
38831
|
return resolvedCliPath3;
|
|
38566
38832
|
}
|
|
38567
38833
|
if (initPromise2) {
|
|
@@ -38569,7 +38835,7 @@ async function getAstGrepPath() {
|
|
|
38569
38835
|
}
|
|
38570
38836
|
initPromise2 = (async () => {
|
|
38571
38837
|
const syncPath = findSgCliPathSync();
|
|
38572
|
-
if (syncPath &&
|
|
38838
|
+
if (syncPath && existsSync41(syncPath)) {
|
|
38573
38839
|
resolvedCliPath3 = syncPath;
|
|
38574
38840
|
setSgCliPath(syncPath);
|
|
38575
38841
|
return syncPath;
|
|
@@ -38603,7 +38869,7 @@ async function runSg(options) {
|
|
|
38603
38869
|
const paths = options.paths && options.paths.length > 0 ? options.paths : ["."];
|
|
38604
38870
|
args.push(...paths);
|
|
38605
38871
|
let cliPath = getSgCliPath();
|
|
38606
|
-
if (!
|
|
38872
|
+
if (!existsSync41(cliPath) && cliPath !== "sg") {
|
|
38607
38873
|
const downloadedPath = await getAstGrepPath();
|
|
38608
38874
|
if (downloadedPath) {
|
|
38609
38875
|
cliPath = downloadedPath;
|
|
@@ -38867,21 +39133,21 @@ var ast_grep_replace = tool({
|
|
|
38867
39133
|
var {spawn: spawn9 } = globalThis.Bun;
|
|
38868
39134
|
|
|
38869
39135
|
// src/tools/grep/constants.ts
|
|
38870
|
-
import { existsSync as
|
|
38871
|
-
import { join as
|
|
39136
|
+
import { existsSync as existsSync43 } from "fs";
|
|
39137
|
+
import { join as join50, dirname as dirname11 } from "path";
|
|
38872
39138
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
38873
39139
|
|
|
38874
39140
|
// src/tools/grep/downloader.ts
|
|
38875
39141
|
init_shared();
|
|
38876
|
-
import { existsSync as
|
|
38877
|
-
import { join as
|
|
39142
|
+
import { existsSync as existsSync42, mkdirSync as mkdirSync14, chmodSync as chmodSync3, unlinkSync as unlinkSync11, readdirSync as readdirSync12 } from "fs";
|
|
39143
|
+
import { join as join49 } from "path";
|
|
38878
39144
|
var {spawn: spawn8 } = globalThis.Bun;
|
|
38879
39145
|
function findFileRecursive(dir, filename) {
|
|
38880
39146
|
try {
|
|
38881
|
-
const entries =
|
|
39147
|
+
const entries = readdirSync12(dir, { withFileTypes: true, recursive: true });
|
|
38882
39148
|
for (const entry of entries) {
|
|
38883
39149
|
if (entry.isFile() && entry.name === filename) {
|
|
38884
|
-
return
|
|
39150
|
+
return join49(entry.parentPath ?? dir, entry.name);
|
|
38885
39151
|
}
|
|
38886
39152
|
}
|
|
38887
39153
|
} catch {
|
|
@@ -38902,11 +39168,11 @@ function getPlatformKey() {
|
|
|
38902
39168
|
}
|
|
38903
39169
|
function getInstallDir() {
|
|
38904
39170
|
const homeDir = process.env.HOME || process.env.USERPROFILE || ".";
|
|
38905
|
-
return
|
|
39171
|
+
return join49(homeDir, ".cache", "oh-my-opencode", "bin");
|
|
38906
39172
|
}
|
|
38907
39173
|
function getRgPath() {
|
|
38908
39174
|
const isWindows2 = process.platform === "win32";
|
|
38909
|
-
return
|
|
39175
|
+
return join49(getInstallDir(), isWindows2 ? "rg.exe" : "rg");
|
|
38910
39176
|
}
|
|
38911
39177
|
async function downloadFile(url2, destPath) {
|
|
38912
39178
|
const response = await fetch(url2);
|
|
@@ -38940,7 +39206,7 @@ async function extractZip2(archivePath, destDir) {
|
|
|
38940
39206
|
const binaryName = process.platform === "win32" ? "rg.exe" : "rg";
|
|
38941
39207
|
const foundPath = findFileRecursive(destDir, binaryName);
|
|
38942
39208
|
if (foundPath) {
|
|
38943
|
-
const destPath =
|
|
39209
|
+
const destPath = join49(destDir, binaryName);
|
|
38944
39210
|
if (foundPath !== destPath) {
|
|
38945
39211
|
const { renameSync } = await import("fs");
|
|
38946
39212
|
renameSync(foundPath, destPath);
|
|
@@ -38955,13 +39221,13 @@ async function downloadAndInstallRipgrep() {
|
|
|
38955
39221
|
}
|
|
38956
39222
|
const installDir = getInstallDir();
|
|
38957
39223
|
const rgPath = getRgPath();
|
|
38958
|
-
if (
|
|
39224
|
+
if (existsSync42(rgPath)) {
|
|
38959
39225
|
return rgPath;
|
|
38960
39226
|
}
|
|
38961
|
-
|
|
39227
|
+
mkdirSync14(installDir, { recursive: true });
|
|
38962
39228
|
const filename = `ripgrep-${RG_VERSION}-${config3.platform}.${config3.extension}`;
|
|
38963
39229
|
const url2 = `https://github.com/BurntSushi/ripgrep/releases/download/${RG_VERSION}/${filename}`;
|
|
38964
|
-
const archivePath =
|
|
39230
|
+
const archivePath = join49(installDir, filename);
|
|
38965
39231
|
try {
|
|
38966
39232
|
await downloadFile(url2, archivePath);
|
|
38967
39233
|
if (config3.extension === "tar.gz") {
|
|
@@ -38972,12 +39238,12 @@ async function downloadAndInstallRipgrep() {
|
|
|
38972
39238
|
if (process.platform !== "win32") {
|
|
38973
39239
|
chmodSync3(rgPath, 493);
|
|
38974
39240
|
}
|
|
38975
|
-
if (!
|
|
39241
|
+
if (!existsSync42(rgPath)) {
|
|
38976
39242
|
throw new Error("ripgrep binary not found after extraction");
|
|
38977
39243
|
}
|
|
38978
39244
|
return rgPath;
|
|
38979
39245
|
} finally {
|
|
38980
|
-
if (
|
|
39246
|
+
if (existsSync42(archivePath)) {
|
|
38981
39247
|
try {
|
|
38982
39248
|
unlinkSync11(archivePath);
|
|
38983
39249
|
} catch {}
|
|
@@ -38986,7 +39252,7 @@ async function downloadAndInstallRipgrep() {
|
|
|
38986
39252
|
}
|
|
38987
39253
|
function getInstalledRipgrepPath() {
|
|
38988
39254
|
const rgPath = getRgPath();
|
|
38989
|
-
return
|
|
39255
|
+
return existsSync42(rgPath) ? rgPath : null;
|
|
38990
39256
|
}
|
|
38991
39257
|
|
|
38992
39258
|
// src/tools/grep/constants.ts
|
|
@@ -39011,14 +39277,14 @@ function getOpenCodeBundledRg() {
|
|
|
39011
39277
|
const isWindows2 = process.platform === "win32";
|
|
39012
39278
|
const rgName = isWindows2 ? "rg.exe" : "rg";
|
|
39013
39279
|
const candidates = [
|
|
39014
|
-
|
|
39015
|
-
|
|
39016
|
-
|
|
39017
|
-
|
|
39018
|
-
|
|
39280
|
+
join50(getDataDir(), "opencode", "bin", rgName),
|
|
39281
|
+
join50(execDir, rgName),
|
|
39282
|
+
join50(execDir, "bin", rgName),
|
|
39283
|
+
join50(execDir, "..", "bin", rgName),
|
|
39284
|
+
join50(execDir, "..", "libexec", rgName)
|
|
39019
39285
|
];
|
|
39020
39286
|
for (const candidate of candidates) {
|
|
39021
|
-
if (
|
|
39287
|
+
if (existsSync43(candidate)) {
|
|
39022
39288
|
return candidate;
|
|
39023
39289
|
}
|
|
39024
39290
|
}
|
|
@@ -39355,26 +39621,26 @@ async function runRgFiles(options, resolvedCli) {
|
|
|
39355
39621
|
const isRg = cli.backend === "rg";
|
|
39356
39622
|
const isWindows2 = process.platform === "win32";
|
|
39357
39623
|
let command;
|
|
39358
|
-
let
|
|
39624
|
+
let cwd2;
|
|
39359
39625
|
if (isRg) {
|
|
39360
39626
|
const args = buildRgArgs2(options);
|
|
39361
39627
|
const paths = options.paths?.length ? options.paths : ["."];
|
|
39362
39628
|
args.push(...paths);
|
|
39363
39629
|
command = [cli.path, ...args];
|
|
39364
|
-
|
|
39630
|
+
cwd2 = undefined;
|
|
39365
39631
|
} else if (isWindows2) {
|
|
39366
39632
|
command = buildPowerShellCommand(options);
|
|
39367
|
-
|
|
39633
|
+
cwd2 = undefined;
|
|
39368
39634
|
} else {
|
|
39369
39635
|
const args = buildFindArgs(options);
|
|
39370
39636
|
const paths = options.paths?.length ? options.paths : ["."];
|
|
39371
|
-
|
|
39637
|
+
cwd2 = paths[0] || ".";
|
|
39372
39638
|
command = [cli.path, ...args];
|
|
39373
39639
|
}
|
|
39374
39640
|
const proc = spawn10(command, {
|
|
39375
39641
|
stdout: "pipe",
|
|
39376
39642
|
stderr: "pipe",
|
|
39377
|
-
cwd
|
|
39643
|
+
cwd: cwd2
|
|
39378
39644
|
});
|
|
39379
39645
|
const timeoutPromise = new Promise((_, reject) => {
|
|
39380
39646
|
const id = setTimeout(() => {
|
|
@@ -39412,7 +39678,7 @@ async function runRgFiles(options, resolvedCli) {
|
|
|
39412
39678
|
} else if (isWindows2) {
|
|
39413
39679
|
filePath = line.trim();
|
|
39414
39680
|
} else {
|
|
39415
|
-
filePath = `${
|
|
39681
|
+
filePath = `${cwd2}/${line}`;
|
|
39416
39682
|
}
|
|
39417
39683
|
const mtime = await getFileMtime(filePath);
|
|
39418
39684
|
files.push({ path: filePath, mtime });
|
|
@@ -39480,8 +39746,8 @@ var glob = tool({
|
|
|
39480
39746
|
init_shared();
|
|
39481
39747
|
init_file_utils();
|
|
39482
39748
|
init_shared();
|
|
39483
|
-
import { existsSync as
|
|
39484
|
-
import { join as
|
|
39749
|
+
import { existsSync as existsSync44, readdirSync as readdirSync13, readFileSync as readFileSync29 } from "fs";
|
|
39750
|
+
import { join as join51, basename as basename4, dirname as dirname12 } from "path";
|
|
39485
39751
|
// src/features/builtin-commands/templates/init-deep.ts
|
|
39486
39752
|
var INIT_DEEP_TEMPLATE = `# /init-deep
|
|
39487
39753
|
|
|
@@ -40597,18 +40863,18 @@ function loadBuiltinCommands(disabledCommands) {
|
|
|
40597
40863
|
}
|
|
40598
40864
|
// src/tools/slashcommand/tools.ts
|
|
40599
40865
|
function discoverCommandsFromDir2(commandsDir, scope) {
|
|
40600
|
-
if (!
|
|
40866
|
+
if (!existsSync44(commandsDir)) {
|
|
40601
40867
|
return [];
|
|
40602
40868
|
}
|
|
40603
|
-
const entries =
|
|
40869
|
+
const entries = readdirSync13(commandsDir, { withFileTypes: true });
|
|
40604
40870
|
const commands2 = [];
|
|
40605
40871
|
for (const entry of entries) {
|
|
40606
40872
|
if (!isMarkdownFile(entry))
|
|
40607
40873
|
continue;
|
|
40608
|
-
const commandPath =
|
|
40874
|
+
const commandPath = join51(commandsDir, entry.name);
|
|
40609
40875
|
const commandName = basename4(entry.name, ".md");
|
|
40610
40876
|
try {
|
|
40611
|
-
const content =
|
|
40877
|
+
const content = readFileSync29(commandPath, "utf-8");
|
|
40612
40878
|
const { data, body } = parseFrontmatter(content);
|
|
40613
40879
|
const isOpencodeSource = scope === "opencode" || scope === "opencode-project";
|
|
40614
40880
|
const metadata = {
|
|
@@ -40634,10 +40900,10 @@ function discoverCommandsFromDir2(commandsDir, scope) {
|
|
|
40634
40900
|
}
|
|
40635
40901
|
function discoverCommandsSync() {
|
|
40636
40902
|
const configDir = getOpenCodeConfigDir({ binary: "opencode" });
|
|
40637
|
-
const userCommandsDir =
|
|
40638
|
-
const projectCommandsDir =
|
|
40639
|
-
const opencodeGlobalDir =
|
|
40640
|
-
const opencodeProjectDir =
|
|
40903
|
+
const userCommandsDir = join51(getClaudeConfigDir(), "commands");
|
|
40904
|
+
const projectCommandsDir = join51(process.cwd(), ".claude", "commands");
|
|
40905
|
+
const opencodeGlobalDir = join51(configDir, "command");
|
|
40906
|
+
const opencodeProjectDir = join51(process.cwd(), ".opencode", "command");
|
|
40641
40907
|
const userCommands = discoverCommandsFromDir2(userCommandsDir, "user");
|
|
40642
40908
|
const opencodeGlobalCommands = discoverCommandsFromDir2(opencodeGlobalDir, "opencode");
|
|
40643
40909
|
const projectCommands = discoverCommandsFromDir2(projectCommandsDir, "project");
|
|
@@ -40814,13 +41080,13 @@ var slashcommand = createSlashcommandTool();
|
|
|
40814
41080
|
// src/tools/session-manager/constants.ts
|
|
40815
41081
|
init_data_path();
|
|
40816
41082
|
init_shared();
|
|
40817
|
-
import { join as
|
|
41083
|
+
import { join as join52 } from "path";
|
|
40818
41084
|
var OPENCODE_STORAGE9 = getOpenCodeStorageDir();
|
|
40819
|
-
var MESSAGE_STORAGE4 =
|
|
40820
|
-
var PART_STORAGE4 =
|
|
40821
|
-
var SESSION_STORAGE =
|
|
40822
|
-
var TODO_DIR2 =
|
|
40823
|
-
var TRANSCRIPT_DIR2 =
|
|
41085
|
+
var MESSAGE_STORAGE4 = join52(OPENCODE_STORAGE9, "message");
|
|
41086
|
+
var PART_STORAGE4 = join52(OPENCODE_STORAGE9, "part");
|
|
41087
|
+
var SESSION_STORAGE = join52(OPENCODE_STORAGE9, "session");
|
|
41088
|
+
var TODO_DIR2 = join52(getClaudeConfigDir(), "todos");
|
|
41089
|
+
var TRANSCRIPT_DIR2 = join52(getClaudeConfigDir(), "transcripts");
|
|
40824
41090
|
var SESSION_LIST_DESCRIPTION = `\u5217\u51FA\u6240\u6709 OpenCode session\uFF0C\u652F\u6301\u53EF\u9009\u8FC7\u6EE4\u3002
|
|
40825
41091
|
|
|
40826
41092
|
\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
|
|
@@ -40893,11 +41159,11 @@ Has Todos: Yes (12 items, 8 completed)
|
|
|
40893
41159
|
Has Transcript: Yes (234 entries)`;
|
|
40894
41160
|
|
|
40895
41161
|
// src/tools/session-manager/storage.ts
|
|
40896
|
-
import { existsSync as
|
|
41162
|
+
import { existsSync as existsSync45, readdirSync as readdirSync14 } from "fs";
|
|
40897
41163
|
import { readdir, readFile } from "fs/promises";
|
|
40898
|
-
import { join as
|
|
41164
|
+
import { join as join53 } from "path";
|
|
40899
41165
|
async function getMainSessions(options) {
|
|
40900
|
-
if (!
|
|
41166
|
+
if (!existsSync45(SESSION_STORAGE))
|
|
40901
41167
|
return [];
|
|
40902
41168
|
const sessions = [];
|
|
40903
41169
|
try {
|
|
@@ -40905,13 +41171,13 @@ async function getMainSessions(options) {
|
|
|
40905
41171
|
for (const projectDir of projectDirs) {
|
|
40906
41172
|
if (!projectDir.isDirectory())
|
|
40907
41173
|
continue;
|
|
40908
|
-
const projectPath =
|
|
41174
|
+
const projectPath = join53(SESSION_STORAGE, projectDir.name);
|
|
40909
41175
|
const sessionFiles = await readdir(projectPath);
|
|
40910
41176
|
for (const file2 of sessionFiles) {
|
|
40911
41177
|
if (!file2.endsWith(".json"))
|
|
40912
41178
|
continue;
|
|
40913
41179
|
try {
|
|
40914
|
-
const content = await readFile(
|
|
41180
|
+
const content = await readFile(join53(projectPath, file2), "utf-8");
|
|
40915
41181
|
const meta = JSON.parse(content);
|
|
40916
41182
|
if (meta.parentID)
|
|
40917
41183
|
continue;
|
|
@@ -40929,7 +41195,7 @@ async function getMainSessions(options) {
|
|
|
40929
41195
|
return sessions.sort((a, b) => b.time.updated - a.time.updated);
|
|
40930
41196
|
}
|
|
40931
41197
|
async function getAllSessions() {
|
|
40932
|
-
if (!
|
|
41198
|
+
if (!existsSync45(MESSAGE_STORAGE4))
|
|
40933
41199
|
return [];
|
|
40934
41200
|
const sessions = [];
|
|
40935
41201
|
async function scanDirectory(dir) {
|
|
@@ -40937,7 +41203,7 @@ async function getAllSessions() {
|
|
|
40937
41203
|
const entries = await readdir(dir, { withFileTypes: true });
|
|
40938
41204
|
for (const entry of entries) {
|
|
40939
41205
|
if (entry.isDirectory()) {
|
|
40940
|
-
const sessionPath =
|
|
41206
|
+
const sessionPath = join53(dir, entry.name);
|
|
40941
41207
|
const files = await readdir(sessionPath);
|
|
40942
41208
|
if (files.some((f) => f.endsWith(".json"))) {
|
|
40943
41209
|
sessions.push(entry.name);
|
|
@@ -40954,16 +41220,16 @@ async function getAllSessions() {
|
|
|
40954
41220
|
return [...new Set(sessions)];
|
|
40955
41221
|
}
|
|
40956
41222
|
function getMessageDir7(sessionID) {
|
|
40957
|
-
if (!
|
|
41223
|
+
if (!existsSync45(MESSAGE_STORAGE4))
|
|
40958
41224
|
return "";
|
|
40959
|
-
const directPath =
|
|
40960
|
-
if (
|
|
41225
|
+
const directPath = join53(MESSAGE_STORAGE4, sessionID);
|
|
41226
|
+
if (existsSync45(directPath)) {
|
|
40961
41227
|
return directPath;
|
|
40962
41228
|
}
|
|
40963
41229
|
try {
|
|
40964
|
-
for (const dir of
|
|
40965
|
-
const sessionPath =
|
|
40966
|
-
if (
|
|
41230
|
+
for (const dir of readdirSync14(MESSAGE_STORAGE4)) {
|
|
41231
|
+
const sessionPath = join53(MESSAGE_STORAGE4, dir, sessionID);
|
|
41232
|
+
if (existsSync45(sessionPath)) {
|
|
40967
41233
|
return sessionPath;
|
|
40968
41234
|
}
|
|
40969
41235
|
}
|
|
@@ -40977,7 +41243,7 @@ function sessionExists(sessionID) {
|
|
|
40977
41243
|
}
|
|
40978
41244
|
async function readSessionMessages(sessionID) {
|
|
40979
41245
|
const messageDir = getMessageDir7(sessionID);
|
|
40980
|
-
if (!messageDir || !
|
|
41246
|
+
if (!messageDir || !existsSync45(messageDir))
|
|
40981
41247
|
return [];
|
|
40982
41248
|
const messages = [];
|
|
40983
41249
|
try {
|
|
@@ -40986,7 +41252,7 @@ async function readSessionMessages(sessionID) {
|
|
|
40986
41252
|
if (!file2.endsWith(".json"))
|
|
40987
41253
|
continue;
|
|
40988
41254
|
try {
|
|
40989
|
-
const content = await readFile(
|
|
41255
|
+
const content = await readFile(join53(messageDir, file2), "utf-8");
|
|
40990
41256
|
const meta = JSON.parse(content);
|
|
40991
41257
|
const parts = await readParts2(meta.id);
|
|
40992
41258
|
messages.push({
|
|
@@ -41012,8 +41278,8 @@ async function readSessionMessages(sessionID) {
|
|
|
41012
41278
|
});
|
|
41013
41279
|
}
|
|
41014
41280
|
async function readParts2(messageID) {
|
|
41015
|
-
const partDir =
|
|
41016
|
-
if (!
|
|
41281
|
+
const partDir = join53(PART_STORAGE4, messageID);
|
|
41282
|
+
if (!existsSync45(partDir))
|
|
41017
41283
|
return [];
|
|
41018
41284
|
const parts = [];
|
|
41019
41285
|
try {
|
|
@@ -41022,7 +41288,7 @@ async function readParts2(messageID) {
|
|
|
41022
41288
|
if (!file2.endsWith(".json"))
|
|
41023
41289
|
continue;
|
|
41024
41290
|
try {
|
|
41025
|
-
const content = await readFile(
|
|
41291
|
+
const content = await readFile(join53(partDir, file2), "utf-8");
|
|
41026
41292
|
parts.push(JSON.parse(content));
|
|
41027
41293
|
} catch {
|
|
41028
41294
|
continue;
|
|
@@ -41034,14 +41300,14 @@ async function readParts2(messageID) {
|
|
|
41034
41300
|
return parts.sort((a, b) => a.id.localeCompare(b.id));
|
|
41035
41301
|
}
|
|
41036
41302
|
async function readSessionTodos(sessionID) {
|
|
41037
|
-
if (!
|
|
41303
|
+
if (!existsSync45(TODO_DIR2))
|
|
41038
41304
|
return [];
|
|
41039
41305
|
try {
|
|
41040
41306
|
const allFiles = await readdir(TODO_DIR2);
|
|
41041
41307
|
const todoFiles = allFiles.filter((f) => f.includes(sessionID) && f.endsWith(".json"));
|
|
41042
41308
|
for (const file2 of todoFiles) {
|
|
41043
41309
|
try {
|
|
41044
|
-
const content = await readFile(
|
|
41310
|
+
const content = await readFile(join53(TODO_DIR2, file2), "utf-8");
|
|
41045
41311
|
const data = JSON.parse(content);
|
|
41046
41312
|
if (Array.isArray(data)) {
|
|
41047
41313
|
return data.map((item) => ({
|
|
@@ -41061,10 +41327,10 @@ async function readSessionTodos(sessionID) {
|
|
|
41061
41327
|
return [];
|
|
41062
41328
|
}
|
|
41063
41329
|
async function readSessionTranscript(sessionID) {
|
|
41064
|
-
if (!
|
|
41330
|
+
if (!existsSync45(TRANSCRIPT_DIR2))
|
|
41065
41331
|
return 0;
|
|
41066
|
-
const transcriptFile =
|
|
41067
|
-
if (!
|
|
41332
|
+
const transcriptFile = join53(TRANSCRIPT_DIR2, `${sessionID}.jsonl`);
|
|
41333
|
+
if (!existsSync45(transcriptFile))
|
|
41068
41334
|
return 0;
|
|
41069
41335
|
try {
|
|
41070
41336
|
const content = await readFile(transcriptFile, "utf-8");
|
|
@@ -42266,19 +42532,19 @@ var CALL_OMO_AGENT_DESCRIPTION = `\u542F\u52A8 explore/librarian agent\u3002run_
|
|
|
42266
42532
|
|
|
42267
42533
|
\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`;
|
|
42268
42534
|
// src/tools/call-omo-agent/tools.ts
|
|
42269
|
-
import { existsSync as
|
|
42270
|
-
import { join as
|
|
42535
|
+
import { existsSync as existsSync46, readdirSync as readdirSync15 } from "fs";
|
|
42536
|
+
import { join as join54 } from "path";
|
|
42271
42537
|
init_shared();
|
|
42272
42538
|
init_session_cursor();
|
|
42273
42539
|
function getMessageDir8(sessionID) {
|
|
42274
|
-
if (!
|
|
42540
|
+
if (!existsSync46(MESSAGE_STORAGE))
|
|
42275
42541
|
return null;
|
|
42276
|
-
const directPath =
|
|
42277
|
-
if (
|
|
42542
|
+
const directPath = join54(MESSAGE_STORAGE, sessionID);
|
|
42543
|
+
if (existsSync46(directPath))
|
|
42278
42544
|
return directPath;
|
|
42279
|
-
for (const dir of
|
|
42280
|
-
const sessionPath =
|
|
42281
|
-
if (
|
|
42545
|
+
for (const dir of readdirSync15(MESSAGE_STORAGE)) {
|
|
42546
|
+
const sessionPath = join54(MESSAGE_STORAGE, dir, sessionID);
|
|
42547
|
+
if (existsSync46(sessionPath))
|
|
42282
42548
|
return sessionPath;
|
|
42283
42549
|
}
|
|
42284
42550
|
return null;
|
|
@@ -42687,8 +42953,8 @@ If the requested information is not found, clearly state what is missing.`;
|
|
|
42687
42953
|
}
|
|
42688
42954
|
// src/tools/delegate-task/tools.ts
|
|
42689
42955
|
init_constants2();
|
|
42690
|
-
import { existsSync as
|
|
42691
|
-
import { join as
|
|
42956
|
+
import { existsSync as existsSync47, readdirSync as readdirSync16 } from "fs";
|
|
42957
|
+
import { join as join55 } from "path";
|
|
42692
42958
|
|
|
42693
42959
|
// src/features/task-toast-manager/manager.ts
|
|
42694
42960
|
class TaskToastManager {
|
|
@@ -42847,14 +43113,14 @@ function parseModelString(model) {
|
|
|
42847
43113
|
return;
|
|
42848
43114
|
}
|
|
42849
43115
|
function getMessageDir9(sessionID) {
|
|
42850
|
-
if (!
|
|
43116
|
+
if (!existsSync47(MESSAGE_STORAGE))
|
|
42851
43117
|
return null;
|
|
42852
|
-
const directPath =
|
|
42853
|
-
if (
|
|
43118
|
+
const directPath = join55(MESSAGE_STORAGE, sessionID);
|
|
43119
|
+
if (existsSync47(directPath))
|
|
42854
43120
|
return directPath;
|
|
42855
|
-
for (const dir of
|
|
42856
|
-
const sessionPath =
|
|
42857
|
-
if (
|
|
43121
|
+
for (const dir of readdirSync16(MESSAGE_STORAGE)) {
|
|
43122
|
+
const sessionPath = join55(MESSAGE_STORAGE, dir, sessionID);
|
|
43123
|
+
if (existsSync47(sessionPath))
|
|
42858
43124
|
return sessionPath;
|
|
42859
43125
|
}
|
|
42860
43126
|
return null;
|
|
@@ -43682,8 +43948,8 @@ class PerformanceAggregator {
|
|
|
43682
43948
|
}
|
|
43683
43949
|
|
|
43684
43950
|
// src/features/background-agent/manager.ts
|
|
43685
|
-
import { existsSync as
|
|
43686
|
-
import { join as
|
|
43951
|
+
import { existsSync as existsSync48, readdirSync as readdirSync17 } from "fs";
|
|
43952
|
+
import { join as join56 } from "path";
|
|
43687
43953
|
var TASK_TTL_MS = 30 * 60 * 1000;
|
|
43688
43954
|
var MIN_STABILITY_TIME_MS = 10 * 1000;
|
|
43689
43955
|
var DEFAULT_STALE_TIMEOUT_MS = 180000;
|
|
@@ -43703,6 +43969,7 @@ class BackgroundManager {
|
|
|
43703
43969
|
shutdownTriggered = false;
|
|
43704
43970
|
config;
|
|
43705
43971
|
perfAggregator = new PerformanceAggregator;
|
|
43972
|
+
perfTracer;
|
|
43706
43973
|
queuesByKey = new Map;
|
|
43707
43974
|
processingKeys = new Set;
|
|
43708
43975
|
constructor(ctx, config3) {
|
|
@@ -43715,6 +43982,9 @@ class BackgroundManager {
|
|
|
43715
43982
|
this.config = config3;
|
|
43716
43983
|
this.registerProcessCleanup();
|
|
43717
43984
|
}
|
|
43985
|
+
setPerfTracer(tracer) {
|
|
43986
|
+
this.perfTracer = tracer;
|
|
43987
|
+
}
|
|
43718
43988
|
async launch(input) {
|
|
43719
43989
|
log("[background-agent] launch() called with:", {
|
|
43720
43990
|
agent: input.agent,
|
|
@@ -44531,124 +44801,132 @@ ${perfSnapshot ? `| \u6392\u961F ${PerfTimer.formatDuration(new Date(0), new Dat
|
|
|
44531
44801
|
}
|
|
44532
44802
|
}
|
|
44533
44803
|
async pollRunningTasks() {
|
|
44534
|
-
this.
|
|
44535
|
-
|
|
44536
|
-
|
|
44537
|
-
|
|
44538
|
-
|
|
44539
|
-
|
|
44540
|
-
|
|
44541
|
-
|
|
44542
|
-
if (!sessionID)
|
|
44543
|
-
continue;
|
|
44544
|
-
try {
|
|
44545
|
-
const sessionStatus = allStatuses[sessionID];
|
|
44546
|
-
if (sessionStatus?.type === "idle") {
|
|
44547
|
-
const hasValidOutput = await this.validateSessionHasOutput(sessionID);
|
|
44548
|
-
if (!hasValidOutput) {
|
|
44549
|
-
log("[background-agent] Polling idle but no valid output yet, waiting:", task.id);
|
|
44550
|
-
continue;
|
|
44551
|
-
}
|
|
44552
|
-
if (task.status !== "running")
|
|
44553
|
-
continue;
|
|
44554
|
-
const hasIncompleteTodos2 = await this.checkSessionTodos(sessionID);
|
|
44555
|
-
if (hasIncompleteTodos2) {
|
|
44556
|
-
log("[background-agent] Task has incomplete todos via polling, waiting:", task.id);
|
|
44557
|
-
continue;
|
|
44558
|
-
}
|
|
44559
|
-
await this.tryCompleteTask(task, "polling (idle status)");
|
|
44804
|
+
const start = this.perfTracer?.isEnabled() ? performance.now() : undefined;
|
|
44805
|
+
try {
|
|
44806
|
+
this.pruneStaleTasksAndNotifications();
|
|
44807
|
+
await this.checkAndInterruptStaleTasks();
|
|
44808
|
+
const statusResult = await this.client.session.status();
|
|
44809
|
+
const allStatuses = statusResult.data ?? {};
|
|
44810
|
+
for (const task of this.tasks.values()) {
|
|
44811
|
+
if (task.status !== "running")
|
|
44560
44812
|
continue;
|
|
44561
|
-
|
|
44562
|
-
|
|
44563
|
-
|
|
44564
|
-
|
|
44565
|
-
|
|
44566
|
-
|
|
44567
|
-
|
|
44568
|
-
|
|
44569
|
-
|
|
44570
|
-
|
|
44571
|
-
for (const msg of assistantMsgs) {
|
|
44572
|
-
const parts = msg.parts ?? [];
|
|
44573
|
-
for (const part of parts) {
|
|
44574
|
-
if (part.type === "tool_use" || part.tool) {
|
|
44575
|
-
toolCalls++;
|
|
44576
|
-
lastTool = part.tool || part.name || "unknown";
|
|
44577
|
-
}
|
|
44578
|
-
if (part.type === "text" && part.text) {
|
|
44579
|
-
lastMessage = part.text;
|
|
44580
|
-
}
|
|
44813
|
+
const sessionID = task.sessionID;
|
|
44814
|
+
if (!sessionID)
|
|
44815
|
+
continue;
|
|
44816
|
+
try {
|
|
44817
|
+
const sessionStatus = allStatuses[sessionID];
|
|
44818
|
+
if (sessionStatus?.type === "idle") {
|
|
44819
|
+
const hasValidOutput = await this.validateSessionHasOutput(sessionID);
|
|
44820
|
+
if (!hasValidOutput) {
|
|
44821
|
+
log("[background-agent] Polling idle but no valid output yet, waiting:", task.id);
|
|
44822
|
+
continue;
|
|
44581
44823
|
}
|
|
44582
|
-
|
|
44583
|
-
|
|
44584
|
-
|
|
44585
|
-
|
|
44586
|
-
|
|
44587
|
-
|
|
44588
|
-
|
|
44589
|
-
|
|
44590
|
-
totalRunMs: now - task.startedAt.getTime(),
|
|
44591
|
-
toolCallCount: 0
|
|
44592
|
-
};
|
|
44593
|
-
}
|
|
44594
|
-
if (task.progress.phaseTiming && task.progress.phaseTiming.firstResponseMs === undefined && assistantMsgs.length > 0) {
|
|
44595
|
-
task.progress.phaseTiming.firstResponseMs = Date.now() - task.startedAt.getTime();
|
|
44596
|
-
}
|
|
44597
|
-
task.progress.toolCalls = toolCalls;
|
|
44598
|
-
task.progress.lastTool = lastTool;
|
|
44599
|
-
task.progress.lastUpdate = new Date;
|
|
44600
|
-
if (lastMessage) {
|
|
44601
|
-
task.progress.lastMessage = lastMessage;
|
|
44602
|
-
task.progress.lastMessageAt = new Date;
|
|
44603
|
-
}
|
|
44604
|
-
const currentMsgCount = messages.length;
|
|
44605
|
-
const startedAt = task.startedAt;
|
|
44606
|
-
if (!startedAt)
|
|
44824
|
+
if (task.status !== "running")
|
|
44825
|
+
continue;
|
|
44826
|
+
const hasIncompleteTodos2 = await this.checkSessionTodos(sessionID);
|
|
44827
|
+
if (hasIncompleteTodos2) {
|
|
44828
|
+
log("[background-agent] Task has incomplete todos via polling, waiting:", task.id);
|
|
44829
|
+
continue;
|
|
44830
|
+
}
|
|
44831
|
+
await this.tryCompleteTask(task, "polling (idle status)");
|
|
44607
44832
|
continue;
|
|
44608
|
-
|
|
44609
|
-
|
|
44610
|
-
|
|
44611
|
-
|
|
44612
|
-
|
|
44613
|
-
|
|
44614
|
-
|
|
44615
|
-
|
|
44616
|
-
|
|
44617
|
-
|
|
44618
|
-
|
|
44619
|
-
|
|
44620
|
-
|
|
44621
|
-
|
|
44622
|
-
|
|
44833
|
+
}
|
|
44834
|
+
const messagesResult = await this.client.session.messages({
|
|
44835
|
+
path: { id: sessionID }
|
|
44836
|
+
});
|
|
44837
|
+
if (!messagesResult.error && messagesResult.data) {
|
|
44838
|
+
const messages = messagesResult.data;
|
|
44839
|
+
const assistantMsgs = messages.filter((m) => m.info?.role === "assistant");
|
|
44840
|
+
let toolCalls = 0;
|
|
44841
|
+
let lastTool;
|
|
44842
|
+
let lastMessage;
|
|
44843
|
+
for (const msg of assistantMsgs) {
|
|
44844
|
+
const parts = msg.parts ?? [];
|
|
44845
|
+
for (const part of parts) {
|
|
44846
|
+
if (part.type === "tool_use" || part.tool) {
|
|
44847
|
+
toolCalls++;
|
|
44848
|
+
lastTool = part.tool || part.name || "unknown";
|
|
44623
44849
|
}
|
|
44624
|
-
|
|
44625
|
-
|
|
44626
|
-
log("[background-agent] Stability reached but no valid output, waiting:", task.id);
|
|
44627
|
-
continue;
|
|
44850
|
+
if (part.type === "text" && part.text) {
|
|
44851
|
+
lastMessage = part.text;
|
|
44628
44852
|
}
|
|
44629
|
-
|
|
44630
|
-
|
|
44631
|
-
|
|
44632
|
-
|
|
44633
|
-
|
|
44634
|
-
|
|
44853
|
+
}
|
|
44854
|
+
}
|
|
44855
|
+
if (!task.progress) {
|
|
44856
|
+
task.progress = { toolCalls: 0, lastUpdate: new Date };
|
|
44857
|
+
}
|
|
44858
|
+
if (task.startedAt && !task.progress.phaseTiming) {
|
|
44859
|
+
const now = Date.now();
|
|
44860
|
+
task.progress.phaseTiming = {
|
|
44861
|
+
queueWaitMs: task.queuedAt ? now - task.queuedAt.getTime() : 0,
|
|
44862
|
+
totalRunMs: now - task.startedAt.getTime(),
|
|
44863
|
+
toolCallCount: 0
|
|
44864
|
+
};
|
|
44865
|
+
}
|
|
44866
|
+
if (task.progress.phaseTiming && task.progress.phaseTiming.firstResponseMs === undefined && assistantMsgs.length > 0) {
|
|
44867
|
+
task.progress.phaseTiming.firstResponseMs = Date.now() - task.startedAt.getTime();
|
|
44868
|
+
}
|
|
44869
|
+
task.progress.toolCalls = toolCalls;
|
|
44870
|
+
task.progress.lastTool = lastTool;
|
|
44871
|
+
task.progress.lastUpdate = new Date;
|
|
44872
|
+
if (lastMessage) {
|
|
44873
|
+
task.progress.lastMessage = lastMessage;
|
|
44874
|
+
task.progress.lastMessageAt = new Date;
|
|
44875
|
+
}
|
|
44876
|
+
const currentMsgCount = messages.length;
|
|
44877
|
+
const startedAt = task.startedAt;
|
|
44878
|
+
if (!startedAt)
|
|
44879
|
+
continue;
|
|
44880
|
+
const elapsedMs = Date.now() - startedAt.getTime();
|
|
44881
|
+
if (elapsedMs >= MIN_STABILITY_TIME_MS) {
|
|
44882
|
+
if (task.lastMsgCount === currentMsgCount) {
|
|
44883
|
+
task.stablePolls = (task.stablePolls ?? 0) + 1;
|
|
44884
|
+
if (task.stablePolls >= 3) {
|
|
44885
|
+
const recheckStatus = await this.client.session.status();
|
|
44886
|
+
const recheckData = recheckStatus.data ?? {};
|
|
44887
|
+
const currentStatus = recheckData[sessionID];
|
|
44888
|
+
if (currentStatus?.type !== "idle") {
|
|
44889
|
+
log("[background-agent] Stability reached but session not idle, resetting:", {
|
|
44890
|
+
taskId: task.id,
|
|
44891
|
+
sessionStatus: currentStatus?.type ?? "not_in_status"
|
|
44892
|
+
});
|
|
44893
|
+
task.stablePolls = 0;
|
|
44894
|
+
continue;
|
|
44895
|
+
}
|
|
44896
|
+
const hasValidOutput = await this.validateSessionHasOutput(sessionID);
|
|
44897
|
+
if (!hasValidOutput) {
|
|
44898
|
+
log("[background-agent] Stability reached but no valid output, waiting:", task.id);
|
|
44899
|
+
continue;
|
|
44900
|
+
}
|
|
44901
|
+
if (task.status !== "running")
|
|
44902
|
+
continue;
|
|
44903
|
+
const hasIncompleteTodos2 = await this.checkSessionTodos(sessionID);
|
|
44904
|
+
if (!hasIncompleteTodos2) {
|
|
44905
|
+
await this.tryCompleteTask(task, "stability detection");
|
|
44906
|
+
continue;
|
|
44907
|
+
}
|
|
44635
44908
|
}
|
|
44909
|
+
} else {
|
|
44910
|
+
task.stablePolls = 0;
|
|
44636
44911
|
}
|
|
44637
|
-
} else {
|
|
44638
|
-
task.stablePolls = 0;
|
|
44639
44912
|
}
|
|
44913
|
+
task.lastMsgCount = currentMsgCount;
|
|
44640
44914
|
}
|
|
44641
|
-
|
|
44915
|
+
} catch (error45) {
|
|
44916
|
+
log("[background-agent] Poll error for task:", { taskId: task.id, error: error45 });
|
|
44642
44917
|
}
|
|
44643
|
-
} catch (error45) {
|
|
44644
|
-
log("[background-agent] Poll error for task:", { taskId: task.id, error: error45 });
|
|
44645
44918
|
}
|
|
44646
|
-
|
|
44647
|
-
|
|
44648
|
-
|
|
44649
|
-
|
|
44650
|
-
|
|
44651
|
-
|
|
44919
|
+
if (!this.hasRunningTasks()) {
|
|
44920
|
+
this.stopPolling();
|
|
44921
|
+
if (this.perfAggregator.taskCount >= 2) {
|
|
44922
|
+
const report = this.perfAggregator.getReport();
|
|
44923
|
+
log("[perf] Session report:", report);
|
|
44924
|
+
}
|
|
44925
|
+
}
|
|
44926
|
+
} finally {
|
|
44927
|
+
if (start !== undefined) {
|
|
44928
|
+
const duration3 = performance.now() - start;
|
|
44929
|
+
this.perfTracer.recordPolling(duration3, this.getRunningTasks().length, new Set(...this.tasks.values().map((t) => t.parentSessionID).filter(Boolean)).size);
|
|
44652
44930
|
}
|
|
44653
44931
|
}
|
|
44654
44932
|
}
|
|
@@ -44686,14 +44964,14 @@ function registerProcessSignal(signal, handler, exitAfter) {
|
|
|
44686
44964
|
return listener;
|
|
44687
44965
|
}
|
|
44688
44966
|
function getMessageDir10(sessionID) {
|
|
44689
|
-
if (!
|
|
44967
|
+
if (!existsSync48(MESSAGE_STORAGE))
|
|
44690
44968
|
return null;
|
|
44691
|
-
const directPath =
|
|
44692
|
-
if (
|
|
44969
|
+
const directPath = join56(MESSAGE_STORAGE, sessionID);
|
|
44970
|
+
if (existsSync48(directPath))
|
|
44693
44971
|
return directPath;
|
|
44694
|
-
for (const dir of
|
|
44695
|
-
const sessionPath =
|
|
44696
|
-
if (
|
|
44972
|
+
for (const dir of readdirSync17(MESSAGE_STORAGE)) {
|
|
44973
|
+
const sessionPath = join56(MESSAGE_STORAGE, dir, sessionID);
|
|
44974
|
+
if (existsSync48(sessionPath))
|
|
44697
44975
|
return sessionPath;
|
|
44698
44976
|
}
|
|
44699
44977
|
return null;
|
|
@@ -62607,6 +62885,7 @@ var HookNameSchema = exports_external2.enum([
|
|
|
62607
62885
|
"edit-error-recovery",
|
|
62608
62886
|
"delegate-task-retry",
|
|
62609
62887
|
"prometheus-md-only",
|
|
62888
|
+
"perf-profiler",
|
|
62610
62889
|
"start-work",
|
|
62611
62890
|
"atlas"
|
|
62612
62891
|
]);
|
|
@@ -62720,11 +62999,21 @@ var DynamicContextPruningConfigSchema = exports_external2.object({
|
|
|
62720
62999
|
}).optional()
|
|
62721
63000
|
}).optional()
|
|
62722
63001
|
});
|
|
63002
|
+
var ProfilingConfigSchema = exports_external2.object({
|
|
63003
|
+
enabled: exports_external2.boolean().default(false),
|
|
63004
|
+
output_dir: exports_external2.string().optional(),
|
|
63005
|
+
slow_threshold_ms: exports_external2.number().default(100),
|
|
63006
|
+
memory_snapshot_interval: exports_external2.number().default(5),
|
|
63007
|
+
trace_api: exports_external2.boolean().default(true),
|
|
63008
|
+
trace_fileio: exports_external2.boolean().default(true),
|
|
63009
|
+
trace_polling: exports_external2.boolean().default(true)
|
|
63010
|
+
});
|
|
62723
63011
|
var ExperimentalConfigSchema = exports_external2.object({
|
|
62724
63012
|
aggressive_truncation: exports_external2.boolean().optional(),
|
|
62725
63013
|
auto_resume: exports_external2.boolean().optional(),
|
|
62726
63014
|
truncate_all_tool_outputs: exports_external2.boolean().optional(),
|
|
62727
|
-
dynamic_context_pruning: DynamicContextPruningConfigSchema.optional()
|
|
63015
|
+
dynamic_context_pruning: DynamicContextPruningConfigSchema.optional(),
|
|
63016
|
+
profiling: ProfilingConfigSchema.optional()
|
|
62728
63017
|
});
|
|
62729
63018
|
var SkillSourceSchema = exports_external2.union([
|
|
62730
63019
|
exports_external2.string(),
|
|
@@ -65753,7 +66042,7 @@ init_file_utils();
|
|
|
65753
66042
|
init_shared();
|
|
65754
66043
|
init_logger();
|
|
65755
66044
|
import { promises as fs11 } from "fs";
|
|
65756
|
-
import { join as
|
|
66045
|
+
import { join as join58, basename as basename6 } from "path";
|
|
65757
66046
|
async function loadCommandsFromDir(commandsDir, scope, visited = new Set, prefix = "") {
|
|
65758
66047
|
try {
|
|
65759
66048
|
await fs11.access(commandsDir);
|
|
@@ -65783,7 +66072,7 @@ async function loadCommandsFromDir(commandsDir, scope, visited = new Set, prefix
|
|
|
65783
66072
|
if (entry.isDirectory()) {
|
|
65784
66073
|
if (entry.name.startsWith("."))
|
|
65785
66074
|
continue;
|
|
65786
|
-
const subDirPath =
|
|
66075
|
+
const subDirPath = join58(commandsDir, entry.name);
|
|
65787
66076
|
const subPrefix = prefix ? `${prefix}:${entry.name}` : entry.name;
|
|
65788
66077
|
const subCommands = await loadCommandsFromDir(subDirPath, scope, visited, subPrefix);
|
|
65789
66078
|
commands2.push(...subCommands);
|
|
@@ -65791,7 +66080,7 @@ async function loadCommandsFromDir(commandsDir, scope, visited = new Set, prefix
|
|
|
65791
66080
|
}
|
|
65792
66081
|
if (!isMarkdownFile(entry))
|
|
65793
66082
|
continue;
|
|
65794
|
-
const commandPath =
|
|
66083
|
+
const commandPath = join58(commandsDir, entry.name);
|
|
65795
66084
|
const baseCommandName = basename6(entry.name, ".md");
|
|
65796
66085
|
const commandName = prefix ? `${prefix}:${baseCommandName}` : baseCommandName;
|
|
65797
66086
|
try {
|
|
@@ -65838,23 +66127,23 @@ function commandsToRecord(commands2) {
|
|
|
65838
66127
|
return result;
|
|
65839
66128
|
}
|
|
65840
66129
|
async function loadUserCommands() {
|
|
65841
|
-
const userCommandsDir =
|
|
66130
|
+
const userCommandsDir = join58(getClaudeConfigDir(), "commands");
|
|
65842
66131
|
const commands2 = await loadCommandsFromDir(userCommandsDir, "user");
|
|
65843
66132
|
return commandsToRecord(commands2);
|
|
65844
66133
|
}
|
|
65845
66134
|
async function loadProjectCommands() {
|
|
65846
|
-
const projectCommandsDir =
|
|
66135
|
+
const projectCommandsDir = join58(process.cwd(), ".claude", "commands");
|
|
65847
66136
|
const commands2 = await loadCommandsFromDir(projectCommandsDir, "project");
|
|
65848
66137
|
return commandsToRecord(commands2);
|
|
65849
66138
|
}
|
|
65850
66139
|
async function loadOpencodeGlobalCommands() {
|
|
65851
66140
|
const configDir = getOpenCodeConfigDir({ binary: "opencode" });
|
|
65852
|
-
const opencodeCommandsDir =
|
|
66141
|
+
const opencodeCommandsDir = join58(configDir, "command");
|
|
65853
66142
|
const commands2 = await loadCommandsFromDir(opencodeCommandsDir, "opencode");
|
|
65854
66143
|
return commandsToRecord(commands2);
|
|
65855
66144
|
}
|
|
65856
66145
|
async function loadOpencodeProjectCommands() {
|
|
65857
|
-
const opencodeProjectDir =
|
|
66146
|
+
const opencodeProjectDir = join58(process.cwd(), ".opencode", "command");
|
|
65858
66147
|
const commands2 = await loadCommandsFromDir(opencodeProjectDir, "opencode-project");
|
|
65859
66148
|
return commandsToRecord(commands2);
|
|
65860
66149
|
}
|
|
@@ -65862,8 +66151,8 @@ async function loadOpencodeProjectCommands() {
|
|
|
65862
66151
|
init_frontmatter();
|
|
65863
66152
|
init_file_utils();
|
|
65864
66153
|
init_shared();
|
|
65865
|
-
import { existsSync as
|
|
65866
|
-
import { join as
|
|
66154
|
+
import { existsSync as existsSync50, readdirSync as readdirSync18, readFileSync as readFileSync31 } from "fs";
|
|
66155
|
+
import { join as join59, basename as basename7 } from "path";
|
|
65867
66156
|
function parseToolsConfig(toolsStr) {
|
|
65868
66157
|
if (!toolsStr)
|
|
65869
66158
|
return;
|
|
@@ -65877,18 +66166,18 @@ function parseToolsConfig(toolsStr) {
|
|
|
65877
66166
|
return result;
|
|
65878
66167
|
}
|
|
65879
66168
|
function loadAgentsFromDir(agentsDir, scope) {
|
|
65880
|
-
if (!
|
|
66169
|
+
if (!existsSync50(agentsDir)) {
|
|
65881
66170
|
return [];
|
|
65882
66171
|
}
|
|
65883
|
-
const entries =
|
|
66172
|
+
const entries = readdirSync18(agentsDir, { withFileTypes: true });
|
|
65884
66173
|
const agents = [];
|
|
65885
66174
|
for (const entry of entries) {
|
|
65886
66175
|
if (!isMarkdownFile(entry))
|
|
65887
66176
|
continue;
|
|
65888
|
-
const agentPath =
|
|
66177
|
+
const agentPath = join59(agentsDir, entry.name);
|
|
65889
66178
|
const agentName = basename7(entry.name, ".md");
|
|
65890
66179
|
try {
|
|
65891
|
-
const content =
|
|
66180
|
+
const content = readFileSync31(agentPath, "utf-8");
|
|
65892
66181
|
const { data, body } = parseFrontmatter(content);
|
|
65893
66182
|
const name = data.name || agentName;
|
|
65894
66183
|
const originalDescription = data.description || "";
|
|
@@ -65915,7 +66204,7 @@ function loadAgentsFromDir(agentsDir, scope) {
|
|
|
65915
66204
|
return agents;
|
|
65916
66205
|
}
|
|
65917
66206
|
function loadUserAgents() {
|
|
65918
|
-
const userAgentsDir =
|
|
66207
|
+
const userAgentsDir = join59(getClaudeConfigDir(), "agents");
|
|
65919
66208
|
const agents = loadAgentsFromDir(userAgentsDir, "user");
|
|
65920
66209
|
const result = {};
|
|
65921
66210
|
for (const agent of agents) {
|
|
@@ -65924,7 +66213,7 @@ function loadUserAgents() {
|
|
|
65924
66213
|
return result;
|
|
65925
66214
|
}
|
|
65926
66215
|
function loadProjectAgents() {
|
|
65927
|
-
const projectAgentsDir =
|
|
66216
|
+
const projectAgentsDir = join59(process.cwd(), ".claude", "agents");
|
|
65928
66217
|
const agents = loadAgentsFromDir(projectAgentsDir, "project");
|
|
65929
66218
|
const result = {};
|
|
65930
66219
|
for (const agent of agents) {
|
|
@@ -65936,18 +66225,18 @@ function loadProjectAgents() {
|
|
|
65936
66225
|
init_frontmatter();
|
|
65937
66226
|
init_file_utils();
|
|
65938
66227
|
init_logger();
|
|
65939
|
-
import { existsSync as
|
|
66228
|
+
import { existsSync as existsSync51, readdirSync as readdirSync19, readFileSync as readFileSync32 } from "fs";
|
|
65940
66229
|
import { homedir as homedir13 } from "os";
|
|
65941
|
-
import { join as
|
|
66230
|
+
import { join as join60, basename as basename8 } from "path";
|
|
65942
66231
|
var CLAUDE_PLUGIN_ROOT_VAR = "${CLAUDE_PLUGIN_ROOT}";
|
|
65943
66232
|
function getPluginsBaseDir() {
|
|
65944
66233
|
if (process.env.CLAUDE_PLUGINS_HOME) {
|
|
65945
66234
|
return process.env.CLAUDE_PLUGINS_HOME;
|
|
65946
66235
|
}
|
|
65947
|
-
return
|
|
66236
|
+
return join60(homedir13(), ".claude", "plugins");
|
|
65948
66237
|
}
|
|
65949
66238
|
function getInstalledPluginsPath() {
|
|
65950
|
-
return
|
|
66239
|
+
return join60(getPluginsBaseDir(), "installed_plugins.json");
|
|
65951
66240
|
}
|
|
65952
66241
|
function resolvePluginPath(path8, pluginRoot) {
|
|
65953
66242
|
return path8.replace(CLAUDE_PLUGIN_ROOT_VAR, pluginRoot);
|
|
@@ -65972,11 +66261,11 @@ function resolvePluginPaths(obj, pluginRoot) {
|
|
|
65972
66261
|
}
|
|
65973
66262
|
function loadInstalledPlugins() {
|
|
65974
66263
|
const dbPath = getInstalledPluginsPath();
|
|
65975
|
-
if (!
|
|
66264
|
+
if (!existsSync51(dbPath)) {
|
|
65976
66265
|
return null;
|
|
65977
66266
|
}
|
|
65978
66267
|
try {
|
|
65979
|
-
const content =
|
|
66268
|
+
const content = readFileSync32(dbPath, "utf-8");
|
|
65980
66269
|
return JSON.parse(content);
|
|
65981
66270
|
} catch (error92) {
|
|
65982
66271
|
log("Failed to load installed plugins database", error92);
|
|
@@ -65987,15 +66276,15 @@ function getClaudeSettingsPath() {
|
|
|
65987
66276
|
if (process.env.CLAUDE_SETTINGS_PATH) {
|
|
65988
66277
|
return process.env.CLAUDE_SETTINGS_PATH;
|
|
65989
66278
|
}
|
|
65990
|
-
return
|
|
66279
|
+
return join60(homedir13(), ".claude", "settings.json");
|
|
65991
66280
|
}
|
|
65992
66281
|
function loadClaudeSettings() {
|
|
65993
66282
|
const settingsPath = getClaudeSettingsPath();
|
|
65994
|
-
if (!
|
|
66283
|
+
if (!existsSync51(settingsPath)) {
|
|
65995
66284
|
return null;
|
|
65996
66285
|
}
|
|
65997
66286
|
try {
|
|
65998
|
-
const content =
|
|
66287
|
+
const content = readFileSync32(settingsPath, "utf-8");
|
|
65999
66288
|
return JSON.parse(content);
|
|
66000
66289
|
} catch (error92) {
|
|
66001
66290
|
log("Failed to load Claude settings", error92);
|
|
@@ -66003,12 +66292,12 @@ function loadClaudeSettings() {
|
|
|
66003
66292
|
}
|
|
66004
66293
|
}
|
|
66005
66294
|
function loadPluginManifest(installPath) {
|
|
66006
|
-
const manifestPath =
|
|
66007
|
-
if (!
|
|
66295
|
+
const manifestPath = join60(installPath, ".claude-plugin", "plugin.json");
|
|
66296
|
+
if (!existsSync51(manifestPath)) {
|
|
66008
66297
|
return null;
|
|
66009
66298
|
}
|
|
66010
66299
|
try {
|
|
66011
|
-
const content =
|
|
66300
|
+
const content = readFileSync32(manifestPath, "utf-8");
|
|
66012
66301
|
return JSON.parse(content);
|
|
66013
66302
|
} catch (error92) {
|
|
66014
66303
|
log(`Failed to load plugin manifest from ${manifestPath}`, error92);
|
|
@@ -66055,7 +66344,7 @@ function discoverInstalledPlugins(options) {
|
|
|
66055
66344
|
continue;
|
|
66056
66345
|
}
|
|
66057
66346
|
const { installPath, scope, version: version3 } = installation;
|
|
66058
|
-
if (!
|
|
66347
|
+
if (!existsSync51(installPath)) {
|
|
66059
66348
|
errors5.push({
|
|
66060
66349
|
pluginKey,
|
|
66061
66350
|
installPath,
|
|
@@ -66073,21 +66362,21 @@ function discoverInstalledPlugins(options) {
|
|
|
66073
66362
|
pluginKey,
|
|
66074
66363
|
manifest: manifest ?? undefined
|
|
66075
66364
|
};
|
|
66076
|
-
if (
|
|
66077
|
-
loadedPlugin.commandsDir =
|
|
66365
|
+
if (existsSync51(join60(installPath, "commands"))) {
|
|
66366
|
+
loadedPlugin.commandsDir = join60(installPath, "commands");
|
|
66078
66367
|
}
|
|
66079
|
-
if (
|
|
66080
|
-
loadedPlugin.agentsDir =
|
|
66368
|
+
if (existsSync51(join60(installPath, "agents"))) {
|
|
66369
|
+
loadedPlugin.agentsDir = join60(installPath, "agents");
|
|
66081
66370
|
}
|
|
66082
|
-
if (
|
|
66083
|
-
loadedPlugin.skillsDir =
|
|
66371
|
+
if (existsSync51(join60(installPath, "skills"))) {
|
|
66372
|
+
loadedPlugin.skillsDir = join60(installPath, "skills");
|
|
66084
66373
|
}
|
|
66085
|
-
const hooksPath =
|
|
66086
|
-
if (
|
|
66374
|
+
const hooksPath = join60(installPath, "hooks", "hooks.json");
|
|
66375
|
+
if (existsSync51(hooksPath)) {
|
|
66087
66376
|
loadedPlugin.hooksPath = hooksPath;
|
|
66088
66377
|
}
|
|
66089
|
-
const mcpPath =
|
|
66090
|
-
if (
|
|
66378
|
+
const mcpPath = join60(installPath, ".mcp.json");
|
|
66379
|
+
if (existsSync51(mcpPath)) {
|
|
66091
66380
|
loadedPlugin.mcpPath = mcpPath;
|
|
66092
66381
|
}
|
|
66093
66382
|
plugins.push(loadedPlugin);
|
|
@@ -66098,17 +66387,17 @@ function discoverInstalledPlugins(options) {
|
|
|
66098
66387
|
function loadPluginCommands(plugins) {
|
|
66099
66388
|
const commands2 = {};
|
|
66100
66389
|
for (const plugin of plugins) {
|
|
66101
|
-
if (!plugin.commandsDir || !
|
|
66390
|
+
if (!plugin.commandsDir || !existsSync51(plugin.commandsDir))
|
|
66102
66391
|
continue;
|
|
66103
|
-
const entries =
|
|
66392
|
+
const entries = readdirSync19(plugin.commandsDir, { withFileTypes: true });
|
|
66104
66393
|
for (const entry of entries) {
|
|
66105
66394
|
if (!isMarkdownFile(entry))
|
|
66106
66395
|
continue;
|
|
66107
|
-
const commandPath =
|
|
66396
|
+
const commandPath = join60(plugin.commandsDir, entry.name);
|
|
66108
66397
|
const commandName = basename8(entry.name, ".md");
|
|
66109
66398
|
const namespacedName = `${plugin.name}:${commandName}`;
|
|
66110
66399
|
try {
|
|
66111
|
-
const content =
|
|
66400
|
+
const content = readFileSync32(commandPath, "utf-8");
|
|
66112
66401
|
const { data, body } = parseFrontmatter(content);
|
|
66113
66402
|
const wrappedTemplate = `<command-instruction>
|
|
66114
66403
|
${body.trim()}
|
|
@@ -66140,21 +66429,21 @@ $ARGUMENTS
|
|
|
66140
66429
|
function loadPluginSkillsAsCommands(plugins) {
|
|
66141
66430
|
const skills = {};
|
|
66142
66431
|
for (const plugin of plugins) {
|
|
66143
|
-
if (!plugin.skillsDir || !
|
|
66432
|
+
if (!plugin.skillsDir || !existsSync51(plugin.skillsDir))
|
|
66144
66433
|
continue;
|
|
66145
|
-
const entries =
|
|
66434
|
+
const entries = readdirSync19(plugin.skillsDir, { withFileTypes: true });
|
|
66146
66435
|
for (const entry of entries) {
|
|
66147
66436
|
if (entry.name.startsWith("."))
|
|
66148
66437
|
continue;
|
|
66149
|
-
const skillPath =
|
|
66438
|
+
const skillPath = join60(plugin.skillsDir, entry.name);
|
|
66150
66439
|
if (!entry.isDirectory() && !entry.isSymbolicLink())
|
|
66151
66440
|
continue;
|
|
66152
66441
|
const resolvedPath = resolveSymlink(skillPath);
|
|
66153
|
-
const skillMdPath =
|
|
66154
|
-
if (!
|
|
66442
|
+
const skillMdPath = join60(resolvedPath, "SKILL.md");
|
|
66443
|
+
if (!existsSync51(skillMdPath))
|
|
66155
66444
|
continue;
|
|
66156
66445
|
try {
|
|
66157
|
-
const content =
|
|
66446
|
+
const content = readFileSync32(skillMdPath, "utf-8");
|
|
66158
66447
|
const { data, body } = parseFrontmatter(content);
|
|
66159
66448
|
const skillName = data.name || entry.name;
|
|
66160
66449
|
const namespacedName = `${plugin.name}:${skillName}`;
|
|
@@ -66201,17 +66490,17 @@ function parseToolsConfig2(toolsStr) {
|
|
|
66201
66490
|
function loadPluginAgents(plugins) {
|
|
66202
66491
|
const agents = {};
|
|
66203
66492
|
for (const plugin of plugins) {
|
|
66204
|
-
if (!plugin.agentsDir || !
|
|
66493
|
+
if (!plugin.agentsDir || !existsSync51(plugin.agentsDir))
|
|
66205
66494
|
continue;
|
|
66206
|
-
const entries =
|
|
66495
|
+
const entries = readdirSync19(plugin.agentsDir, { withFileTypes: true });
|
|
66207
66496
|
for (const entry of entries) {
|
|
66208
66497
|
if (!isMarkdownFile(entry))
|
|
66209
66498
|
continue;
|
|
66210
|
-
const agentPath =
|
|
66499
|
+
const agentPath = join60(plugin.agentsDir, entry.name);
|
|
66211
66500
|
const agentName = basename8(entry.name, ".md");
|
|
66212
66501
|
const namespacedName = `${plugin.name}:${agentName}`;
|
|
66213
66502
|
try {
|
|
66214
|
-
const content =
|
|
66503
|
+
const content = readFileSync32(agentPath, "utf-8");
|
|
66215
66504
|
const { data, body } = parseFrontmatter(content);
|
|
66216
66505
|
const name = data.name || agentName;
|
|
66217
66506
|
const originalDescription = data.description || "";
|
|
@@ -66237,7 +66526,7 @@ function loadPluginAgents(plugins) {
|
|
|
66237
66526
|
async function loadPluginMcpServers(plugins) {
|
|
66238
66527
|
const servers = {};
|
|
66239
66528
|
for (const plugin of plugins) {
|
|
66240
|
-
if (!plugin.mcpPath || !
|
|
66529
|
+
if (!plugin.mcpPath || !existsSync51(plugin.mcpPath))
|
|
66241
66530
|
continue;
|
|
66242
66531
|
try {
|
|
66243
66532
|
const content = await Bun.file(plugin.mcpPath).text();
|
|
@@ -66269,10 +66558,10 @@ async function loadPluginMcpServers(plugins) {
|
|
|
66269
66558
|
function loadPluginHooksConfigs(plugins) {
|
|
66270
66559
|
const configs = [];
|
|
66271
66560
|
for (const plugin of plugins) {
|
|
66272
|
-
if (!plugin.hooksPath || !
|
|
66561
|
+
if (!plugin.hooksPath || !existsSync51(plugin.hooksPath))
|
|
66273
66562
|
continue;
|
|
66274
66563
|
try {
|
|
66275
|
-
const content =
|
|
66564
|
+
const content = readFileSync32(plugin.hooksPath, "utf-8");
|
|
66276
66565
|
let config4 = JSON.parse(content);
|
|
66277
66566
|
config4 = resolvePluginPaths(config4, plugin.installPath);
|
|
66278
66567
|
configs.push(config4);
|
|
@@ -67798,6 +68087,44 @@ function createConfigHandler(deps) {
|
|
|
67798
68087
|
};
|
|
67799
68088
|
};
|
|
67800
68089
|
}
|
|
68090
|
+
// src/index.ts
|
|
68091
|
+
init_perf_tracer();
|
|
68092
|
+
init_fileio_monitor();
|
|
68093
|
+
|
|
68094
|
+
// src/tools/perf-profiler/client-patch.ts
|
|
68095
|
+
function patchSessionClient(client2, tracer) {
|
|
68096
|
+
if (!tracer.isEnabled())
|
|
68097
|
+
return;
|
|
68098
|
+
const session = client2.session;
|
|
68099
|
+
if (!session || typeof session !== "object")
|
|
68100
|
+
return;
|
|
68101
|
+
function wrap(methodName, extractMessageCount) {
|
|
68102
|
+
const original = session[methodName];
|
|
68103
|
+
if (typeof original !== "function")
|
|
68104
|
+
return;
|
|
68105
|
+
session[methodName] = async function(opts) {
|
|
68106
|
+
const start = performance.now();
|
|
68107
|
+
let error92;
|
|
68108
|
+
try {
|
|
68109
|
+
const result = await original.call(session, opts);
|
|
68110
|
+
const durationMs = performance.now() - start;
|
|
68111
|
+
tracer.recordApiCall(methodName, durationMs, opts?.path?.id ?? "", extractMessageCount ? extractMessageCount(result) : undefined);
|
|
68112
|
+
return result;
|
|
68113
|
+
} catch (err) {
|
|
68114
|
+
const durationMs = performance.now() - start;
|
|
68115
|
+
error92 = err instanceof Error ? err.message : String(err);
|
|
68116
|
+
tracer.recordApiCall(methodName, durationMs, opts?.path?.id ?? "", undefined, error92);
|
|
68117
|
+
throw err;
|
|
68118
|
+
}
|
|
68119
|
+
};
|
|
68120
|
+
}
|
|
68121
|
+
wrap("messages", (r) => r?.data?.length ?? undefined);
|
|
68122
|
+
wrap("prompt", (r) => r?.data ? 1 : undefined);
|
|
68123
|
+
wrap("todo", (r) => r?.data?.length ?? undefined);
|
|
68124
|
+
wrap("status", (r) => r?.data ? Object.keys(r.data).length : undefined);
|
|
68125
|
+
wrap("summarize");
|
|
68126
|
+
}
|
|
68127
|
+
|
|
67801
68128
|
// src/index.ts
|
|
67802
68129
|
var OhMyOpenCodePlugin = async (ctx) => {
|
|
67803
68130
|
log("[OhMyOpenCodePlugin] ENTRY - plugin loading", { directory: ctx.directory });
|
|
@@ -67863,6 +68190,34 @@ var OhMyOpenCodePlugin = async (ctx) => {
|
|
|
67863
68190
|
const taskResumeInfo = createTaskResumeInfoHook();
|
|
67864
68191
|
const backgroundManager = new BackgroundManager(ctx, pluginConfig.background_task);
|
|
67865
68192
|
const atlasHook = isHookEnabled("atlas") ? createAtlasHook(ctx, { directory: ctx.directory, backgroundManager }) : null;
|
|
68193
|
+
const perfTracer = pluginConfig.experimental?.profiling?.enabled ? new PerfTracer({
|
|
68194
|
+
enabled: true,
|
|
68195
|
+
outputDir: pluginConfig.experimental.profiling.output_dir,
|
|
68196
|
+
slowThreshold: pluginConfig.experimental.profiling.slow_threshold_ms,
|
|
68197
|
+
memorySnapshotInterval: pluginConfig.experimental.profiling.memory_snapshot_interval
|
|
68198
|
+
}) : new PerfTracer({ enabled: false });
|
|
68199
|
+
const memoryProbes = {};
|
|
68200
|
+
if (perfTracer.isEnabled()) {
|
|
68201
|
+
memoryProbes.subagentSessions = () => subagentSessions.size;
|
|
68202
|
+
memoryProbes.backgroundRunningTasks = () => backgroundManager.getRunningTasks().length;
|
|
68203
|
+
memoryProbes.backgroundCompletedTasks = () => backgroundManager.getCompletedTasks().length;
|
|
68204
|
+
}
|
|
68205
|
+
const perfProfiler = isHookEnabled("perf-profiler") ? createPerfProfilerHook({
|
|
68206
|
+
config: pluginConfig.experimental?.profiling ?? { enabled: false, slow_threshold_ms: 100, memory_snapshot_interval: 5, trace_api: true, trace_fileio: true, trace_polling: true },
|
|
68207
|
+
tracer: perfTracer,
|
|
68208
|
+
memoryProbes
|
|
68209
|
+
}) : null;
|
|
68210
|
+
if (perfTracer.isEnabled()) {
|
|
68211
|
+
try {
|
|
68212
|
+
patchSessionClient(ctx.client, perfTracer);
|
|
68213
|
+
} catch {}
|
|
68214
|
+
try {
|
|
68215
|
+
setFileIOMonitor(createFileIOMonitor(perfTracer));
|
|
68216
|
+
} catch {}
|
|
68217
|
+
try {
|
|
68218
|
+
backgroundManager.setPerfTracer(perfTracer);
|
|
68219
|
+
} catch {}
|
|
68220
|
+
}
|
|
67866
68221
|
initTaskToastManager(ctx.client);
|
|
67867
68222
|
const todoContinuationEnforcer = isHookEnabled("todo-continuation-enforcer") ? createTodoContinuationEnforcer(ctx, { backgroundManager }) : null;
|
|
67868
68223
|
if (sessionRecovery && todoContinuationEnforcer) {
|
|
@@ -67927,6 +68282,27 @@ var OhMyOpenCodePlugin = async (ctx) => {
|
|
|
67927
68282
|
pluginConfig,
|
|
67928
68283
|
modelCacheState
|
|
67929
68284
|
});
|
|
68285
|
+
async function wrapWithTiming(tracer, pipeline2, hookName, fn, sessionID, tool3) {
|
|
68286
|
+
const start = performance.now();
|
|
68287
|
+
let error92;
|
|
68288
|
+
try {
|
|
68289
|
+
await fn();
|
|
68290
|
+
} catch (e) {
|
|
68291
|
+
error92 = String(e);
|
|
68292
|
+
throw e;
|
|
68293
|
+
} finally {
|
|
68294
|
+
tracer.recordHook(pipeline2, hookName, performance.now() - start, sessionID ?? "", tool3, error92);
|
|
68295
|
+
}
|
|
68296
|
+
}
|
|
68297
|
+
function getEventSessionID(input) {
|
|
68298
|
+
const props = input.event.properties;
|
|
68299
|
+
if (!props)
|
|
68300
|
+
return "";
|
|
68301
|
+
const info = props.info;
|
|
68302
|
+
if (input.event.type === "session.deleted" || input.event.type === "session.created")
|
|
68303
|
+
return info?.id ?? "";
|
|
68304
|
+
return props.sessionID ?? "";
|
|
68305
|
+
}
|
|
67930
68306
|
return {
|
|
67931
68307
|
tool: {
|
|
67932
68308
|
...builtinTools,
|
|
@@ -67953,10 +68329,17 @@ var OhMyOpenCodePlugin = async (ctx) => {
|
|
|
67953
68329
|
} else {
|
|
67954
68330
|
applyAgentVariant(pluginConfig, input.agent, message);
|
|
67955
68331
|
}
|
|
67956
|
-
|
|
67957
|
-
|
|
67958
|
-
await
|
|
67959
|
-
|
|
68332
|
+
const pipelineStart = performance.now();
|
|
68333
|
+
let hookCount = 0;
|
|
68334
|
+
await wrapWithTiming(perfTracer, "chat.message", "keywordDetector", () => keywordDetector?.["chat.message"]?.(input, output), input.sessionID);
|
|
68335
|
+
hookCount++;
|
|
68336
|
+
await wrapWithTiming(perfTracer, "chat.message", "claudeCodeHooks", () => claudeCodeHooks["chat.message"]?.(input, output), input.sessionID);
|
|
68337
|
+
hookCount++;
|
|
68338
|
+
await wrapWithTiming(perfTracer, "chat.message", "autoSlashCommand", () => autoSlashCommand?.["chat.message"]?.(input, output), input.sessionID);
|
|
68339
|
+
hookCount++;
|
|
68340
|
+
await wrapWithTiming(perfTracer, "chat.message", "startWork", () => startWork?.["chat.message"]?.(input, output), input.sessionID);
|
|
68341
|
+
hookCount++;
|
|
68342
|
+
perfTracer.recordPipeline("chat.message", performance.now() - pipelineStart, hookCount, input.sessionID);
|
|
67960
68343
|
if (ralphLoop) {
|
|
67961
68344
|
const parts = output.parts;
|
|
67962
68345
|
const promptText = parts?.filter((p) => p.type === "text" && p.text).map((p) => p.text).join(`
|
|
@@ -67986,27 +68369,49 @@ var OhMyOpenCodePlugin = async (ctx) => {
|
|
|
67986
68369
|
}
|
|
67987
68370
|
}
|
|
67988
68371
|
},
|
|
68372
|
+
"chat.params": async (input, output) => {
|
|
68373
|
+
await thinkMode?.["chat.params"]?.(input, output);
|
|
68374
|
+
},
|
|
67989
68375
|
"experimental.chat.messages.transform": async (input, output) => {
|
|
67990
68376
|
await contextInjectorMessagesTransform?.["experimental.chat.messages.transform"]?.(input, output);
|
|
67991
68377
|
await thinkingBlockValidator?.["experimental.chat.messages.transform"]?.(input, output);
|
|
67992
68378
|
},
|
|
67993
68379
|
config: configHandler,
|
|
67994
68380
|
event: async (input) => {
|
|
67995
|
-
|
|
67996
|
-
|
|
67997
|
-
await
|
|
67998
|
-
|
|
67999
|
-
await
|
|
68000
|
-
|
|
68001
|
-
await
|
|
68002
|
-
|
|
68003
|
-
await
|
|
68004
|
-
|
|
68005
|
-
await
|
|
68006
|
-
|
|
68007
|
-
await
|
|
68008
|
-
|
|
68009
|
-
await
|
|
68381
|
+
const pipelineStart = performance.now();
|
|
68382
|
+
let hookCount = 0;
|
|
68383
|
+
await perfProfiler?.event?.(input);
|
|
68384
|
+
const evtSessionID = getEventSessionID(input);
|
|
68385
|
+
await wrapWithTiming(perfTracer, "event", "autoUpdateChecker", () => autoUpdateChecker?.event(input), evtSessionID);
|
|
68386
|
+
hookCount++;
|
|
68387
|
+
await wrapWithTiming(perfTracer, "event", "claudeCodeHooks", () => claudeCodeHooks.event(input), evtSessionID);
|
|
68388
|
+
hookCount++;
|
|
68389
|
+
await wrapWithTiming(perfTracer, "event", "backgroundNotificationHook", () => backgroundNotificationHook?.event(input), evtSessionID);
|
|
68390
|
+
hookCount++;
|
|
68391
|
+
await wrapWithTiming(perfTracer, "event", "sessionNotification", () => sessionNotification?.(input), evtSessionID);
|
|
68392
|
+
hookCount++;
|
|
68393
|
+
await wrapWithTiming(perfTracer, "event", "todoContinuationEnforcer", () => todoContinuationEnforcer?.handler(input), evtSessionID);
|
|
68394
|
+
hookCount++;
|
|
68395
|
+
await wrapWithTiming(perfTracer, "event", "contextWindowMonitor", () => contextWindowMonitor?.event(input), evtSessionID);
|
|
68396
|
+
hookCount++;
|
|
68397
|
+
await wrapWithTiming(perfTracer, "event", "directoryAgentsInjector", () => directoryAgentsInjector?.event(input), evtSessionID);
|
|
68398
|
+
hookCount++;
|
|
68399
|
+
await wrapWithTiming(perfTracer, "event", "directoryReadmeInjector", () => directoryReadmeInjector?.event(input), evtSessionID);
|
|
68400
|
+
hookCount++;
|
|
68401
|
+
await wrapWithTiming(perfTracer, "event", "rulesInjector", () => rulesInjector?.event(input), evtSessionID);
|
|
68402
|
+
hookCount++;
|
|
68403
|
+
await wrapWithTiming(perfTracer, "event", "thinkMode", () => thinkMode?.event(input), evtSessionID);
|
|
68404
|
+
hookCount++;
|
|
68405
|
+
await wrapWithTiming(perfTracer, "event", "anthropicContextWindowLimitRecovery", () => anthropicContextWindowLimitRecovery?.event(input), evtSessionID);
|
|
68406
|
+
hookCount++;
|
|
68407
|
+
await wrapWithTiming(perfTracer, "event", "agentUsageReminder", () => agentUsageReminder?.event(input), evtSessionID);
|
|
68408
|
+
hookCount++;
|
|
68409
|
+
await wrapWithTiming(perfTracer, "event", "interactiveBashSession", () => interactiveBashSession?.event(input), evtSessionID);
|
|
68410
|
+
hookCount++;
|
|
68411
|
+
await wrapWithTiming(perfTracer, "event", "ralphLoop", () => ralphLoop?.event(input), evtSessionID);
|
|
68412
|
+
hookCount++;
|
|
68413
|
+
await wrapWithTiming(perfTracer, "event", "atlasHook", () => atlasHook?.handler(input), evtSessionID);
|
|
68414
|
+
hookCount++;
|
|
68010
68415
|
const { event } = input;
|
|
68011
68416
|
const props = event.properties;
|
|
68012
68417
|
if (event.type === "session.created") {
|
|
@@ -68059,17 +68464,30 @@ var OhMyOpenCodePlugin = async (ctx) => {
|
|
|
68059
68464
|
}
|
|
68060
68465
|
}
|
|
68061
68466
|
}
|
|
68467
|
+
perfTracer.recordPipeline("event", performance.now() - pipelineStart, hookCount, evtSessionID);
|
|
68468
|
+
perfTracer.flush();
|
|
68062
68469
|
},
|
|
68063
68470
|
"tool.execute.before": async (input, output) => {
|
|
68064
|
-
|
|
68065
|
-
|
|
68066
|
-
await
|
|
68067
|
-
|
|
68068
|
-
await
|
|
68069
|
-
|
|
68070
|
-
await
|
|
68071
|
-
|
|
68072
|
-
await
|
|
68471
|
+
const pipelineStart = performance.now();
|
|
68472
|
+
let hookCount = 0;
|
|
68473
|
+
await wrapWithTiming(perfTracer, "tool.execute.before", "questionLabelTruncator", () => questionLabelTruncator["tool.execute.before"]?.(input, output), input.sessionID, input.tool);
|
|
68474
|
+
hookCount++;
|
|
68475
|
+
await wrapWithTiming(perfTracer, "tool.execute.before", "claudeCodeHooks", () => claudeCodeHooks["tool.execute.before"](input, output), input.sessionID, input.tool);
|
|
68476
|
+
hookCount++;
|
|
68477
|
+
await wrapWithTiming(perfTracer, "tool.execute.before", "nonInteractiveEnv", () => nonInteractiveEnv?.["tool.execute.before"](input, output), input.sessionID, input.tool);
|
|
68478
|
+
hookCount++;
|
|
68479
|
+
await wrapWithTiming(perfTracer, "tool.execute.before", "commentChecker", () => commentChecker?.["tool.execute.before"](input, output), input.sessionID, input.tool);
|
|
68480
|
+
hookCount++;
|
|
68481
|
+
await wrapWithTiming(perfTracer, "tool.execute.before", "directoryAgentsInjector", () => directoryAgentsInjector?.["tool.execute.before"]?.(input, output), input.sessionID, input.tool);
|
|
68482
|
+
hookCount++;
|
|
68483
|
+
await wrapWithTiming(perfTracer, "tool.execute.before", "directoryReadmeInjector", () => directoryReadmeInjector?.["tool.execute.before"]?.(input, output), input.sessionID, input.tool);
|
|
68484
|
+
hookCount++;
|
|
68485
|
+
await wrapWithTiming(perfTracer, "tool.execute.before", "rulesInjector", () => rulesInjector?.["tool.execute.before"]?.(input, output), input.sessionID, input.tool);
|
|
68486
|
+
hookCount++;
|
|
68487
|
+
await wrapWithTiming(perfTracer, "tool.execute.before", "prometheusMdOnly", () => prometheusMdOnly?.["tool.execute.before"]?.(input, output), input.sessionID, input.tool);
|
|
68488
|
+
hookCount++;
|
|
68489
|
+
await wrapWithTiming(perfTracer, "tool.execute.before", "atlasHook", () => atlasHook?.["tool.execute.before"]?.(input, output), input.sessionID, input.tool);
|
|
68490
|
+
hookCount++;
|
|
68073
68491
|
if (input.tool === "task") {
|
|
68074
68492
|
const args = output.args;
|
|
68075
68493
|
const subagentType = args.subagent_type;
|
|
@@ -68109,22 +68527,40 @@ var OhMyOpenCodePlugin = async (ctx) => {
|
|
|
68109
68527
|
});
|
|
68110
68528
|
}
|
|
68111
68529
|
}
|
|
68530
|
+
perfTracer.recordPipeline("tool.execute.before", performance.now() - pipelineStart, hookCount, input.sessionID);
|
|
68112
68531
|
},
|
|
68113
68532
|
"tool.execute.after": async (input, output) => {
|
|
68114
|
-
|
|
68115
|
-
|
|
68116
|
-
await
|
|
68117
|
-
|
|
68118
|
-
await
|
|
68119
|
-
|
|
68120
|
-
await
|
|
68121
|
-
|
|
68122
|
-
await
|
|
68123
|
-
|
|
68124
|
-
await
|
|
68125
|
-
|
|
68126
|
-
await
|
|
68127
|
-
|
|
68533
|
+
const pipelineStart = performance.now();
|
|
68534
|
+
let hookCount = 0;
|
|
68535
|
+
await wrapWithTiming(perfTracer, "tool.execute.after", "claudeCodeHooks", () => claudeCodeHooks["tool.execute.after"](input, output), input.sessionID, input.tool);
|
|
68536
|
+
hookCount++;
|
|
68537
|
+
await wrapWithTiming(perfTracer, "tool.execute.after", "toolOutputTruncator", () => toolOutputTruncator?.["tool.execute.after"](input, output), input.sessionID, input.tool);
|
|
68538
|
+
hookCount++;
|
|
68539
|
+
await wrapWithTiming(perfTracer, "tool.execute.after", "contextWindowMonitor", () => contextWindowMonitor?.["tool.execute.after"](input, output), input.sessionID, input.tool);
|
|
68540
|
+
hookCount++;
|
|
68541
|
+
await wrapWithTiming(perfTracer, "tool.execute.after", "commentChecker", () => commentChecker?.["tool.execute.after"](input, output), input.sessionID, input.tool);
|
|
68542
|
+
hookCount++;
|
|
68543
|
+
await wrapWithTiming(perfTracer, "tool.execute.after", "directoryAgentsInjector", () => directoryAgentsInjector?.["tool.execute.after"](input, output), input.sessionID, input.tool);
|
|
68544
|
+
hookCount++;
|
|
68545
|
+
await wrapWithTiming(perfTracer, "tool.execute.after", "directoryReadmeInjector", () => directoryReadmeInjector?.["tool.execute.after"](input, output), input.sessionID, input.tool);
|
|
68546
|
+
hookCount++;
|
|
68547
|
+
await wrapWithTiming(perfTracer, "tool.execute.after", "rulesInjector", () => rulesInjector?.["tool.execute.after"](input, output), input.sessionID, input.tool);
|
|
68548
|
+
hookCount++;
|
|
68549
|
+
await wrapWithTiming(perfTracer, "tool.execute.after", "emptyTaskResponseDetector", () => emptyTaskResponseDetector?.["tool.execute.after"](input, output), input.sessionID, input.tool);
|
|
68550
|
+
hookCount++;
|
|
68551
|
+
await wrapWithTiming(perfTracer, "tool.execute.after", "agentUsageReminder", () => agentUsageReminder?.["tool.execute.after"](input, output), input.sessionID, input.tool);
|
|
68552
|
+
hookCount++;
|
|
68553
|
+
await wrapWithTiming(perfTracer, "tool.execute.after", "interactiveBashSession", () => interactiveBashSession?.["tool.execute.after"](input, output), input.sessionID, input.tool);
|
|
68554
|
+
hookCount++;
|
|
68555
|
+
await wrapWithTiming(perfTracer, "tool.execute.after", "editErrorRecovery", () => editErrorRecovery?.["tool.execute.after"](input, output), input.sessionID, input.tool);
|
|
68556
|
+
hookCount++;
|
|
68557
|
+
await wrapWithTiming(perfTracer, "tool.execute.after", "delegateTaskRetry", () => delegateTaskRetry?.["tool.execute.after"](input, output), input.sessionID, input.tool);
|
|
68558
|
+
hookCount++;
|
|
68559
|
+
await wrapWithTiming(perfTracer, "tool.execute.after", "atlasHook", () => atlasHook?.["tool.execute.after"]?.(input, output), input.sessionID, input.tool);
|
|
68560
|
+
hookCount++;
|
|
68561
|
+
await wrapWithTiming(perfTracer, "tool.execute.after", "taskResumeInfo", () => taskResumeInfo["tool.execute.after"](input, output), input.sessionID, input.tool);
|
|
68562
|
+
hookCount++;
|
|
68563
|
+
perfTracer.recordPipeline("tool.execute.after", performance.now() - pipelineStart, hookCount, input.sessionID);
|
|
68128
68564
|
}
|
|
68129
68565
|
};
|
|
68130
68566
|
};
|