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/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(str2) {
178
- if (typeof str2 !== "string" || str2 === "") {
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(str2)) {
182
+ while (match = /(\\).|([@?!+*]\(.*\))/g.exec(str3)) {
183
183
  if (match[2]) return true;
184
- str2 = str2.slice(match.index + match[0].length);
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(str2) {
199
- if (str2[0] === "!") {
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 < str2.length) {
209
- if (str2[index] === "*") {
208
+ while (index < str3.length) {
209
+ if (str3[index] === "*") {
210
210
  return true;
211
211
  }
212
- if (str2[index + 1] === "?" && /[\].+)]/.test(str2[index])) {
212
+ if (str3[index + 1] === "?" && /[\].+)]/.test(str3[index])) {
213
213
  return true;
214
214
  }
215
- if (closeSquareIndex !== -1 && str2[index] === "[" && str2[index + 1] !== "]") {
215
+ if (closeSquareIndex !== -1 && str3[index] === "[" && str3[index + 1] !== "]") {
216
216
  if (closeSquareIndex < index) {
217
- closeSquareIndex = str2.indexOf("]", index);
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 = str2.indexOf("\\", index);
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 && str2[index] === "{" && str2[index + 1] !== "}") {
230
- closeCurlyIndex = str2.indexOf("}", index);
229
+ if (closeCurlyIndex !== -1 && str3[index] === "{" && str3[index + 1] !== "}") {
230
+ closeCurlyIndex = str3.indexOf("}", index);
231
231
  if (closeCurlyIndex > index) {
232
- backSlashIndex = str2.indexOf("\\", index);
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 && str2[index] === "(" && str2[index + 1] === "?" && /[:!=]/.test(str2[index + 2]) && str2[index + 3] !== ")") {
239
- closeParenIndex = str2.indexOf(")", index);
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 = str2.indexOf("\\", index);
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 && str2[index] === "(" && str2[index + 1] !== "|") {
247
+ if (pipeIndex !== -1 && str3[index] === "(" && str3[index + 1] !== "|") {
248
248
  if (pipeIndex < index) {
249
- pipeIndex = str2.indexOf("|", index);
249
+ pipeIndex = str3.indexOf("|", index);
250
250
  }
251
- if (pipeIndex !== -1 && str2[pipeIndex + 1] !== ")") {
252
- closeParenIndex = str2.indexOf(")", pipeIndex);
251
+ if (pipeIndex !== -1 && str3[pipeIndex + 1] !== ")") {
252
+ closeParenIndex = str3.indexOf(")", pipeIndex);
253
253
  if (closeParenIndex > pipeIndex) {
254
- backSlashIndex = str2.indexOf("\\", pipeIndex);
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 (str2[index] === "\\") {
262
- var open4 = str2[index + 1];
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 = str2.indexOf(close, index);
266
+ var n = str3.indexOf(close, index);
267
267
  if (n !== -1) {
268
268
  index = n + 1;
269
269
  }
270
270
  }
271
- if (str2[index] === "!") {
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(str2) {
281
- if (str2[0] === "!") {
280
+ var relaxedCheck = function(str3) {
281
+ if (str3[0] === "!") {
282
282
  return true;
283
283
  }
284
284
  var index = 0;
285
- while (index < str2.length) {
286
- if (/[*?{}()[\]]/.test(str2[index])) {
285
+ while (index < str3.length) {
286
+ if (/[*?{}()[\]]/.test(str3[index])) {
287
287
  return true;
288
288
  }
289
- if (str2[index] === "\\") {
290
- var open4 = str2[index + 1];
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 = str2.indexOf(close, index);
294
+ var n = str3.indexOf(close, index);
295
295
  if (n !== -1) {
296
296
  index = n + 1;
297
297
  }
298
298
  }
299
- if (str2[index] === "!") {
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(str2, options) {
309
- if (typeof str2 !== "string" || str2 === "") {
308
+ module.exports = function isGlob(str3, options) {
309
+ if (typeof str3 !== "string" || str3 === "") {
310
310
  return false;
311
311
  }
312
- if (isExtglob(str2)) {
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(str2);
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(str2, opts) {
337
+ module.exports = function globParent(str3, opts) {
338
338
  var options = Object.assign({ flipBackslashes: true }, opts);
339
- if (options.flipBackslashes && isWin32 && str2.indexOf(slash) < 0) {
340
- str2 = str2.replace(backslash, slash);
339
+ if (options.flipBackslashes && isWin32 && str3.indexOf(slash) < 0) {
340
+ str3 = str3.replace(backslash, slash);
341
341
  }
342
- if (enclosure.test(str2)) {
343
- str2 += slash;
342
+ if (enclosure.test(str3)) {
343
+ str3 += slash;
344
344
  }
345
- str2 += "a";
345
+ str3 += "a";
346
346
  do {
347
- str2 = pathPosixDirname(str2);
348
- } while (isGlob(str2) || globby.test(str2));
349
- return str2.replace(escaped, "$1");
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(str2) {
672
- return /^-?(0+)\d/.test(str2);
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 = (str2) => REGEX_SPECIAL_CHARS.test(str2);
1663
- exports.isRegexChar = (str2) => str2.length === 1 && exports.hasRegexChars(str2);
1664
- exports.escapeRegex = (str2) => str2.replace(REGEX_SPECIAL_CHARS_GLOBAL, "\\$1");
1665
- exports.toPosixSlashes = (str2) => str2.replace(REGEX_BACKSLASH, "/");
1666
- exports.removeBackslashes = (str2) => {
1667
- return str2.replace(REGEX_REMOVE_BACKSLASH, (match) => {
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 str2 = input2;
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 = () => str2.charCodeAt(index + 1);
1782
+ const peek = () => str3.charCodeAt(index + 1);
1783
1783
  const advance = () => {
1784
1784
  prev = code;
1785
- return str2.charCodeAt(++index);
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 = str2;
1953
+ let base = str3;
1954
1954
  let prefix = "";
1955
1955
  let glob = "";
1956
1956
  if (start > 0) {
1957
- prefix = str2.slice(0, start);
1958
- str2 = str2.slice(start);
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 = str2.slice(0, lastIndex);
1963
- glob = str2.slice(lastIndex);
1962
+ base = str3.slice(0, lastIndex);
1963
+ glob = str3.slice(lastIndex);
1964
1964
  } else if (isGlob === true) {
1965
1965
  base = "";
1966
- glob = str2;
1966
+ glob = str3;
1967
1967
  } else {
1968
- base = str2;
1968
+ base = str3;
1969
1969
  }
1970
- if (base && base !== "" && base !== "/" && base !== str2) {
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 = (str2) => {
3007
- switch (str2) {
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(str2);
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 = (str2) => {
3058
+ const arrayMatcher = (str3) => {
3059
3059
  for (const isMatch of fns) {
3060
- const state2 = isMatch(str2);
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 = (str2, patterns, options) => picomatch(patterns, options)(str2);
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 = (str2, patterns, options) => picomatch(patterns, options)(str2);
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 = (str2, pattern, options) => {
3271
- if (typeof str2 !== "string") {
3272
- throw new TypeError(`Expected a string: "${util.inspect(str2)}"`);
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(str2, p, options));
3275
+ return pattern.some((p) => micromatch.contains(str3, p, options));
3276
3276
  }
3277
3277
  if (typeof pattern === "string") {
3278
- if (isEmptyString(str2) || isEmptyString(pattern)) {
3278
+ if (isEmptyString(str3) || isEmptyString(pattern)) {
3279
3279
  return false;
3280
3280
  }
3281
- if (str2.includes(pattern) || str2.startsWith("./") && str2.slice(2).includes(pattern)) {
3281
+ if (str3.includes(pattern) || str3.startsWith("./") && str3.slice(2).includes(pattern)) {
3282
3282
  return true;
3283
3283
  }
3284
3284
  }
3285
- return micromatch.isMatch(str2, pattern, { ...options, contains: true });
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 = (str2, patterns, options) => {
3317
- if (typeof str2 !== "string") {
3318
- throw new TypeError(`Expected a string: "${util.inspect(str2)}"`);
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)(str2));
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 str2 of braces(String(pattern), options)) {
3336
- res.push(picomatch.parse(str2, options));
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/index.ts
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 str2 = "";
6731
+ let str3 = "";
6970
6732
  for (let i = 0; i < length; i++) {
6971
- str2 += chars[Math.floor(Math.random() * chars.length)];
6733
+ str3 += chars[Math.floor(Math.random() * chars.length)];
6972
6734
  }
6973
- return str2;
6735
+ return str3;
6974
6736
  }
6975
- function esc(str2) {
6976
- return JSON.stringify(str2);
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(str2) {
7091
- return str2.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
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(str2) {
7358
- const units = str2.length;
7359
- if (!highSurrogate.test(str2))
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 ((str2.charCodeAt(i) & 64512) === 55296 && (str2.charCodeAt(i + 1) & 64512) === 56320) {
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 as createHash2 } from "crypto";
26223
- import { existsSync as existsSync2, realpathSync as realpathSync2 } from "fs";
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 realpathSync2(root);
26010
+ return realpathSync(root);
26249
26011
  } catch {
26250
26012
  return root;
26251
26013
  }
26252
26014
  }
26253
26015
  function projectId(root) {
26254
- return createHash2("sha256").update(root).digest("hex").slice(0, 16);
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/index/indexer.ts
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 { createHash as createHash3 } from "crypto";
26286
- var DEFAULT_CHUNKER = { maxChars: 1800, overlapLines: 5 };
26287
- function hashText(s) {
26288
- return createHash3("sha1").update(s).digest("hex");
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 existsSync3, openSync, readdirSync, readSync, statSync as statSync2 } from "fs";
30386
- import { homedir as homedir2 } from "os";
30387
- import { basename, dirname as dirname2, join as join4, resolve as resolve3, sep } from "path";
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 str(v) {
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 = str(part.type);
30425
- if (kind === "text" || typeof part.text === "string") n += str(part.text)?.length ?? 0;
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 = str(e.type);
30666
+ const type = str2(e.type);
30471
30667
  if (!type) continue;
30472
- const sessionId = str(e.sessionId) ?? ctx.sessionId;
30473
- const agentId = str(e.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 = str(msg.id);
30483
- const requestId = str(e.requestId) ?? messageId;
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 = str(block.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: str(block.name) ?? prev2?.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 = str(msg.model) ?? "unknown";
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: str(usage.service_tier),
30530
- speed: str(usage.speed),
30531
- stop_reason: str(msg.stop_reason) ?? prev?.stop_reason ?? null,
30532
- prompt_id: str(e.promptId) ?? prev?.prompt_id ?? null,
30533
- git_branch: str(e.gitBranch) ?? prev?.git_branch ?? null,
30534
- cwd: str(e.cwd) ?? prev?.cwd ?? null,
30535
- effort: str(e.effort) ?? prev?.effort ?? null,
30536
- version: str(e.version) ?? prev?.version ?? null,
30537
- entrypoint: str(e.entrypoint) ?? prev?.entrypoint ?? null
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 = str(block.tool_use_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 = str(e.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 ? str(meta3.trigger) : null,
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 && str(run.command) === "clear") {
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 || join4(homedir2(), ".claude");
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 join4(claudeDir(), "projects", transcriptSlug(root));
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) => join4(dir, 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(join4(dir, sessionId, "subagents")).filter(inside);
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 homedir5 } from "os";
31196
- import { extname as extname2, join as join12, relative as relative4, resolve as resolve4 } from "path";
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 existsSync4, mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync } from "fs";
31201
- import { dirname as dirname3, join as join5 } from "path";
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 join5(root, rel);
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 (!existsSync4(file3)) return empty();
31432
+ if (!existsSync5(file3)) return empty();
31237
31433
  try {
31238
- return normalize(JSON.parse(readFileSync3(file3, "utf8")));
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 existsSync5, readFileSync as readFileSync4, realpathSync as realpathSync3, statSync as statSync3 } from "fs";
31250
- import { homedir as homedir3 } from "os";
31251
- import { join as join6 } from "path";
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 (!existsSync5(file3)) return {};
31484
+ if (!existsSync6(file3)) return {};
31289
31485
  try {
31290
- const s = JSON.parse(readFileSync4(file3, "utf8"));
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
- join6(homedir3(), ".claude", "settings.json"),
31307
- join6(root, ".claude", "settings.json"),
31308
- join6(root, ".claude", "settings.local.json")
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 existsSync7, readFileSync as readFileSync6 } from "fs";
31347
- import { join as join8 } from "path";
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 existsSync6,
31382
- mkdirSync as mkdirSync3,
31383
- readFileSync as readFileSync5,
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 writeFileSync2
31583
+ writeFileSync as writeFileSync3
31388
31584
  } from "fs";
31389
- import { dirname as dirname4, join as join7, relative as relative3, sep as sep2 } from "path";
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 join7(ctx.root, memoriesRel(ctx));
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 = join8(memoriesDir(ctx), "onboarding", "overview.md");
31445
- if (!existsSync7(file3)) return void 0;
31640
+ const file3 = join9(memoriesDir(ctx), "onboarding", "overview.md");
31641
+ if (!existsSync8(file3)) return void 0;
31446
31642
  try {
31447
- const body = parseMemoryFile(readFileSync6(file3, "utf8")).body.trim();
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 existsSync8, mkdirSync as mkdirSync4, readdirSync as readdirSync2, rmSync, writeFileSync as writeFileSync3 } from "fs";
31517
- import { join as join9 } from "path";
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 join9(projectDir(ctx.id), "servers");
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 (!existsSync8(dir)) return [];
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 rmSync(join9(dir, name), { force: true });
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 readFileSync8 } from "fs";
31548
- import { join as join11 } from "path";
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 existsSync9,
31555
- mkdirSync as mkdirSync5,
31750
+ existsSync as existsSync10,
31751
+ mkdirSync as mkdirSync6,
31556
31752
  readdirSync as readdirSync3,
31557
- readFileSync as readFileSync7,
31558
- writeFileSync as writeFileSync4
31753
+ readFileSync as readFileSync8,
31754
+ writeFileSync as writeFileSync5
31559
31755
  } from "fs";
31560
- import { homedir as homedir4 } from "os";
31561
- import { dirname as dirname5, join as join10 } from "path";
31562
- var claudeDir2 = () => process.env.CLAUDE_CONFIG_DIR || join10(homedir4(), ".claude");
31563
- var pluginsDir = () => join10(claudeDir2(), "plugins");
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(readFileSync8(join11(pluginsDir(), "installed_plugins.json"), "utf8"));
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(join12(root, ".eminiar", "docs.json")).sources;
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 = join12(homedir5(), f.slice(2));
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 existsSync10, readdirSync as readdirSync4 } from "fs";
32209
- import { join as join14 } from "path";
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 readFileSync9, statSync as statSync6, writeFileSync as writeFileSync5 } from "fs";
32214
- import { join as join13 } from "path";
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 join13(projectDir(ctx.id), "current-session");
32412
+ return join14(projectDir(ctx.id), "current-session");
32217
32413
  }
32218
32414
  function setCurrentSession(ctx, sessionId) {
32219
- writeFileSync5(file2(ctx), sessionId);
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 = join14(memoriesDir(ctx), "onboarding");
32309
- const onboarded = existsSync10(onboarding) && readdirSync4(onboarding).some((f) => f.endsWith(".md"));
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 (existsSync10(join14(ctx.root, ".git")) && !db.metaGet("history_files"))
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/hook.ts
32360
- async function readStdin() {
32361
- const chunks = [];
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
- input2 = raw.trim() ? JSON.parse(raw) : {};
32559
+ parsed = raw.trim() ? JSON.parse(raw) : {};
32374
32560
  } catch (err) {
32375
32561
  hookLog("error", `bad stdin JSON: ${err.message}`);
32376
- return emit({});
32562
+ return "{}";
32377
32563
  }
32378
- if (forced !== -1 && process.argv[forced + 1]) input2.hook_event_name = process.argv[forced + 1];
32379
- if (process.argv.includes("--selftest")) return emit({ systemMessage: "eminiar hook ok" });
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 emit({});
32570
+ if (!handler) return "{}";
32382
32571
  try {
32383
32572
  const out = await handler(input2);
32384
- emit(out ?? {});
32573
+ return JSON.stringify(out ?? {});
32385
32574
  } catch (err) {
32386
32575
  hookLog("error", `${input2.hook_event_name}: ${err.stack ?? String(err)}`);
32387
- emit({});
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("{}");