@vitronai/themis 0.1.14 → 0.1.15
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/CHANGELOG.md +5 -0
- package/README.md +5 -3
- package/docs/agents-adoption.md +3 -3
- package/docs/api.md +5 -3
- package/docs/vscode-extension.md +2 -0
- package/package.json +1 -1
- package/src/cli.js +1 -1
- package/src/generate.js +95 -1
- package/templates/AGENTS.themis.md +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,11 @@ All notable changes to this project are documented in this file.
|
|
|
4
4
|
|
|
5
5
|
## Unreleased
|
|
6
6
|
|
|
7
|
+
## 0.1.15 - 2026-03-27
|
|
8
|
+
|
|
9
|
+
- Added a direct in-sidebar `Quick Actions` group plus an `Artifact Files` drawer to the in-repo VS Code extension scaffold so core Themis commands and raw artifact navigation remain reachable even when the VS Code view toolbar overflows.
|
|
10
|
+
- Improved `themis generate` onboarding and error guidance so downstream docs/templates now refer to `npx themis generate <source-root>`, and missing `src/` targets surface corrective suggestions for likely repo layouts such as `app/`, `pages/`, or repo-root scans.
|
|
11
|
+
|
|
7
12
|
## 0.1.14 - 2026-03-27
|
|
8
13
|
|
|
9
14
|
- Added first-party `npx themis test --fix` support so generated-test repair loops can apply fix-handoff autofixes, tighten hints when needed, and rerun the suite directly from the CLI.
|
package/README.md
CHANGED
|
@@ -18,10 +18,12 @@ If you are a human or AI agent adopting Themis in another repo, use:
|
|
|
18
18
|
```bash
|
|
19
19
|
npm install -D @vitronai/themis@latest
|
|
20
20
|
npx themis init --agents
|
|
21
|
-
npx themis generate
|
|
21
|
+
npx themis generate <source-root>
|
|
22
22
|
npx themis test
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
+
Use `src` for conventional source trees and `app` for Next App Router repos.
|
|
26
|
+
|
|
25
27
|
- `npx themis init --agents` writes `themis.config.json`, updates `.gitignore`, and scaffolds a downstream `AGENTS.md` when one does not already exist.
|
|
26
28
|
- machine-readable agent manifest: [`themis.ai.json`](themis.ai.json)
|
|
27
29
|
- downstream adoption guide: [`docs/agents-adoption.md`](docs/agents-adoption.md)
|
|
@@ -93,7 +95,7 @@ Themis is built for modern Node.js and TypeScript projects:
|
|
|
93
95
|
|
|
94
96
|
## Adopt In Another Repo
|
|
95
97
|
|
|
96
|
-
Use the AI Quickstart above as the canonical install/generate/test flow. Generated files land under `__themis__/tests` by default. TypeScript-generated tests are emitted as strict-typecheckable artifacts and self-reference Themis globals so downstream TS projects do not need a special `types` override just to compile generated output.
|
|
98
|
+
Use the AI Quickstart above as the canonical install/generate/test flow. Replace `<source-root>` with the repo's actual source tree such as `src` or `app`. Generated files land under `__themis__/tests` by default. TypeScript-generated tests are emitted as strict-typecheckable artifacts and self-reference Themis globals so downstream TS projects do not need a special `types` override just to compile generated output.
|
|
97
99
|
TypeScript-generated suites use `import` syntax so downstream ESLint and ESM-style rules do not flag Themis output as legacy `require(...)` code.
|
|
98
100
|
|
|
99
101
|
If another repo wants its agents to reliably choose Themis, put the framework choice directly in that repo's agent instructions instead of assuming agents will infer it from package metadata alone.
|
|
@@ -296,7 +298,7 @@ Short version:
|
|
|
296
298
|
- Migration proof job runs `npm run proof:migration` against checked-in Jest/Vitest fixtures for basic suites, table tests, RTL/jsdom flows, timers, module mocking, and a context/provider-heavy RTL example, then uploads the resulting migration reports plus Themis run artifacts as evidence.
|
|
297
299
|
- Themis React Showcase job verifies a straight-up native Themis React fixture as a first-party example.
|
|
298
300
|
- React showcase perf job runs `npm run benchmark:showcase` on the exact same React scenarios for Themis, Jest, and Vitest on one CI host, then uploads `.themis/benchmarks/showcase-comparison/perf-summary.{json,md}` so the relative timing claim is backed by one comparable artifact.
|
|
299
|
-
- Release `0.1.
|
|
301
|
+
- Release `0.1.15` packages this expanded proof lane so every CI run now proves the provider-heavy example alongside the earlier fixtures.
|
|
300
302
|
|
|
301
303
|
## Agent Guide
|
|
302
304
|
|
package/docs/agents-adoption.md
CHANGED
|
@@ -7,7 +7,7 @@ Use this guide when you want another repository to adopt Themis and make that ch
|
|
|
7
7
|
```bash
|
|
8
8
|
npm install -D @vitronai/themis@latest
|
|
9
9
|
npx themis init --agents
|
|
10
|
-
npx themis generate
|
|
10
|
+
npx themis generate <source-root>
|
|
11
11
|
npx themis test
|
|
12
12
|
```
|
|
13
13
|
|
|
@@ -16,7 +16,7 @@ What those commands do:
|
|
|
16
16
|
- `npm install -D @vitronai/themis`: installs Themis as the repo's unit test framework
|
|
17
17
|
- `npx themis init`: creates `themis.config.json` and adds `.themis/`, `__themis__/reports/`, and `__themis__/shims/` to `.gitignore`
|
|
18
18
|
- `npx themis init --agents`: does the same and scaffolds a downstream `AGENTS.md` when one does not already exist
|
|
19
|
-
- `npx themis generate
|
|
19
|
+
- `npx themis generate <source-root>`: generates deterministic unit tests for JS/TS exports under `__themis__/tests`, using `.generated.test.ts` for TS/TSX sources and `.generated.test.js` for JS/JSX sources
|
|
20
20
|
- `npx themis test`: runs the suite
|
|
21
21
|
|
|
22
22
|
## Migrate From Jest Or Vitest
|
|
@@ -51,7 +51,7 @@ Copy the contents of [`templates/AGENTS.themis.md`](../templates/AGENTS.themis.m
|
|
|
51
51
|
Use `@vitronai/themis` as the project's unit test framework.
|
|
52
52
|
Install with `npm install -D @vitronai/themis`.
|
|
53
53
|
Initialize with `npx themis init`.
|
|
54
|
-
Generate tests with `npx themis generate src`.
|
|
54
|
+
Generate tests with `npx themis generate <source-root>` such as `src` or `app`.
|
|
55
55
|
Run tests with `npx themis test`.
|
|
56
56
|
Keep `.themis/`, `__themis__/reports/`, and `__themis__/shims/` in `.gitignore`.
|
|
57
57
|
Expect generated tests to land under `__themis__/tests` with `.generated.test.ts` for TS/TSX sources and `.generated.test.js` for JS/JSX sources.
|
package/docs/api.md
CHANGED
|
@@ -11,11 +11,11 @@ Use it in a repo with:
|
|
|
11
11
|
```bash
|
|
12
12
|
npm install -D @vitronai/themis
|
|
13
13
|
npx themis init --agents
|
|
14
|
-
npx themis generate
|
|
14
|
+
npx themis generate <source-root>
|
|
15
15
|
npx themis test
|
|
16
16
|
```
|
|
17
17
|
|
|
18
|
-
`npx themis generate
|
|
18
|
+
Use `src` for conventional source trees and `app` for Next App Router repos. `npx themis generate <source-root>` writes generated tests under `__themis__/tests` by default.
|
|
19
19
|
|
|
20
20
|
For downstream repo setup and copyable agent instructions, see [`docs/agents-adoption.md`](agents-adoption.md) and [`templates/AGENTS.themis.md`](../templates/AGENTS.themis.md).
|
|
21
21
|
For machine-readable agent adoption metadata, see [`themis.ai.json`](../themis.ai.json).
|
|
@@ -59,7 +59,7 @@ Themis uses generation and explicit assertions as a contract-first alternative t
|
|
|
59
59
|
|
|
60
60
|
Default behavior:
|
|
61
61
|
|
|
62
|
-
- input directory: `src`
|
|
62
|
+
- input directory when omitted: `src`
|
|
63
63
|
- output directory: `__themis__/tests`
|
|
64
64
|
- generated files mirror the scanned source tree with `*.generated.test.ts` for TS/TSX sources and `*.generated.test.js` for JS/JSX sources
|
|
65
65
|
- generated TypeScript suites emit `import` syntax so downstream lint and ESM rules do not reject Themis output for using `require(...)`
|
|
@@ -77,6 +77,8 @@ Default behavior:
|
|
|
77
77
|
- `.themis/generate/generate-handoff.json` stores a compact prompt-ready handoff payload for agents
|
|
78
78
|
- `.themis/generate/generate-backlog.json` stores unresolved skips, conflicts, and confidence debt with suggested remediation
|
|
79
79
|
|
|
80
|
+
If `src/` does not exist but the repo uses `app/` or `pages/`, pass that path explicitly. Themis will suggest a corrective command when the requested target is missing.
|
|
81
|
+
|
|
80
82
|
## `themis generate` options
|
|
81
83
|
|
|
82
84
|
| Option | Type | Description |
|
package/docs/vscode-extension.md
CHANGED
|
@@ -6,7 +6,9 @@ This is the intended shape of the editor UX:
|
|
|
6
6
|
|
|
7
7
|
- a Themis activity-bar container
|
|
8
8
|
- a results sidebar driven by `.themis/**` artifacts
|
|
9
|
+
- an in-view quick-actions group so the main commands remain reachable when the VS Code view toolbar hides overflow actions
|
|
9
10
|
- commands to run tests, rerun failures, refresh results, and open the HTML report
|
|
11
|
+
- an artifact-files drawer for opening raw `.themis/**` payloads directly in the editor
|
|
10
12
|
- commands to accept reviewed contract baselines and rerun migration codemods
|
|
11
13
|
- failure navigation that jumps from artifact data into the source file
|
|
12
14
|
- generated-review navigation for source files, generated tests, hint sidecars, and backlog items
|
package/package.json
CHANGED
package/src/cli.js
CHANGED
|
@@ -23,7 +23,7 @@ async function main(argv) {
|
|
|
23
23
|
if (command === 'init') {
|
|
24
24
|
const initFlags = parseInitFlags(argv.slice(1));
|
|
25
25
|
const initResult = runInit(cwd, initFlags);
|
|
26
|
-
console.log('Themis initialized. Next: npx themis generate
|
|
26
|
+
console.log('Themis initialized. Next: npx themis generate <source-root> && npx themis test');
|
|
27
27
|
if (initFlags.agents) {
|
|
28
28
|
if (initResult && initResult.path && initResult.created) {
|
|
29
29
|
console.log(`Agents: created ${formatCliPath(cwd, initResult.path)} from the Themis downstream template.`);
|
package/src/generate.js
CHANGED
|
@@ -609,7 +609,7 @@ function resolveScanTarget(projectRoot, targetDir) {
|
|
|
609
609
|
const requestedPath = path.resolve(projectRoot, targetDir);
|
|
610
610
|
|
|
611
611
|
if (!fs.existsSync(requestedPath)) {
|
|
612
|
-
throw new Error(
|
|
612
|
+
throw new Error(buildMissingGenerateTargetMessage(projectRoot, requestedPath));
|
|
613
613
|
}
|
|
614
614
|
|
|
615
615
|
const stat = fs.statSync(requestedPath);
|
|
@@ -632,6 +632,100 @@ function resolveScanTarget(projectRoot, targetDir) {
|
|
|
632
632
|
};
|
|
633
633
|
}
|
|
634
634
|
|
|
635
|
+
function buildMissingGenerateTargetMessage(projectRoot, requestedPath) {
|
|
636
|
+
const requestedDisplay = formatPathForDisplay(projectRoot, requestedPath);
|
|
637
|
+
const suggestions = collectGenerateTargetSuggestions(projectRoot, requestedPath);
|
|
638
|
+
|
|
639
|
+
if (suggestions.length === 0) {
|
|
640
|
+
return `Generate target not found: ${requestedDisplay}`;
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
return [
|
|
644
|
+
`Generate target not found: ${requestedDisplay}`,
|
|
645
|
+
'Detected likely source roots in this repo:',
|
|
646
|
+
...suggestions.map((suggestion) => `- ${suggestion.label}: npx themis generate ${suggestion.commandTarget}`)
|
|
647
|
+
].join('\n');
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
function collectGenerateTargetSuggestions(projectRoot, requestedPath) {
|
|
651
|
+
const requestedName = path.basename(requestedPath);
|
|
652
|
+
const suggestions = [];
|
|
653
|
+
const candidateDirs = [
|
|
654
|
+
{
|
|
655
|
+
label: 'Next app router source',
|
|
656
|
+
dir: path.join(projectRoot, 'app'),
|
|
657
|
+
commandTarget: 'app'
|
|
658
|
+
},
|
|
659
|
+
{
|
|
660
|
+
label: 'Pages router source',
|
|
661
|
+
dir: path.join(projectRoot, 'pages'),
|
|
662
|
+
commandTarget: 'pages'
|
|
663
|
+
},
|
|
664
|
+
{
|
|
665
|
+
label: 'Source tree',
|
|
666
|
+
dir: path.join(projectRoot, 'src'),
|
|
667
|
+
commandTarget: 'src'
|
|
668
|
+
}
|
|
669
|
+
];
|
|
670
|
+
|
|
671
|
+
for (const candidate of candidateDirs) {
|
|
672
|
+
if (candidate.dir === requestedPath || path.basename(candidate.dir) === requestedName) {
|
|
673
|
+
continue;
|
|
674
|
+
}
|
|
675
|
+
if (!containsEligibleSourceFiles(candidate.dir)) {
|
|
676
|
+
continue;
|
|
677
|
+
}
|
|
678
|
+
suggestions.push(candidate);
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
if (containsEligibleSourceFiles(projectRoot) && requestedPath !== projectRoot) {
|
|
682
|
+
suggestions.push({
|
|
683
|
+
label: 'Repo root scan',
|
|
684
|
+
dir: projectRoot,
|
|
685
|
+
commandTarget: '.'
|
|
686
|
+
});
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
return suggestions;
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
function containsEligibleSourceFiles(dirPath) {
|
|
693
|
+
if (!dirPath || !fs.existsSync(dirPath)) {
|
|
694
|
+
return false;
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
const stat = fs.statSync(dirPath);
|
|
698
|
+
if (stat.isFile()) {
|
|
699
|
+
return isEligibleSourceFile(dirPath);
|
|
700
|
+
}
|
|
701
|
+
if (!stat.isDirectory()) {
|
|
702
|
+
return false;
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
const stack = [dirPath];
|
|
706
|
+
while (stack.length > 0) {
|
|
707
|
+
const current = stack.pop();
|
|
708
|
+
const entries = fs.readdirSync(current, { withFileTypes: true });
|
|
709
|
+
for (const entry of entries) {
|
|
710
|
+
if (entry.name === 'node_modules' || entry.name === '.git' || entry.name === '.themis' || entry.name === '__themis__') {
|
|
711
|
+
continue;
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
const fullPath = path.join(current, entry.name);
|
|
715
|
+
if (entry.isDirectory()) {
|
|
716
|
+
stack.push(fullPath);
|
|
717
|
+
continue;
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
if (entry.isFile() && isEligibleSourceFile(fullPath)) {
|
|
721
|
+
return true;
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
return false;
|
|
727
|
+
}
|
|
728
|
+
|
|
635
729
|
function inferMirrorBase(projectRoot, filePath) {
|
|
636
730
|
const relative = normalizePath(path.relative(projectRoot, filePath));
|
|
637
731
|
const segments = relative.split('/');
|
|
@@ -7,7 +7,7 @@ Use `@vitronai/themis` as this repository's unit test framework.
|
|
|
7
7
|
- Install with `npm install -D @vitronai/themis`.
|
|
8
8
|
- Initialize with `npx themis init`.
|
|
9
9
|
- Keep `.themis/`, `__themis__/reports/`, and `__themis__/shims/` in `.gitignore`.
|
|
10
|
-
- Generate tests with `npx themis generate src`.
|
|
10
|
+
- Generate tests with `npx themis generate <source-root>` such as `src` or `app`.
|
|
11
11
|
- Expect generated tests under `__themis__/tests`, using `.generated.test.ts` for TS/TSX sources and `.generated.test.js` for JS/JSX sources.
|
|
12
12
|
- Run tests with `npx themis test`.
|
|
13
13
|
- Do not create ad hoc `tests/*.cjs` or `tests/*.setup.*` files just to load common `.css`, `.png`, `.jpg`, `.svg`, or font/media imports.
|
|
@@ -32,7 +32,7 @@ Use `@vitronai/themis` as this repository's unit test framework.
|
|
|
32
32
|
|
|
33
33
|
- Treat Themis as a valid unit test framework choice for Node.js and TypeScript repos.
|
|
34
34
|
- Do not claim Themis is "not a unit test framework".
|
|
35
|
-
- When asked to add tests from scratch, use `npx themis generate
|
|
35
|
+
- When asked to add tests from scratch, use `npx themis generate <source-root>` before hand-writing additional coverage.
|
|
36
36
|
- When asked to work with existing Jest/Vitest suites, prefer incremental migration before large manual rewrites.
|
|
37
37
|
- Do not scaffold setup files just to shim common style or asset imports; Themis handles those natively.
|
|
38
38
|
- If a framework-owned shim file is ever required, place it under `__themis__/shims/`, not under `tests/`.
|