eminiar 0.10.1 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +1 -1
- package/.cursor-plugin/mcp.json +11 -0
- package/.cursor-plugin/plugin.json +23 -0
- package/README.md +12 -8
- package/dist/cli.js +595 -401
- package/dist/hook.js +687 -463
- package/hooks/cursor.json +36 -0
- package/package.json +7 -4
- package/rules/eminiar.mdc +15 -0
package/dist/hook.js
CHANGED
|
@@ -174,14 +174,14 @@ var require_is_extglob = __commonJS({
|
|
|
174
174
|
"node_modules/is-extglob/index.js"(exports, module) {
|
|
175
175
|
"use strict";
|
|
176
176
|
init_esm_shims();
|
|
177
|
-
module.exports = function isExtglob(
|
|
178
|
-
if (typeof
|
|
177
|
+
module.exports = function isExtglob(str3) {
|
|
178
|
+
if (typeof str3 !== "string" || str3 === "") {
|
|
179
179
|
return false;
|
|
180
180
|
}
|
|
181
181
|
var match;
|
|
182
|
-
while (match = /(\\).|([@?!+*]\(.*\))/g.exec(
|
|
182
|
+
while (match = /(\\).|([@?!+*]\(.*\))/g.exec(str3)) {
|
|
183
183
|
if (match[2]) return true;
|
|
184
|
-
|
|
184
|
+
str3 = str3.slice(match.index + match[0].length);
|
|
185
185
|
}
|
|
186
186
|
return false;
|
|
187
187
|
};
|
|
@@ -195,8 +195,8 @@ var require_is_glob = __commonJS({
|
|
|
195
195
|
init_esm_shims();
|
|
196
196
|
var isExtglob = require_is_extglob();
|
|
197
197
|
var chars = { "{": "}", "(": ")", "[": "]" };
|
|
198
|
-
var strictCheck = function(
|
|
199
|
-
if (
|
|
198
|
+
var strictCheck = function(str3) {
|
|
199
|
+
if (str3[0] === "!") {
|
|
200
200
|
return true;
|
|
201
201
|
}
|
|
202
202
|
var index = 0;
|
|
@@ -205,70 +205,70 @@ var require_is_glob = __commonJS({
|
|
|
205
205
|
var closeCurlyIndex = -2;
|
|
206
206
|
var closeParenIndex = -2;
|
|
207
207
|
var backSlashIndex = -2;
|
|
208
|
-
while (index <
|
|
209
|
-
if (
|
|
208
|
+
while (index < str3.length) {
|
|
209
|
+
if (str3[index] === "*") {
|
|
210
210
|
return true;
|
|
211
211
|
}
|
|
212
|
-
if (
|
|
212
|
+
if (str3[index + 1] === "?" && /[\].+)]/.test(str3[index])) {
|
|
213
213
|
return true;
|
|
214
214
|
}
|
|
215
|
-
if (closeSquareIndex !== -1 &&
|
|
215
|
+
if (closeSquareIndex !== -1 && str3[index] === "[" && str3[index + 1] !== "]") {
|
|
216
216
|
if (closeSquareIndex < index) {
|
|
217
|
-
closeSquareIndex =
|
|
217
|
+
closeSquareIndex = str3.indexOf("]", index);
|
|
218
218
|
}
|
|
219
219
|
if (closeSquareIndex > index) {
|
|
220
220
|
if (backSlashIndex === -1 || backSlashIndex > closeSquareIndex) {
|
|
221
221
|
return true;
|
|
222
222
|
}
|
|
223
|
-
backSlashIndex =
|
|
223
|
+
backSlashIndex = str3.indexOf("\\", index);
|
|
224
224
|
if (backSlashIndex === -1 || backSlashIndex > closeSquareIndex) {
|
|
225
225
|
return true;
|
|
226
226
|
}
|
|
227
227
|
}
|
|
228
228
|
}
|
|
229
|
-
if (closeCurlyIndex !== -1 &&
|
|
230
|
-
closeCurlyIndex =
|
|
229
|
+
if (closeCurlyIndex !== -1 && str3[index] === "{" && str3[index + 1] !== "}") {
|
|
230
|
+
closeCurlyIndex = str3.indexOf("}", index);
|
|
231
231
|
if (closeCurlyIndex > index) {
|
|
232
|
-
backSlashIndex =
|
|
232
|
+
backSlashIndex = str3.indexOf("\\", index);
|
|
233
233
|
if (backSlashIndex === -1 || backSlashIndex > closeCurlyIndex) {
|
|
234
234
|
return true;
|
|
235
235
|
}
|
|
236
236
|
}
|
|
237
237
|
}
|
|
238
|
-
if (closeParenIndex !== -1 &&
|
|
239
|
-
closeParenIndex =
|
|
238
|
+
if (closeParenIndex !== -1 && str3[index] === "(" && str3[index + 1] === "?" && /[:!=]/.test(str3[index + 2]) && str3[index + 3] !== ")") {
|
|
239
|
+
closeParenIndex = str3.indexOf(")", index);
|
|
240
240
|
if (closeParenIndex > index) {
|
|
241
|
-
backSlashIndex =
|
|
241
|
+
backSlashIndex = str3.indexOf("\\", index);
|
|
242
242
|
if (backSlashIndex === -1 || backSlashIndex > closeParenIndex) {
|
|
243
243
|
return true;
|
|
244
244
|
}
|
|
245
245
|
}
|
|
246
246
|
}
|
|
247
|
-
if (pipeIndex !== -1 &&
|
|
247
|
+
if (pipeIndex !== -1 && str3[index] === "(" && str3[index + 1] !== "|") {
|
|
248
248
|
if (pipeIndex < index) {
|
|
249
|
-
pipeIndex =
|
|
249
|
+
pipeIndex = str3.indexOf("|", index);
|
|
250
250
|
}
|
|
251
|
-
if (pipeIndex !== -1 &&
|
|
252
|
-
closeParenIndex =
|
|
251
|
+
if (pipeIndex !== -1 && str3[pipeIndex + 1] !== ")") {
|
|
252
|
+
closeParenIndex = str3.indexOf(")", pipeIndex);
|
|
253
253
|
if (closeParenIndex > pipeIndex) {
|
|
254
|
-
backSlashIndex =
|
|
254
|
+
backSlashIndex = str3.indexOf("\\", pipeIndex);
|
|
255
255
|
if (backSlashIndex === -1 || backSlashIndex > closeParenIndex) {
|
|
256
256
|
return true;
|
|
257
257
|
}
|
|
258
258
|
}
|
|
259
259
|
}
|
|
260
260
|
}
|
|
261
|
-
if (
|
|
262
|
-
var open4 =
|
|
261
|
+
if (str3[index] === "\\") {
|
|
262
|
+
var open4 = str3[index + 1];
|
|
263
263
|
index += 2;
|
|
264
264
|
var close = chars[open4];
|
|
265
265
|
if (close) {
|
|
266
|
-
var n =
|
|
266
|
+
var n = str3.indexOf(close, index);
|
|
267
267
|
if (n !== -1) {
|
|
268
268
|
index = n + 1;
|
|
269
269
|
}
|
|
270
270
|
}
|
|
271
|
-
if (
|
|
271
|
+
if (str3[index] === "!") {
|
|
272
272
|
return true;
|
|
273
273
|
}
|
|
274
274
|
} else {
|
|
@@ -277,26 +277,26 @@ var require_is_glob = __commonJS({
|
|
|
277
277
|
}
|
|
278
278
|
return false;
|
|
279
279
|
};
|
|
280
|
-
var relaxedCheck = function(
|
|
281
|
-
if (
|
|
280
|
+
var relaxedCheck = function(str3) {
|
|
281
|
+
if (str3[0] === "!") {
|
|
282
282
|
return true;
|
|
283
283
|
}
|
|
284
284
|
var index = 0;
|
|
285
|
-
while (index <
|
|
286
|
-
if (/[*?{}()[\]]/.test(
|
|
285
|
+
while (index < str3.length) {
|
|
286
|
+
if (/[*?{}()[\]]/.test(str3[index])) {
|
|
287
287
|
return true;
|
|
288
288
|
}
|
|
289
|
-
if (
|
|
290
|
-
var open4 =
|
|
289
|
+
if (str3[index] === "\\") {
|
|
290
|
+
var open4 = str3[index + 1];
|
|
291
291
|
index += 2;
|
|
292
292
|
var close = chars[open4];
|
|
293
293
|
if (close) {
|
|
294
|
-
var n =
|
|
294
|
+
var n = str3.indexOf(close, index);
|
|
295
295
|
if (n !== -1) {
|
|
296
296
|
index = n + 1;
|
|
297
297
|
}
|
|
298
298
|
}
|
|
299
|
-
if (
|
|
299
|
+
if (str3[index] === "!") {
|
|
300
300
|
return true;
|
|
301
301
|
}
|
|
302
302
|
} else {
|
|
@@ -305,18 +305,18 @@ var require_is_glob = __commonJS({
|
|
|
305
305
|
}
|
|
306
306
|
return false;
|
|
307
307
|
};
|
|
308
|
-
module.exports = function isGlob(
|
|
309
|
-
if (typeof
|
|
308
|
+
module.exports = function isGlob(str3, options) {
|
|
309
|
+
if (typeof str3 !== "string" || str3 === "") {
|
|
310
310
|
return false;
|
|
311
311
|
}
|
|
312
|
-
if (isExtglob(
|
|
312
|
+
if (isExtglob(str3)) {
|
|
313
313
|
return true;
|
|
314
314
|
}
|
|
315
315
|
var check2 = strictCheck;
|
|
316
316
|
if (options && options.strict === false) {
|
|
317
317
|
check2 = relaxedCheck;
|
|
318
318
|
}
|
|
319
|
-
return check2(
|
|
319
|
+
return check2(str3);
|
|
320
320
|
};
|
|
321
321
|
}
|
|
322
322
|
});
|
|
@@ -334,19 +334,19 @@ var require_glob_parent = __commonJS({
|
|
|
334
334
|
var enclosure = /[\{\[].*[\}\]]$/;
|
|
335
335
|
var globby = /(^|[^\\])([\{\[]|\([^\)]+$)/;
|
|
336
336
|
var escaped = /\\([\!\*\?\|\[\]\(\)\{\}])/g;
|
|
337
|
-
module.exports = function globParent(
|
|
337
|
+
module.exports = function globParent(str3, opts) {
|
|
338
338
|
var options = Object.assign({ flipBackslashes: true }, opts);
|
|
339
|
-
if (options.flipBackslashes && isWin32 &&
|
|
340
|
-
|
|
339
|
+
if (options.flipBackslashes && isWin32 && str3.indexOf(slash) < 0) {
|
|
340
|
+
str3 = str3.replace(backslash, slash);
|
|
341
341
|
}
|
|
342
|
-
if (enclosure.test(
|
|
343
|
-
|
|
342
|
+
if (enclosure.test(str3)) {
|
|
343
|
+
str3 += slash;
|
|
344
344
|
}
|
|
345
|
-
|
|
345
|
+
str3 += "a";
|
|
346
346
|
do {
|
|
347
|
-
|
|
348
|
-
} while (isGlob(
|
|
349
|
-
return
|
|
347
|
+
str3 = pathPosixDirname(str3);
|
|
348
|
+
} while (isGlob(str3) || globby.test(str3));
|
|
349
|
+
return str3.replace(escaped, "$1");
|
|
350
350
|
};
|
|
351
351
|
}
|
|
352
352
|
});
|
|
@@ -668,8 +668,8 @@ var require_to_regex_range = __commonJS({
|
|
|
668
668
|
function toCharacterClass(a, b, options) {
|
|
669
669
|
return `[${a}${b - a === 1 ? "" : "-"}${b}]`;
|
|
670
670
|
}
|
|
671
|
-
function hasPadding(
|
|
672
|
-
return /^-?(0+)\d/.test(
|
|
671
|
+
function hasPadding(str3) {
|
|
672
|
+
return /^-?(0+)\d/.test(str3);
|
|
673
673
|
}
|
|
674
674
|
function padZeros(value, tok2, options) {
|
|
675
675
|
if (!tok2.isPadded) {
|
|
@@ -1659,12 +1659,12 @@ var require_utils2 = __commonJS({
|
|
|
1659
1659
|
REGEX_SPECIAL_CHARS_GLOBAL
|
|
1660
1660
|
} = require_constants2();
|
|
1661
1661
|
exports.isObject = (val) => val !== null && typeof val === "object" && !Array.isArray(val);
|
|
1662
|
-
exports.hasRegexChars = (
|
|
1663
|
-
exports.isRegexChar = (
|
|
1664
|
-
exports.escapeRegex = (
|
|
1665
|
-
exports.toPosixSlashes = (
|
|
1666
|
-
exports.removeBackslashes = (
|
|
1667
|
-
return
|
|
1662
|
+
exports.hasRegexChars = (str3) => REGEX_SPECIAL_CHARS.test(str3);
|
|
1663
|
+
exports.isRegexChar = (str3) => str3.length === 1 && exports.hasRegexChars(str3);
|
|
1664
|
+
exports.escapeRegex = (str3) => str3.replace(REGEX_SPECIAL_CHARS_GLOBAL, "\\$1");
|
|
1665
|
+
exports.toPosixSlashes = (str3) => str3.replace(REGEX_BACKSLASH, "/");
|
|
1666
|
+
exports.removeBackslashes = (str3) => {
|
|
1667
|
+
return str3.replace(REGEX_REMOVE_BACKSLASH, (match) => {
|
|
1668
1668
|
return match === "\\" ? "" : match;
|
|
1669
1669
|
});
|
|
1670
1670
|
};
|
|
@@ -1760,7 +1760,7 @@ var require_scan = __commonJS({
|
|
|
1760
1760
|
const slashes = [];
|
|
1761
1761
|
const tokens = [];
|
|
1762
1762
|
const parts = [];
|
|
1763
|
-
let
|
|
1763
|
+
let str3 = input2;
|
|
1764
1764
|
let index = -1;
|
|
1765
1765
|
let start = 0;
|
|
1766
1766
|
let lastIndex = 0;
|
|
@@ -1779,10 +1779,10 @@ var require_scan = __commonJS({
|
|
|
1779
1779
|
let code;
|
|
1780
1780
|
let token = { value: "", depth: 0, isGlob: false };
|
|
1781
1781
|
const eos = () => index >= length;
|
|
1782
|
-
const peek = () =>
|
|
1782
|
+
const peek = () => str3.charCodeAt(index + 1);
|
|
1783
1783
|
const advance = () => {
|
|
1784
1784
|
prev = code;
|
|
1785
|
-
return
|
|
1785
|
+
return str3.charCodeAt(++index);
|
|
1786
1786
|
};
|
|
1787
1787
|
while (index < length) {
|
|
1788
1788
|
code = advance();
|
|
@@ -1950,24 +1950,24 @@ var require_scan = __commonJS({
|
|
|
1950
1950
|
isExtglob = false;
|
|
1951
1951
|
isGlob = false;
|
|
1952
1952
|
}
|
|
1953
|
-
let base =
|
|
1953
|
+
let base = str3;
|
|
1954
1954
|
let prefix = "";
|
|
1955
1955
|
let glob = "";
|
|
1956
1956
|
if (start > 0) {
|
|
1957
|
-
prefix =
|
|
1958
|
-
|
|
1957
|
+
prefix = str3.slice(0, start);
|
|
1958
|
+
str3 = str3.slice(start);
|
|
1959
1959
|
lastIndex -= start;
|
|
1960
1960
|
}
|
|
1961
1961
|
if (base && isGlob === true && lastIndex > 0) {
|
|
1962
|
-
base =
|
|
1963
|
-
glob =
|
|
1962
|
+
base = str3.slice(0, lastIndex);
|
|
1963
|
+
glob = str3.slice(lastIndex);
|
|
1964
1964
|
} else if (isGlob === true) {
|
|
1965
1965
|
base = "";
|
|
1966
|
-
glob =
|
|
1966
|
+
glob = str3;
|
|
1967
1967
|
} else {
|
|
1968
|
-
base =
|
|
1968
|
+
base = str3;
|
|
1969
1969
|
}
|
|
1970
|
-
if (base && base !== "" && base !== "/" && base !==
|
|
1970
|
+
if (base && base !== "" && base !== "/" && base !== str3) {
|
|
1971
1971
|
if (isPathSeparator(base.charCodeAt(base.length - 1))) {
|
|
1972
1972
|
base = base.slice(0, -1);
|
|
1973
1973
|
}
|
|
@@ -3003,8 +3003,8 @@ var require_parse2 = __commonJS({
|
|
|
3003
3003
|
if (opts2.noglobstar === true) return star;
|
|
3004
3004
|
return `(${capture}(?:(?!${START_ANCHOR}${opts2.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`;
|
|
3005
3005
|
};
|
|
3006
|
-
const create = (
|
|
3007
|
-
switch (
|
|
3006
|
+
const create = (str3) => {
|
|
3007
|
+
switch (str3) {
|
|
3008
3008
|
case "*":
|
|
3009
3009
|
return `${nodot}${ONE_CHAR}${star}`;
|
|
3010
3010
|
case ".*":
|
|
@@ -3022,7 +3022,7 @@ var require_parse2 = __commonJS({
|
|
|
3022
3022
|
case "**/.*":
|
|
3023
3023
|
return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${DOT_LITERAL}${ONE_CHAR}${star}`;
|
|
3024
3024
|
default: {
|
|
3025
|
-
const match = /^(.*?)\.(\w+)$/.exec(
|
|
3025
|
+
const match = /^(.*?)\.(\w+)$/.exec(str3);
|
|
3026
3026
|
if (!match) return;
|
|
3027
3027
|
const source2 = create(match[1]);
|
|
3028
3028
|
if (!source2) return;
|
|
@@ -3055,9 +3055,9 @@ var require_picomatch = __commonJS({
|
|
|
3055
3055
|
var picomatch = (glob, options, returnState = false) => {
|
|
3056
3056
|
if (Array.isArray(glob)) {
|
|
3057
3057
|
const fns = glob.map((input2) => picomatch(input2, options, returnState));
|
|
3058
|
-
const arrayMatcher = (
|
|
3058
|
+
const arrayMatcher = (str3) => {
|
|
3059
3059
|
for (const isMatch of fns) {
|
|
3060
|
-
const state2 = isMatch(
|
|
3060
|
+
const state2 = isMatch(str3);
|
|
3061
3061
|
if (state2) return state2;
|
|
3062
3062
|
}
|
|
3063
3063
|
return false;
|
|
@@ -3133,7 +3133,7 @@ var require_picomatch = __commonJS({
|
|
|
3133
3133
|
const regex = glob instanceof RegExp ? glob : picomatch.makeRe(glob, options);
|
|
3134
3134
|
return regex.test(path2.basename(input2));
|
|
3135
3135
|
};
|
|
3136
|
-
picomatch.isMatch = (
|
|
3136
|
+
picomatch.isMatch = (str3, patterns, options) => picomatch(patterns, options)(str3);
|
|
3137
3137
|
picomatch.parse = (pattern, options) => {
|
|
3138
3138
|
if (Array.isArray(pattern)) return pattern.map((p) => picomatch.parse(p, options));
|
|
3139
3139
|
return parse4(pattern, { ...options, fastpaths: false });
|
|
@@ -3249,7 +3249,7 @@ var require_micromatch = __commonJS({
|
|
|
3249
3249
|
};
|
|
3250
3250
|
micromatch.match = micromatch;
|
|
3251
3251
|
micromatch.matcher = (pattern, options) => picomatch(pattern, options);
|
|
3252
|
-
micromatch.isMatch = (
|
|
3252
|
+
micromatch.isMatch = (str3, patterns, options) => picomatch(patterns, options)(str3);
|
|
3253
3253
|
micromatch.any = micromatch.isMatch;
|
|
3254
3254
|
micromatch.not = (list, patterns, options = {}) => {
|
|
3255
3255
|
patterns = [].concat(patterns).map(String);
|
|
@@ -3267,22 +3267,22 @@ var require_micromatch = __commonJS({
|
|
|
3267
3267
|
}
|
|
3268
3268
|
return [...result];
|
|
3269
3269
|
};
|
|
3270
|
-
micromatch.contains = (
|
|
3271
|
-
if (typeof
|
|
3272
|
-
throw new TypeError(`Expected a string: "${util.inspect(
|
|
3270
|
+
micromatch.contains = (str3, pattern, options) => {
|
|
3271
|
+
if (typeof str3 !== "string") {
|
|
3272
|
+
throw new TypeError(`Expected a string: "${util.inspect(str3)}"`);
|
|
3273
3273
|
}
|
|
3274
3274
|
if (Array.isArray(pattern)) {
|
|
3275
|
-
return pattern.some((p) => micromatch.contains(
|
|
3275
|
+
return pattern.some((p) => micromatch.contains(str3, p, options));
|
|
3276
3276
|
}
|
|
3277
3277
|
if (typeof pattern === "string") {
|
|
3278
|
-
if (isEmptyString(
|
|
3278
|
+
if (isEmptyString(str3) || isEmptyString(pattern)) {
|
|
3279
3279
|
return false;
|
|
3280
3280
|
}
|
|
3281
|
-
if (
|
|
3281
|
+
if (str3.includes(pattern) || str3.startsWith("./") && str3.slice(2).includes(pattern)) {
|
|
3282
3282
|
return true;
|
|
3283
3283
|
}
|
|
3284
3284
|
}
|
|
3285
|
-
return micromatch.isMatch(
|
|
3285
|
+
return micromatch.isMatch(str3, pattern, { ...options, contains: true });
|
|
3286
3286
|
};
|
|
3287
3287
|
micromatch.matchKeys = (obj, patterns, options) => {
|
|
3288
3288
|
if (!utils.isObject(obj)) {
|
|
@@ -3313,11 +3313,11 @@ var require_micromatch = __commonJS({
|
|
|
3313
3313
|
}
|
|
3314
3314
|
return true;
|
|
3315
3315
|
};
|
|
3316
|
-
micromatch.all = (
|
|
3317
|
-
if (typeof
|
|
3318
|
-
throw new TypeError(`Expected a string: "${util.inspect(
|
|
3316
|
+
micromatch.all = (str3, patterns, options) => {
|
|
3317
|
+
if (typeof str3 !== "string") {
|
|
3318
|
+
throw new TypeError(`Expected a string: "${util.inspect(str3)}"`);
|
|
3319
3319
|
}
|
|
3320
|
-
return [].concat(patterns).every((p) => picomatch(p, options)(
|
|
3320
|
+
return [].concat(patterns).every((p) => picomatch(p, options)(str3));
|
|
3321
3321
|
};
|
|
3322
3322
|
micromatch.capture = (glob, input2, options) => {
|
|
3323
3323
|
let posix = utils.isWindows(options);
|
|
@@ -3332,8 +3332,8 @@ var require_micromatch = __commonJS({
|
|
|
3332
3332
|
micromatch.parse = (patterns, options) => {
|
|
3333
3333
|
let res = [];
|
|
3334
3334
|
for (let pattern of [].concat(patterns || [])) {
|
|
3335
|
-
for (let
|
|
3336
|
-
res.push(picomatch.parse(
|
|
3335
|
+
for (let str3 of braces(String(pattern), options)) {
|
|
3336
|
+
res.push(picomatch.parse(str3, options));
|
|
3337
3337
|
}
|
|
3338
3338
|
}
|
|
3339
3339
|
return res;
|
|
@@ -5873,246 +5873,8 @@ var require_out4 = __commonJS({
|
|
|
5873
5873
|
// src/hook.ts
|
|
5874
5874
|
init_esm_shims();
|
|
5875
5875
|
|
|
5876
|
-
// src/hooks/
|
|
5877
|
-
init_esm_shims();
|
|
5878
|
-
|
|
5879
|
-
// src/hooks/capture.ts
|
|
5880
|
-
init_esm_shims();
|
|
5881
|
-
|
|
5882
|
-
// src/capture/classify.ts
|
|
5883
|
-
init_esm_shims();
|
|
5884
|
-
import { createHash } from "crypto";
|
|
5885
|
-
import { realpathSync } from "fs";
|
|
5886
|
-
import { isAbsolute, relative } from "path";
|
|
5887
|
-
|
|
5888
|
-
// src/capture/categories.ts
|
|
5876
|
+
// src/hooks/dispatch.ts
|
|
5889
5877
|
init_esm_shims();
|
|
5890
|
-
var CATEGORIES = {
|
|
5891
|
-
// P1
|
|
5892
|
-
files: 1,
|
|
5893
|
-
tasks: 1,
|
|
5894
|
-
plans: 1,
|
|
5895
|
-
rules: 1,
|
|
5896
|
-
user_prompt: 1,
|
|
5897
|
-
// P2
|
|
5898
|
-
decision: 2,
|
|
5899
|
-
git: 2,
|
|
5900
|
-
error: 2,
|
|
5901
|
-
error_resolution: 2,
|
|
5902
|
-
constraint: 2,
|
|
5903
|
-
blocker: 2,
|
|
5904
|
-
rejected: 2,
|
|
5905
|
-
environment: 2,
|
|
5906
|
-
agent_findings: 2,
|
|
5907
|
-
iteration_loop: 2,
|
|
5908
|
-
assistant_summary: 2,
|
|
5909
|
-
// P3
|
|
5910
|
-
latency: 3,
|
|
5911
|
-
mcp_tool: 3,
|
|
5912
|
-
subagent: 3,
|
|
5913
|
-
skill: 3,
|
|
5914
|
-
external_ref: 3,
|
|
5915
|
-
role: 3,
|
|
5916
|
-
// P4
|
|
5917
|
-
intent: 4,
|
|
5918
|
-
data: 4,
|
|
5919
|
-
tool_call: 4,
|
|
5920
|
-
session_start: 4,
|
|
5921
|
-
/** A proactive recall decision (fired or quiet) and what it showed; never in the guide. */
|
|
5922
|
-
recall: 4,
|
|
5923
|
-
/** A routing decision (allow / annotate / deny) for one native call; never in the guide. */
|
|
5924
|
-
routing: 4
|
|
5925
|
-
};
|
|
5926
|
-
var GUIDE_ORDER = [
|
|
5927
|
-
{ title: "Last Request", categories: ["user_prompt"] },
|
|
5928
|
-
{ title: "Tasks", categories: ["tasks"] },
|
|
5929
|
-
{ title: "Plans", categories: ["plans"] },
|
|
5930
|
-
{ title: "Key Decisions", categories: ["decision"] },
|
|
5931
|
-
{ title: "Files Modified", categories: ["files"] },
|
|
5932
|
-
{ title: "Unresolved Errors", categories: ["error"] },
|
|
5933
|
-
{ title: "Resolved", categories: ["error_resolution"] },
|
|
5934
|
-
{ title: "Constraints", categories: ["constraint"] },
|
|
5935
|
-
{ title: "Blockers", categories: ["blocker"] },
|
|
5936
|
-
{ title: "Git", categories: ["git"] },
|
|
5937
|
-
{ title: "Project Rules", categories: ["rules"] },
|
|
5938
|
-
{ title: "Loops", categories: ["iteration_loop"] },
|
|
5939
|
-
{ title: "Last Reply", categories: ["assistant_summary"] },
|
|
5940
|
-
{ title: "MCP Tools Used", categories: ["mcp_tool"] },
|
|
5941
|
-
{ title: "Subagent Tasks", categories: ["subagent", "agent_findings"] },
|
|
5942
|
-
{ title: "Skills", categories: ["skill"] },
|
|
5943
|
-
{ title: "Rejected Approaches", categories: ["rejected"] },
|
|
5944
|
-
{ title: "External Refs", categories: ["external_ref"] },
|
|
5945
|
-
{ title: "Environment", categories: ["environment"] },
|
|
5946
|
-
{ title: "Slow Calls", categories: ["latency"] },
|
|
5947
|
-
{ title: "Data refs", categories: ["data"] },
|
|
5948
|
-
{ title: "Intent", categories: ["intent"] }
|
|
5949
|
-
];
|
|
5950
|
-
|
|
5951
|
-
// src/capture/classify.ts
|
|
5952
|
-
function relPath(root, fp) {
|
|
5953
|
-
const tryRel = (base, p) => {
|
|
5954
|
-
const r = relative(base, p);
|
|
5955
|
-
return r && !r.startsWith("..") && !isAbsolute(r) ? r : void 0;
|
|
5956
|
-
};
|
|
5957
|
-
const direct = tryRel(root, fp);
|
|
5958
|
-
if (direct) return direct;
|
|
5959
|
-
try {
|
|
5960
|
-
const real = tryRel(realpathSync(root), realpathSync(fp));
|
|
5961
|
-
if (real) return real;
|
|
5962
|
-
} catch {
|
|
5963
|
-
}
|
|
5964
|
-
return fp;
|
|
5965
|
-
}
|
|
5966
|
-
function ev(category, payload, tool) {
|
|
5967
|
-
return { category, payload, tool };
|
|
5968
|
-
}
|
|
5969
|
-
function withPriority(sessionId, drafts) {
|
|
5970
|
-
return drafts.map((d) => ({ ...d, sessionId, priority: CATEGORIES[d.category] }));
|
|
5971
|
-
}
|
|
5972
|
-
var clip = (s, n) => {
|
|
5973
|
-
const str2 = typeof s === "string" ? s : JSON.stringify(s ?? "");
|
|
5974
|
-
return str2.length > n ? `${str2.slice(0, n - 1)}\u2026` : str2;
|
|
5975
|
-
};
|
|
5976
|
-
var DECISION = /\b(let'?s go with|we'?ll use|decided|decision:|go with|use (?:the )?\w+ instead|stick with|switch(?:ing)? to|chose|prefer(?:red)?)\b/i;
|
|
5977
|
-
var CONSTRAINT = /\b(must(?: not)?|never|always|only|do not|don'?t|should not|required?|hard requirement|no\s+\w+ allowed)\b/i;
|
|
5978
|
-
var REJECTED = /\b(instead of|rather than|not \w+ing|don'?t use|drop(?:ped)?|revert(?:ed)?|abandon(?:ed)?|scrap(?:ped)?)\b/i;
|
|
5979
|
-
var BLOCKER = /\b(blocked|blocker|can'?t (?:proceed|continue)|waiting (?:on|for)|need(?:s)? (?:access|permission|approval))\b/i;
|
|
5980
|
-
var RESOLVED = /\b(fixed|resolved|now passes|passing now|works now|solved|green)\b/i;
|
|
5981
|
-
var INTENT = /^\s*(?:(?:please|can you|could you|let'?s|i want to|i'?d like to|help me)\s+)?(\w+(?:\s+\w+){0,5})/i;
|
|
5982
|
-
function classifyPrompt(prompt) {
|
|
5983
|
-
const out = [ev("user_prompt", { text: clip(prompt, 600) })];
|
|
5984
|
-
const first = prompt.split("\n").find((l) => l.trim()) ?? "";
|
|
5985
|
-
if (DECISION.test(prompt))
|
|
5986
|
-
out.push(ev("decision", { text: clip(firstMatchLine(prompt, DECISION), 300), by: "user" }));
|
|
5987
|
-
if (CONSTRAINT.test(prompt) && prompt.length < 2e3)
|
|
5988
|
-
out.push(ev("constraint", { text: clip(firstMatchLine(prompt, CONSTRAINT), 300) }));
|
|
5989
|
-
if (REJECTED.test(prompt))
|
|
5990
|
-
out.push(ev("rejected", { text: clip(firstMatchLine(prompt, REJECTED), 300) }));
|
|
5991
|
-
if (BLOCKER.test(prompt))
|
|
5992
|
-
out.push(ev("blocker", { text: clip(firstMatchLine(prompt, BLOCKER), 300) }));
|
|
5993
|
-
const m = INTENT.exec(first);
|
|
5994
|
-
if (m?.[1]) out.push(ev("intent", { text: clip(m[1], 80) }));
|
|
5995
|
-
return out;
|
|
5996
|
-
}
|
|
5997
|
-
function firstMatchLine(text, re) {
|
|
5998
|
-
return text.split("\n").find((l) => re.test(l)) ?? text;
|
|
5999
|
-
}
|
|
6000
|
-
var EDIT_TOOLS = /* @__PURE__ */ new Set(["Edit", "Write", "MultiEdit", "NotebookEdit"]);
|
|
6001
|
-
var GIT_OP = /^\s*git\s+(commit|checkout|switch|merge|rebase|push|pull|stash|reset|revert|cherry-pick|tag|branch\s+-[dD])/;
|
|
6002
|
-
function callKey(toolName, toolInput) {
|
|
6003
|
-
return `${toolName}:${createHash("sha1").update(JSON.stringify(toolInput)).digest("hex").slice(0, 12)}`;
|
|
6004
|
-
}
|
|
6005
|
-
function responseText(r) {
|
|
6006
|
-
if (typeof r === "string") return r;
|
|
6007
|
-
if (r && typeof r === "object") {
|
|
6008
|
-
const o = r;
|
|
6009
|
-
if (typeof o.stdout === "string")
|
|
6010
|
-
return `${o.stdout}
|
|
6011
|
-
${typeof o.stderr === "string" ? o.stderr : ""}`;
|
|
6012
|
-
if (Array.isArray(o.content)) {
|
|
6013
|
-
return o.content.map(
|
|
6014
|
-
(c) => c && typeof c === "object" && typeof c.text === "string" ? c.text : ""
|
|
6015
|
-
).join("\n");
|
|
6016
|
-
}
|
|
6017
|
-
if (typeof o.error === "string") return o.error;
|
|
6018
|
-
}
|
|
6019
|
-
return "";
|
|
6020
|
-
}
|
|
6021
|
-
function responseFailed(r) {
|
|
6022
|
-
if (!r || typeof r !== "object") return void 0;
|
|
6023
|
-
const o = r;
|
|
6024
|
-
if (o.is_error === true || o.isError === true) return clip(responseText(r), 400);
|
|
6025
|
-
if (typeof o.exit_code === "number" && o.exit_code !== 0) return clip(responseText(r), 400);
|
|
6026
|
-
if (typeof o.interrupted === "boolean" && o.interrupted) return "interrupted";
|
|
6027
|
-
return void 0;
|
|
6028
|
-
}
|
|
6029
|
-
function classifyToolCall(info) {
|
|
6030
|
-
const { toolName, toolInput, root } = info;
|
|
6031
|
-
const out = [];
|
|
6032
|
-
const key = callKey(toolName, toolInput);
|
|
6033
|
-
out.push(ev("tool_call", { key, summary: summarizeInput(toolName, toolInput) }, toolName));
|
|
6034
|
-
if (EDIT_TOOLS.has(toolName)) {
|
|
6035
|
-
const fp = String(toolInput.file_path ?? toolInput.notebook_path ?? "");
|
|
6036
|
-
if (fp) {
|
|
6037
|
-
const rel = relPath(root, fp);
|
|
6038
|
-
if (/\.claude\/plans\/|\/plans\/.*\.md$/.test(fp))
|
|
6039
|
-
out.push(ev("plans", { path: rel, action: toolName }, toolName));
|
|
6040
|
-
else out.push(ev("files", { path: rel, action: toolName }, toolName));
|
|
6041
|
-
if (/(^|\/)(CLAUDE|AGENTS)\.md$|\.claude\/settings/.test(fp))
|
|
6042
|
-
out.push(ev("rules", { path: rel, action: toolName }, toolName));
|
|
6043
|
-
}
|
|
6044
|
-
}
|
|
6045
|
-
if (toolName === "Bash") {
|
|
6046
|
-
const cmd = String(toolInput.command ?? "");
|
|
6047
|
-
if (GIT_OP.test(cmd)) out.push(ev("git", { command: clip(cmd, 200) }, toolName));
|
|
6048
|
-
}
|
|
6049
|
-
if (toolName === "TodoWrite" && Array.isArray(toolInput.todos)) {
|
|
6050
|
-
const todos = toolInput.todos;
|
|
6051
|
-
out.push(
|
|
6052
|
-
ev(
|
|
6053
|
-
"tasks",
|
|
6054
|
-
{
|
|
6055
|
-
todos: todos.slice(0, 12).map(
|
|
6056
|
-
(t) => `${t.status === "completed" ? "x" : t.status === "in_progress" ? ">" : " "} ${clip(t.content, 80)}`
|
|
6057
|
-
)
|
|
6058
|
-
},
|
|
6059
|
-
toolName
|
|
6060
|
-
)
|
|
6061
|
-
);
|
|
6062
|
-
}
|
|
6063
|
-
if (toolName === "ExitPlanMode") out.push(ev("plans", { action: "plan approved" }, toolName));
|
|
6064
|
-
if (toolName === "Agent" || toolName === "Task") {
|
|
6065
|
-
out.push(
|
|
6066
|
-
ev(
|
|
6067
|
-
"subagent",
|
|
6068
|
-
{ description: clip(toolInput.description, 120), type: toolInput.subagent_type },
|
|
6069
|
-
toolName
|
|
6070
|
-
)
|
|
6071
|
-
);
|
|
6072
|
-
}
|
|
6073
|
-
if (toolName === "Skill") out.push(ev("skill", { skill: clip(toolInput.skill, 80) }, toolName));
|
|
6074
|
-
if (toolName === "WebFetch" || toolName === "WebSearch") {
|
|
6075
|
-
out.push(ev("external_ref", { url: clip(toolInput.url ?? toolInput.query, 200) }, toolName));
|
|
6076
|
-
}
|
|
6077
|
-
if (toolName.startsWith("mcp__")) out.push(ev("mcp_tool", { tool: toolName }, toolName));
|
|
6078
|
-
if (info.durationMs && info.durationMs > 5e3) {
|
|
6079
|
-
out.push(
|
|
6080
|
-
ev(
|
|
6081
|
-
"latency",
|
|
6082
|
-
{ ms: info.durationMs, summary: summarizeInput(toolName, toolInput) },
|
|
6083
|
-
toolName
|
|
6084
|
-
)
|
|
6085
|
-
);
|
|
6086
|
-
}
|
|
6087
|
-
const failure2 = info.error ?? responseFailed(info.toolResponse);
|
|
6088
|
-
if (failure2)
|
|
6089
|
-
out.push(
|
|
6090
|
-
ev(
|
|
6091
|
-
"error",
|
|
6092
|
-
{ tool: toolName, summary: summarizeInput(toolName, toolInput), error: clip(failure2, 400) },
|
|
6093
|
-
toolName
|
|
6094
|
-
)
|
|
6095
|
-
);
|
|
6096
|
-
return out;
|
|
6097
|
-
}
|
|
6098
|
-
function summarizeInput(toolName, input2) {
|
|
6099
|
-
const pick2 = input2.command ?? input2.file_path ?? input2.pattern ?? input2.url ?? input2.prompt ?? input2.query ?? input2.description ?? input2.skill;
|
|
6100
|
-
return clip(`${toolName} ${pick2 ?? ""}`.trim(), 160);
|
|
6101
|
-
}
|
|
6102
|
-
function classifyAssistant(message) {
|
|
6103
|
-
const out = [];
|
|
6104
|
-
if (!message.trim()) return out;
|
|
6105
|
-
out.push(ev("assistant_summary", { text: clip(message.replace(/\s+/g, " "), 500) }));
|
|
6106
|
-
if (DECISION.test(message))
|
|
6107
|
-
out.push(
|
|
6108
|
-
ev("decision", { text: clip(firstMatchLine(message, DECISION), 300), by: "assistant" })
|
|
6109
|
-
);
|
|
6110
|
-
if (RESOLVED.test(message))
|
|
6111
|
-
out.push(ev("error_resolution", { text: clip(firstMatchLine(message, RESOLVED), 300) }));
|
|
6112
|
-
if (BLOCKER.test(message))
|
|
6113
|
-
out.push(ev("blocker", { text: clip(firstMatchLine(message, BLOCKER), 300), by: "assistant" }));
|
|
6114
|
-
return out;
|
|
6115
|
-
}
|
|
6116
5878
|
|
|
6117
5879
|
// src/context.ts
|
|
6118
5880
|
init_esm_shims();
|
|
@@ -6966,14 +6728,14 @@ function promiseAllObject(promisesObj) {
|
|
|
6966
6728
|
}
|
|
6967
6729
|
function randomString(length = 10) {
|
|
6968
6730
|
const chars = "abcdefghijklmnopqrstuvwxyz";
|
|
6969
|
-
let
|
|
6731
|
+
let str3 = "";
|
|
6970
6732
|
for (let i = 0; i < length; i++) {
|
|
6971
|
-
|
|
6733
|
+
str3 += chars[Math.floor(Math.random() * chars.length)];
|
|
6972
6734
|
}
|
|
6973
|
-
return
|
|
6735
|
+
return str3;
|
|
6974
6736
|
}
|
|
6975
|
-
function esc(
|
|
6976
|
-
return JSON.stringify(
|
|
6737
|
+
function esc(str3) {
|
|
6738
|
+
return JSON.stringify(str3);
|
|
6977
6739
|
}
|
|
6978
6740
|
function slugify(input2) {
|
|
6979
6741
|
return input2.toLowerCase().trim().replace(/[^\w\s-]/g, "").replace(/[\s_-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
@@ -7087,8 +6849,8 @@ var primitiveTypes = /* @__PURE__ */ new Set([
|
|
|
7087
6849
|
"symbol",
|
|
7088
6850
|
"undefined"
|
|
7089
6851
|
]);
|
|
7090
|
-
function escapeRegex(
|
|
7091
|
-
return
|
|
6852
|
+
function escapeRegex(str3) {
|
|
6853
|
+
return str3.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
7092
6854
|
}
|
|
7093
6855
|
function clone(inst, def, params) {
|
|
7094
6856
|
const cl = new inst._zod.constr(def ?? inst._zod.def);
|
|
@@ -7354,13 +7116,13 @@ function getSizableOrigin(input2) {
|
|
|
7354
7116
|
return "unknown";
|
|
7355
7117
|
}
|
|
7356
7118
|
var highSurrogate = /[\uD800-\uDBFF]/;
|
|
7357
|
-
function codePointLength(
|
|
7358
|
-
const units =
|
|
7359
|
-
if (!highSurrogate.test(
|
|
7119
|
+
function codePointLength(str3) {
|
|
7120
|
+
const units = str3.length;
|
|
7121
|
+
if (!highSurrogate.test(str3))
|
|
7360
7122
|
return units;
|
|
7361
7123
|
let count = units;
|
|
7362
7124
|
for (let i = 0; i < units - 1; i++) {
|
|
7363
|
-
if ((
|
|
7125
|
+
if ((str3.charCodeAt(i) & 64512) === 55296 && (str3.charCodeAt(i + 1) & 64512) === 56320) {
|
|
7364
7126
|
count--;
|
|
7365
7127
|
i++;
|
|
7366
7128
|
}
|
|
@@ -26219,8 +25981,8 @@ function loadConfig(projectRoot) {
|
|
|
26219
25981
|
|
|
26220
25982
|
// src/project.ts
|
|
26221
25983
|
init_esm_shims();
|
|
26222
|
-
import { createHash
|
|
26223
|
-
import { existsSync as existsSync2, realpathSync
|
|
25984
|
+
import { createHash } from "crypto";
|
|
25985
|
+
import { existsSync as existsSync2, realpathSync } from "fs";
|
|
26224
25986
|
import { dirname, join as join3, resolve } from "path";
|
|
26225
25987
|
var ROOT_MARKERS = [
|
|
26226
25988
|
".git",
|
|
@@ -26245,13 +26007,13 @@ function resolveProjectRoot(hint) {
|
|
|
26245
26007
|
const candidate = hint || process.env.EMINIAR_PROJECT_ROOT || process.env.CLAUDE_PROJECT_DIR || process.cwd();
|
|
26246
26008
|
const root = findProjectRoot(candidate);
|
|
26247
26009
|
try {
|
|
26248
|
-
return
|
|
26010
|
+
return realpathSync(root);
|
|
26249
26011
|
} catch {
|
|
26250
26012
|
return root;
|
|
26251
26013
|
}
|
|
26252
26014
|
}
|
|
26253
26015
|
function projectId(root) {
|
|
26254
|
-
return
|
|
26016
|
+
return createHash("sha256").update(root).digest("hex").slice(0, 16);
|
|
26255
26017
|
}
|
|
26256
26018
|
|
|
26257
26019
|
// src/context.ts
|
|
@@ -26267,25 +26029,459 @@ function getContext(rootHint) {
|
|
|
26267
26029
|
return ctx;
|
|
26268
26030
|
}
|
|
26269
26031
|
|
|
26270
|
-
// src/
|
|
26271
|
-
init_esm_shims();
|
|
26272
|
-
var import_fast_glob = __toESM(require_out4(), 1);
|
|
26273
|
-
import { readFileSync as readFileSync2, statSync } from "fs";
|
|
26274
|
-
import { relative as relative2, resolve as resolve2 } from "path";
|
|
26275
|
-
|
|
26276
|
-
// src/chunker/index.ts
|
|
26277
|
-
init_esm_shims();
|
|
26278
|
-
import { extname } from "path";
|
|
26279
|
-
|
|
26280
|
-
// src/chunker/code.ts
|
|
26281
|
-
init_esm_shims();
|
|
26282
|
-
|
|
26283
|
-
// src/chunker/types.ts
|
|
26032
|
+
// src/hooks/cursor.ts
|
|
26284
26033
|
init_esm_shims();
|
|
26285
|
-
import {
|
|
26286
|
-
|
|
26287
|
-
|
|
26288
|
-
|
|
26034
|
+
import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync2, rmSync, writeFileSync } from "fs";
|
|
26035
|
+
import { homedir as homedir2 } from "os";
|
|
26036
|
+
import { join as join4 } from "path";
|
|
26037
|
+
var CURSOR_EVENTS = {
|
|
26038
|
+
sessionStart: "SessionStart",
|
|
26039
|
+
beforeSubmitPrompt: "UserPromptSubmit",
|
|
26040
|
+
preToolUse: "PreToolUse",
|
|
26041
|
+
postToolUse: "PostToolUse",
|
|
26042
|
+
postToolUseFailure: "PostToolUseFailure",
|
|
26043
|
+
subagentStop: "SubagentStop",
|
|
26044
|
+
preCompact: "PreCompact",
|
|
26045
|
+
// afterAgentResponse carries the assistant text that Claude Code's Stop event carries.
|
|
26046
|
+
afterAgentResponse: "Stop",
|
|
26047
|
+
stop: "Stop",
|
|
26048
|
+
afterFileEdit: "PostToolUse",
|
|
26049
|
+
sessionEnd: "SessionEnd"
|
|
26050
|
+
};
|
|
26051
|
+
var TOOL_NAMES = { Shell: "Bash" };
|
|
26052
|
+
var PENDING_TTL_MS = 10 * 6e4;
|
|
26053
|
+
var PENDING_MAX = 8e3;
|
|
26054
|
+
function cursorDir() {
|
|
26055
|
+
return process.env.CURSOR_CONFIG_DIR || join4(homedir2(), ".cursor");
|
|
26056
|
+
}
|
|
26057
|
+
function detectClient(input2, argv) {
|
|
26058
|
+
const i = argv.indexOf("--client");
|
|
26059
|
+
if (i !== -1 && argv[i + 1]) return argv[i + 1] === "cursor" ? "cursor" : "claude";
|
|
26060
|
+
const ev3 = typeof input2.hook_event_name === "string" ? input2.hook_event_name : "";
|
|
26061
|
+
if (typeof input2.cursor_version === "string" || Array.isArray(input2.workspace_roots) || typeof input2.conversation_id === "string" && !input2.session_id || ev3 in CURSOR_EVENTS)
|
|
26062
|
+
return "cursor";
|
|
26063
|
+
return "claude";
|
|
26064
|
+
}
|
|
26065
|
+
var str = (v) => typeof v === "string" && v.length ? v : void 0;
|
|
26066
|
+
function mapToolName(name) {
|
|
26067
|
+
if (name in TOOL_NAMES) return TOOL_NAMES[name];
|
|
26068
|
+
const mcp = /^MCP:(.+)$/.exec(name);
|
|
26069
|
+
if (mcp) return `mcp__cursor__${mcp[1]}`;
|
|
26070
|
+
return name;
|
|
26071
|
+
}
|
|
26072
|
+
function toolInputOf(v) {
|
|
26073
|
+
let obj = v;
|
|
26074
|
+
if (typeof obj === "string") {
|
|
26075
|
+
try {
|
|
26076
|
+
obj = JSON.parse(obj);
|
|
26077
|
+
} catch {
|
|
26078
|
+
return void 0;
|
|
26079
|
+
}
|
|
26080
|
+
}
|
|
26081
|
+
if (!obj || typeof obj !== "object" || Array.isArray(obj)) return void 0;
|
|
26082
|
+
const input2 = { ...obj };
|
|
26083
|
+
if (typeof input2.path === "string" && input2.file_path === void 0) input2.file_path = input2.path;
|
|
26084
|
+
return input2;
|
|
26085
|
+
}
|
|
26086
|
+
function toolResponseOf(v) {
|
|
26087
|
+
if (typeof v !== "string") return v;
|
|
26088
|
+
try {
|
|
26089
|
+
return JSON.parse(v);
|
|
26090
|
+
} catch {
|
|
26091
|
+
return v;
|
|
26092
|
+
}
|
|
26093
|
+
}
|
|
26094
|
+
function fromCursor(raw) {
|
|
26095
|
+
const event = str(raw.hook_event_name) ?? "";
|
|
26096
|
+
const roots = Array.isArray(raw.workspace_roots) ? raw.workspace_roots.filter((r) => typeof r === "string") : [];
|
|
26097
|
+
const cwd = str(raw.cwd) ?? roots[0] ?? process.env.CURSOR_PROJECT_DIR ?? process.env.CLAUDE_PROJECT_DIR ?? process.cwd();
|
|
26098
|
+
const input2 = {
|
|
26099
|
+
session_id: str(raw.session_id) ?? str(raw.conversation_id) ?? process.env.EMINIAR_SESSION_ID ?? "cursor",
|
|
26100
|
+
cwd,
|
|
26101
|
+
hook_event_name: CURSOR_EVENTS[event] ?? event
|
|
26102
|
+
};
|
|
26103
|
+
const transcript = str(raw.transcript_path);
|
|
26104
|
+
if (transcript) input2.transcript_path = transcript;
|
|
26105
|
+
if (input2.hook_event_name === "SessionStart") input2.source = "startup";
|
|
26106
|
+
const prompt = str(raw.prompt);
|
|
26107
|
+
if (prompt) input2.prompt = prompt;
|
|
26108
|
+
if (event === "afterFileEdit") {
|
|
26109
|
+
input2.tool_name = "Edit";
|
|
26110
|
+
const ti = {};
|
|
26111
|
+
if (str(raw.file_path)) ti.file_path = raw.file_path;
|
|
26112
|
+
if (Array.isArray(raw.edits)) ti.edits = raw.edits;
|
|
26113
|
+
input2.tool_input = ti;
|
|
26114
|
+
} else {
|
|
26115
|
+
const tool = str(raw.tool_name);
|
|
26116
|
+
if (tool) input2.tool_name = mapToolName(tool);
|
|
26117
|
+
const ti = toolInputOf(raw.tool_input);
|
|
26118
|
+
if (ti) input2.tool_input = ti;
|
|
26119
|
+
}
|
|
26120
|
+
const useId = str(raw.tool_use_id);
|
|
26121
|
+
if (useId) input2.tool_use_id = useId;
|
|
26122
|
+
if (raw.tool_output !== void 0) input2.tool_response = toolResponseOf(raw.tool_output);
|
|
26123
|
+
const dur = typeof raw.duration === "number" ? raw.duration : raw.duration_ms;
|
|
26124
|
+
if (typeof dur === "number") input2.duration_ms = dur;
|
|
26125
|
+
const err = str(raw.error_message) ?? str(raw.error);
|
|
26126
|
+
if (err) input2.error = err;
|
|
26127
|
+
const text = str(raw.text) ?? str(raw.summary) ?? str(raw.last_assistant_message);
|
|
26128
|
+
if (text) input2.last_assistant_message = text;
|
|
26129
|
+
const agent = str(raw.subagent_type) ?? str(raw.agent_type);
|
|
26130
|
+
if (agent) input2.agent_type = agent;
|
|
26131
|
+
const agentTranscript = str(raw.agent_transcript_path);
|
|
26132
|
+
if (agentTranscript) input2.agent_transcript_path = agentTranscript;
|
|
26133
|
+
if (raw.trigger === "manual" || raw.trigger === "auto") input2.trigger = raw.trigger;
|
|
26134
|
+
const reason = str(raw.reason);
|
|
26135
|
+
if (reason) input2.reason = reason;
|
|
26136
|
+
return input2;
|
|
26137
|
+
}
|
|
26138
|
+
function pendingFile(root, sessionId) {
|
|
26139
|
+
const id = getContext(root).id;
|
|
26140
|
+
return join4(projectDir(id), "pending-context", `${sessionId.replace(/[^\w.-]/g, "_")}.json`);
|
|
26141
|
+
}
|
|
26142
|
+
function readPending(file3) {
|
|
26143
|
+
try {
|
|
26144
|
+
const list = JSON.parse(readFileSync2(file3, "utf8"));
|
|
26145
|
+
return Array.isArray(list) ? list : [];
|
|
26146
|
+
} catch {
|
|
26147
|
+
return [];
|
|
26148
|
+
}
|
|
26149
|
+
}
|
|
26150
|
+
function stashContext(root, sessionId, text) {
|
|
26151
|
+
if (!text.trim()) return;
|
|
26152
|
+
const file3 = pendingFile(root, sessionId);
|
|
26153
|
+
mkdirSync2(join4(file3, ".."), { recursive: true });
|
|
26154
|
+
const now = Date.now();
|
|
26155
|
+
const list = readPending(file3).filter((p) => now - p.t < PENDING_TTL_MS);
|
|
26156
|
+
list.push({ t: now, text });
|
|
26157
|
+
writeFileSync(file3, JSON.stringify(list));
|
|
26158
|
+
}
|
|
26159
|
+
function takeContext(root, sessionId) {
|
|
26160
|
+
const file3 = pendingFile(root, sessionId);
|
|
26161
|
+
if (!existsSync3(file3)) return void 0;
|
|
26162
|
+
const now = Date.now();
|
|
26163
|
+
const list = readPending(file3).filter((p) => now - p.t < PENDING_TTL_MS);
|
|
26164
|
+
rmSync(file3, { force: true });
|
|
26165
|
+
const seen = /* @__PURE__ */ new Set();
|
|
26166
|
+
const texts = list.map((p) => p.text).filter((t) => !seen.has(t) && seen.add(t));
|
|
26167
|
+
const joined = texts.join("\n\n").slice(0, PENDING_MAX);
|
|
26168
|
+
return joined || void 0;
|
|
26169
|
+
}
|
|
26170
|
+
function cursorHasServer() {
|
|
26171
|
+
try {
|
|
26172
|
+
const raw = readFileSync2(join4(cursorDir(), "mcp.json"), "utf8");
|
|
26173
|
+
return raw.includes("em-server");
|
|
26174
|
+
} catch {
|
|
26175
|
+
return false;
|
|
26176
|
+
}
|
|
26177
|
+
}
|
|
26178
|
+
var joinText = (...parts) => {
|
|
26179
|
+
const kept = parts.filter((p) => !!p?.trim());
|
|
26180
|
+
return kept.length ? kept.join("\n\n") : void 0;
|
|
26181
|
+
};
|
|
26182
|
+
function toCursor(event, out, scope) {
|
|
26183
|
+
const specific2 = out?.hookSpecificOutput;
|
|
26184
|
+
const context = specific2?.additionalContext;
|
|
26185
|
+
switch (event) {
|
|
26186
|
+
case "PreToolUse": {
|
|
26187
|
+
if (specific2?.permissionDecision === "deny") {
|
|
26188
|
+
if (!cursorHasServer()) {
|
|
26189
|
+
stashContext(
|
|
26190
|
+
scope.root,
|
|
26191
|
+
scope.sessionId,
|
|
26192
|
+
`${specific2.permissionDecisionReason ?? ""} (eminiar MCP server is not registered with Cursor, so the call was allowed; run \`npx eminiar install --cursor\`)`.trim()
|
|
26193
|
+
);
|
|
26194
|
+
return { permission: "allow" };
|
|
26195
|
+
}
|
|
26196
|
+
const reason = joinText(specific2.permissionDecisionReason, context) ?? "eminiar: denied";
|
|
26197
|
+
return { permission: "deny", user_message: reason, agent_message: reason };
|
|
26198
|
+
}
|
|
26199
|
+
const res = { permission: "allow" };
|
|
26200
|
+
if (specific2?.updatedInput) res.updated_input = specific2.updatedInput;
|
|
26201
|
+
if (context) stashContext(scope.root, scope.sessionId, context);
|
|
26202
|
+
return res;
|
|
26203
|
+
}
|
|
26204
|
+
case "PostToolUse":
|
|
26205
|
+
case "PostToolUseFailure": {
|
|
26206
|
+
const text = joinText(takeContext(scope.root, scope.sessionId), context);
|
|
26207
|
+
return text ? { additional_context: text } : {};
|
|
26208
|
+
}
|
|
26209
|
+
case "SessionStart": {
|
|
26210
|
+
const res = {
|
|
26211
|
+
env: { EMINIAR_SESSION_ID: scope.sessionId, EMINIAR_PROJECT_ROOT: scope.root }
|
|
26212
|
+
};
|
|
26213
|
+
if (context) res.additional_context = context;
|
|
26214
|
+
return res;
|
|
26215
|
+
}
|
|
26216
|
+
case "UserPromptSubmit": {
|
|
26217
|
+
if (context) stashContext(scope.root, scope.sessionId, context);
|
|
26218
|
+
return { continue: true };
|
|
26219
|
+
}
|
|
26220
|
+
default:
|
|
26221
|
+
return {};
|
|
26222
|
+
}
|
|
26223
|
+
}
|
|
26224
|
+
|
|
26225
|
+
// src/hooks/index.ts
|
|
26226
|
+
init_esm_shims();
|
|
26227
|
+
|
|
26228
|
+
// src/hooks/capture.ts
|
|
26229
|
+
init_esm_shims();
|
|
26230
|
+
|
|
26231
|
+
// src/capture/classify.ts
|
|
26232
|
+
init_esm_shims();
|
|
26233
|
+
import { createHash as createHash2 } from "crypto";
|
|
26234
|
+
import { realpathSync as realpathSync2 } from "fs";
|
|
26235
|
+
import { isAbsolute, relative } from "path";
|
|
26236
|
+
|
|
26237
|
+
// src/capture/categories.ts
|
|
26238
|
+
init_esm_shims();
|
|
26239
|
+
var CATEGORIES = {
|
|
26240
|
+
// P1
|
|
26241
|
+
files: 1,
|
|
26242
|
+
tasks: 1,
|
|
26243
|
+
plans: 1,
|
|
26244
|
+
rules: 1,
|
|
26245
|
+
user_prompt: 1,
|
|
26246
|
+
// P2
|
|
26247
|
+
decision: 2,
|
|
26248
|
+
git: 2,
|
|
26249
|
+
error: 2,
|
|
26250
|
+
error_resolution: 2,
|
|
26251
|
+
constraint: 2,
|
|
26252
|
+
blocker: 2,
|
|
26253
|
+
rejected: 2,
|
|
26254
|
+
environment: 2,
|
|
26255
|
+
agent_findings: 2,
|
|
26256
|
+
iteration_loop: 2,
|
|
26257
|
+
assistant_summary: 2,
|
|
26258
|
+
// P3
|
|
26259
|
+
latency: 3,
|
|
26260
|
+
mcp_tool: 3,
|
|
26261
|
+
subagent: 3,
|
|
26262
|
+
skill: 3,
|
|
26263
|
+
external_ref: 3,
|
|
26264
|
+
role: 3,
|
|
26265
|
+
// P4
|
|
26266
|
+
intent: 4,
|
|
26267
|
+
data: 4,
|
|
26268
|
+
tool_call: 4,
|
|
26269
|
+
session_start: 4,
|
|
26270
|
+
/** A proactive recall decision (fired or quiet) and what it showed; never in the guide. */
|
|
26271
|
+
recall: 4,
|
|
26272
|
+
/** A routing decision (allow / annotate / deny) for one native call; never in the guide. */
|
|
26273
|
+
routing: 4
|
|
26274
|
+
};
|
|
26275
|
+
var GUIDE_ORDER = [
|
|
26276
|
+
{ title: "Last Request", categories: ["user_prompt"] },
|
|
26277
|
+
{ title: "Tasks", categories: ["tasks"] },
|
|
26278
|
+
{ title: "Plans", categories: ["plans"] },
|
|
26279
|
+
{ title: "Key Decisions", categories: ["decision"] },
|
|
26280
|
+
{ title: "Files Modified", categories: ["files"] },
|
|
26281
|
+
{ title: "Unresolved Errors", categories: ["error"] },
|
|
26282
|
+
{ title: "Resolved", categories: ["error_resolution"] },
|
|
26283
|
+
{ title: "Constraints", categories: ["constraint"] },
|
|
26284
|
+
{ title: "Blockers", categories: ["blocker"] },
|
|
26285
|
+
{ title: "Git", categories: ["git"] },
|
|
26286
|
+
{ title: "Project Rules", categories: ["rules"] },
|
|
26287
|
+
{ title: "Loops", categories: ["iteration_loop"] },
|
|
26288
|
+
{ title: "Last Reply", categories: ["assistant_summary"] },
|
|
26289
|
+
{ title: "MCP Tools Used", categories: ["mcp_tool"] },
|
|
26290
|
+
{ title: "Subagent Tasks", categories: ["subagent", "agent_findings"] },
|
|
26291
|
+
{ title: "Skills", categories: ["skill"] },
|
|
26292
|
+
{ title: "Rejected Approaches", categories: ["rejected"] },
|
|
26293
|
+
{ title: "External Refs", categories: ["external_ref"] },
|
|
26294
|
+
{ title: "Environment", categories: ["environment"] },
|
|
26295
|
+
{ title: "Slow Calls", categories: ["latency"] },
|
|
26296
|
+
{ title: "Data refs", categories: ["data"] },
|
|
26297
|
+
{ title: "Intent", categories: ["intent"] }
|
|
26298
|
+
];
|
|
26299
|
+
|
|
26300
|
+
// src/capture/classify.ts
|
|
26301
|
+
function relPath(root, fp) {
|
|
26302
|
+
const tryRel = (base, p) => {
|
|
26303
|
+
const r = relative(base, p);
|
|
26304
|
+
return r && !r.startsWith("..") && !isAbsolute(r) ? r : void 0;
|
|
26305
|
+
};
|
|
26306
|
+
const direct = tryRel(root, fp);
|
|
26307
|
+
if (direct) return direct;
|
|
26308
|
+
try {
|
|
26309
|
+
const real = tryRel(realpathSync2(root), realpathSync2(fp));
|
|
26310
|
+
if (real) return real;
|
|
26311
|
+
} catch {
|
|
26312
|
+
}
|
|
26313
|
+
return fp;
|
|
26314
|
+
}
|
|
26315
|
+
function ev(category, payload, tool) {
|
|
26316
|
+
return { category, payload, tool };
|
|
26317
|
+
}
|
|
26318
|
+
function withPriority(sessionId, drafts) {
|
|
26319
|
+
return drafts.map((d) => ({ ...d, sessionId, priority: CATEGORIES[d.category] }));
|
|
26320
|
+
}
|
|
26321
|
+
var clip = (s, n) => {
|
|
26322
|
+
const str3 = typeof s === "string" ? s : JSON.stringify(s ?? "");
|
|
26323
|
+
return str3.length > n ? `${str3.slice(0, n - 1)}\u2026` : str3;
|
|
26324
|
+
};
|
|
26325
|
+
var DECISION = /\b(let'?s go with|we'?ll use|decided|decision:|go with|use (?:the )?\w+ instead|stick with|switch(?:ing)? to|chose|prefer(?:red)?)\b/i;
|
|
26326
|
+
var CONSTRAINT = /\b(must(?: not)?|never|always|only|do not|don'?t|should not|required?|hard requirement|no\s+\w+ allowed)\b/i;
|
|
26327
|
+
var REJECTED = /\b(instead of|rather than|not \w+ing|don'?t use|drop(?:ped)?|revert(?:ed)?|abandon(?:ed)?|scrap(?:ped)?)\b/i;
|
|
26328
|
+
var BLOCKER = /\b(blocked|blocker|can'?t (?:proceed|continue)|waiting (?:on|for)|need(?:s)? (?:access|permission|approval))\b/i;
|
|
26329
|
+
var RESOLVED = /\b(fixed|resolved|now passes|passing now|works now|solved|green)\b/i;
|
|
26330
|
+
var INTENT = /^\s*(?:(?:please|can you|could you|let'?s|i want to|i'?d like to|help me)\s+)?(\w+(?:\s+\w+){0,5})/i;
|
|
26331
|
+
function classifyPrompt(prompt) {
|
|
26332
|
+
const out = [ev("user_prompt", { text: clip(prompt, 600) })];
|
|
26333
|
+
const first = prompt.split("\n").find((l) => l.trim()) ?? "";
|
|
26334
|
+
if (DECISION.test(prompt))
|
|
26335
|
+
out.push(ev("decision", { text: clip(firstMatchLine(prompt, DECISION), 300), by: "user" }));
|
|
26336
|
+
if (CONSTRAINT.test(prompt) && prompt.length < 2e3)
|
|
26337
|
+
out.push(ev("constraint", { text: clip(firstMatchLine(prompt, CONSTRAINT), 300) }));
|
|
26338
|
+
if (REJECTED.test(prompt))
|
|
26339
|
+
out.push(ev("rejected", { text: clip(firstMatchLine(prompt, REJECTED), 300) }));
|
|
26340
|
+
if (BLOCKER.test(prompt))
|
|
26341
|
+
out.push(ev("blocker", { text: clip(firstMatchLine(prompt, BLOCKER), 300) }));
|
|
26342
|
+
const m = INTENT.exec(first);
|
|
26343
|
+
if (m?.[1]) out.push(ev("intent", { text: clip(m[1], 80) }));
|
|
26344
|
+
return out;
|
|
26345
|
+
}
|
|
26346
|
+
function firstMatchLine(text, re) {
|
|
26347
|
+
return text.split("\n").find((l) => re.test(l)) ?? text;
|
|
26348
|
+
}
|
|
26349
|
+
var EDIT_TOOLS = /* @__PURE__ */ new Set(["Edit", "Write", "MultiEdit", "NotebookEdit"]);
|
|
26350
|
+
var GIT_OP = /^\s*git\s+(commit|checkout|switch|merge|rebase|push|pull|stash|reset|revert|cherry-pick|tag|branch\s+-[dD])/;
|
|
26351
|
+
function callKey(toolName, toolInput) {
|
|
26352
|
+
return `${toolName}:${createHash2("sha1").update(JSON.stringify(toolInput)).digest("hex").slice(0, 12)}`;
|
|
26353
|
+
}
|
|
26354
|
+
function responseText(r) {
|
|
26355
|
+
if (typeof r === "string") return r;
|
|
26356
|
+
if (r && typeof r === "object") {
|
|
26357
|
+
const o = r;
|
|
26358
|
+
if (typeof o.stdout === "string")
|
|
26359
|
+
return `${o.stdout}
|
|
26360
|
+
${typeof o.stderr === "string" ? o.stderr : ""}`;
|
|
26361
|
+
if (Array.isArray(o.content)) {
|
|
26362
|
+
return o.content.map(
|
|
26363
|
+
(c) => c && typeof c === "object" && typeof c.text === "string" ? c.text : ""
|
|
26364
|
+
).join("\n");
|
|
26365
|
+
}
|
|
26366
|
+
if (typeof o.error === "string") return o.error;
|
|
26367
|
+
}
|
|
26368
|
+
return "";
|
|
26369
|
+
}
|
|
26370
|
+
function responseFailed(r) {
|
|
26371
|
+
if (!r || typeof r !== "object") return void 0;
|
|
26372
|
+
const o = r;
|
|
26373
|
+
if (o.is_error === true || o.isError === true) return clip(responseText(r), 400);
|
|
26374
|
+
if (typeof o.exit_code === "number" && o.exit_code !== 0) return clip(responseText(r), 400);
|
|
26375
|
+
if (typeof o.interrupted === "boolean" && o.interrupted) return "interrupted";
|
|
26376
|
+
return void 0;
|
|
26377
|
+
}
|
|
26378
|
+
function classifyToolCall(info) {
|
|
26379
|
+
const { toolName, toolInput, root } = info;
|
|
26380
|
+
const out = [];
|
|
26381
|
+
const key = callKey(toolName, toolInput);
|
|
26382
|
+
out.push(ev("tool_call", { key, summary: summarizeInput(toolName, toolInput) }, toolName));
|
|
26383
|
+
if (EDIT_TOOLS.has(toolName)) {
|
|
26384
|
+
const fp = String(toolInput.file_path ?? toolInput.notebook_path ?? "");
|
|
26385
|
+
if (fp) {
|
|
26386
|
+
const rel = relPath(root, fp);
|
|
26387
|
+
if (/\.claude\/plans\/|\/plans\/.*\.md$/.test(fp))
|
|
26388
|
+
out.push(ev("plans", { path: rel, action: toolName }, toolName));
|
|
26389
|
+
else out.push(ev("files", { path: rel, action: toolName }, toolName));
|
|
26390
|
+
if (/(^|\/)(CLAUDE|AGENTS)\.md$|\.claude\/settings/.test(fp))
|
|
26391
|
+
out.push(ev("rules", { path: rel, action: toolName }, toolName));
|
|
26392
|
+
}
|
|
26393
|
+
}
|
|
26394
|
+
if (toolName === "Bash") {
|
|
26395
|
+
const cmd = String(toolInput.command ?? "");
|
|
26396
|
+
if (GIT_OP.test(cmd)) out.push(ev("git", { command: clip(cmd, 200) }, toolName));
|
|
26397
|
+
}
|
|
26398
|
+
if (toolName === "TodoWrite" && Array.isArray(toolInput.todos)) {
|
|
26399
|
+
const todos = toolInput.todos;
|
|
26400
|
+
out.push(
|
|
26401
|
+
ev(
|
|
26402
|
+
"tasks",
|
|
26403
|
+
{
|
|
26404
|
+
todos: todos.slice(0, 12).map(
|
|
26405
|
+
(t) => `${t.status === "completed" ? "x" : t.status === "in_progress" ? ">" : " "} ${clip(t.content, 80)}`
|
|
26406
|
+
)
|
|
26407
|
+
},
|
|
26408
|
+
toolName
|
|
26409
|
+
)
|
|
26410
|
+
);
|
|
26411
|
+
}
|
|
26412
|
+
if (toolName === "ExitPlanMode") out.push(ev("plans", { action: "plan approved" }, toolName));
|
|
26413
|
+
if (toolName === "Agent" || toolName === "Task") {
|
|
26414
|
+
out.push(
|
|
26415
|
+
ev(
|
|
26416
|
+
"subagent",
|
|
26417
|
+
{ description: clip(toolInput.description, 120), type: toolInput.subagent_type },
|
|
26418
|
+
toolName
|
|
26419
|
+
)
|
|
26420
|
+
);
|
|
26421
|
+
}
|
|
26422
|
+
if (toolName === "Skill") out.push(ev("skill", { skill: clip(toolInput.skill, 80) }, toolName));
|
|
26423
|
+
if (toolName === "WebFetch" || toolName === "WebSearch") {
|
|
26424
|
+
out.push(ev("external_ref", { url: clip(toolInput.url ?? toolInput.query, 200) }, toolName));
|
|
26425
|
+
}
|
|
26426
|
+
if (toolName.startsWith("mcp__")) out.push(ev("mcp_tool", { tool: toolName }, toolName));
|
|
26427
|
+
if (info.durationMs && info.durationMs > 5e3) {
|
|
26428
|
+
out.push(
|
|
26429
|
+
ev(
|
|
26430
|
+
"latency",
|
|
26431
|
+
{ ms: info.durationMs, summary: summarizeInput(toolName, toolInput) },
|
|
26432
|
+
toolName
|
|
26433
|
+
)
|
|
26434
|
+
);
|
|
26435
|
+
}
|
|
26436
|
+
const failure2 = info.error ?? responseFailed(info.toolResponse);
|
|
26437
|
+
if (failure2)
|
|
26438
|
+
out.push(
|
|
26439
|
+
ev(
|
|
26440
|
+
"error",
|
|
26441
|
+
{ tool: toolName, summary: summarizeInput(toolName, toolInput), error: clip(failure2, 400) },
|
|
26442
|
+
toolName
|
|
26443
|
+
)
|
|
26444
|
+
);
|
|
26445
|
+
return out;
|
|
26446
|
+
}
|
|
26447
|
+
function summarizeInput(toolName, input2) {
|
|
26448
|
+
const pick2 = input2.command ?? input2.file_path ?? input2.pattern ?? input2.url ?? input2.prompt ?? input2.query ?? input2.description ?? input2.skill;
|
|
26449
|
+
return clip(`${toolName} ${pick2 ?? ""}`.trim(), 160);
|
|
26450
|
+
}
|
|
26451
|
+
function classifyAssistant(message) {
|
|
26452
|
+
const out = [];
|
|
26453
|
+
if (!message.trim()) return out;
|
|
26454
|
+
out.push(ev("assistant_summary", { text: clip(message.replace(/\s+/g, " "), 500) }));
|
|
26455
|
+
if (DECISION.test(message))
|
|
26456
|
+
out.push(
|
|
26457
|
+
ev("decision", { text: clip(firstMatchLine(message, DECISION), 300), by: "assistant" })
|
|
26458
|
+
);
|
|
26459
|
+
if (RESOLVED.test(message))
|
|
26460
|
+
out.push(ev("error_resolution", { text: clip(firstMatchLine(message, RESOLVED), 300) }));
|
|
26461
|
+
if (BLOCKER.test(message))
|
|
26462
|
+
out.push(ev("blocker", { text: clip(firstMatchLine(message, BLOCKER), 300), by: "assistant" }));
|
|
26463
|
+
return out;
|
|
26464
|
+
}
|
|
26465
|
+
|
|
26466
|
+
// src/index/indexer.ts
|
|
26467
|
+
init_esm_shims();
|
|
26468
|
+
var import_fast_glob = __toESM(require_out4(), 1);
|
|
26469
|
+
import { readFileSync as readFileSync3, statSync } from "fs";
|
|
26470
|
+
import { relative as relative2, resolve as resolve2 } from "path";
|
|
26471
|
+
|
|
26472
|
+
// src/chunker/index.ts
|
|
26473
|
+
init_esm_shims();
|
|
26474
|
+
import { extname } from "path";
|
|
26475
|
+
|
|
26476
|
+
// src/chunker/code.ts
|
|
26477
|
+
init_esm_shims();
|
|
26478
|
+
|
|
26479
|
+
// src/chunker/types.ts
|
|
26480
|
+
init_esm_shims();
|
|
26481
|
+
import { createHash as createHash3 } from "crypto";
|
|
26482
|
+
var DEFAULT_CHUNKER = { maxChars: 1800, overlapLines: 5 };
|
|
26483
|
+
function hashText(s) {
|
|
26484
|
+
return createHash3("sha1").update(s).digest("hex");
|
|
26289
26485
|
}
|
|
26290
26486
|
function finalize2(raw, contentType) {
|
|
26291
26487
|
return raw.filter((r) => r.body.trim().length > 0).map((r, ord) => ({
|
|
@@ -30382,9 +30578,9 @@ function budgetWarnings(db, ctx, sessionId, now = Date.now()) {
|
|
|
30382
30578
|
// src/usage/ingest.ts
|
|
30383
30579
|
init_esm_shims();
|
|
30384
30580
|
import { createHash as createHash4 } from "crypto";
|
|
30385
|
-
import { closeSync, existsSync as
|
|
30386
|
-
import { homedir as
|
|
30387
|
-
import { basename, dirname as dirname2, join as
|
|
30581
|
+
import { closeSync, existsSync as existsSync4, openSync, readdirSync, readSync, statSync as statSync2 } from "fs";
|
|
30582
|
+
import { homedir as homedir3 } from "os";
|
|
30583
|
+
import { basename, dirname as dirname2, join as join5, resolve as resolve3, sep } from "path";
|
|
30388
30584
|
|
|
30389
30585
|
// src/usage/transcript.ts
|
|
30390
30586
|
init_esm_shims();
|
|
@@ -30393,7 +30589,7 @@ var DENIAL_RE = /^\s*PreToolUse:|hook error|\bdenied\b/i;
|
|
|
30393
30589
|
function isObj(v) {
|
|
30394
30590
|
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
30395
30591
|
}
|
|
30396
|
-
function
|
|
30592
|
+
function str2(v) {
|
|
30397
30593
|
return typeof v === "string" && v.length ? v : null;
|
|
30398
30594
|
}
|
|
30399
30595
|
function num3(v) {
|
|
@@ -30421,8 +30617,8 @@ function resultChars(content) {
|
|
|
30421
30617
|
n += safeJsonLength(part);
|
|
30422
30618
|
continue;
|
|
30423
30619
|
}
|
|
30424
|
-
const kind =
|
|
30425
|
-
if (kind === "text" || typeof part.text === "string") n +=
|
|
30620
|
+
const kind = str2(part.type);
|
|
30621
|
+
if (kind === "text" || typeof part.text === "string") n += str2(part.text)?.length ?? 0;
|
|
30426
30622
|
else if (kind === "image" || kind === "document" || kind === "tool_reference")
|
|
30427
30623
|
n += NON_TEXT_PART_CHARS;
|
|
30428
30624
|
else n += safeJsonLength(part);
|
|
@@ -30467,10 +30663,10 @@ function parseTranscriptLines(lines, ctx) {
|
|
|
30467
30663
|
continue;
|
|
30468
30664
|
}
|
|
30469
30665
|
if (!isObj(e)) continue;
|
|
30470
|
-
const type =
|
|
30666
|
+
const type = str2(e.type);
|
|
30471
30667
|
if (!type) continue;
|
|
30472
|
-
const sessionId =
|
|
30473
|
-
const agentId =
|
|
30668
|
+
const sessionId = str2(e.sessionId) ?? ctx.sessionId;
|
|
30669
|
+
const agentId = str2(e.agentId);
|
|
30474
30670
|
const sidechain = e.isSidechain === true ? 1 : 0;
|
|
30475
30671
|
const real = tsOf(e);
|
|
30476
30672
|
const ts = real ?? prevTs ?? fallbackTs;
|
|
@@ -30479,12 +30675,12 @@ function parseTranscriptLines(lines, ctx) {
|
|
|
30479
30675
|
if (type === "assistant") {
|
|
30480
30676
|
const msg = isObj(e.message) ? e.message : void 0;
|
|
30481
30677
|
if (!msg) continue;
|
|
30482
|
-
const messageId =
|
|
30483
|
-
const requestId =
|
|
30678
|
+
const messageId = str2(msg.id);
|
|
30679
|
+
const requestId = str2(e.requestId) ?? messageId;
|
|
30484
30680
|
if (Array.isArray(msg.content)) {
|
|
30485
30681
|
for (const block of msg.content) {
|
|
30486
30682
|
if (!isObj(block) || block.type !== "tool_use") continue;
|
|
30487
|
-
const id =
|
|
30683
|
+
const id = str2(block.id);
|
|
30488
30684
|
if (!id) continue;
|
|
30489
30685
|
const prev2 = toolUses.get(id);
|
|
30490
30686
|
toolUses.set(id, {
|
|
@@ -30492,7 +30688,7 @@ function parseTranscriptLines(lines, ctx) {
|
|
|
30492
30688
|
session_id: prev2?.session_id ?? sessionId,
|
|
30493
30689
|
agent_id: prev2?.agent_id ?? agentId,
|
|
30494
30690
|
ts: prev2?.ts ?? ts,
|
|
30495
|
-
tool:
|
|
30691
|
+
tool: str2(block.name) ?? prev2?.tool ?? "",
|
|
30496
30692
|
input_chars: block.input === void 0 ? 0 : safeJsonLength(block.input),
|
|
30497
30693
|
result_chars: prev2?.result_chars ?? null,
|
|
30498
30694
|
is_error: prev2?.is_error ?? 0,
|
|
@@ -30502,7 +30698,7 @@ function parseTranscriptLines(lines, ctx) {
|
|
|
30502
30698
|
}
|
|
30503
30699
|
const usage = isObj(msg.usage) ? msg.usage : void 0;
|
|
30504
30700
|
if (!usage || !messageId || !requestId) continue;
|
|
30505
|
-
const model =
|
|
30701
|
+
const model = str2(msg.model) ?? "unknown";
|
|
30506
30702
|
const cc = isObj(usage.cache_creation) ? usage.cache_creation : void 0;
|
|
30507
30703
|
const create5m = cc ? num3(cc.ephemeral_5m_input_tokens) : num3(usage.cache_creation_input_tokens);
|
|
30508
30704
|
const create1h = cc ? num3(cc.ephemeral_1h_input_tokens) : 0;
|
|
@@ -30526,15 +30722,15 @@ function parseTranscriptLines(lines, ctx) {
|
|
|
30526
30722
|
thinking_tokens: details ? num3(details.thinking_tokens) : 0,
|
|
30527
30723
|
web_searches: server ? num3(server.web_search_requests) : 0,
|
|
30528
30724
|
web_fetches: server ? num3(server.web_fetch_requests) : 0,
|
|
30529
|
-
service_tier:
|
|
30530
|
-
speed:
|
|
30531
|
-
stop_reason:
|
|
30532
|
-
prompt_id:
|
|
30533
|
-
git_branch:
|
|
30534
|
-
cwd:
|
|
30535
|
-
effort:
|
|
30536
|
-
version:
|
|
30537
|
-
entrypoint:
|
|
30725
|
+
service_tier: str2(usage.service_tier),
|
|
30726
|
+
speed: str2(usage.speed),
|
|
30727
|
+
stop_reason: str2(msg.stop_reason) ?? prev?.stop_reason ?? null,
|
|
30728
|
+
prompt_id: str2(e.promptId) ?? prev?.prompt_id ?? null,
|
|
30729
|
+
git_branch: str2(e.gitBranch) ?? prev?.git_branch ?? null,
|
|
30730
|
+
cwd: str2(e.cwd) ?? prev?.cwd ?? null,
|
|
30731
|
+
effort: str2(e.effort) ?? prev?.effort ?? null,
|
|
30732
|
+
version: str2(e.version) ?? prev?.version ?? null,
|
|
30733
|
+
entrypoint: str2(e.entrypoint) ?? prev?.entrypoint ?? null
|
|
30538
30734
|
});
|
|
30539
30735
|
continue;
|
|
30540
30736
|
}
|
|
@@ -30543,7 +30739,7 @@ function parseTranscriptLines(lines, ctx) {
|
|
|
30543
30739
|
if (!msg || !Array.isArray(msg.content)) continue;
|
|
30544
30740
|
for (const block of msg.content) {
|
|
30545
30741
|
if (!isObj(block) || block.type !== "tool_result") continue;
|
|
30546
|
-
const id =
|
|
30742
|
+
const id = str2(block.tool_use_id);
|
|
30547
30743
|
if (!id) continue;
|
|
30548
30744
|
const prev = toolUses.get(id);
|
|
30549
30745
|
let isError = prev?.is_error ?? 0;
|
|
@@ -30566,20 +30762,20 @@ function parseTranscriptLines(lines, ctx) {
|
|
|
30566
30762
|
continue;
|
|
30567
30763
|
}
|
|
30568
30764
|
if (type === "system") {
|
|
30569
|
-
const subtype =
|
|
30765
|
+
const subtype = str2(e.subtype);
|
|
30570
30766
|
if (subtype === "compact_boundary") {
|
|
30571
30767
|
const meta3 = isObj(e.compactMetadata) ? e.compactMetadata : void 0;
|
|
30572
30768
|
contextEvents.push({
|
|
30573
30769
|
session_id: sessionId,
|
|
30574
30770
|
ts,
|
|
30575
30771
|
kind: "compact",
|
|
30576
|
-
trigger: meta3 ?
|
|
30772
|
+
trigger: meta3 ? str2(meta3.trigger) : null,
|
|
30577
30773
|
pre_tokens: meta3 ? numOrNull(meta3.preTokens) : null,
|
|
30578
30774
|
post_tokens: meta3 ? numOrNull(meta3.postTokens) : null
|
|
30579
30775
|
});
|
|
30580
30776
|
} else if (subtype === "local_command") {
|
|
30581
30777
|
const run = isObj(e.commandRun) ? e.commandRun : void 0;
|
|
30582
|
-
if (run &&
|
|
30778
|
+
if (run && str2(run.command) === "clear") {
|
|
30583
30779
|
contextEvents.push({
|
|
30584
30780
|
session_id: sessionId,
|
|
30585
30781
|
ts,
|
|
@@ -30612,7 +30808,7 @@ function isValidSessionId(id) {
|
|
|
30612
30808
|
return SESSION_ID_RE.test(id);
|
|
30613
30809
|
}
|
|
30614
30810
|
function claudeDir() {
|
|
30615
|
-
return process.env.EMINIAR_CLAUDE_DIR ||
|
|
30811
|
+
return process.env.EMINIAR_CLAUDE_DIR || join5(homedir3(), ".claude");
|
|
30616
30812
|
}
|
|
30617
30813
|
function insideDir(path2, dir) {
|
|
30618
30814
|
const d = resolve3(dir);
|
|
@@ -30631,7 +30827,7 @@ function transcriptSlug(root) {
|
|
|
30631
30827
|
return root.replace(/[^A-Za-z0-9]/g, "-");
|
|
30632
30828
|
}
|
|
30633
30829
|
function transcriptDirFor(root) {
|
|
30634
|
-
return
|
|
30830
|
+
return join5(claudeDir(), "projects", transcriptSlug(root));
|
|
30635
30831
|
}
|
|
30636
30832
|
function usageEnabled(ctx) {
|
|
30637
30833
|
return ctx.config.usage.enabled !== false;
|
|
@@ -30801,7 +30997,7 @@ function add(a, b) {
|
|
|
30801
30997
|
}
|
|
30802
30998
|
function listJsonl(dir) {
|
|
30803
30999
|
try {
|
|
30804
|
-
return readdirSync(dir).filter((f) => f.endsWith(".jsonl")).map((f) =>
|
|
31000
|
+
return readdirSync(dir).filter((f) => f.endsWith(".jsonl")).map((f) => join5(dir, f));
|
|
30805
31001
|
} catch {
|
|
30806
31002
|
return [];
|
|
30807
31003
|
}
|
|
@@ -30821,7 +31017,7 @@ function firstEntrySessionId(path2) {
|
|
|
30821
31017
|
function sidechainFilesFor(db, dir, sessionId) {
|
|
30822
31018
|
if (!isValidSessionId(sessionId)) return [];
|
|
30823
31019
|
const inside = (p) => insideDir(p, dir) && p.endsWith(".jsonl");
|
|
30824
|
-
const out = listJsonl(
|
|
31020
|
+
const out = listJsonl(join5(dir, sessionId, "subagents")).filter(inside);
|
|
30825
31021
|
for (const path2 of listJsonl(dir)) {
|
|
30826
31022
|
if (!inside(path2) || !basename(path2).startsWith("agent-")) continue;
|
|
30827
31023
|
const known = db.transcriptFileGet(path2)?.session_id;
|
|
@@ -31192,20 +31388,20 @@ var preCompact = (input2) => {
|
|
|
31192
31388
|
// src/hooks/routing.ts
|
|
31193
31389
|
init_esm_shims();
|
|
31194
31390
|
import { realpathSync as realpathSync4, statSync as statSync5 } from "fs";
|
|
31195
|
-
import { homedir as
|
|
31196
|
-
import { extname as extname2, join as
|
|
31391
|
+
import { homedir as homedir6 } from "os";
|
|
31392
|
+
import { extname as extname2, join as join13, relative as relative4, resolve as resolve4 } from "path";
|
|
31197
31393
|
|
|
31198
31394
|
// src/docs/manifest.ts
|
|
31199
31395
|
init_esm_shims();
|
|
31200
|
-
import { existsSync as
|
|
31201
|
-
import { dirname as dirname3, join as
|
|
31396
|
+
import { existsSync as existsSync5, mkdirSync as mkdirSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync2 } from "fs";
|
|
31397
|
+
import { dirname as dirname3, join as join6 } from "path";
|
|
31202
31398
|
var DOCS_PREFIX = "docs:";
|
|
31203
31399
|
var NAME_RE = /^[a-z0-9][a-z0-9._-]{0,63}$/;
|
|
31204
31400
|
function isValidName(name) {
|
|
31205
31401
|
return NAME_RE.test(name);
|
|
31206
31402
|
}
|
|
31207
31403
|
function manifestPathAt(root, rel = ".eminiar/docs.json") {
|
|
31208
|
-
return
|
|
31404
|
+
return join6(root, rel);
|
|
31209
31405
|
}
|
|
31210
31406
|
function manifestPath(ctx) {
|
|
31211
31407
|
return manifestPathAt(ctx.root, ctx.config.docs.manifest);
|
|
@@ -31233,9 +31429,9 @@ function normalize(raw) {
|
|
|
31233
31429
|
return { version: 1, sources: out };
|
|
31234
31430
|
}
|
|
31235
31431
|
function readManifestAt(file3) {
|
|
31236
|
-
if (!
|
|
31432
|
+
if (!existsSync5(file3)) return empty();
|
|
31237
31433
|
try {
|
|
31238
|
-
return normalize(JSON.parse(
|
|
31434
|
+
return normalize(JSON.parse(readFileSync4(file3, "utf8")));
|
|
31239
31435
|
} catch {
|
|
31240
31436
|
return empty();
|
|
31241
31437
|
}
|
|
@@ -31246,9 +31442,9 @@ function readManifest(ctx) {
|
|
|
31246
31442
|
|
|
31247
31443
|
// src/permissions/settings.ts
|
|
31248
31444
|
init_esm_shims();
|
|
31249
|
-
import { existsSync as
|
|
31250
|
-
import { homedir as
|
|
31251
|
-
import { join as
|
|
31445
|
+
import { existsSync as existsSync6, readFileSync as readFileSync5, realpathSync as realpathSync3, statSync as statSync3 } from "fs";
|
|
31446
|
+
import { homedir as homedir4 } from "os";
|
|
31447
|
+
import { join as join7 } from "path";
|
|
31252
31448
|
|
|
31253
31449
|
// src/permissions/rules.ts
|
|
31254
31450
|
init_esm_shims();
|
|
@@ -31285,9 +31481,9 @@ init_esm_shims();
|
|
|
31285
31481
|
|
|
31286
31482
|
// src/permissions/settings.ts
|
|
31287
31483
|
function readRules(file3) {
|
|
31288
|
-
if (!
|
|
31484
|
+
if (!existsSync6(file3)) return {};
|
|
31289
31485
|
try {
|
|
31290
|
-
const s = JSON.parse(
|
|
31486
|
+
const s = JSON.parse(readFileSync5(file3, "utf8"));
|
|
31291
31487
|
return s.permissions ?? {};
|
|
31292
31488
|
} catch {
|
|
31293
31489
|
return {};
|
|
@@ -31303,9 +31499,9 @@ function stamp(file3) {
|
|
|
31303
31499
|
var cache2 = /* @__PURE__ */ new Map();
|
|
31304
31500
|
function loadPermissionRules(root, extraDeny = []) {
|
|
31305
31501
|
const files = [
|
|
31306
|
-
|
|
31307
|
-
|
|
31308
|
-
|
|
31502
|
+
join7(homedir4(), ".claude", "settings.json"),
|
|
31503
|
+
join7(root, ".claude", "settings.json"),
|
|
31504
|
+
join7(root, ".claude", "settings.local.json")
|
|
31309
31505
|
];
|
|
31310
31506
|
const key = `${root}\0${extraDeny.join("\0")}`;
|
|
31311
31507
|
const stamps = files.map(stamp);
|
|
@@ -31343,8 +31539,8 @@ function checkReadPath(rules, abs) {
|
|
|
31343
31539
|
|
|
31344
31540
|
// src/session/brief.ts
|
|
31345
31541
|
init_esm_shims();
|
|
31346
|
-
import { existsSync as
|
|
31347
|
-
import { join as
|
|
31542
|
+
import { existsSync as existsSync8, readFileSync as readFileSync7 } from "fs";
|
|
31543
|
+
import { join as join9 } from "path";
|
|
31348
31544
|
|
|
31349
31545
|
// src/memory/frontmatter.ts
|
|
31350
31546
|
init_esm_shims();
|
|
@@ -31378,15 +31574,15 @@ function parseMemoryFile(text) {
|
|
|
31378
31574
|
init_esm_shims();
|
|
31379
31575
|
var import_fast_glob2 = __toESM(require_out4(), 1);
|
|
31380
31576
|
import {
|
|
31381
|
-
existsSync as
|
|
31382
|
-
mkdirSync as
|
|
31383
|
-
readFileSync as
|
|
31577
|
+
existsSync as existsSync7,
|
|
31578
|
+
mkdirSync as mkdirSync4,
|
|
31579
|
+
readFileSync as readFileSync6,
|
|
31384
31580
|
renameSync,
|
|
31385
31581
|
statSync as statSync4,
|
|
31386
31582
|
unlinkSync,
|
|
31387
|
-
writeFileSync as
|
|
31583
|
+
writeFileSync as writeFileSync3
|
|
31388
31584
|
} from "fs";
|
|
31389
|
-
import { dirname as dirname4, join as
|
|
31585
|
+
import { dirname as dirname4, join as join8, relative as relative3, sep as sep2 } from "path";
|
|
31390
31586
|
|
|
31391
31587
|
// src/storage/types.ts
|
|
31392
31588
|
init_esm_shims();
|
|
@@ -31398,7 +31594,7 @@ function memoriesRel(ctx) {
|
|
|
31398
31594
|
return ctx.config.memories.dir.replace(/^\.\//, "").replace(/\/+$/, "");
|
|
31399
31595
|
}
|
|
31400
31596
|
function memoriesDir(ctx) {
|
|
31401
|
-
return
|
|
31597
|
+
return join8(ctx.root, memoriesRel(ctx));
|
|
31402
31598
|
}
|
|
31403
31599
|
|
|
31404
31600
|
// src/session/brief.ts
|
|
@@ -31441,10 +31637,10 @@ function historyLine(db) {
|
|
|
31441
31637
|
return `${parts.join("; ")}. em_history {action:"file", path} before editing, {action:"risk"} before committing.`;
|
|
31442
31638
|
}
|
|
31443
31639
|
function overviewParagraph(ctx) {
|
|
31444
|
-
const file3 =
|
|
31445
|
-
if (!
|
|
31640
|
+
const file3 = join9(memoriesDir(ctx), "onboarding", "overview.md");
|
|
31641
|
+
if (!existsSync8(file3)) return void 0;
|
|
31446
31642
|
try {
|
|
31447
|
-
const body = parseMemoryFile(
|
|
31643
|
+
const body = parseMemoryFile(readFileSync7(file3, "utf8")).body.trim();
|
|
31448
31644
|
const para = body.split(/\n\s*\n/).map(
|
|
31449
31645
|
(p) => p.replace(/^#+\s.*$/m, "").replace(/\s+/g, " ").trim()
|
|
31450
31646
|
).find((p) => p.length > 20);
|
|
@@ -31513,10 +31709,10 @@ function recordRouting(db, sessionId, e) {
|
|
|
31513
31709
|
|
|
31514
31710
|
// src/session/server-alive.ts
|
|
31515
31711
|
init_esm_shims();
|
|
31516
|
-
import { existsSync as
|
|
31517
|
-
import { join as
|
|
31712
|
+
import { existsSync as existsSync9, mkdirSync as mkdirSync5, readdirSync as readdirSync2, rmSync as rmSync2, writeFileSync as writeFileSync4 } from "fs";
|
|
31713
|
+
import { join as join10 } from "path";
|
|
31518
31714
|
function markersDir(ctx) {
|
|
31519
|
-
return
|
|
31715
|
+
return join10(projectDir(ctx.id), "servers");
|
|
31520
31716
|
}
|
|
31521
31717
|
function processAlive(pid) {
|
|
31522
31718
|
try {
|
|
@@ -31528,13 +31724,13 @@ function processAlive(pid) {
|
|
|
31528
31724
|
}
|
|
31529
31725
|
function liveServers(ctx) {
|
|
31530
31726
|
const dir = markersDir(ctx);
|
|
31531
|
-
if (!
|
|
31727
|
+
if (!existsSync9(dir)) return [];
|
|
31532
31728
|
const live2 = [];
|
|
31533
31729
|
for (const name of readdirSync2(dir)) {
|
|
31534
31730
|
const pid = Number(name);
|
|
31535
31731
|
if (!Number.isInteger(pid) || pid <= 0) continue;
|
|
31536
31732
|
if (processAlive(pid)) live2.push(pid);
|
|
31537
|
-
else
|
|
31733
|
+
else rmSync2(join10(dir, name), { force: true });
|
|
31538
31734
|
}
|
|
31539
31735
|
return live2;
|
|
31540
31736
|
}
|
|
@@ -31544,30 +31740,30 @@ function serverAlive(ctx) {
|
|
|
31544
31740
|
|
|
31545
31741
|
// src/hooks/coexist.ts
|
|
31546
31742
|
init_esm_shims();
|
|
31547
|
-
import { readFileSync as
|
|
31548
|
-
import { join as
|
|
31743
|
+
import { readFileSync as readFileSync9 } from "fs";
|
|
31744
|
+
import { join as join12 } from "path";
|
|
31549
31745
|
|
|
31550
31746
|
// src/install/claude-config.ts
|
|
31551
31747
|
init_esm_shims();
|
|
31552
31748
|
import {
|
|
31553
31749
|
copyFileSync,
|
|
31554
|
-
existsSync as
|
|
31555
|
-
mkdirSync as
|
|
31750
|
+
existsSync as existsSync10,
|
|
31751
|
+
mkdirSync as mkdirSync6,
|
|
31556
31752
|
readdirSync as readdirSync3,
|
|
31557
|
-
readFileSync as
|
|
31558
|
-
writeFileSync as
|
|
31753
|
+
readFileSync as readFileSync8,
|
|
31754
|
+
writeFileSync as writeFileSync5
|
|
31559
31755
|
} from "fs";
|
|
31560
|
-
import { homedir as
|
|
31561
|
-
import { dirname as dirname5, join as
|
|
31562
|
-
var claudeDir2 = () => process.env.CLAUDE_CONFIG_DIR ||
|
|
31563
|
-
var pluginsDir = () =>
|
|
31756
|
+
import { homedir as homedir5 } from "os";
|
|
31757
|
+
import { dirname as dirname5, join as join11 } from "path";
|
|
31758
|
+
var claudeDir2 = () => process.env.CLAUDE_CONFIG_DIR || join11(homedir5(), ".claude");
|
|
31759
|
+
var pluginsDir = () => join11(claudeDir2(), "plugins");
|
|
31564
31760
|
|
|
31565
31761
|
// src/hooks/coexist.ts
|
|
31566
31762
|
var cached2;
|
|
31567
31763
|
function contextModeInstalled() {
|
|
31568
31764
|
if (cached2 !== void 0) return cached2;
|
|
31569
31765
|
try {
|
|
31570
|
-
const reg = JSON.parse(
|
|
31766
|
+
const reg = JSON.parse(readFileSync9(join12(pluginsDir(), "installed_plugins.json"), "utf8"));
|
|
31571
31767
|
cached2 = Object.keys(reg.plugins ?? {}).some((id) => id.startsWith("context-mode@"));
|
|
31572
31768
|
} catch {
|
|
31573
31769
|
cached2 = false;
|
|
@@ -31651,7 +31847,7 @@ function historyCall(cmd) {
|
|
|
31651
31847
|
}
|
|
31652
31848
|
function docsSources(root) {
|
|
31653
31849
|
try {
|
|
31654
|
-
return readManifestAt(
|
|
31850
|
+
return readManifestAt(join13(root, ".eminiar", "docs.json")).sources;
|
|
31655
31851
|
} catch {
|
|
31656
31852
|
return [];
|
|
31657
31853
|
}
|
|
@@ -31799,7 +31995,7 @@ function fileOperands(stage, cwd) {
|
|
|
31799
31995
|
for (let f of files) {
|
|
31800
31996
|
if (/[*?[\]{}$`\\]/.test(f)) return void 0;
|
|
31801
31997
|
f = f.replace(/^['"]|['"]$/g, "");
|
|
31802
|
-
if (f.startsWith("~/")) f =
|
|
31998
|
+
if (f.startsWith("~/")) f = join13(homedir6(), f.slice(2));
|
|
31803
31999
|
out.push(resolve4(cwd, f));
|
|
31804
32000
|
}
|
|
31805
32001
|
return out;
|
|
@@ -32205,18 +32401,18 @@ function annotate(s, note = "") {
|
|
|
32205
32401
|
|
|
32206
32402
|
// src/hooks/session-start.ts
|
|
32207
32403
|
init_esm_shims();
|
|
32208
|
-
import { appendFileSync as appendFileSync2, existsSync as
|
|
32209
|
-
import { join as
|
|
32404
|
+
import { appendFileSync as appendFileSync2, existsSync as existsSync11, readdirSync as readdirSync4 } from "fs";
|
|
32405
|
+
import { join as join15 } from "path";
|
|
32210
32406
|
|
|
32211
32407
|
// src/session/current.ts
|
|
32212
32408
|
init_esm_shims();
|
|
32213
|
-
import { readFileSync as
|
|
32214
|
-
import { join as
|
|
32409
|
+
import { readFileSync as readFileSync10, statSync as statSync6, writeFileSync as writeFileSync6 } from "fs";
|
|
32410
|
+
import { join as join14 } from "path";
|
|
32215
32411
|
function file2(ctx) {
|
|
32216
|
-
return
|
|
32412
|
+
return join14(projectDir(ctx.id), "current-session");
|
|
32217
32413
|
}
|
|
32218
32414
|
function setCurrentSession(ctx, sessionId) {
|
|
32219
|
-
|
|
32415
|
+
writeFileSync6(file2(ctx), sessionId);
|
|
32220
32416
|
}
|
|
32221
32417
|
|
|
32222
32418
|
// src/hooks/session-start.ts
|
|
@@ -32305,8 +32501,8 @@ ${guide}`);
|
|
|
32305
32501
|
} catch {
|
|
32306
32502
|
}
|
|
32307
32503
|
try {
|
|
32308
|
-
const onboarding =
|
|
32309
|
-
const onboarded =
|
|
32504
|
+
const onboarding = join15(memoriesDir(ctx), "onboarding");
|
|
32505
|
+
const onboarded = existsSync11(onboarding) && readdirSync4(onboarding).some((f) => f.endsWith(".md"));
|
|
32310
32506
|
if (!onboarded)
|
|
32311
32507
|
parts.push(
|
|
32312
32508
|
"No onboarding memories yet: run /eminiar:em-onboard once so future sessions start with the project's structure, build and test commands."
|
|
@@ -32320,7 +32516,7 @@ ${guide}`);
|
|
|
32320
32516
|
} catch {
|
|
32321
32517
|
}
|
|
32322
32518
|
try {
|
|
32323
|
-
if (
|
|
32519
|
+
if (existsSync11(join15(ctx.root, ".git")) && !db.metaGet("history_files"))
|
|
32324
32520
|
parts.push(
|
|
32325
32521
|
'Git history is not classified yet: em_history {action:"overview"} builds it (the server also does this in the background shortly after start); bug-prone files are flagged before you read or edit them once it exists.'
|
|
32326
32522
|
);
|
|
@@ -32356,37 +32552,65 @@ var handlers = {
|
|
|
32356
32552
|
SessionEnd: sessionEnd
|
|
32357
32553
|
};
|
|
32358
32554
|
|
|
32359
|
-
// src/
|
|
32360
|
-
async function
|
|
32361
|
-
|
|
32362
|
-
for await (const chunk2 of process.stdin) chunks.push(chunk2);
|
|
32363
|
-
return Buffer.concat(chunks).toString("utf8");
|
|
32364
|
-
}
|
|
32365
|
-
function emit(out) {
|
|
32366
|
-
process.stdout.write(JSON.stringify(out));
|
|
32367
|
-
}
|
|
32368
|
-
async function main() {
|
|
32369
|
-
const forced = process.argv.indexOf("--event");
|
|
32370
|
-
const raw = await readStdin();
|
|
32371
|
-
let input2;
|
|
32555
|
+
// src/hooks/dispatch.ts
|
|
32556
|
+
async function dispatch(raw, argv) {
|
|
32557
|
+
let parsed;
|
|
32372
32558
|
try {
|
|
32373
|
-
|
|
32559
|
+
parsed = raw.trim() ? JSON.parse(raw) : {};
|
|
32374
32560
|
} catch (err) {
|
|
32375
32561
|
hookLog("error", `bad stdin JSON: ${err.message}`);
|
|
32376
|
-
return
|
|
32562
|
+
return "{}";
|
|
32377
32563
|
}
|
|
32378
|
-
|
|
32379
|
-
if (
|
|
32564
|
+
const forced = argv.indexOf("--event");
|
|
32565
|
+
if (forced !== -1 && argv[forced + 1]) parsed.hook_event_name = argv[forced + 1];
|
|
32566
|
+
if (argv.includes("--selftest")) return JSON.stringify({ systemMessage: "eminiar hook ok" });
|
|
32567
|
+
if (detectClient(parsed, argv) === "cursor") return runCursor(parsed);
|
|
32568
|
+
const input2 = parsed;
|
|
32380
32569
|
const handler = handlers[input2.hook_event_name];
|
|
32381
|
-
if (!handler) return
|
|
32570
|
+
if (!handler) return "{}";
|
|
32382
32571
|
try {
|
|
32383
32572
|
const out = await handler(input2);
|
|
32384
|
-
|
|
32573
|
+
return JSON.stringify(out ?? {});
|
|
32385
32574
|
} catch (err) {
|
|
32386
32575
|
hookLog("error", `${input2.hook_event_name}: ${err.stack ?? String(err)}`);
|
|
32387
|
-
|
|
32576
|
+
return "{}";
|
|
32388
32577
|
}
|
|
32389
32578
|
}
|
|
32579
|
+
async function runCursor(parsed) {
|
|
32580
|
+
const input2 = fromCursor(parsed);
|
|
32581
|
+
const event = input2.hook_event_name;
|
|
32582
|
+
let out;
|
|
32583
|
+
const handler = handlers[event];
|
|
32584
|
+
if (handler) {
|
|
32585
|
+
try {
|
|
32586
|
+
out = await handler(input2);
|
|
32587
|
+
} catch (err) {
|
|
32588
|
+
hookLog("error", `cursor ${event}: ${err.stack ?? String(err)}`);
|
|
32589
|
+
}
|
|
32590
|
+
}
|
|
32591
|
+
let root = input2.cwd;
|
|
32592
|
+
try {
|
|
32593
|
+
root = getContext(input2.cwd).root;
|
|
32594
|
+
} catch {
|
|
32595
|
+
}
|
|
32596
|
+
try {
|
|
32597
|
+
return JSON.stringify(toCursor(event, out, { root, sessionId: input2.session_id }));
|
|
32598
|
+
} catch (err) {
|
|
32599
|
+
hookLog("error", `cursor ${event} output: ${err.stack ?? String(err)}`);
|
|
32600
|
+
return event === "PreToolUse" ? '{"permission":"allow"}' : "{}";
|
|
32601
|
+
}
|
|
32602
|
+
}
|
|
32603
|
+
|
|
32604
|
+
// src/hook.ts
|
|
32605
|
+
async function readStdin() {
|
|
32606
|
+
const chunks = [];
|
|
32607
|
+
for await (const chunk2 of process.stdin) chunks.push(chunk2);
|
|
32608
|
+
return Buffer.concat(chunks).toString("utf8");
|
|
32609
|
+
}
|
|
32610
|
+
async function main() {
|
|
32611
|
+
const raw = await readStdin();
|
|
32612
|
+
process.stdout.write(await dispatch(raw, process.argv.slice(2)));
|
|
32613
|
+
}
|
|
32390
32614
|
main().catch((err) => {
|
|
32391
32615
|
hookLog("error", `fatal: ${err.stack ?? String(err)}`);
|
|
32392
32616
|
process.stdout.write("{}");
|