@jrpool/kilotest 46.1.2 → 47.0.1

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 (147) hide show
  1. package/.claude/settings.local.json +13 -1
  2. package/.devin/config.local.json +5 -1
  3. package/.github/workflows/ci.yml +0 -3
  4. package/.github/workflows/periodic-smoke-tests.yml +30 -0
  5. package/.github/workflows/publish-mcp.yml +4 -4
  6. package/{alerts.test.js → alerts.test.ts} +17 -29
  7. package/{alerts.js → alerts.ts} +10 -13
  8. package/api/{getReport.test.js → getReport.test.ts} +9 -10
  9. package/api/{getReport.js → getReport.ts} +23 -24
  10. package/api/{listDiagnoses.test.js → listDiagnoses.test.ts} +26 -27
  11. package/api/{listDiagnoses.js → listDiagnoses.ts} +46 -70
  12. package/api/{listIssues.test.js → listIssues.test.ts} +21 -14
  13. package/api/{listIssues.js → listIssues.ts} +75 -74
  14. package/api/{listReports.test.js → listReports.test.ts} +17 -16
  15. package/api/listReports.ts +87 -0
  16. package/api/{listViolators.test.js → listViolators.test.ts} +19 -20
  17. package/api/{listViolators.js → listViolators.ts} +45 -70
  18. package/api/requestFeature.test.ts +54 -0
  19. package/api/{requestFeature.js → requestFeature.ts} +18 -15
  20. package/api/{requestRetest.test.js → requestRetest.test.ts} +33 -28
  21. package/api/{requestRetest.js → requestRetest.ts} +32 -25
  22. package/api/{requestTest.test.js → requestTest.test.ts} +35 -30
  23. package/api/{requestTest.js → requestTest.ts} +35 -28
  24. package/api/{routes.test.js → routes.test.ts} +5 -5
  25. package/api/{routes.js → routes.ts} +6 -6
  26. package/api/{schemas.js → schemas.ts} +69 -50
  27. package/api/{util.test.js → util.test.ts} +31 -11
  28. package/api/{util.js → util.ts} +61 -36
  29. package/api/version.ts +8 -0
  30. package/{apiIntegration.test.js → apiIntegration.test.ts} +12 -13
  31. package/balances.ts +87 -0
  32. package/{checkinfo.js → checkinfo.ts} +24 -20
  33. package/docs/AI-TOOLS.md +4 -4
  34. package/docs/BACKLOG.md +356 -0
  35. package/docs/SERVICE.md +144 -17
  36. package/docs/decisions/002-coverage-tool.md +40 -0
  37. package/docs/decisions/003-adr-threshold.md +34 -0
  38. package/docs/decisions/004-docs-directory.md +23 -0
  39. package/docs/decisions/005-observability.md +28 -0
  40. package/docs/decisions/006-git-workflow.md +28 -0
  41. package/docs/decisions/007-internal-testing.md +34 -0
  42. package/docs/decisions/008-dependencies.md +28 -0
  43. package/docs/decisions/009-qai-integration.md +40 -0
  44. package/docs/decisions/QAI-HISTORICAL-CONTEXT.md +42 -0
  45. package/eslint.config.mjs +27 -0
  46. package/index.html +3 -3
  47. package/{index.test.js → index.test.ts} +380 -143
  48. package/{index.js → index.ts} +382 -283
  49. package/{indexBalances.test.js → indexBalances.test.ts} +21 -17
  50. package/{indexServe.test.js → indexServe.test.ts} +9 -9
  51. package/linkValidation.test.ts +190 -0
  52. package/{mcp.test.js → mcp.test.ts} +53 -26
  53. package/{mcp.js → mcp.ts} +29 -20
  54. package/memory/MEMORY.md +7 -0
  55. package/memory/user_maintainer_context.md +24 -0
  56. package/openapi.yaml +115 -68
  57. package/package.json +35 -15
  58. package/pm2.config.cjs +29 -0
  59. package/{routes.test.js → routes.test.ts} +8 -7
  60. package/{routing.test.js → routing.test.ts} +11 -12
  61. package/scripts/{generate-openapi.js → generate-openapi.ts} +13 -13
  62. package/serve.ts +15 -0
  63. package/smokeTest.ts +234 -0
  64. package/test/dbFixture.ts +21 -0
  65. package/test/fixtures/{buildFixtures.js → buildFixtures.ts} +14 -13
  66. package/test/{setup.cjs → setup.ts} +2 -2
  67. package/tsconfig.json +16 -0
  68. package/{util.test.js → util.test.ts} +350 -257
  69. package/util.ts +921 -0
  70. package/web/ai0BalanceForm/{ai0BalanceForm.test.js → ai0BalanceForm.test.ts} +15 -15
  71. package/web/ai0BalanceForm/{index.js → index.ts} +10 -18
  72. package/web/enqueue/index.ts +56 -0
  73. package/web/enqueueForm/index.html +9 -9
  74. package/web/enqueueForm/index.ts +43 -0
  75. package/web/expungeReportsForm/{expungeReportsForm.test.js → expungeReportsForm.test.ts} +18 -20
  76. package/web/expungeReportsForm/index.ts +18 -0
  77. package/web/hideReportForm/{hideReportForm.test.js → hideReportForm.test.ts} +14 -14
  78. package/web/hideReportForm/{index.js → index.ts} +17 -21
  79. package/web/listDiagnoses/{index.js → index.ts} +48 -58
  80. package/web/listDiagnoses/{listDiagnoses.test.js → listDiagnoses.test.ts} +39 -34
  81. package/web/listIssues/{index.js → index.ts} +67 -92
  82. package/web/listIssues/{listIssues.test.js → listIssues.test.ts} +45 -51
  83. package/web/listReports/index.html +3 -3
  84. package/web/listReports/{index.js → index.ts} +48 -53
  85. package/web/listReports/{listReports.test.js → listReports.test.ts} +41 -43
  86. package/web/listRules/{index.js → index.ts} +18 -23
  87. package/web/listRules/{listRules.test.js → listRules.test.ts} +26 -19
  88. package/web/listTopIssues/{index.js → index.ts} +36 -47
  89. package/web/listTopIssues/{listTopIssues.test.js → listTopIssues.test.ts} +26 -17
  90. package/web/listViolators/{index.js → index.ts} +51 -71
  91. package/web/listViolators/{listViolators.test.js → listViolators.test.ts} +43 -36
  92. package/web/manage/index.ts +22 -0
  93. package/web/pruneReportsForm/index.ts +18 -0
  94. package/web/pruneReportsForm/{pruneReportsForm.test.js → pruneReportsForm.test.ts} +11 -11
  95. package/web/reannotate/index.ts +70 -0
  96. package/web/reannotate/{reannotate.test.js → reannotate.test.ts} +19 -22
  97. package/web/reannotateForm/{index.js → index.ts} +41 -50
  98. package/web/reannotateForm/{reannotateForm.test.js → reannotateForm.test.ts} +13 -16
  99. package/web/renewWCAG/{index.js → index.ts} +9 -9
  100. package/web/renewWCAG/{renewWCAG.test.js → renewWCAG.test.ts} +17 -20
  101. package/web/renewWCAGForm/index.ts +22 -0
  102. package/web/{expungeReportsForm/index.js → reportDeletion.ts} +56 -38
  103. package/web/requestRetest/index.html +7 -7
  104. package/web/requestRetest/index.ts +31 -0
  105. package/web/requestRetest/requestRetest.test.ts +116 -0
  106. package/web/requestRetestForm/{index.js → index.ts} +10 -16
  107. package/web/requestRetestForm/{requestRetestForm.test.js → requestRetestForm.test.ts} +11 -12
  108. package/web/requestTest/index.html +7 -7
  109. package/web/requestTest/{index.js → index.ts} +5 -5
  110. package/web/requestTest/{requestTest.test.js → requestTest.test.ts} +21 -21
  111. package/web/requestTestForm/index.html +4 -4
  112. package/web/requestTestForm/index.ts +21 -0
  113. package/web/requestTestForm/{requestTestForm.test.js → requestTestForm.test.ts} +9 -9
  114. package/web/rewindReportsForm/index.ts +18 -0
  115. package/web/rewindReportsForm/{rewindReportsForm.test.js → rewindReportsForm.test.ts} +11 -11
  116. package/web/tutorialAI/index.html +184 -0
  117. package/web/tutorialAI/index.ts +80 -0
  118. package/web/tutorialAI/tutorialAI.test.ts +192 -0
  119. package/web/{tutorial → tutorialWeb}/index.html +9 -8
  120. package/web/tutorialWeb/index.ts +78 -0
  121. package/web/tutorialWeb/tutorialWeb.test.ts +195 -0
  122. package/web/unhideReportForm/{index.js → index.ts} +17 -21
  123. package/web/unhideReportForm/{unhideReportForm.test.js → unhideReportForm.test.ts} +16 -16
  124. package/aceconfig.js +0 -28
  125. package/api/listReports.js +0 -89
  126. package/api/requestFeature.test.js +0 -58
  127. package/api/version.js +0 -8
  128. package/indexFallback.test.js +0 -33
  129. package/indexWorkers.test.js +0 -79
  130. package/jsconfig.json +0 -8
  131. package/pm2.config.js +0 -18
  132. package/smokeTest.js +0 -128
  133. package/util.js +0 -744
  134. package/web/enqueue/index.js +0 -67
  135. package/web/enqueueForm/index.js +0 -49
  136. package/web/manage/index.js +0 -22
  137. package/web/pruneReportsForm/index.js +0 -123
  138. package/web/reannotate/index.js +0 -58
  139. package/web/renewWCAGForm/index.js +0 -22
  140. package/web/requestRetest/index.js +0 -31
  141. package/web/requestRetest/requestRetest.test.js +0 -119
  142. package/web/requestTestForm/index.js +0 -21
  143. package/web/rewindReportsForm/index.js +0 -121
  144. package/web/tutorial/index.js +0 -63
  145. package/web/tutorial/tutorial.test.js +0 -97
  146. /package/test/fixtures/db/jobs/{recs.json → testRequests.json} +0 -0
  147. /package/web/{tutorial → tutorialWeb}/images/newsletter-form.png +0 -0
@@ -1,63 +0,0 @@
1
- /*
2
- index.js
3
- Serves the tutorial and saves tutorial comments.
4
- */
5
-
6
- // IMPORTS
7
-
8
- const {sendAlert} = require('../../alerts');
9
- const {getJSON, getNowStamp} = require('../../util');
10
- const fs = require('fs/promises');
11
- const path = require('path');
12
-
13
- // CONSTANTS
14
-
15
- const commentsPath = path.join(__dirname, 'comments.json');
16
-
17
- // FUNCTIONS
18
-
19
- // Strips HTML tags and control characters, trims, and limits to 500 characters.
20
- const sanitize = str => str
21
- .replace(/<[^>]*>/g, '')
22
- .replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g, '')
23
- .trim()
24
- .slice(0, 500);
25
-
26
- // Returns the tutorial page.
27
- exports.answer = async () => {
28
- let answerPage = await fs.readFile(path.join(__dirname, 'index.html'), 'utf8');
29
- return {
30
- status: 'ok',
31
- answerPage
32
- };
33
- };
34
- // Sanitizes and saves a tutorial comment to comments.json.
35
- exports.handleComment = async content => {
36
- if (!content || typeof content !== 'string') {
37
- return {status: 'error', message: 'No content provided'};
38
- }
39
- const sanitized = sanitize(content);
40
- if (!sanitized) {
41
- return {status: 'error', message: 'Comment is empty after sanitization'};
42
- }
43
- let comments = [];
44
- try {
45
- // Get the existing comments.
46
- const existing = await fs.readFile(commentsPath, 'utf8');
47
- comments = JSON.parse(existing);
48
- }
49
- // If there are none:
50
- catch {
51
- // Initialize a comments array.
52
- }
53
- // Add the comment to the existing ones.
54
- comments.push({
55
- timeStamp: getNowStamp(),
56
- content: sanitized
57
- });
58
- // Save the revised comments.
59
- await fs.writeFile(commentsPath, getJSON(comments));
60
- // Send an alert to the manager.
61
- await sendAlert('New tutorial comment received', 'A new tutorial comment has been received.');
62
- return {status: 'ok'};
63
- };
@@ -1,97 +0,0 @@
1
- /*
2
- tutorial.test.js
3
- Unit tests for web/tutorial/index.js, covering the answer and handleComment exports.
4
- */
5
-
6
- // IMPORTS
7
-
8
- const {test, before, after} = require('node:test');
9
- const assert = require('node:assert/strict');
10
- const fs = require('node:fs/promises');
11
- const path = require('node:path');
12
- const {answer, handleComment} = require('./index');
13
-
14
- // CONSTANTS
15
-
16
- const commentsPath = path.join(__dirname, 'comments.json');
17
-
18
- // SETUP AND TEARDOWN
19
-
20
- let originalComments;
21
-
22
- before(async () => {
23
- originalComments = await fs.readFile(commentsPath, 'utf8').catch(() => null);
24
- });
25
-
26
- after(async () => {
27
- if (originalComments !== null) {
28
- await fs.writeFile(commentsPath, originalComments);
29
- }
30
- else {
31
- await fs.unlink(commentsPath).catch(() => {});
32
- }
33
- });
34
-
35
- // TESTS
36
-
37
- test('answer returns the tutorial page with status ok', async () => {
38
- const result = await answer();
39
- assert.equal(result.status, 'ok');
40
- assert.ok(result.answerPage);
41
- assert.ok(result.answerPage.length > 0);
42
- });
43
-
44
- test('handleComment returns an error for empty content', async () => {
45
- const result = await handleComment('');
46
- assert.equal(result.status, 'error');
47
- assert.equal(result.message, 'No content provided');
48
- });
49
-
50
- test('handleComment returns an error for non-string content', async () => {
51
- const result = await handleComment(null);
52
- assert.equal(result.status, 'error');
53
- assert.equal(result.message, 'No content provided');
54
- });
55
-
56
- test('handleComment returns an error for content that is empty after sanitization', async () => {
57
- const result = await handleComment('<script></script>');
58
- assert.equal(result.status, 'error');
59
- assert.equal(result.message, 'Comment is empty after sanitization');
60
- });
61
-
62
- test('handleComment saves a sanitized comment and returns ok', {timeout: 500}, async () => {
63
- // Replace comments with an empty array for a clean test.
64
- await fs.writeFile(commentsPath, '[]\n');
65
- const result = await handleComment('This is a <b>test</b> comment.');
66
- assert.equal(result.status, 'ok');
67
- const comments = JSON.parse(await fs.readFile(commentsPath, 'utf8'));
68
- assert.equal(comments.length, 1);
69
- assert.equal(comments[0].content, 'This is a test comment.');
70
- assert.ok(comments[0].timeStamp);
71
- });
72
-
73
- test('handleComment strips HTML tags and control characters', {timeout: 500}, async () => {
74
- await fs.writeFile(commentsPath, '[]\n');
75
- const result = await handleComment('<img src=x onerror=alert(1)>\x00\x07Hello');
76
- assert.equal(result.status, 'ok');
77
- const comments = JSON.parse(await fs.readFile(commentsPath, 'utf8'));
78
- assert.equal(comments[0].content, 'Hello');
79
- });
80
-
81
- test('handleComment truncates content to 500 characters', {timeout: 500}, async () => {
82
- await fs.writeFile(commentsPath, '[]\n');
83
- const longComment = 'x'.repeat(600);
84
- const result = await handleComment(longComment);
85
- assert.equal(result.status, 'ok');
86
- const comments = JSON.parse(await fs.readFile(commentsPath, 'utf8'));
87
- assert.equal(comments[0].content.length, 500);
88
- });
89
-
90
- test('handleComment creates comments.json when it does not exist', {timeout: 500}, async () => {
91
- await fs.unlink(commentsPath).catch(() => {});
92
- const result = await handleComment('Test comment for missing file');
93
- assert.equal(result.status, 'ok');
94
- const comments = JSON.parse(await fs.readFile(commentsPath, 'utf8'));
95
- assert.equal(comments.length, 1);
96
- assert.equal(comments[0].content, 'Test comment for missing file');
97
- });