@jrpool/kilotest 59.1.1 → 59.1.3
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/.claude/settings.local.json +0 -1
- package/README.md +1 -1
- package/docs/AI-TOOLS.md +4 -7
- package/docs/SERVICE.md +2 -3
- package/docs/decisions/001-api-design.md +13 -87
- package/lhm.plugin.json +9 -6
- package/llms.txt +1 -1
- package/openapi.yaml +1 -1
- package/package.json +2 -2
- package/scripts/update-versions.ts +38 -0
- package/server.json +1 -1
- package/docs/BACKLOG.md +0 -580
- package/docs/IDEAS.md +0 -5927
- package/docs/decisions/009-qai-integration.md +0 -40
- package/docs/decisions/QAI-HISTORICAL-CONTEXT.md +0 -42
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
"Bash(gh api *)",
|
|
6
6
|
"WebFetch(domain:raw.githubusercontent.com)",
|
|
7
7
|
"Bash(ls -la /Users/pool/Documents/Topics/repos/a11yTesting/kilotest/*.json)",
|
|
8
|
-
"Bash(grep -n \"^import\\\\|^export\" /Users/pool/Documents/Topics/repos/a11yTesting/qai/src/*.ts)",
|
|
9
8
|
"Bash(find /Users/pool/Documents/Topics/repos/a11yTesting/kilotest -type f \\\\\\( -name \"*.test.js\" -o -name \"*.test.cjs\" -o -name \"test.js\" \\\\\\) ! -path \"*/node_modules/*\" -exec wc -l {} +)",
|
|
10
9
|
"Bash(find /Users/pool/Documents/Topics/repos/a11yTesting/kilotest -type f \\\\\\( -name \"*.test.js\" -o -name \"*.test.cjs\" -o -name \"test.js\" \\\\\\) ! -path \"*/node_modules/*\" -exec grep -h \"^test\\(\" {} +)",
|
|
11
10
|
"Bash(npm install:*)",
|
package/README.md
CHANGED
|
@@ -62,7 +62,7 @@ The URL for models using the MCP server is `https://kilotest.com/mcp`. The MCP s
|
|
|
62
62
|
|
|
63
63
|
There is additional documentation at:
|
|
64
64
|
|
|
65
|
-
- [
|
|
65
|
+
- [Tutorial: authorizing AI assistants to use Kilotest](https://kilotest.com/tutorialAI.html)
|
|
66
66
|
- [AI-TOOLS.md](docs/AI-TOOLS.md): how Kilotest implements the MCP protocol
|
|
67
67
|
- [Summary of Kilotest capabilities](https://kilotest.com/capability.md)
|
|
68
68
|
- [llms.txt](llms.txt): basic documentation for LLMs
|
package/docs/AI-TOOLS.md
CHANGED
|
@@ -62,11 +62,9 @@ The external features that support the use of Kilotest as a collection of AI too
|
|
|
62
62
|
|
|
63
63
|
## Required maintenance
|
|
64
64
|
|
|
65
|
-
Whenever the
|
|
65
|
+
Whenever the `version` property of the `package.json` file is updated:
|
|
66
66
|
|
|
67
|
-
- Update the `server.json`
|
|
68
|
-
- Update the `lhm.plugin.json` file (version field).
|
|
69
|
-
- Regenerate `openapi.yaml` (`npm run generate:openapi`).
|
|
67
|
+
- Update `openapi.yaml` and the versions of `server.json` and `lhm.plugin.json` (`npm run generate`).
|
|
70
68
|
- Create a pull request and merge to `main` (triggers `publish-mcp.yml` automatically for the MCP Registry).
|
|
71
69
|
- Execute `lhm plugin update --dir .` (for LobeHub).
|
|
72
70
|
|
|
@@ -95,12 +93,11 @@ To-dos recommended by Claude Sonnet 5 Medium on Devin:
|
|
|
95
93
|
|
|
96
94
|
- **Other directories not yet targeted.** The [mcp.so](https://mcp.so/submit) directory offers a free tier but steers submitters toward a $39 paid listing; deferred as a commercial decision. The Docker MCP Catalog is not a fit because it requires stdio transport and a Dockerfile, and Kilotest is streamable-http.
|
|
97
95
|
|
|
98
|
-
- **Client-onboarding friction isn't documented.** Some MCP clients need the `mcp-remote` npx bridge to use a remote streamable-HTTP server like Kilotest's. Ready-made Claude Desktop/Cursor/Windsurf config instructions added to
|
|
96
|
+
- **Client-onboarding friction isn't documented.** Some MCP clients need the `mcp-remote` npx bridge to use a remote streamable-HTTP server like Kilotest's. Ready-made Claude Desktop/Cursor/Windsurf config instructions added to the AI tutorial would convert "discovered" into "used" faster, since case 3 of your use cases assumes a technically savvy discoverer but not all users are.
|
|
99
97
|
|
|
100
98
|
Other future work:
|
|
101
99
|
|
|
102
|
-
- Add to
|
|
103
|
-
- Consider subscribing to a `Claude.ai` Team plan and submitting Kilotest to the [Claude Connectors Directory](https://claude.com/docs/connectors/building/submission). Details provided by GLM-5.2 High: “If accepted, Kilotest would get a permanent listing URL like `https://claude.ai/directory/connectors/kilotest` with a Connect button, and would appear in Claude’s in-product browse/search and ‘Suggested Connectors’. This is the highest-value listing for your use cases, because it puts Kilotest directly in front of Claude users who have not explicitly searched for it.”
|
|
100
|
+
- Add to the AI tutorial, or replace much of the current AI tutorial content with, an [Add Custom Connector link](https://claude.ai/customize/connectors?modal=add-custom-connector&connectorName=Kilotest&connectorUrl=https%3A%2F%2Fkilotest.com%2Fmcp).
|
|
104
101
|
- Recommended by GLM-5.2 High: Submit a Kilotest-appropriate request to one or more AI platforms and discover whether the model discovers Kilotest and, if so, either uses it or offers to use it in the creation of a response.
|
|
105
102
|
- Recommended by ChatGPT: A general capability manifest that says, in one machine-readable place: Here are the capabilities Kilotest provides; here are all the interfaces through which you can invoke them; here are their requirements and effects. For example:
|
|
106
103
|
|
package/docs/SERVICE.md
CHANGED
|
@@ -326,9 +326,8 @@ Both logs are rotated; see “PM2 log rotation” above for the application log
|
|
|
326
326
|
When the Kilotest web, API, or MCP interface is revised in a feature branch:
|
|
327
327
|
|
|
328
328
|
1. Update the version in `package.json`
|
|
329
|
-
1. Update the
|
|
330
|
-
1.
|
|
331
|
-
1. If the API has changed, run the `generate:openapi` script
|
|
329
|
+
1. Update any changes in the API in `lhm.plugin.json`
|
|
330
|
+
1. Run the `generate` script
|
|
332
331
|
1. Execute the command `npx @lobehub/market-cli plugin update --dir .`
|
|
333
332
|
1. Commit and push the changes to the feature branch
|
|
334
333
|
1. Create a pull request to merge the feature branch into `main`
|
|
@@ -5,111 +5,37 @@ status: accepted
|
|
|
5
5
|
|
|
6
6
|
# API design
|
|
7
7
|
|
|
8
|
-
## Context and
|
|
8
|
+
## Context, problem, and decision
|
|
9
9
|
|
|
10
10
|
Kilotest manages data that are organized into reports. Each report contains the results of one session in which multiple rule engines were used for testing the front-end quality of one web page.
|
|
11
11
|
|
|
12
|
-
The
|
|
12
|
+
The API offers existing data as a hierarchy of granularity:
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
1. All tested pages.
|
|
15
|
+
2. Reports available about one page.
|
|
16
|
+
3. Details of one report, including summaries of the reported issues.
|
|
17
|
+
4. Details of one issue, including summaries of its violators.
|
|
18
|
+
5. Details of one violator, including its diagnoses.
|
|
15
19
|
|
|
16
|
-
|
|
17
|
-
2. Details of one report, including summaries of the reported issues.
|
|
18
|
-
3. Details of one issue, including summaries of its violators.
|
|
19
|
-
4. Details of one violator, including its diagnoses.
|
|
20
|
+
It also offers downloads of complete reports in JSON format.
|
|
20
21
|
|
|
21
|
-
|
|
22
|
+
The API would be simpler to implement if it offered only one-shot interrogation, i.e. downloads of complete reports. But the available evidence indicates that this would be inferior for typical users.
|
|
22
23
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
The responses to requests in the UI at any level include some of the information about the previous levels. For example, a response at level 3 includes a summary of information about the report and about the issues in that report. The prior-level summarized information is based on assumptions about what a typical human user would value. For example, at level 3, the prior-level information does not summarize all the available reports, but does include a list of the rule engines that succeeded and failed in testing the page and the counts of issues reported.
|
|
26
|
-
|
|
27
|
-
These assumptions for human UI users may or may not be valid for how API consumers prefer to interact with a Kilotest API. Those interactions may vary depending on the tasks that they are performing. Consider three scenarios:
|
|
28
|
-
|
|
29
|
-
1. A user asks a language model for all available information about the front-end quality of a particular web page.
|
|
30
|
-
2. A user asks a language model for all the available information about issues related to a particular topic, such as keyboard navigation, for a particular web page.
|
|
31
|
-
3. A user asks a language model to describe the front-end quality of a particular web page. Having consumed the description, the user asks the model to describe one of the reported issues. Having consumed that description, the user asks the model to describe one of the reported violators of that issue. Having consumed that description, the user asks the model to describe the diagnoses of that violation.
|
|
32
|
-
|
|
33
|
-
Scenario 1 seems to justify an API that can aggregate all information from all available reports about the page into a single response.
|
|
34
|
-
|
|
35
|
-
Scenario 2 seems to justify an API that filters out from the scenario-1 response all information about issues unrelated to the specified topic.
|
|
36
|
-
|
|
37
|
-
Scenario 3 seems to justify an API that mimics the UI in structure.
|
|
38
|
-
|
|
39
|
-
Even these apparently justified API designs depend on the assumption that users mean what they say. For example, in scenario 1 a user asks for **all** available information about the front-end quality of a particular web page. The user may really want all that information only if it is not too voluminous, and otherwise want a summary.
|
|
40
|
-
|
|
41
|
-
Uncertainty about how consumers will interact with the API creates a design problem: How should the API be further developed?
|
|
42
|
-
|
|
43
|
-
As of the date of this decision, a partial initial API version already exists: an API that mimics the UI for levels 1, 2, and 3. It is exposed as a traditional HTTP REST API and also as a connector to a collection of MCP tools. For each level, the API provides an operation.
|
|
44
|
-
|
|
45
|
-
## Considered options
|
|
46
|
-
|
|
47
|
-
1. **Iterate and instrument.** (1) Finish redesigning the operations at levels 1, 2, and 3, to represent the hypothesized typical needs of language-model consumers. Then (2) add an operation that implements level 4. Then (3) add an operation that collects comments from consumers on how the API design could better satisfy their needs. Then (4) add metrics to make API usage and submitted comments available to Kilotest managers.
|
|
48
|
-
2. **Research first.** (1) Pause further API development while doing fundamental research to predict consumer needs. Then (2) resume API and metrics development, including API redesign if the research results warrant.
|
|
49
|
-
|
|
50
|
-
## Decision
|
|
51
|
-
|
|
52
|
-
The decision is to adopt **option 1: iterate and instrument**.
|
|
53
|
-
|
|
54
|
-
## Empirical basis
|
|
55
|
-
|
|
56
|
-
The decision is based on the working hypothesis that the typical consumer will be a language model (most often a foundation model) performing a task for a human user. Even without a pause for fundamental research, there is enough empirical evidence to justify this decision.
|
|
57
|
-
|
|
58
|
-
### Completion of the 4-level hierarchy
|
|
59
|
-
|
|
60
|
-
There is empirical support for an API optimized for scenario 3, i.e. incremental rather than one-shot interrogation. Both single-shot comprehensive requests and incremental drill-downs occur in significant numbers in real-world language-model use.
|
|
24
|
+
Both one-shot comprehensive requests and incremental drill-downs occur in significant numbers in real-world language-model use.
|
|
61
25
|
|
|
62
26
|
- Jian _et al._ (2024) studied experienced ChatGPT users and found that **43.8% of prompts were single-component**, **38.2% were dual-component**, and only **18.0% were multi-component**. A request such as scenario 1 (“tell me everything about page X”) or scenario 2 (“tell me about defect class X on page Y”) is structurally common because it is typically a single-component prompt.
|
|
63
27
|
- However, follow-up refinement is frequent. Mysore _et al._ (2025) analyzed large-scale Bing Copilot and WildChat writing sessions and report: “Rather than passively accepting output, users actively refine, explore, and co-construct text.” This matches scenario 3.
|
|
64
28
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
### Usage and suggestion metrics
|
|
68
|
-
|
|
69
|
-
There is also empirical support for modesty in any estimate of the adequacy of the current or any other single API design. As found by Zhu _et al._ (2025), “users do not transfer existing conversational norms to LLM interactions, but instead develop new registers with distinct pragmatic features.” Metrics will help to inform the contributors to the API about how consumers are actually using it and about proposed improvements.
|
|
29
|
+
Anthropic’s tool-using agent documentation describes an agentic loop in which the full conversation history is kept and “every turn sees the complete prior context”. Cohere’s multi-step tool-use documentation explains that the model can use information learned from one tool call to parameterize a subsequent call. MCP’s typed tool schemas support this pattern.
|
|
70
30
|
|
|
71
|
-
|
|
31
|
+
Zhu _et al._ (2025) found that “users do not transfer existing conversational norms to LLM interactions, but instead develop new registers with distinct pragmatic features.”
|
|
72
32
|
|
|
73
|
-
A user-friendly rendering of an entire Kilotest report is estimated at about 5 MB of text, or roughly 1.25 million tokens.
|
|
33
|
+
A user-friendly rendering of an entire Kilotest report is estimated at about 5 MB of text, or roughly 1.25 million tokens. That exceeds a typical context window, so a language model cannot consume the whole report in one prompt. On the basis of a 2026 pricing estimate of $0.0005 per 1,000 tokens, if the report is passed chunked, each pass will cost roughly $3.75 in input tokens. Every subsequent question about it will require re-sending it. By contrast, a four-level drill-down through page → report → issue → violator → diagnosis costs roughly $0.07 for a typical path.
|
|
74
34
|
|
|
75
35
|
These estimates can be applied to a hypothetically typical conversation. It would involve one report, two issues, and six violators (two per issue). The user would not ask about diagnoses. Delivering such results with the full-report method requires one pass to identify the report, two passes to describe the issues, and six passes to describe the violators, for a total of about $33.75. Doing so incrementally costs about $0.26, which is only **1/130th** of the cost of the same result with the full-report strategy.
|
|
76
36
|
|
|
77
37
|
On the basis of these cost estimates, even if a user initially wanted a comprehensive report and then wanted a language model to interpret it, the impact of that strategy on cost would likely motivate the user to switch to an incremental strategy as a default.
|
|
78
38
|
|
|
79
|
-
## Sub-decision: ancestor information in level responses
|
|
80
|
-
|
|
81
|
-
Given this decision, a secondary decision to make is what information from prior levels to repeat in a response. Four alternatives were considered:
|
|
82
|
-
|
|
83
|
-
1. **Identifiers only:** The report, issue, and violator would be described by their unique identifiers only. The consumer would use the identifiers to retrieve from its conversation-history context any forgotten information needed about them.
|
|
84
|
-
2. **Identifiers plus labels:** Ancestor entities (report, issue, and/or violator) would be described only by their unique identifiers and human-interpretable labels. If the consumer needs other forgotten facts about them, it would use the identifiers to retrieve those facts by repeating ancestor requests.
|
|
85
|
-
3. **Currently pertinent facts:** The facts from ancestor requests would be repeated if, and only if, the consumer could need them for interpreting the response to the current-level request. For example, if the current-level request is about one report, facts about other reports are not pertinent, but any facts about the report are pertinent. Likewise for one issue or one violator.
|
|
86
|
-
4. **Cumulative facts:** All the information from the prior responses would be repeated, so that any needed information would be available in the current response and no search of the conversation history would be needed.
|
|
87
|
-
|
|
88
|
-
The sub-decision was **currently pertinent facts** (option 3). This decision was based on cost and reliability, as follows.
|
|
89
|
-
|
|
90
|
-
- **Cost:** Option 3 is slightly more costly than option 2 when all pertinent facts are remembered, because it provides duplicate information. But option 3 is substantially less costly than option 2 if needed facts are forgotten, because option 3 avoids the need to repeat an ancestor request to re-retrieve forgotten facts. Option 4 is much more costly than option 3, because of the much larger response bodies and the inclusion of much irrelevant information in responses.
|
|
91
|
-
- **Quality:** Option 2 provides better locality than option 1, and option 3 provides better locality than option 2. Locality improves the probability that a language model will actually make use of pertinent facts instead of ignoring them or fabricating hallucinated replacements for them.
|
|
92
|
-
- **Reliability:** Option 1 entails a greater risk of information loss and hallucination than option 2. With option 1, the consumer could be unable to retrieve the needed information using identifiers if the conversation history were truncated, if an operation were invoked in isolation, or if the model were asked later to summarize findings in natural language.
|
|
93
|
-
|
|
94
|
-
No sub-decision option is optimal under all possible conditions, but the working hypothesis about prevailing use patterns favors option 3.
|
|
95
|
-
|
|
96
|
-
## Implementation plan
|
|
97
|
-
|
|
98
|
-
- The existing request handlers for levels 1, 2, and 3 will be revised. After revision, they will omit excess information about prior levels and include all currently pertinent facts.
|
|
99
|
-
- Level 4 will be implemented. It will return the diagnoses for one violator of one issue in one report.
|
|
100
|
-
- A comment operation will be provided. This will allow consumers to report friction or suggest improvements to the API design.
|
|
101
|
-
- Usage metrics will be defined, captured, and recorded. This will allow Kilotest managers to observe which levels, issues, and patterns are most common and what comments have been received.
|
|
102
|
-
- If the empirical data later show that the API does not serve some common scenario well, the API will be redesigned accordingly.
|
|
103
|
-
|
|
104
|
-
### Risks and mitigations
|
|
105
|
-
|
|
106
|
-
- **Risk:** The hierarchy may not match the way consumers actually want to query the data.
|
|
107
|
-
- **Mitigation:** The comment operation and usage metrics will surface mismatches early, allowing Kilotest managers to make data-driven decisions about API improvements.
|
|
108
|
-
- **Risk:** The cost estimates assume the typical consumer preserves conversation history. A poorly implemented consumer could still incur higher-than-necessary costs.
|
|
109
|
-
- **Mitigation:** It is hypothesized that typical consumers will be models that maintain message history. When they do not, the ancestor labels provide a minimal human-friendly substitute that facilitates history reconstruction when needed.
|
|
110
|
-
- **Risk:** Scenario 1 consumers may still want an aggregated “everything about page X” response.
|
|
111
|
-
- **Mitigation:** A future operation can be added to aggregate the hierarchy on the server side and return a structured summary. That decision is deferred until usage and comment data justify it.
|
|
112
|
-
|
|
113
39
|
## References
|
|
114
40
|
|
|
115
41
|
- Jian, J., _et al._ (2024). [Understanding User Prompting Behavior in Generative AI](https://dl.acm.org/doi/abs/10.1002/pra2.1318).
|
package/lhm.plugin.json
CHANGED
|
@@ -10,10 +10,13 @@
|
|
|
10
10
|
"tags": [
|
|
11
11
|
"accessibility",
|
|
12
12
|
"a11y",
|
|
13
|
-
"testing",
|
|
14
13
|
"mcp",
|
|
15
14
|
"mcp-server",
|
|
16
|
-
"modelcontextprotocol"
|
|
15
|
+
"modelcontextprotocol",
|
|
16
|
+
"testing",
|
|
17
|
+
"w3c",
|
|
18
|
+
"wcag",
|
|
19
|
+
"web standards"
|
|
17
20
|
],
|
|
18
21
|
"tools": [
|
|
19
22
|
{
|
|
@@ -412,7 +415,7 @@
|
|
|
412
415
|
},
|
|
413
416
|
{
|
|
414
417
|
"name": "listIssues",
|
|
415
|
-
"description": "Lists the issues reported in one report, along with the history of all reports about the same page. Use this after listPages to drill into a specific report, identified by its timestamp and job identifier. Returns basics about the report
|
|
418
|
+
"description": "Lists the issues reported in one report, along with the history of all reports about the same page. Use this after listPages to drill into a specific report, identified by its timestamp and job identifier. Returns basics about the report’s issues and a list of every report about the same page, from oldest to latest.",
|
|
416
419
|
"inputSchema": {
|
|
417
420
|
"type": "object",
|
|
418
421
|
"properties": {
|
|
@@ -1151,7 +1154,7 @@
|
|
|
1151
1154
|
},
|
|
1152
1155
|
{
|
|
1153
1156
|
"name": "listViolators",
|
|
1154
|
-
"description": "Lists the elements of a tested page that were reported as exhibiting one issue in one report. Use this after listIssues to drill from an issue down to the elements it affects. Returns basics about each violating element, including its identifier in the page
|
|
1157
|
+
"description": "Lists the elements of a tested page that were reported as exhibiting one issue in one report. Use this after listIssues to drill from an issue down to the elements it affects. Returns basics about each violating element, including its identifier in the page’s element catalog.",
|
|
1155
1158
|
"inputSchema": {
|
|
1156
1159
|
"type": "object",
|
|
1157
1160
|
"properties": {
|
|
@@ -4184,7 +4187,7 @@
|
|
|
4184
4187
|
},
|
|
4185
4188
|
{
|
|
4186
4189
|
"name": "awaitTest",
|
|
4187
|
-
"description": "Waits for a job ordered via the orderNewTest or orderRetest tool to finish, using the report identifier either tool returned. Use this instead of polling listIssues when an immediate answer is preferred. Blocks until the report is ready, the job fails, or a maximum wait time elapses, sending no interim notices; returns the finished job
|
|
4190
|
+
"description": "Waits for a job ordered via the orderNewTest or orderRetest tool to finish, using the report identifier either tool returned. Use this instead of polling listIssues when an immediate answer is preferred. Blocks until the report is ready, the job fails, or a maximum wait time elapses, sending no interim notices; returns the finished job’s status and, if ready, its report identifier.",
|
|
4188
4191
|
"inputSchema": {
|
|
4189
4192
|
"type": "object",
|
|
4190
4193
|
"properties": {
|
|
@@ -4506,5 +4509,5 @@
|
|
|
4506
4509
|
}
|
|
4507
4510
|
}
|
|
4508
4511
|
],
|
|
4509
|
-
"version": "59.
|
|
4512
|
+
"version": "59.1.3"
|
|
4510
4513
|
}
|
package/llms.txt
CHANGED
|
@@ -40,4 +40,4 @@ Kilotest integrates an ensemble of 12 rule engines, with about 1,300 rules, to t
|
|
|
40
40
|
- [Privacy policy](https://kilotest.com/privacy.html)
|
|
41
41
|
- [OpenAPI specification for Kilotest](https://kilotest.com/openapi.yaml)
|
|
42
42
|
- [Kilotest as connector to and collection of AI Tools](https://github.com/jrpool/kilotest/blob/main/docs/AI-TOOLS.md)
|
|
43
|
-
- [Tutorial on authorizing language models to use Kilotest](https://kilotest.com/
|
|
43
|
+
- [Tutorial on authorizing language models to use Kilotest](https://kilotest.com/tutorialAI.html)
|
package/openapi.yaml
CHANGED
|
@@ -2,7 +2,7 @@ openapi: 3.1.0
|
|
|
2
2
|
info:
|
|
3
3
|
title: Kilotest API
|
|
4
4
|
description: 'Kilotest is an ensemble testing and reporting service for front-end web quality. It uses an ensemble of 12 rule engines to test web pages for front-end quality (accessibility, usability, and web standards, including HTML, CSS, ARIA, and WCAG). Kilotest acts as a web server for human users, an MCP server for AI platforms, and an API for programmatic access. With this API you can request that a page be tested or retested, discover available reports, incrementally retrieve facts from a report: from what reports are available, to what issues were reported in one report, to what elements violated one issue, to what diagnoses rule engines gave for one violation.'
|
|
5
|
-
version: 59.1.
|
|
5
|
+
version: 59.1.3
|
|
6
6
|
license:
|
|
7
7
|
name: MIT
|
|
8
8
|
identifier: MIT
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jrpool/kilotest",
|
|
3
|
-
"version": "59.1.
|
|
3
|
+
"version": "59.1.3",
|
|
4
4
|
"description": "Ensemble testing for front-end web quality",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.ts",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"test": "c8 node --require ./test/setup.ts --experimental-test-module-mocks --test --test-concurrency=1 --test-randomize '**/*.test.ts'",
|
|
15
15
|
"test:smoke": "node smokeTest.ts",
|
|
16
16
|
"checkinfo": "node checkinfo.ts",
|
|
17
|
-
"generate
|
|
17
|
+
"generate": "node scripts/generate-openapi.ts && node scripts/update-versions.ts"
|
|
18
18
|
},
|
|
19
19
|
"repository": {
|
|
20
20
|
"type": "git",
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/*
|
|
2
|
+
update-versions.ts
|
|
3
|
+
Copies the version field of package.json into the version fields of server.json and lhm.plugin.json, keeping package.json the single source of truth for the Kilotest version.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// IMPORTS
|
|
7
|
+
|
|
8
|
+
import fs from 'node:fs';
|
|
9
|
+
import path from 'node:path';
|
|
10
|
+
import pkg from '../package.json' with {type: 'json'};
|
|
11
|
+
|
|
12
|
+
// CONSTANTS
|
|
13
|
+
|
|
14
|
+
const {version} = pkg;
|
|
15
|
+
const targetFiles = ['server.json', 'lhm.plugin.json'];
|
|
16
|
+
|
|
17
|
+
// FUNCTIONS
|
|
18
|
+
|
|
19
|
+
// Replaces the version field of a JSON file with the package.json version, leaving all other content byte-for-byte unchanged.
|
|
20
|
+
const updateVersion = (fileName: string): void => {
|
|
21
|
+
const filePath = path.join(import.meta.dirname, '..', fileName);
|
|
22
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
23
|
+
const match = content.match(/^(\s*)"version": "([^"]+)"/m);
|
|
24
|
+
if (!match) {
|
|
25
|
+
throw new Error(`No version field found in ${fileName}`);
|
|
26
|
+
}
|
|
27
|
+
const oldVersion = match[2];
|
|
28
|
+
if (oldVersion === version) {
|
|
29
|
+
console.log(`${fileName} already at version ${version}`);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
fs.writeFileSync(filePath, content.replace(match[0], `${match[1]}"version": "${version}"`));
|
|
33
|
+
console.log(`Updated ${fileName} version: ${oldVersion} → ${version}`);
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
// EXECUTION
|
|
37
|
+
|
|
38
|
+
targetFiles.forEach(updateVersion);
|