@stupify/cli 0.0.3 → 0.0.4

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.
Files changed (59) hide show
  1. package/README.md +26 -31
  2. package/dist/analysis.d.ts +11 -9
  3. package/dist/analysis.js +30 -173
  4. package/dist/checks.d.ts +1 -0
  5. package/dist/checks.js +89 -2
  6. package/dist/command.js +55 -91
  7. package/dist/constants.d.ts +1 -1
  8. package/dist/constants.js +1 -1
  9. package/dist/counter-scout.js +70 -8
  10. package/dist/doctor.d.ts +4 -0
  11. package/dist/doctor.js +131 -0
  12. package/dist/git.d.ts +4 -1
  13. package/dist/git.js +34 -0
  14. package/dist/hooks.d.ts +3 -0
  15. package/dist/hooks.js +117 -0
  16. package/dist/model.d.ts +1 -15
  17. package/dist/model.js +37 -21
  18. package/dist/prompts.d.ts +8 -5
  19. package/dist/prompts.js +58 -168
  20. package/dist/render.d.ts +2 -2
  21. package/dist/render.js +70 -78
  22. package/dist/repomix-provider.d.ts +10 -2
  23. package/dist/repomix-provider.js +62 -11
  24. package/dist/search-bench.d.ts +1 -0
  25. package/dist/search-bench.js +675 -0
  26. package/dist/search-profile.d.ts +6 -0
  27. package/dist/search-profile.js +73 -0
  28. package/dist/sem-provider.d.ts +2 -2
  29. package/dist/sem-provider.js +33 -7
  30. package/dist/stupify.d.ts +2 -0
  31. package/dist/stupify.js +183 -333
  32. package/dist/types.d.ts +193 -109
  33. package/package.json +1 -1
  34. package/src/analysis.ts +48 -268
  35. package/src/checks.ts +91 -2
  36. package/src/command.ts +62 -107
  37. package/src/constants.ts +1 -1
  38. package/src/counter-scout.ts +63 -7
  39. package/src/doctor.ts +140 -0
  40. package/src/git.ts +35 -1
  41. package/src/hooks.ts +134 -0
  42. package/src/model.ts +39 -26
  43. package/src/prompts.ts +66 -202
  44. package/src/render.ts +68 -79
  45. package/src/repomix-provider.ts +66 -10
  46. package/src/search-bench.ts +783 -0
  47. package/src/search-profile.ts +89 -0
  48. package/src/sem-provider.ts +36 -9
  49. package/src/stupify.ts +213 -526
  50. package/src/types.ts +195 -119
  51. package/dist/batcher.d.ts +0 -3
  52. package/dist/batcher.js +0 -142
  53. package/dist/candidate-context.d.ts +0 -2
  54. package/dist/candidate-context.js +0 -40
  55. package/dist/experiment.d.ts +0 -1
  56. package/dist/experiment.js +0 -225
  57. package/src/batcher.ts +0 -198
  58. package/src/candidate-context.ts +0 -43
  59. package/src/experiment.ts +0 -317
@@ -5,18 +5,23 @@ import { pack, setLogLevel } from "repomix";
5
5
  const MAX_PACK_FILE_SIZE_BYTES = 48 * 1024;
6
6
  const MAX_PACK_TOTAL_SIZE_BYTES = 128 * 1024;
7
7
  export function emptyContextPack() {
8
+ const config = repomixSearchConfig();
8
9
  return {
9
10
  provider: "repomix",
10
11
  filePaths: [],
11
12
  totalCharacters: 0,
12
13
  totalTokens: 0,
13
14
  text: "",
15
+ config,
14
16
  };
15
17
  }
16
- export async function repomixContextPack(cwd, contexts, changes) {
17
- const filePaths = await candidateFilePaths(cwd, contexts, changes);
18
+ export async function repomixContextPack(cwd, contexts, changes, config = repomixSearchConfig()) {
19
+ const filePaths = await candidateFilePaths(cwd, contexts, changes, config);
18
20
  if (filePaths.length === 0) {
19
- return emptyContextPack();
21
+ return {
22
+ ...emptyContextPack(),
23
+ config,
24
+ };
20
25
  }
21
26
  setLogLevel(-1);
22
27
  const tempDir = await mkdtemp(path.join(tmpdir(), "stupify-repomix-"));
@@ -24,7 +29,7 @@ export async function repomixContextPack(cwd, contexts, changes) {
24
29
  try {
25
30
  const result = await pack([cwd], {
26
31
  cwd,
27
- input: { maxFileSize: MAX_PACK_FILE_SIZE_BYTES },
32
+ input: { maxFileSize: config.maxFileSizeBytes },
28
33
  output: {
29
34
  filePath: outputPath,
30
35
  style: "xml",
@@ -33,10 +38,10 @@ export async function repomixContextPack(cwd, contexts, changes) {
33
38
  directoryStructure: false,
34
39
  files: true,
35
40
  removeComments: false,
36
- removeEmptyLines: true,
37
- compress: true,
41
+ removeEmptyLines: config.removeEmptyLines,
42
+ compress: config.compress,
38
43
  topFilesLength: 0,
39
- showLineNumbers: true,
44
+ showLineNumbers: config.showLineNumbers,
40
45
  truncateBase64: true,
41
46
  copyToClipboard: false,
42
47
  includeFullDirectoryStructure: false,
@@ -54,7 +59,7 @@ export async function repomixContextPack(cwd, contexts, changes) {
54
59
  useGitignore: true,
55
60
  useDotIgnore: true,
56
61
  useDefaultPatterns: true,
57
- customPatterns: [],
62
+ customPatterns: [...config.ignorePatterns],
58
63
  },
59
64
  security: { enableSecurityCheck: false },
60
65
  tokenCount: { encoding: "o200k_base" },
@@ -65,6 +70,7 @@ export async function repomixContextPack(cwd, contexts, changes) {
65
70
  totalCharacters: result.totalCharacters,
66
71
  totalTokens: result.totalTokens,
67
72
  text: await readFile(outputPath, "utf8"),
73
+ config,
68
74
  };
69
75
  }
70
76
  finally {
@@ -98,23 +104,68 @@ export function entityContextsFromChanges(candidates, changes) {
98
104
  }];
99
105
  });
100
106
  }
101
- async function candidateFilePaths(cwd, contexts, changes) {
107
+ async function candidateFilePaths(cwd, contexts, changes, config) {
102
108
  const byEntityId = new Map(changes.map((change) => [change.entityId, change.filePath]));
103
109
  const paths = contexts.flatMap((context) => context.filePath ?? byEntityId.get(context.entityId) ?? []);
104
110
  const safePaths = [...new Set(paths)].filter(isSafeRelativeFilePath);
105
111
  const selected = [];
106
112
  let totalBytes = 0;
107
113
  for (const filePath of safePaths) {
114
+ if (matchesAnyPattern(filePath, config.ignorePatterns))
115
+ continue;
108
116
  const bytes = await fileSize(cwd, filePath);
109
- if (bytes === null || bytes > MAX_PACK_FILE_SIZE_BYTES)
117
+ if (bytes === null || bytes > config.maxFileSizeBytes)
110
118
  continue;
111
- if (totalBytes + bytes > MAX_PACK_TOTAL_SIZE_BYTES)
119
+ if (totalBytes + bytes > config.maxTotalSizeBytes)
112
120
  continue;
113
121
  totalBytes += bytes;
114
122
  selected.push(filePath);
115
123
  }
116
124
  return selected;
117
125
  }
126
+ export function repomixSearchConfig() {
127
+ return {
128
+ compress: envBoolean("STUPIFY_REPOMIX_COMPRESS", true),
129
+ showLineNumbers: envBoolean("STUPIFY_REPOMIX_SHOW_LINE_NUMBERS", true),
130
+ removeEmptyLines: envBoolean("STUPIFY_REPOMIX_REMOVE_EMPTY_LINES", true),
131
+ maxFileSizeBytes: envInteger("STUPIFY_REPOMIX_MAX_FILE_BYTES", MAX_PACK_FILE_SIZE_BYTES),
132
+ maxTotalSizeBytes: envInteger("STUPIFY_REPOMIX_MAX_TOTAL_BYTES", MAX_PACK_TOTAL_SIZE_BYTES),
133
+ ignorePatterns: envList("STUPIFY_REPOMIX_IGNORE_PATTERNS"),
134
+ };
135
+ }
136
+ function envBoolean(name, fallback) {
137
+ const value = process.env[name];
138
+ if (value === undefined || value === "")
139
+ return fallback;
140
+ return /^(1|true|yes|on)$/i.test(value);
141
+ }
142
+ function envInteger(name, fallback) {
143
+ const value = Number(process.env[name]);
144
+ return Number.isInteger(value) && value > 0 ? value : fallback;
145
+ }
146
+ function envList(name) {
147
+ return (process.env[name] ?? "")
148
+ .split(",")
149
+ .map((item) => item.trim())
150
+ .filter(Boolean);
151
+ }
152
+ function matchesAnyPattern(filePath, patterns) {
153
+ return patterns.some((pattern) => matchesPattern(filePath, pattern));
154
+ }
155
+ function matchesPattern(filePath, pattern) {
156
+ if (pattern === filePath)
157
+ return true;
158
+ if (!pattern.includes("*"))
159
+ return false;
160
+ const escaped = pattern
161
+ .split("*")
162
+ .map(escapeRegExp)
163
+ .join(".*");
164
+ return new RegExp(`^${escaped}$`).test(filePath);
165
+ }
166
+ function escapeRegExp(value) {
167
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
168
+ }
118
169
  function isSafeRelativeFilePath(value) {
119
170
  if (!value || path.isAbsolute(value))
120
171
  return false;
@@ -0,0 +1 @@
1
+ export declare function runSearchBench(configPath: string): Promise<string>;