comp-gate 0.1.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.
Files changed (130) hide show
  1. package/README.md +353 -0
  2. package/dist/agents/agents-md.d.ts +2 -0
  3. package/dist/agents/agents-md.d.ts.map +1 -0
  4. package/dist/agents/agents-md.js +25 -0
  5. package/dist/agents/agents-md.js.map +1 -0
  6. package/dist/agents/claude.d.ts +2 -0
  7. package/dist/agents/claude.d.ts.map +1 -0
  8. package/dist/agents/claude.js +45 -0
  9. package/dist/agents/claude.js.map +1 -0
  10. package/dist/agents/cursor.d.ts +2 -0
  11. package/dist/agents/cursor.d.ts.map +1 -0
  12. package/dist/agents/cursor.js +28 -0
  13. package/dist/agents/cursor.js.map +1 -0
  14. package/dist/agents/detect.d.ts +4 -0
  15. package/dist/agents/detect.d.ts.map +1 -0
  16. package/dist/agents/detect.js +96 -0
  17. package/dist/agents/detect.js.map +1 -0
  18. package/dist/agents/shared.d.ts +9 -0
  19. package/dist/agents/shared.d.ts.map +1 -0
  20. package/dist/agents/shared.js +83 -0
  21. package/dist/agents/shared.js.map +1 -0
  22. package/dist/agents/types.d.ts +14 -0
  23. package/dist/agents/types.d.ts.map +1 -0
  24. package/dist/agents/types.js +8 -0
  25. package/dist/agents/types.js.map +1 -0
  26. package/dist/agents/windsurf.d.ts +2 -0
  27. package/dist/agents/windsurf.d.ts.map +1 -0
  28. package/dist/agents/windsurf.js +27 -0
  29. package/dist/agents/windsurf.js.map +1 -0
  30. package/dist/bootstrap-summary.d.ts +2 -0
  31. package/dist/bootstrap-summary.d.ts.map +1 -0
  32. package/dist/bootstrap-summary.js +262 -0
  33. package/dist/bootstrap-summary.js.map +1 -0
  34. package/dist/categories.d.ts +13 -0
  35. package/dist/categories.d.ts.map +1 -0
  36. package/dist/categories.js +382 -0
  37. package/dist/categories.js.map +1 -0
  38. package/dist/cli.d.ts +3 -0
  39. package/dist/cli.d.ts.map +1 -0
  40. package/dist/cli.js +361 -0
  41. package/dist/cli.js.map +1 -0
  42. package/dist/config-init.d.ts +16 -0
  43. package/dist/config-init.d.ts.map +1 -0
  44. package/dist/config-init.js +53 -0
  45. package/dist/config-init.js.map +1 -0
  46. package/dist/config.d.ts +11 -0
  47. package/dist/config.d.ts.map +1 -0
  48. package/dist/config.js +127 -0
  49. package/dist/config.js.map +1 -0
  50. package/dist/constants.d.ts +2 -0
  51. package/dist/constants.d.ts.map +1 -0
  52. package/dist/constants.js +2 -0
  53. package/dist/constants.js.map +1 -0
  54. package/dist/detect.d.ts +4 -0
  55. package/dist/detect.d.ts.map +1 -0
  56. package/dist/detect.js +244 -0
  57. package/dist/detect.js.map +1 -0
  58. package/dist/diff.d.ts +11 -0
  59. package/dist/diff.d.ts.map +1 -0
  60. package/dist/diff.js +198 -0
  61. package/dist/diff.js.map +1 -0
  62. package/dist/generate.d.ts +7 -0
  63. package/dist/generate.d.ts.map +1 -0
  64. package/dist/generate.js +71 -0
  65. package/dist/generate.js.map +1 -0
  66. package/dist/gitignore.d.ts +12 -0
  67. package/dist/gitignore.d.ts.map +1 -0
  68. package/dist/gitignore.js +106 -0
  69. package/dist/gitignore.js.map +1 -0
  70. package/dist/hooks.d.ts +22 -0
  71. package/dist/hooks.d.ts.map +1 -0
  72. package/dist/hooks.js +199 -0
  73. package/dist/hooks.js.map +1 -0
  74. package/dist/init.d.ts +24 -0
  75. package/dist/init.d.ts.map +1 -0
  76. package/dist/init.js +218 -0
  77. package/dist/init.js.map +1 -0
  78. package/dist/paths.d.ts +13 -0
  79. package/dist/paths.d.ts.map +1 -0
  80. package/dist/paths.js +18 -0
  81. package/dist/paths.js.map +1 -0
  82. package/dist/prompts.d.ts +9 -0
  83. package/dist/prompts.d.ts.map +1 -0
  84. package/dist/prompts.js +88 -0
  85. package/dist/prompts.js.map +1 -0
  86. package/dist/repo-stats.d.ts +10 -0
  87. package/dist/repo-stats.d.ts.map +1 -0
  88. package/dist/repo-stats.js +117 -0
  89. package/dist/repo-stats.js.map +1 -0
  90. package/dist/setup-wizard.d.ts +34 -0
  91. package/dist/setup-wizard.d.ts.map +1 -0
  92. package/dist/setup-wizard.js +251 -0
  93. package/dist/setup-wizard.js.map +1 -0
  94. package/dist/testing.d.ts +6 -0
  95. package/dist/testing.d.ts.map +1 -0
  96. package/dist/testing.js +24 -0
  97. package/dist/testing.js.map +1 -0
  98. package/dist/types.d.ts +156 -0
  99. package/dist/types.d.ts.map +1 -0
  100. package/dist/types.js +31 -0
  101. package/dist/types.js.map +1 -0
  102. package/dist/verify.d.ts +38 -0
  103. package/dist/verify.d.ts.map +1 -0
  104. package/dist/verify.js +254 -0
  105. package/dist/verify.js.map +1 -0
  106. package/package.json +52 -0
  107. package/src/templates/PROMPTS.md +6 -0
  108. package/src/templates/SKILL.md +253 -0
  109. package/src/templates/SUMMARY.md +29 -0
  110. package/src/templates/agents/agents-md/section.md +11 -0
  111. package/src/templates/agents/claude/SKILL.md +8 -0
  112. package/src/templates/agents/claude/settings.fragment.json +16 -0
  113. package/src/templates/agents/claude/testing-SKILL.md +9 -0
  114. package/src/templates/agents/cursor/SKILL.md +9 -0
  115. package/src/templates/agents/cursor/hooks.json +23 -0
  116. package/src/templates/agents/cursor/testing-SKILL.md +9 -0
  117. package/src/templates/agents/windsurf/SKILL.md +8 -0
  118. package/src/templates/agents/windsurf/hooks.json +10 -0
  119. package/src/templates/agents/windsurf/testing-SKILL.md +9 -0
  120. package/src/templates/hooks/after-push.sh +17 -0
  121. package/src/templates/hooks/block-commit.sh +29 -0
  122. package/src/templates/hooks/block-push.sh +29 -0
  123. package/src/templates/hooks/claude-pre-tool.sh +59 -0
  124. package/src/templates/hooks/git-pre-commit.sh +35 -0
  125. package/src/templates/hooks/git-pre-push.sh +53 -0
  126. package/src/templates/hooks/statusline.sh +3 -0
  127. package/src/templates/hooks/windsurf-pre-run.sh +39 -0
  128. package/src/templates/hooks.json +23 -0
  129. package/src/templates/testing-SKILL.md +33 -0
  130. package/src/templates/testme.config.json +32 -0
package/dist/cli.js ADDED
@@ -0,0 +1,361 @@
1
+ #!/usr/bin/env node
2
+ import { existsSync } from "node:fs";
3
+ import path from "node:path";
4
+ import { Command } from "commander";
5
+ import { formatConfigForDisplay, initConfig, showConfig } from "./config-init.js";
6
+ import { detectProject } from "./detect.js";
7
+ import { analyzeDiff } from "./diff.js";
8
+ import { generateSession, parseCategoryList, warnIfBelowMin } from "./generate.js";
9
+ import { resolveConfig } from "./generate.js";
10
+ import { afterPushHook, beforeCommitHook, beforePushHook, beforePushRefHook, resolveProtectedBranches, resolveWorkingBranch } from "./hooks.js";
11
+ import { copyHookScripts, installGitHooks, resetTestmeState } from "./init.js";
12
+ import { promptsHasContent } from "./prompts.js";
13
+ import { isPassValid, loadPassFile, loadSession, verifySession } from "./verify.js";
14
+ import { formatGateBanner, formatStatusline, isGateEnabled, setGateEnabled, toggleGateEnabled, } from "./testing.js";
15
+ const program = new Command();
16
+ program
17
+ .name("comp-gate")
18
+ .description("Comprehension gate for desktop coding agents (testme workflow)")
19
+ .option("-b, --branch <name>", "override working branch for diff and pass validation");
20
+ program
21
+ .command("init")
22
+ .description("Install testme templates, hooks, and skill into the current repo")
23
+ .option("--agent <agents>", "comma-separated agents: cursor,claude,windsurf,agents-md,all")
24
+ .option("--questions <n>", "number of questions per session (1-5)")
25
+ .option("--difficulty <level>", "easy, medium, or hard")
26
+ .option("--local-only <bool>", "gitignore agent skills (true/false); default true")
27
+ .option("--summary <mode>", "SUMMARY.md setup: blank (default) or generate")
28
+ .option("--yes", "skip interactive prompts")
29
+ .option("--force", "re-run wizard and overwrite config preferences")
30
+ .action(async (options) => {
31
+ const { initProject } = await import("./init.js");
32
+ const { parseAgentList } = await import("./agents/detect.js");
33
+ const { parseDifficultyOption, parseLocalOnlyOption, parseQuestionsOption, parseSummaryModeOption } = await import("./setup-wizard.js");
34
+ const initOptions = {
35
+ yes: Boolean(options.yes),
36
+ force: Boolean(options.force),
37
+ };
38
+ if (options.agent) {
39
+ initOptions.agents = parseAgentList(options.agent);
40
+ }
41
+ if (options.questions ||
42
+ options.difficulty ||
43
+ options.localOnly !== undefined ||
44
+ options.summary) {
45
+ if (options.force || !existsSync(path.join(process.cwd(), "testme.config.json"))) {
46
+ initOptions.wizard = {
47
+ questions: options.questions
48
+ ? parseQuestionsOption(options.questions)
49
+ : { min: 2, max: 3 },
50
+ difficulty: options.difficulty ? parseDifficultyOption(options.difficulty) : "medium",
51
+ localOnly: options.localOnly !== undefined ? parseLocalOnlyOption(options.localOnly) : true,
52
+ summaryMode: options.summary ? parseSummaryModeOption(options.summary) : "blank",
53
+ };
54
+ }
55
+ initOptions.skipWizard = true;
56
+ }
57
+ if (options.summary) {
58
+ initOptions.summaryMode = parseSummaryModeOption(options.summary);
59
+ }
60
+ const created = await initProject(process.cwd(), initOptions);
61
+ console.log("comp-gate initialized.");
62
+ for (const item of created) {
63
+ console.log(` + ${item}`);
64
+ }
65
+ });
66
+ program
67
+ .command("generate")
68
+ .description("Generate comprehension questions from SUMMARY.md, PROMPTS.md, and git diff")
69
+ .option("--max-questions <n>", "override max question count", (v) => Number.parseInt(v, 10))
70
+ .option("--min-questions <n>", "override min question count", (v) => Number.parseInt(v, 10))
71
+ .option("--category <list>", "comma-separated category keys to enable for this run")
72
+ .action((options, cmd) => {
73
+ const branch = resolveWorkingBranch(process.cwd(), cmd.parent?.opts().branch);
74
+ const cwd = process.cwd();
75
+ if (!promptsHasContent()) {
76
+ console.warn("Warning: PROMPTS.md has no change bullets yet. Add session notes for better rubrics.");
77
+ }
78
+ const generateOptions = {
79
+ maxQuestions: options.maxQuestions,
80
+ minQuestions: options.minQuestions,
81
+ categories: options.category ? parseCategoryList(options.category) : undefined,
82
+ };
83
+ const config = resolveConfig(cwd, generateOptions);
84
+ const session = generateSession(cwd, branch, generateOptions);
85
+ const warning = warnIfBelowMin(session, config);
86
+ console.log(`Generated ${session.questions.length} question(s).`);
87
+ if (warning) {
88
+ console.warn(warning);
89
+ }
90
+ console.log(`Session written to .testme/session.json`);
91
+ console.log(`Diff base: ${session.baseRef}`);
92
+ for (const question of session.questions) {
93
+ console.log(` - ${question.id} [${question.category}]: ${question.prompt}`);
94
+ }
95
+ });
96
+ program
97
+ .command("detect")
98
+ .description("Show project-aware category suggestions")
99
+ .action((_, cmd) => {
100
+ const cwd = process.cwd();
101
+ const analysis = analyzeDiff(cwd, resolveWorkingBranch(cwd, cmd.parent?.opts().branch));
102
+ const detection = detectProject(cwd, analysis);
103
+ console.log(`Domain: ${detection.domain ?? "(not set)"}`);
104
+ const entries = Object.entries(detection.suggestedCategories);
105
+ if (entries.length === 0) {
106
+ console.log("No domain categories detected.");
107
+ return;
108
+ }
109
+ for (const [key, suggestion] of entries) {
110
+ console.log(` ${key}: ${suggestion.enabled ? "on" : "off"} (${Math.round(suggestion.confidence * 100)}%) — ${suggestion.reason}`);
111
+ }
112
+ });
113
+ const configCmd = program.command("config").description("Manage testme configuration");
114
+ configCmd
115
+ .command("init")
116
+ .description("Create testme.config.json with auto-detected category defaults")
117
+ .option("--force", "overwrite existing testme.config.json")
118
+ .action((options) => {
119
+ const result = initConfig(process.cwd(), Boolean(options.force));
120
+ if (result.created) {
121
+ console.log(`Created ${result.path}`);
122
+ }
123
+ else {
124
+ console.log(`${result.path} already exists (use --force to overwrite)`);
125
+ }
126
+ });
127
+ configCmd
128
+ .command("show")
129
+ .description("Print merged config (defaults + repo + local overrides)")
130
+ .action(() => {
131
+ console.log(formatConfigForDisplay(showConfig(process.cwd())));
132
+ });
133
+ program
134
+ .command("verify")
135
+ .description("Verify answers in .testme/answers.json against the current session")
136
+ .action((_, cmd) => {
137
+ const branch = resolveWorkingBranch(process.cwd(), cmd.parent?.opts().branch);
138
+ const result = verifySession(process.cwd(), branch);
139
+ if (result.questionScores && result.questionScores.length > 0) {
140
+ console.log("Scores:");
141
+ for (const item of result.questionScores) {
142
+ const status = item.passed ? "pass" : "fail";
143
+ console.log(` ${item.id}: ${item.accuracy}% accuracy · ${item.alignment} alignment · ${status}`);
144
+ console.log(` summary: ${item.userSummary}`);
145
+ }
146
+ if (result.passThreshold !== undefined) {
147
+ console.log(`Pass threshold: ${result.passThreshold}% accuracy`);
148
+ }
149
+ }
150
+ if (result.passed) {
151
+ console.log(`PASS (${result.score}% overall accuracy) — push to ${branch} is allowed.`);
152
+ process.exit(0);
153
+ }
154
+ console.error(`FAIL (${result.score}% overall accuracy) — fix answers and re-run verify.`);
155
+ for (const failure of result.failures) {
156
+ console.error(` ${failure.id}: ${failure.prompt}`);
157
+ if (failure.accuracy !== undefined) {
158
+ console.error(` accuracy: ${failure.accuracy}%`);
159
+ }
160
+ if (failure.feedback) {
161
+ console.error(` feedback: ${failure.feedback}`);
162
+ }
163
+ if (failure.alignment) {
164
+ console.error(` alignment: ${failure.alignment}`);
165
+ }
166
+ if (failure.userSummary) {
167
+ console.error(` summary: ${failure.userSummary}`);
168
+ }
169
+ if (failure.missingTerms && failure.missingTerms.length > 0) {
170
+ console.error(` missing terms: ${failure.missingTerms.join(", ")}`);
171
+ }
172
+ if (failure.tooShort) {
173
+ console.error(" answer too short");
174
+ }
175
+ if (failure.missingSymbol) {
176
+ console.error(` missing symbol: ${failure.missingSymbol}`);
177
+ }
178
+ }
179
+ process.exit(1);
180
+ });
181
+ program
182
+ .command("status")
183
+ .description("Show whether the current pass is valid for the diff")
184
+ .action((_, cmd) => {
185
+ const cwd = process.cwd();
186
+ const cliBranch = cmd.parent?.opts().branch;
187
+ const branch = resolveWorkingBranch(cwd, cliBranch);
188
+ const pass = loadPassFile();
189
+ const valid = isPassValid(cwd, branch);
190
+ console.log(`Working branch: ${branch}`);
191
+ console.log(`Protected branches: ${resolveProtectedBranches(cwd, cliBranch).join(", ")}`);
192
+ console.log(`Pass valid: ${valid ? "yes" : "no"}`);
193
+ console.log(`Gate enabled: ${isGateEnabled(cwd) ? "yes" : "no"}`);
194
+ if (pass) {
195
+ console.log(`Last verified: ${pass.verifiedAt}`);
196
+ console.log(`Questions answered: ${pass.questionsAnswered}`);
197
+ }
198
+ else {
199
+ console.log("No pass file found.");
200
+ }
201
+ try {
202
+ const session = loadSession();
203
+ console.log(`Pending session questions: ${session.questions.length}`);
204
+ }
205
+ catch {
206
+ console.log("No active session.");
207
+ }
208
+ if (!promptsHasContent()) {
209
+ console.log("PROMPTS.md is empty — document changes before generate.");
210
+ }
211
+ });
212
+ const testingCmd = program
213
+ .command("testing")
214
+ .description("Toggle the testme comprehension gate on or off (local per developer)");
215
+ testingCmd
216
+ .command("status")
217
+ .description("Show whether the gate is enabled")
218
+ .action(() => {
219
+ const cwd = process.cwd();
220
+ const enabled = isGateEnabled(cwd);
221
+ console.log(formatGateBanner(enabled));
222
+ console.log(`gateEnabled: ${enabled}`);
223
+ });
224
+ testingCmd
225
+ .command("on")
226
+ .description("Enable the comprehension gate")
227
+ .action(() => {
228
+ const cwd = process.cwd();
229
+ setGateEnabled(cwd, true);
230
+ console.log(formatGateBanner(true));
231
+ console.log("gateEnabled: true");
232
+ });
233
+ testingCmd
234
+ .command("off")
235
+ .description("Disable the comprehension gate")
236
+ .action(() => {
237
+ const cwd = process.cwd();
238
+ setGateEnabled(cwd, false);
239
+ console.log(formatGateBanner(false));
240
+ console.log("gateEnabled: false");
241
+ console.warn("Warning: commit and push will no longer require /testme until re-enabled.");
242
+ });
243
+ testingCmd
244
+ .command("toggle")
245
+ .description("Flip the gate on or off")
246
+ .action(() => {
247
+ const cwd = process.cwd();
248
+ const enabled = toggleGateEnabled(cwd);
249
+ console.log(formatGateBanner(enabled));
250
+ console.log(`gateEnabled: ${enabled}`);
251
+ if (!enabled) {
252
+ console.warn("Warning: commit and push will no longer require /testme until re-enabled.");
253
+ }
254
+ });
255
+ testingCmd.action(() => {
256
+ const cwd = process.cwd();
257
+ const enabled = toggleGateEnabled(cwd);
258
+ console.log(formatGateBanner(enabled));
259
+ console.log(`gateEnabled: ${enabled}`);
260
+ if (!enabled) {
261
+ console.warn("Warning: commit and push will no longer require /testme until re-enabled.");
262
+ }
263
+ });
264
+ program
265
+ .command("statusline")
266
+ .description("One-line gate status for Cursor status line integration")
267
+ .action(() => {
268
+ console.log(formatStatusline(isGateEnabled(process.cwd())));
269
+ });
270
+ program
271
+ .command("reset")
272
+ .description("Clear .testme session state without touching PROMPTS.md")
273
+ .action(() => {
274
+ resetTestmeState(process.cwd(), false);
275
+ console.log("Cleared .testme/ session state.");
276
+ });
277
+ const hook = program.command("hook").description("Cursor hook helpers");
278
+ hook
279
+ .command("before-commit")
280
+ .description("Check whether a git commit should be allowed")
281
+ .requiredOption("-c, --command <cmd>", "shell command to evaluate")
282
+ .option("--json", "output hook JSON response")
283
+ .action((options, cmd) => {
284
+ const branch = cmd.parent?.parent?.opts().branch;
285
+ const result = beforeCommitHook(process.cwd(), options.command, branch);
286
+ if (options.json) {
287
+ console.log(JSON.stringify(result));
288
+ process.exit(result.permission === "allow" ? 0 : 2);
289
+ }
290
+ if (result.permission === "allow") {
291
+ process.exit(0);
292
+ }
293
+ console.error(result.agent_message ?? "Commit blocked by testme.");
294
+ process.exit(2);
295
+ });
296
+ hook
297
+ .command("before-push")
298
+ .description("Check whether a git push to a protected branch should be allowed")
299
+ .requiredOption("-c, --command <cmd>", "shell command to evaluate")
300
+ .option("--json", "output hook JSON response")
301
+ .action((options, cmd) => {
302
+ const branch = cmd.parent?.parent?.opts().branch ?? undefined;
303
+ const result = beforePushHook(process.cwd(), options.command, branch);
304
+ if (options.json) {
305
+ console.log(JSON.stringify(result));
306
+ process.exit(result.permission === "allow" ? 0 : 2);
307
+ }
308
+ if (result.permission === "allow") {
309
+ process.exit(0);
310
+ }
311
+ console.error(result.agent_message ?? "Push blocked by testme.");
312
+ process.exit(2);
313
+ });
314
+ hook
315
+ .command("before-push-ref")
316
+ .description("Check whether a git pre-push ref should be allowed")
317
+ .requiredOption("-r, --remote-ref <ref>", "remote ref being pushed (e.g. refs/heads/main)")
318
+ .option("--json", "output hook JSON response")
319
+ .action((options, cmd) => {
320
+ const branch = cmd.parent?.parent?.opts().branch ?? undefined;
321
+ const result = beforePushRefHook(process.cwd(), options.remoteRef, branch);
322
+ if (options.json) {
323
+ console.log(JSON.stringify(result));
324
+ process.exit(result.permission === "allow" ? 0 : 2);
325
+ }
326
+ if (result.permission === "allow") {
327
+ process.exit(0);
328
+ }
329
+ console.error(result.agent_message ?? "Push blocked by testme.");
330
+ process.exit(2);
331
+ });
332
+ hook
333
+ .command("install-git")
334
+ .description("Install git pre-commit and pre-push hooks into .git/hooks")
335
+ .action(() => {
336
+ copyHookScripts(process.cwd());
337
+ const installed = installGitHooks(process.cwd());
338
+ if (installed.length === 0) {
339
+ console.log("No git hooks installed (not a git repo or hooks already managed elsewhere).");
340
+ return;
341
+ }
342
+ for (const item of installed) {
343
+ console.log(` + ${item}`);
344
+ }
345
+ });
346
+ hook
347
+ .command("after-push")
348
+ .description("Reset PROMPTS.md and session state after successful push to a protected branch")
349
+ .option("-c, --command <cmd>", "shell command that was executed")
350
+ .action((options, cmd) => {
351
+ const branch = cmd.parent?.parent?.opts().branch ?? undefined;
352
+ if (options.command) {
353
+ afterPushHook(process.cwd(), options.command, branch);
354
+ }
355
+ else {
356
+ afterPushHook(process.cwd(), "git push origin main", branch);
357
+ }
358
+ process.exit(0);
359
+ });
360
+ program.parse();
361
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { TestmeConfig } from "./types.js";
2
+ export declare function createInitialConfig(cwd: string): TestmeConfig;
3
+ export declare function initConfig(cwd: string, force?: boolean): {
4
+ created: boolean;
5
+ path: string;
6
+ config: TestmeConfig;
7
+ };
8
+ export declare function initConfigWithWizard(cwd: string, config: TestmeConfig, applyWizard?: boolean): {
9
+ created: boolean;
10
+ updated: boolean;
11
+ path: string;
12
+ config: TestmeConfig;
13
+ };
14
+ export declare function showConfig(cwd: string): TestmeConfig;
15
+ export declare function formatConfigForDisplay(config: TestmeConfig): string;
16
+ //# sourceMappingURL=config-init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-init.d.ts","sourceRoot":"","sources":["../src/config-init.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,CAO7D;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,UAAQ,GAAG;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,YAAY,CAAA;CAAE,CAW/G;AAED,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,YAAY,EACpB,WAAW,UAAO,GACjB;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,YAAY,CAAA;CAAE,CA0B5E;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,CAEpD;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAEnE"}
@@ -0,0 +1,53 @@
1
+ import { existsSync } from "node:fs";
2
+ import path from "node:path";
3
+ import { DEFAULT_CONFIG, loadConfig, mergeConfig, normalizeConfig, stripDetected, writeConfigFile } from "./config.js";
4
+ import { analyzeDiff } from "./diff.js";
5
+ import { applyDetectionToConfig, detectProject } from "./detect.js";
6
+ export function createInitialConfig(cwd) {
7
+ const analysis = analyzeDiff(cwd);
8
+ let config = mergeConfig(DEFAULT_CONFIG, null);
9
+ const detection = detectProject(cwd, analysis);
10
+ config = applyDetectionToConfig(config, detection);
11
+ config.gateCommits = true;
12
+ return normalizeConfig(config);
13
+ }
14
+ export function initConfig(cwd, force = false) {
15
+ const configPath = path.join(cwd, "testme.config.json");
16
+ if (existsSync(configPath) && !force) {
17
+ return { created: false, path: configPath, config: loadConfig(cwd) };
18
+ }
19
+ const config = createInitialConfig(cwd);
20
+ writeConfigFile(configPath, config);
21
+ return { created: true, path: configPath, config };
22
+ }
23
+ export function initConfigWithWizard(cwd, config, applyWizard = true) {
24
+ const configPath = path.join(cwd, "testme.config.json");
25
+ const exists = existsSync(configPath);
26
+ if (exists && !applyWizard) {
27
+ return { created: false, updated: false, path: configPath, config: loadConfig(cwd) };
28
+ }
29
+ if (exists) {
30
+ const existing = loadConfig(cwd);
31
+ const merged = normalizeConfig({
32
+ ...existing,
33
+ questions: config.questions,
34
+ passThreshold: config.passThreshold,
35
+ minAlignment: config.minAlignment,
36
+ difficulty: config.difficulty,
37
+ categories: config.categories,
38
+ autoDetect: config.autoDetect,
39
+ gateCommits: config.gateCommits,
40
+ });
41
+ writeConfigFile(configPath, merged);
42
+ return { created: false, updated: true, path: configPath, config: merged };
43
+ }
44
+ writeConfigFile(configPath, config);
45
+ return { created: true, updated: false, path: configPath, config };
46
+ }
47
+ export function showConfig(cwd) {
48
+ return loadConfig(cwd);
49
+ }
50
+ export function formatConfigForDisplay(config) {
51
+ return JSON.stringify(stripDetected(config), null, 2);
52
+ }
53
+ //# sourceMappingURL=config-init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-init.js","sourceRoot":"","sources":["../src/config-init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { CategoryKey, GenerateOptions, TestmeConfig, TestmeConfigInput } from "./types.js";
2
+ export declare const DEFAULT_CONFIG: TestmeConfig;
3
+ export declare function mergeConfig(base: TestmeConfig, patch?: TestmeConfigInput | null): TestmeConfig;
4
+ export declare function normalizeConfig(config: TestmeConfig): TestmeConfig;
5
+ export declare function loadConfig(cwd?: string): TestmeConfig;
6
+ export declare function stripDetected(config: TestmeConfig): TestmeConfig;
7
+ export declare function applyGenerateOptions(config: TestmeConfig, options?: GenerateOptions): TestmeConfig;
8
+ export declare function enabledCategories(config: TestmeConfig): CategoryKey[];
9
+ export declare function writeConfigFile(filePath: string, config: TestmeConfig): void;
10
+ export declare function patchLocalConfig(cwd: string, patch: TestmeConfigInput): void;
11
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,WAAW,EACX,eAAe,EACf,YAAY,EACZ,iBAAiB,EAClB,MAAM,YAAY,CAAC;AAGpB,eAAO,MAAM,cAAc,EAAE,YAgC5B,CAAC;AAyBF,wBAAgB,WAAW,CACzB,IAAI,EAAE,YAAY,EAClB,KAAK,CAAC,EAAE,iBAAiB,GAAG,IAAI,GAC/B,YAAY,CAwBd;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,YAAY,GAAG,YAAY,CAUlE;AAED,wBAAgB,UAAU,CAAC,GAAG,GAAE,MAAsB,GAAG,YAAY,CAQpE;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,YAAY,GAAG,YAAY,CAGhE;AAED,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,YAAY,EACpB,OAAO,GAAE,eAAoB,GAC5B,YAAY,CAkBd;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,YAAY,GAAG,WAAW,EAAE,CAErE;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CAG5E;AAED,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,iBAAiB,GACvB,IAAI,CAMN"}
package/dist/config.js ADDED
@@ -0,0 +1,127 @@
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
+ import path from "node:path";
3
+ import { ALL_CATEGORY_KEYS } from "./types.js";
4
+ export const DEFAULT_CONFIG = {
5
+ questions: { min: 2, max: 5 },
6
+ categories: {
7
+ changeRationale: true,
8
+ symbols: true,
9
+ architecture: true,
10
+ runtime: false,
11
+ dataStructures: false,
12
+ dependencies: false,
13
+ testing: false,
14
+ errorHandling: false,
15
+ apiContracts: false,
16
+ security: false,
17
+ performance: false,
18
+ database: false,
19
+ machineLearning: false,
20
+ cybersecurity: false,
21
+ frontend: false,
22
+ backend: false,
23
+ devops: false,
24
+ mobile: false,
25
+ dataEngineering: false,
26
+ },
27
+ autoDetect: true,
28
+ domain: null,
29
+ grading: "semantic",
30
+ passThreshold: 70,
31
+ minAlignment: "medium",
32
+ protectedBranches: ["main"],
33
+ gateCommits: false,
34
+ gateEnabled: true,
35
+ autoProtectCurrentBranch: true,
36
+ };
37
+ function readJsonFile(filePath) {
38
+ if (!existsSync(filePath)) {
39
+ return null;
40
+ }
41
+ try {
42
+ return JSON.parse(readFileSync(filePath, "utf8"));
43
+ }
44
+ catch {
45
+ return null;
46
+ }
47
+ }
48
+ function mergeCategories(base, patch) {
49
+ if (!patch) {
50
+ return { ...base };
51
+ }
52
+ return { ...base, ...patch };
53
+ }
54
+ export function mergeConfig(base, patch) {
55
+ if (!patch) {
56
+ return { ...base, categories: { ...base.categories } };
57
+ }
58
+ return {
59
+ questions: {
60
+ min: patch.questions?.min ?? base.questions.min,
61
+ max: patch.questions?.max ?? base.questions.max,
62
+ },
63
+ categories: mergeCategories(base.categories, patch.categories),
64
+ autoDetect: patch.autoDetect ?? base.autoDetect,
65
+ domain: patch.domain !== undefined ? patch.domain : base.domain,
66
+ grading: patch.grading ?? base.grading,
67
+ passThreshold: patch.passThreshold ?? base.passThreshold,
68
+ minAlignment: patch.minAlignment ?? base.minAlignment,
69
+ difficulty: patch.difficulty ?? base.difficulty,
70
+ protectedBranches: patch.protectedBranches ?? base.protectedBranches,
71
+ gateCommits: patch.gateCommits ?? base.gateCommits,
72
+ gateEnabled: patch.gateEnabled ?? base.gateEnabled,
73
+ autoProtectCurrentBranch: patch.autoProtectCurrentBranch ?? base.autoProtectCurrentBranch,
74
+ _detected: patch._detected ?? base._detected,
75
+ };
76
+ }
77
+ export function normalizeConfig(config) {
78
+ const min = Math.max(1, config.questions.min);
79
+ const max = Math.max(min, config.questions.max);
80
+ return {
81
+ ...config,
82
+ questions: { min, max },
83
+ passThreshold: Math.min(100, Math.max(0, config.passThreshold ?? 70)),
84
+ categories: mergeCategories(DEFAULT_CONFIG.categories, config.categories),
85
+ };
86
+ }
87
+ export function loadConfig(cwd = process.cwd()) {
88
+ const repoPath = path.join(cwd, "testme.config.json");
89
+ const localPath = path.join(cwd, ".testme", "config.json");
90
+ let config = mergeConfig(DEFAULT_CONFIG, readJsonFile(repoPath));
91
+ config = mergeConfig(config, readJsonFile(localPath));
92
+ return normalizeConfig(config);
93
+ }
94
+ export function stripDetected(config) {
95
+ const { _detected, ...rest } = config;
96
+ return rest;
97
+ }
98
+ export function applyGenerateOptions(config, options = {}) {
99
+ const next = { ...config, categories: { ...config.categories } };
100
+ if (options.maxQuestions !== undefined) {
101
+ next.questions = { ...next.questions, max: options.maxQuestions };
102
+ }
103
+ if (options.minQuestions !== undefined) {
104
+ next.questions = { ...next.questions, min: options.minQuestions };
105
+ }
106
+ if (options.categories && options.categories.length > 0) {
107
+ for (const key of ALL_CATEGORY_KEYS) {
108
+ next.categories[key] = options.categories.includes(key);
109
+ }
110
+ }
111
+ return normalizeConfig(next);
112
+ }
113
+ export function enabledCategories(config) {
114
+ return ALL_CATEGORY_KEYS.filter((key) => config.categories[key]);
115
+ }
116
+ export function writeConfigFile(filePath, config) {
117
+ mkdirSync(path.dirname(filePath), { recursive: true });
118
+ writeFileSync(filePath, `${JSON.stringify(stripDetected(config), null, 2)}\n`, "utf8");
119
+ }
120
+ export function patchLocalConfig(cwd, patch) {
121
+ const localPath = path.join(cwd, ".testme", "config.json");
122
+ const existing = readJsonFile(localPath) ?? {};
123
+ const merged = { ...existing, ...patch };
124
+ mkdirSync(path.dirname(localPath), { recursive: true });
125
+ writeFileSync(localPath, `${JSON.stringify(merged, null, 2)}\n`, "utf8");
126
+ }
127
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare const ADOPTING_EXISTING_REPOS_URL = "https://github.com/ROrmand/comp-gate/blob/main/docs/adopting-existing-repos.md";
2
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,2BAA2B,mFAC0C,CAAC"}
@@ -0,0 +1,2 @@
1
+ export const ADOPTING_EXISTING_REPOS_URL = "https://github.com/ROrmand/comp-gate/blob/main/docs/adopting-existing-repos.md";
2
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,2BAA2B,GACtC,gFAAgF,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { DetectionResult, DiffAnalysis } from "./types.js";
2
+ export declare function detectProject(cwd: string, analysis?: DiffAnalysis): DetectionResult;
3
+ export declare function applyDetectionToConfig(config: import("./types.js").TestmeConfig, detection: DetectionResult): import("./types.js").TestmeConfig;
4
+ //# sourceMappingURL=detect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detect.d.ts","sourceRoot":"","sources":["../src/detect.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAe,eAAe,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AA4J7E,wBAAgB,aAAa,CAC3B,GAAG,EAAE,MAAM,EACX,QAAQ,CAAC,EAAE,YAAY,GACtB,eAAe,CAmFjB;AAED,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,OAAO,YAAY,EAAE,YAAY,EACzC,SAAS,EAAE,eAAe,GACzB,OAAO,YAAY,EAAE,YAAY,CAgCnC"}