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
@@ -0,0 +1,156 @@
1
+ export type QuestionType = "change_rationale" | "symbol" | "architecture" | "category";
2
+ export type CategoryKey = "changeRationale" | "symbols" | "architecture" | "runtime" | "dataStructures" | "dependencies" | "testing" | "errorHandling" | "apiContracts" | "security" | "performance" | "database" | "machineLearning" | "cybersecurity" | "frontend" | "backend" | "devops" | "mobile" | "dataEngineering";
3
+ export declare const ALL_CATEGORY_KEYS: CategoryKey[];
4
+ export declare const DOMAIN_CATEGORY_KEYS: CategoryKey[];
5
+ export type GradingMode = "semantic" | "keywords";
6
+ export type Difficulty = "easy" | "medium" | "hard";
7
+ export type AlignmentLevel = "low" | "medium" | "high";
8
+ export interface Rubric {
9
+ requiredTerms: string[];
10
+ minLength: number;
11
+ requiredSymbol?: string;
12
+ }
13
+ export interface Question {
14
+ id: string;
15
+ type: QuestionType;
16
+ category: CategoryKey;
17
+ prompt: string;
18
+ files: string[];
19
+ rubric: Rubric;
20
+ }
21
+ export interface Session {
22
+ diffHash: string;
23
+ baseRef: string;
24
+ generatedAt: string;
25
+ questions: Question[];
26
+ }
27
+ export interface PassFile {
28
+ diffHash: string;
29
+ score: number;
30
+ verifiedAt: string;
31
+ questionsAnswered: number;
32
+ headSha?: string;
33
+ hadUncommitted?: boolean;
34
+ }
35
+ export interface FileChange {
36
+ path: string;
37
+ symbols: string[];
38
+ }
39
+ export interface DiffAnalysis {
40
+ diffHash: string;
41
+ baseRef: string;
42
+ rawDiff: string;
43
+ files: FileChange[];
44
+ }
45
+ export interface VerifyResult {
46
+ passed: boolean;
47
+ score: number;
48
+ total: number;
49
+ grading: GradingMode;
50
+ passThreshold?: number;
51
+ questionScores?: Array<{
52
+ id: string;
53
+ prompt: string;
54
+ accuracy: number;
55
+ alignment: "low" | "medium" | "high";
56
+ passed: boolean;
57
+ userSummary: string;
58
+ feedback: string;
59
+ }>;
60
+ failures: Array<{
61
+ id: string;
62
+ prompt: string;
63
+ missingTerms?: string[];
64
+ tooShort?: boolean;
65
+ missingSymbol?: string;
66
+ feedback?: string;
67
+ alignment?: string;
68
+ userSummary?: string;
69
+ accuracy?: number;
70
+ }>;
71
+ }
72
+ export interface QuestionJudgment {
73
+ passed: boolean;
74
+ accuracy: number;
75
+ userSummary: string;
76
+ alignment: "low" | "medium" | "high";
77
+ feedback: string;
78
+ }
79
+ export interface JudgmentsFile {
80
+ diffHash: string;
81
+ gradedAt: string;
82
+ judgments: Record<string, QuestionJudgment>;
83
+ }
84
+ export interface ReferencesFile {
85
+ diffHash: string;
86
+ generatedAt: string;
87
+ references: Record<string, string>;
88
+ }
89
+ export interface PromptsSection {
90
+ file: string;
91
+ bullets: string[];
92
+ }
93
+ export type CategoryFlags = Partial<Record<CategoryKey, boolean>>;
94
+ export interface QuestionsConfig {
95
+ min: number;
96
+ max: number;
97
+ }
98
+ export interface TestmeConfig {
99
+ questions: QuestionsConfig;
100
+ categories: Record<CategoryKey, boolean>;
101
+ autoDetect: boolean;
102
+ domain: string | null;
103
+ grading: GradingMode;
104
+ passThreshold: number;
105
+ minAlignment?: AlignmentLevel;
106
+ difficulty?: Difficulty;
107
+ protectedBranches: string[];
108
+ gateCommits: boolean;
109
+ gateEnabled: boolean;
110
+ autoProtectCurrentBranch: boolean;
111
+ _detected?: Record<string, {
112
+ confidence: number;
113
+ reason: string;
114
+ }>;
115
+ }
116
+ export interface TestmeConfigInput {
117
+ questions?: Partial<QuestionsConfig>;
118
+ categories?: CategoryFlags;
119
+ autoDetect?: boolean;
120
+ domain?: string | null;
121
+ grading?: GradingMode;
122
+ passThreshold?: number;
123
+ minAlignment?: AlignmentLevel;
124
+ difficulty?: Difficulty;
125
+ protectedBranches?: string[];
126
+ gateCommits?: boolean;
127
+ gateEnabled?: boolean;
128
+ autoProtectCurrentBranch?: boolean;
129
+ _detected?: Record<string, {
130
+ confidence: number;
131
+ reason: string;
132
+ }>;
133
+ }
134
+ export interface GenerateOptions {
135
+ maxQuestions?: number;
136
+ minQuestions?: number;
137
+ categories?: CategoryKey[];
138
+ }
139
+ export interface CategorySuggestion {
140
+ enabled: boolean;
141
+ confidence: number;
142
+ reason: string;
143
+ }
144
+ export interface DetectionResult {
145
+ suggestedCategories: Partial<Record<CategoryKey, CategorySuggestion>>;
146
+ domain: string | null;
147
+ }
148
+ export interface QuestionCandidate {
149
+ category: CategoryKey;
150
+ type: QuestionType;
151
+ prompt: string;
152
+ files: string[];
153
+ rubric: Rubric;
154
+ priority: number;
155
+ }
156
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,31 @@
1
+ export const ALL_CATEGORY_KEYS = [
2
+ "changeRationale",
3
+ "symbols",
4
+ "architecture",
5
+ "runtime",
6
+ "dataStructures",
7
+ "dependencies",
8
+ "testing",
9
+ "errorHandling",
10
+ "apiContracts",
11
+ "security",
12
+ "performance",
13
+ "database",
14
+ "machineLearning",
15
+ "cybersecurity",
16
+ "frontend",
17
+ "backend",
18
+ "devops",
19
+ "mobile",
20
+ "dataEngineering",
21
+ ];
22
+ export const DOMAIN_CATEGORY_KEYS = [
23
+ "machineLearning",
24
+ "cybersecurity",
25
+ "frontend",
26
+ "backend",
27
+ "devops",
28
+ "mobile",
29
+ "dataEngineering",
30
+ ];
31
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAuBA,MAAM,CAAC,MAAM,iBAAiB,GAAkB;IAC9C,iBAAiB;IACjB,SAAS;IACT,cAAc;IACd,SAAS;IACT,gBAAgB;IAChB,cAAc;IACd,SAAS;IACT,eAAe;IACf,cAAc;IACd,UAAU;IACV,aAAa;IACb,UAAU;IACV,iBAAiB;IACjB,eAAe;IACf,UAAU;IACV,SAAS;IACT,QAAQ;IACR,QAAQ;IACR,iBAAiB;CAClB,CAAC;AAEF,MAAM,CAAC,MAAM,oBAAoB,GAAkB;IACjD,iBAAiB;IACjB,eAAe;IACf,UAAU;IACV,SAAS;IACT,QAAQ;IACR,QAAQ;IACR,iBAAiB;CAClB,CAAC"}
@@ -0,0 +1,38 @@
1
+ import type { JudgmentsFile, PassFile, Question, ReferencesFile, Session, VerifyResult, AlignmentLevel } from "./types.js";
2
+ export declare function scoreAnswer(answer: string, question: Question): {
3
+ passed: boolean;
4
+ missingTerms: string[];
5
+ tooShort: boolean;
6
+ missingSymbol?: string;
7
+ };
8
+ export declare function verifyAnswersKeywords(session: Session, answers: Record<string, string>): VerifyResult;
9
+ export declare function normalizeJudgment(judgment: {
10
+ passed: boolean;
11
+ accuracy?: number;
12
+ alignment: "low" | "medium" | "high";
13
+ }): number;
14
+ export declare function isQuestionPassing(judgment: {
15
+ passed: boolean;
16
+ accuracy?: number;
17
+ alignment: "low" | "medium" | "high";
18
+ }, passThreshold: number, minAlignment?: AlignmentLevel): boolean;
19
+ export declare function verifyAnswersSemantic(session: Session, judgments: JudgmentsFile, passThreshold?: number, minAlignment?: AlignmentLevel): VerifyResult;
20
+ export declare function loadSession(): Session;
21
+ export declare function loadAnswers(): Record<string, string>;
22
+ export declare function loadReferences(): ReferencesFile | null;
23
+ export declare function loadJudgments(): JudgmentsFile;
24
+ export declare function writeJudgments(judgments: JudgmentsFile): void;
25
+ export declare function writeReferences(references: ReferencesFile): void;
26
+ export declare function verifySession(cwd: string, branch?: string): VerifyResult;
27
+ export declare function loadPassFile(): PassFile | null;
28
+ export declare function passStillValid(options: {
29
+ pass: PassFile;
30
+ currentDiffHash: string;
31
+ headSha: string;
32
+ hasUncommitted: boolean;
33
+ verifiedHeadIsAncestor: boolean;
34
+ }): boolean;
35
+ export declare function evaluatePassValidity(pass: PassFile, cwd: string, branch?: string): boolean;
36
+ export declare function isPassValid(cwd: string, branch?: string): boolean;
37
+ export declare function verifyAnswers(session: Session, answers: Record<string, string>): VerifyResult;
38
+ //# sourceMappingURL=verify.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAEV,aAAa,EACb,QAAQ,EACR,QAAQ,EACR,cAAc,EACd,OAAO,EACP,YAAY,EACZ,cAAc,EACf,MAAM,YAAY,CAAC;AAepB,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG;IAC/D,MAAM,EAAE,OAAO,CAAC;IAChB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,QAAQ,EAAE,OAAO,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAeA;AAED,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC9B,YAAY,CAgCd;AAeD,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE;IAC1C,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;CACtC,GAAG,MAAM,CAMT;AAeD,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE;IACR,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;CACtC,EACD,aAAa,EAAE,MAAM,EACrB,YAAY,GAAE,cAAyB,GACtC,OAAO,CAOT;AAED,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,aAAa,EACxB,aAAa,SAAK,EAClB,YAAY,GAAE,cAAyB,GACtC,YAAY,CA0Dd;AAED,wBAAgB,WAAW,IAAI,OAAO,CAMrC;AAED,wBAAgB,WAAW,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAMpD;AAED,wBAAgB,cAAc,IAAI,cAAc,GAAG,IAAI,CAMtD;AAED,wBAAgB,aAAa,IAAI,aAAa,CAQ7C;AAED,wBAAgB,cAAc,CAAC,SAAS,EAAE,aAAa,GAAG,IAAI,CAG7D;AAED,wBAAgB,eAAe,CAAC,UAAU,EAAE,cAAc,GAAG,IAAI,CAGhE;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,SAAS,GAAG,YAAY,CAqDxE;AAED,wBAAgB,YAAY,IAAI,QAAQ,GAAG,IAAI,CAM9C;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE;IACtC,IAAI,EAAE,QAAQ,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,OAAO,CAAC;IACxB,sBAAsB,EAAE,OAAO,CAAC;CACjC,GAAG,OAAO,CA0BV;AAED,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,QAAQ,EACd,GAAG,EAAE,MAAM,EACX,MAAM,SAAS,GACd,OAAO,CAWT;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,SAAS,GAAG,OAAO,CAOjE;AAGD,wBAAgB,aAAa,CAC3B,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC9B,YAAY,CAEd"}
package/dist/verify.js ADDED
@@ -0,0 +1,254 @@
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
+ import { loadConfig } from "./config.js";
3
+ import { analyzeDiff, getHeadSha, hasUncommittedChanges, isGitAncestor } from "./diff.js";
4
+ import { ANSWERS_PATH, JUDGMENTS_PATH, PASS_PATH, REFERENCES_PATH, SESSION_PATH, TESTME_DIR, } from "./paths.js";
5
+ function escapeRegex(value) {
6
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
7
+ }
8
+ function hasTerm(answer, term) {
9
+ if (term.includes("/") || term.includes(".")) {
10
+ return answer.toLowerCase().includes(term.toLowerCase());
11
+ }
12
+ const pattern = new RegExp(`\\b${escapeRegex(term)}\\b`, "i");
13
+ return pattern.test(answer);
14
+ }
15
+ export function scoreAnswer(answer, question) {
16
+ const trimmed = answer.trim();
17
+ const missingTerms = question.rubric.requiredTerms.filter((term) => !hasTerm(trimmed, term));
18
+ const tooShort = trimmed.length < question.rubric.minLength;
19
+ let missingSymbol;
20
+ if (question.rubric.requiredSymbol && !hasTerm(trimmed, question.rubric.requiredSymbol)) {
21
+ missingSymbol = question.rubric.requiredSymbol;
22
+ }
23
+ const passed = missingTerms.length === 0 && !tooShort && !missingSymbol;
24
+ return { passed, missingTerms, tooShort, missingSymbol };
25
+ }
26
+ export function verifyAnswersKeywords(session, answers) {
27
+ const failures = [];
28
+ let passedCount = 0;
29
+ for (const question of session.questions) {
30
+ const answer = answers[question.id] ?? "";
31
+ const result = scoreAnswer(answer, question);
32
+ if (result.passed) {
33
+ passedCount += 1;
34
+ continue;
35
+ }
36
+ failures.push({
37
+ id: question.id,
38
+ prompt: question.prompt,
39
+ missingTerms: result.missingTerms,
40
+ tooShort: result.tooShort,
41
+ missingSymbol: result.missingSymbol,
42
+ });
43
+ }
44
+ const total = session.questions.length;
45
+ const passed = failures.length === 0 && total > 0;
46
+ return {
47
+ passed,
48
+ score: total === 0 ? 0 : Math.round((passedCount / total) * 100),
49
+ total,
50
+ grading: "keywords",
51
+ failures,
52
+ };
53
+ }
54
+ const ALIGNMENT_SCORE = {
55
+ high: 100,
56
+ medium: 75,
57
+ low: 0,
58
+ };
59
+ function clampAccuracy(value) {
60
+ if (Number.isNaN(value)) {
61
+ return 0;
62
+ }
63
+ return Math.min(100, Math.max(0, Math.round(value)));
64
+ }
65
+ export function normalizeJudgment(judgment) {
66
+ if (judgment.accuracy !== undefined) {
67
+ return clampAccuracy(judgment.accuracy);
68
+ }
69
+ return ALIGNMENT_SCORE[judgment.alignment] ?? 0;
70
+ }
71
+ const ALIGNMENT_RANK = {
72
+ low: 1,
73
+ medium: 2,
74
+ high: 3,
75
+ };
76
+ function alignmentMeetsMinimum(alignment, minAlignment = "medium") {
77
+ return ALIGNMENT_RANK[alignment] >= ALIGNMENT_RANK[minAlignment];
78
+ }
79
+ export function isQuestionPassing(judgment, passThreshold, minAlignment = "medium") {
80
+ const accuracy = normalizeJudgment(judgment);
81
+ return (judgment.passed &&
82
+ accuracy >= passThreshold &&
83
+ alignmentMeetsMinimum(judgment.alignment, minAlignment));
84
+ }
85
+ export function verifyAnswersSemantic(session, judgments, passThreshold = 70, minAlignment = "medium") {
86
+ const failures = [];
87
+ const questionScores = [];
88
+ let accuracySum = 0;
89
+ for (const question of session.questions) {
90
+ const judgment = judgments.judgments[question.id];
91
+ if (!judgment) {
92
+ failures.push({
93
+ id: question.id,
94
+ prompt: question.prompt,
95
+ feedback: "No semantic judgment recorded for this question.",
96
+ });
97
+ continue;
98
+ }
99
+ const accuracy = normalizeJudgment(judgment);
100
+ const passed = isQuestionPassing(judgment, passThreshold, minAlignment);
101
+ questionScores.push({
102
+ id: question.id,
103
+ prompt: question.prompt,
104
+ accuracy,
105
+ alignment: judgment.alignment,
106
+ passed,
107
+ userSummary: judgment.userSummary,
108
+ feedback: judgment.feedback,
109
+ });
110
+ accuracySum += accuracy;
111
+ if (passed) {
112
+ continue;
113
+ }
114
+ failures.push({
115
+ id: question.id,
116
+ prompt: question.prompt,
117
+ feedback: judgment.feedback,
118
+ alignment: judgment.alignment,
119
+ userSummary: judgment.userSummary,
120
+ accuracy,
121
+ });
122
+ }
123
+ const total = session.questions.length;
124
+ const passed = failures.length === 0 && total > 0;
125
+ return {
126
+ passed,
127
+ score: total === 0 ? 0 : Math.round(accuracySum / total),
128
+ total,
129
+ grading: "semantic",
130
+ passThreshold,
131
+ questionScores,
132
+ failures,
133
+ };
134
+ }
135
+ export function loadSession() {
136
+ if (!existsSync(SESSION_PATH)) {
137
+ throw new Error("No session found. Run `npx comp-gate generate` first.");
138
+ }
139
+ return JSON.parse(readFileSync(SESSION_PATH, "utf8"));
140
+ }
141
+ export function loadAnswers() {
142
+ if (!existsSync(ANSWERS_PATH)) {
143
+ throw new Error("No answers found. Collect answers in chat first.");
144
+ }
145
+ return JSON.parse(readFileSync(ANSWERS_PATH, "utf8"));
146
+ }
147
+ export function loadReferences() {
148
+ if (!existsSync(REFERENCES_PATH)) {
149
+ return null;
150
+ }
151
+ return JSON.parse(readFileSync(REFERENCES_PATH, "utf8"));
152
+ }
153
+ export function loadJudgments() {
154
+ if (!existsSync(JUDGMENTS_PATH)) {
155
+ throw new Error("No judgments found. The agent must grade answers semantically and write .testme/judgments.json before verify.");
156
+ }
157
+ return JSON.parse(readFileSync(JUDGMENTS_PATH, "utf8"));
158
+ }
159
+ export function writeJudgments(judgments) {
160
+ mkdirSync(TESTME_DIR, { recursive: true });
161
+ writeFileSync(JUDGMENTS_PATH, `${JSON.stringify(judgments, null, 2)}\n`, "utf8");
162
+ }
163
+ export function writeReferences(references) {
164
+ mkdirSync(TESTME_DIR, { recursive: true });
165
+ writeFileSync(REFERENCES_PATH, `${JSON.stringify(references, null, 2)}\n`, "utf8");
166
+ }
167
+ export function verifySession(cwd, branch = "main") {
168
+ const session = loadSession();
169
+ const answers = loadAnswers();
170
+ const config = loadConfig(cwd);
171
+ const current = analyzeDiff(cwd, branch);
172
+ if (session.diffHash !== current.diffHash) {
173
+ throw new Error("Session is stale. The diff changed since generate — run `npx comp-gate generate` again.");
174
+ }
175
+ const answerIds = new Set(Object.keys(answers));
176
+ for (const question of session.questions) {
177
+ if (!answerIds.has(question.id) || !answers[question.id]?.trim()) {
178
+ throw new Error(`Missing answer for ${question.id}.`);
179
+ }
180
+ }
181
+ let result;
182
+ if (config.grading === "keywords") {
183
+ result = verifyAnswersKeywords(session, answers);
184
+ }
185
+ else {
186
+ const judgments = loadJudgments();
187
+ if (judgments.diffHash !== session.diffHash) {
188
+ throw new Error("Judgments are stale. Re-grade answers against the current session.");
189
+ }
190
+ result = verifyAnswersSemantic(session, judgments, config.passThreshold, config.minAlignment ?? "medium");
191
+ }
192
+ if (result.passed) {
193
+ const pass = {
194
+ diffHash: session.diffHash,
195
+ score: result.score,
196
+ verifiedAt: new Date().toISOString(),
197
+ questionsAnswered: session.questions.length,
198
+ headSha: getHeadSha(cwd),
199
+ hadUncommitted: hasUncommittedChanges(cwd),
200
+ };
201
+ mkdirSync(TESTME_DIR, { recursive: true });
202
+ writeFileSync(PASS_PATH, `${JSON.stringify(pass, null, 2)}\n`, "utf8");
203
+ }
204
+ return result;
205
+ }
206
+ export function loadPassFile() {
207
+ if (!existsSync(PASS_PATH)) {
208
+ return null;
209
+ }
210
+ return JSON.parse(readFileSync(PASS_PATH, "utf8"));
211
+ }
212
+ export function passStillValid(options) {
213
+ const { pass, currentDiffHash, headSha, hasUncommitted, verifiedHeadIsAncestor } = options;
214
+ if (pass.diffHash === currentDiffHash) {
215
+ return true;
216
+ }
217
+ if (!pass.headSha) {
218
+ return false;
219
+ }
220
+ if (pass.hadUncommitted &&
221
+ !hasUncommitted &&
222
+ headSha !== pass.headSha &&
223
+ verifiedHeadIsAncestor) {
224
+ return true;
225
+ }
226
+ if (pass.headSha === headSha && !hasUncommitted) {
227
+ return true;
228
+ }
229
+ return false;
230
+ }
231
+ export function evaluatePassValidity(pass, cwd, branch = "main") {
232
+ const headSha = getHeadSha(cwd);
233
+ return passStillValid({
234
+ pass,
235
+ currentDiffHash: analyzeDiff(cwd, branch).diffHash,
236
+ headSha,
237
+ hasUncommitted: hasUncommittedChanges(cwd),
238
+ verifiedHeadIsAncestor: pass.headSha
239
+ ? isGitAncestor(pass.headSha, headSha, cwd)
240
+ : false,
241
+ });
242
+ }
243
+ export function isPassValid(cwd, branch = "main") {
244
+ const pass = loadPassFile();
245
+ if (!pass) {
246
+ return false;
247
+ }
248
+ return evaluatePassValidity(pass, cwd, branch);
249
+ }
250
+ // Backwards-compatible export used in tests
251
+ export function verifyAnswers(session, answers) {
252
+ return verifyAnswersKeywords(session, answers);
253
+ }
254
+ //# sourceMappingURL=verify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify.js","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "comp-gate",
3
+ "version": "0.1.0",
4
+ "description": "Comprehension gate for desktop coding agents — block git push to main until you pass a deterministic test",
5
+ "type": "module",
6
+ "bin": {
7
+ "comp-gate": "./dist/cli.js",
8
+ "testme": "./dist/cli.js"
9
+ },
10
+ "files": [
11
+ "dist",
12
+ "src/templates"
13
+ ],
14
+ "scripts": {
15
+ "build": "tsc",
16
+ "dev": "tsc --watch",
17
+ "test": "node --experimental-vm-modules node_modules/vitest/vitest.mjs run",
18
+ "prepare": "npm run build",
19
+ "prepublishOnly": "npm run build"
20
+ },
21
+ "repository": {
22
+ "type": "git",
23
+ "url": "git+https://github.com/ROrmand/comp-gate.git"
24
+ },
25
+ "homepage": "https://github.com/ROrmand/comp-gate#readme",
26
+ "bugs": {
27
+ "url": "https://github.com/ROrmand/comp-gate/issues"
28
+ },
29
+ "keywords": [
30
+ "cursor",
31
+ "claude",
32
+ "windsurf",
33
+ "agent",
34
+ "git",
35
+ "comprehension",
36
+ "hooks",
37
+ "pre-push",
38
+ "pre-commit"
39
+ ],
40
+ "license": "MIT",
41
+ "engines": {
42
+ "node": ">=18"
43
+ },
44
+ "dependencies": {
45
+ "commander": "^13.1.0"
46
+ },
47
+ "devDependencies": {
48
+ "@types/node": "^22.13.10",
49
+ "typescript": "^5.8.2",
50
+ "vitest": "^3.0.9"
51
+ }
52
+ }
@@ -0,0 +1,6 @@
1
+ # Session Changes
2
+
3
+ Document what changed during this session. testme uses these bullets to build comprehension rubrics.
4
+
5
+ ## example/path.ts
6
+ - Describe what changed and why