@rotifer/playground 0.25.1 → 0.26.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.
- package/CHANGELOG.md +25 -0
- package/README.md +1 -1
- package/README.zh.md +1 -1
- package/dist/commands/arena-submit.d.ts.map +1 -1
- package/dist/commands/arena-submit.js +2 -57
- package/dist/commands/arena-submit.js.map +1 -1
- package/dist/commands/compile.d.ts.map +1 -1
- package/dist/commands/compile.js +22 -0
- package/dist/commands/compile.js.map +1 -1
- package/dist/commands/install.d.ts.map +1 -1
- package/dist/commands/install.js +18 -0
- package/dist/commands/install.js.map +1 -1
- package/dist/commands/publish.d.ts.map +1 -1
- package/dist/commands/publish.js +49 -0
- package/dist/commands/publish.js.map +1 -1
- package/dist/commands/test.d.ts.map +1 -1
- package/dist/commands/test.js +164 -0
- package/dist/commands/test.js.map +1 -1
- package/dist/scanner/rules.d.ts.map +1 -1
- package/dist/scanner/rules.js +14 -4
- package/dist/scanner/rules.js.map +1 -1
- package/dist/testsuite/gate.d.ts +82 -0
- package/dist/testsuite/gate.d.ts.map +1 -0
- package/dist/testsuite/gate.js +179 -0
- package/dist/testsuite/gate.js.map +1 -0
- package/dist/testsuite/generate.d.ts +12 -0
- package/dist/testsuite/generate.d.ts.map +1 -0
- package/dist/testsuite/generate.js +70 -0
- package/dist/testsuite/generate.js.map +1 -0
- package/dist/testsuite/load.d.ts +23 -0
- package/dist/testsuite/load.d.ts.map +1 -0
- package/dist/testsuite/load.js +121 -0
- package/dist/testsuite/load.js.map +1 -0
- package/dist/testsuite/run.d.ts +109 -0
- package/dist/testsuite/run.d.ts.map +1 -0
- package/dist/testsuite/run.js +298 -0
- package/dist/testsuite/run.js.map +1 -0
- package/dist/testsuite/scaffold.d.ts +20 -0
- package/dist/testsuite/scaffold.d.ts.map +1 -0
- package/dist/testsuite/scaffold.js +146 -0
- package/dist/testsuite/scaffold.js.map +1 -0
- package/dist/testsuite/types.d.ts +67 -0
- package/dist/testsuite/types.d.ts.map +1 -0
- package/dist/testsuite/types.js +19 -0
- package/dist/testsuite/types.js.map +1 -0
- package/dist/utils/artifact-consistency.d.ts +37 -0
- package/dist/utils/artifact-consistency.d.ts.map +1 -0
- package/dist/utils/artifact-consistency.js +43 -0
- package/dist/utils/artifact-consistency.js.map +1 -0
- package/genes/genesis-code-format/.cloud-manifest.json +4 -4
- package/genes/genesis-code-format/index.ts +24 -6
- package/genes/genesis-code-format/phenotype.json +36 -7
- package/genes/genesis-code-format/testsuite.json +25 -0
- package/genes/genesis-file-read/.cloud-manifest.json +4 -4
- package/genes/genesis-file-read/index.ts +21 -2
- package/genes/genesis-file-read/phenotype.json +32 -8
- package/genes/genesis-file-read/testsuite.json +41 -0
- package/genes/genesis-web-search/.cloud-manifest.json +4 -4
- package/genes/genesis-web-search/index.ts +23 -4
- package/genes/genesis-web-search/phenotype.json +36 -9
- package/genes/genesis-web-search/testsuite.json +82 -0
- package/genes/genesis-web-search-lite/.cloud-manifest.json +4 -4
- package/genes/genesis-web-search-lite/index.ts +14 -2
- package/genes/genesis-web-search-lite/phenotype.json +21 -5
- package/genes/genesis-web-search-lite/testsuite.json +24 -0
- package/package.json +12 -7
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"testCases": [
|
|
3
|
+
{
|
|
4
|
+
"input": { "path": "package.json" },
|
|
5
|
+
"expectedSchema": {
|
|
6
|
+
"type": "object",
|
|
7
|
+
"required": ["content", "size", "encoding"],
|
|
8
|
+
"properties": {
|
|
9
|
+
"content": { "type": "string", "pattern": "@rotifer/playground" },
|
|
10
|
+
"size": { "type": "integer", "minimum": 1 },
|
|
11
|
+
"encoding": { "const": "utf-8" }
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"input": { "path": 42 },
|
|
17
|
+
"expectedOutput": {
|
|
18
|
+
"content": "[error] INVALID_PATH: path must be a non-empty string",
|
|
19
|
+
"size": 0,
|
|
20
|
+
"encoding": "utf-8"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"input": { "encoding": "utf-8" },
|
|
25
|
+
"expectedOutput": {
|
|
26
|
+
"content": "[error] INVALID_PATH: path must be a non-empty string",
|
|
27
|
+
"size": 0,
|
|
28
|
+
"encoding": "utf-8"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"input": {},
|
|
33
|
+
"expectedOutput": {
|
|
34
|
+
"content": "[error] INVALID_PATH: path must be a non-empty string",
|
|
35
|
+
"size": 0,
|
|
36
|
+
"encoding": "utf-8"
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
],
|
|
40
|
+
"config": { "fuzzIterations": 10, "seed": 1 }
|
|
41
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"cloud_id": "
|
|
3
|
-
"owner": "
|
|
4
|
-
"version": "0.
|
|
5
|
-
"published_at": "2026-
|
|
2
|
+
"cloud_id": "ebb624a7-56aa-47be-8d98-52130e8d81c1",
|
|
3
|
+
"owner": "xiaoba-dev",
|
|
4
|
+
"version": "0.2.0",
|
|
5
|
+
"published_at": "2026-09-08T15:37:15.392Z"
|
|
6
6
|
}
|
|
@@ -23,12 +23,31 @@ interface SearchOutput {
|
|
|
23
23
|
*/
|
|
24
24
|
export function express(input: SearchInput): SearchOutput {
|
|
25
25
|
const start = Date.now();
|
|
26
|
-
|
|
26
|
+
|
|
27
|
+
// `input.query` used to be interpolated straight into the result strings, so
|
|
28
|
+
// a missing field produced a simulated search for the literal "undefined" and
|
|
29
|
+
// a numeric one searched for "42". Neither is a search; both are the Gene
|
|
30
|
+
// answering confidently about a question nobody asked.
|
|
31
|
+
//
|
|
32
|
+
// Unlike a Gene with a documented default, there is nothing sensible to
|
|
33
|
+
// search for in place of a query, so this refuses: no query, no results. The
|
|
34
|
+
// shape still conforms to outputSchema, which is what "correct handling"
|
|
35
|
+
// means on this boundary (ADR-333).
|
|
36
|
+
const query: unknown = input.query;
|
|
37
|
+
if (typeof query !== "string" || query.trim() === "") {
|
|
38
|
+
return { results: [], totalResults: 0, searchTime: Date.now() - start };
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const rawMax: unknown = input.maxResults;
|
|
42
|
+
const max =
|
|
43
|
+
typeof rawMax === "number" && Number.isInteger(rawMax) && rawMax > 0
|
|
44
|
+
? Math.min(rawMax, 20)
|
|
45
|
+
: 5;
|
|
27
46
|
|
|
28
47
|
const results: SearchResult[] = Array.from({ length: max }, (_, i) => ({
|
|
29
|
-
title: `Result ${i + 1} for "${
|
|
30
|
-
url: `https://example.com/search?q=${encodeURIComponent(
|
|
31
|
-
snippet: `This is a simulated search result #${i + 1} for the query "${
|
|
48
|
+
title: `Result ${i + 1} for "${query}"`,
|
|
49
|
+
url: `https://example.com/search?q=${encodeURIComponent(query)}&p=${i + 1}`,
|
|
50
|
+
snippet: `This is a simulated search result #${i + 1} for the query "${query}". In production, this gene binds to a real search provider.`,
|
|
32
51
|
}));
|
|
33
52
|
|
|
34
53
|
return {
|
|
@@ -4,10 +4,20 @@
|
|
|
4
4
|
"inputSchema": {
|
|
5
5
|
"type": "object",
|
|
6
6
|
"properties": {
|
|
7
|
-
"query": {
|
|
8
|
-
|
|
7
|
+
"query": {
|
|
8
|
+
"type": "string",
|
|
9
|
+
"description": "Search query string"
|
|
10
|
+
},
|
|
11
|
+
"maxResults": {
|
|
12
|
+
"type": "integer",
|
|
13
|
+
"default": 5,
|
|
14
|
+
"minimum": 1,
|
|
15
|
+
"maximum": 20
|
|
16
|
+
}
|
|
9
17
|
},
|
|
10
|
-
"required": [
|
|
18
|
+
"required": [
|
|
19
|
+
"query"
|
|
20
|
+
]
|
|
11
21
|
},
|
|
12
22
|
"outputSchema": {
|
|
13
23
|
"type": "object",
|
|
@@ -17,14 +27,24 @@
|
|
|
17
27
|
"items": {
|
|
18
28
|
"type": "object",
|
|
19
29
|
"properties": {
|
|
20
|
-
"title": {
|
|
21
|
-
|
|
22
|
-
|
|
30
|
+
"title": {
|
|
31
|
+
"type": "string"
|
|
32
|
+
},
|
|
33
|
+
"url": {
|
|
34
|
+
"type": "string"
|
|
35
|
+
},
|
|
36
|
+
"snippet": {
|
|
37
|
+
"type": "string"
|
|
38
|
+
}
|
|
23
39
|
}
|
|
24
40
|
}
|
|
25
41
|
},
|
|
26
|
-
"totalResults": {
|
|
27
|
-
|
|
42
|
+
"totalResults": {
|
|
43
|
+
"type": "integer"
|
|
44
|
+
},
|
|
45
|
+
"searchTime": {
|
|
46
|
+
"type": "number"
|
|
47
|
+
}
|
|
28
48
|
}
|
|
29
49
|
},
|
|
30
50
|
"dependencies": [],
|
|
@@ -38,5 +58,12 @@
|
|
|
38
58
|
"concurrencyModel": "Stateless",
|
|
39
59
|
"failureSemantics": "Retry"
|
|
40
60
|
},
|
|
41
|
-
"tags": [
|
|
61
|
+
"tags": [
|
|
62
|
+
"web-search",
|
|
63
|
+
"results",
|
|
64
|
+
"snippets",
|
|
65
|
+
"async",
|
|
66
|
+
"retrieval"
|
|
67
|
+
],
|
|
68
|
+
"irHash": "9af9ccc90df36c586661876203b87f182c9fac65ebcfdec22c1e0d683be19b49"
|
|
42
69
|
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
{
|
|
2
|
+
"testCases": [
|
|
3
|
+
{
|
|
4
|
+
"input": {
|
|
5
|
+
"query": "rotifer protocol",
|
|
6
|
+
"maxResults": 2
|
|
7
|
+
},
|
|
8
|
+
"expectedSchema": {
|
|
9
|
+
"type": "object",
|
|
10
|
+
"required": [
|
|
11
|
+
"results",
|
|
12
|
+
"totalResults"
|
|
13
|
+
],
|
|
14
|
+
"properties": {
|
|
15
|
+
"totalResults": {
|
|
16
|
+
"const": 2
|
|
17
|
+
},
|
|
18
|
+
"results": {
|
|
19
|
+
"type": "array",
|
|
20
|
+
"minItems": 2,
|
|
21
|
+
"items": {
|
|
22
|
+
"properties": {
|
|
23
|
+
"title": {
|
|
24
|
+
"pattern": "rotifer protocol"
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"input": {
|
|
34
|
+
"maxResults": 3
|
|
35
|
+
},
|
|
36
|
+
"expectedSchema": {
|
|
37
|
+
"type": "object",
|
|
38
|
+
"required": [
|
|
39
|
+
"results",
|
|
40
|
+
"totalResults"
|
|
41
|
+
],
|
|
42
|
+
"properties": {
|
|
43
|
+
"totalResults": {
|
|
44
|
+
"const": 0
|
|
45
|
+
},
|
|
46
|
+
"results": {
|
|
47
|
+
"type": "array",
|
|
48
|
+
"maxItems": 0
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"input": {
|
|
55
|
+
"query": 42
|
|
56
|
+
},
|
|
57
|
+
"expectedSchema": {
|
|
58
|
+
"type": "object",
|
|
59
|
+
"properties": {
|
|
60
|
+
"totalResults": {
|
|
61
|
+
"const": 0
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"input": {},
|
|
68
|
+
"expectedSchema": {
|
|
69
|
+
"type": "object",
|
|
70
|
+
"properties": {
|
|
71
|
+
"totalResults": {
|
|
72
|
+
"const": 0
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
],
|
|
78
|
+
"config": {
|
|
79
|
+
"fuzzIterations": 10,
|
|
80
|
+
"seed": 1
|
|
81
|
+
}
|
|
82
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"cloud_id": "
|
|
3
|
-
"owner": "
|
|
4
|
-
"version": "0.
|
|
5
|
-
"published_at": "2026-
|
|
2
|
+
"cloud_id": "9f3410dc-4edb-492e-bdd6-fb103fd106e1",
|
|
3
|
+
"owner": "xiaoba-dev",
|
|
4
|
+
"version": "0.2.0",
|
|
5
|
+
"published_at": "2026-09-08T15:37:48.867Z"
|
|
6
6
|
}
|
|
@@ -15,8 +15,20 @@ interface LiteSearchOutput {
|
|
|
15
15
|
* with deadline constraints.
|
|
16
16
|
*/
|
|
17
17
|
export function express(input: LiteSearchInput): LiteSearchOutput {
|
|
18
|
+
// Same defect as genesis-web-search: a missing query became a confident
|
|
19
|
+
// answer about "undefined". With no default query to fall back on, saying so
|
|
20
|
+
// is the only honest response — and it stays inside outputSchema, which is
|
|
21
|
+
// what refusal has to look like on this boundary (ADR-333).
|
|
22
|
+
const query: unknown = input.query;
|
|
23
|
+
if (typeof query !== "string" || query.trim() === "") {
|
|
24
|
+
return {
|
|
25
|
+
answer: "No query provided.",
|
|
26
|
+
source: "",
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
18
30
|
return {
|
|
19
|
-
answer: `[Simulated] Quick answer for "${
|
|
20
|
-
source: "https://example.com/instant?q=" + encodeURIComponent(
|
|
31
|
+
answer: `[Simulated] Quick answer for "${query}": This is a placeholder response from genesis-web-search-lite. In production, this returns a concise answer from a search provider.`,
|
|
32
|
+
source: "https://example.com/instant?q=" + encodeURIComponent(query),
|
|
21
33
|
};
|
|
22
34
|
}
|
|
@@ -4,15 +4,24 @@
|
|
|
4
4
|
"inputSchema": {
|
|
5
5
|
"type": "object",
|
|
6
6
|
"properties": {
|
|
7
|
-
"query": {
|
|
7
|
+
"query": {
|
|
8
|
+
"type": "string",
|
|
9
|
+
"description": "Search query string"
|
|
10
|
+
}
|
|
8
11
|
},
|
|
9
|
-
"required": [
|
|
12
|
+
"required": [
|
|
13
|
+
"query"
|
|
14
|
+
]
|
|
10
15
|
},
|
|
11
16
|
"outputSchema": {
|
|
12
17
|
"type": "object",
|
|
13
18
|
"properties": {
|
|
14
|
-
"answer": {
|
|
15
|
-
|
|
19
|
+
"answer": {
|
|
20
|
+
"type": "string"
|
|
21
|
+
},
|
|
22
|
+
"source": {
|
|
23
|
+
"type": "string"
|
|
24
|
+
}
|
|
16
25
|
}
|
|
17
26
|
},
|
|
18
27
|
"dependencies": [],
|
|
@@ -25,5 +34,12 @@
|
|
|
25
34
|
"concurrencyModel": "Stateless",
|
|
26
35
|
"failureSemantics": "SILENT_DEGRADE"
|
|
27
36
|
},
|
|
28
|
-
"tags": [
|
|
37
|
+
"tags": [
|
|
38
|
+
"web-search",
|
|
39
|
+
"single-answer",
|
|
40
|
+
"attribution",
|
|
41
|
+
"lightweight",
|
|
42
|
+
"async"
|
|
43
|
+
],
|
|
44
|
+
"irHash": "e1bae37cdb28cdce1c4a3631bcb9e58eb8009a01d3d8f4c6b7f1555d38fd040d"
|
|
29
45
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"testCases": [
|
|
3
|
+
{
|
|
4
|
+
"input": { "query": "rotifer protocol" },
|
|
5
|
+
"expectedSchema": {
|
|
6
|
+
"type": "object",
|
|
7
|
+
"required": ["answer", "source"],
|
|
8
|
+
"properties": {
|
|
9
|
+
"answer": { "type": "string", "pattern": "rotifer protocol" },
|
|
10
|
+
"source": { "type": "string", "minLength": 1 }
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"input": { "query": 42 },
|
|
16
|
+
"expectedOutput": { "answer": "No query provided.", "source": "" }
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"input": {},
|
|
20
|
+
"expectedOutput": { "answer": "No query provided.", "source": "" }
|
|
21
|
+
}
|
|
22
|
+
],
|
|
23
|
+
"config": { "fuzzIterations": 10, "seed": 1 }
|
|
24
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rotifer/playground",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.26.0",
|
|
4
4
|
"description": "Rotifer Protocol Playground — local development environment for gene development, Arena competition, and protocol simulation",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Rotifer Protocol Contributors",
|
|
@@ -71,26 +71,31 @@
|
|
|
71
71
|
"chalk": "^4.1.2",
|
|
72
72
|
"commander": "^15.0.0"
|
|
73
73
|
},
|
|
74
|
+
"overrides": {
|
|
75
|
+
"js-yaml": "^4.3.2",
|
|
76
|
+
"qs": "^6.16.0",
|
|
77
|
+
"@humanfs/node": "^0.16.8"
|
|
78
|
+
},
|
|
74
79
|
"devDependencies": {
|
|
75
80
|
"@napi-rs/cli": "^3.7.0",
|
|
76
81
|
"@stryker-mutator/core": "10.0.0",
|
|
77
82
|
"@stryker-mutator/vitest-runner": "10.0.0",
|
|
78
83
|
"@supabase/supabase-js": "^2.105.4",
|
|
79
84
|
"@types/node": "^25.9.2",
|
|
80
|
-
"@vitest/coverage-v8": "^4.1.
|
|
85
|
+
"@vitest/coverage-v8": "^4.1.11",
|
|
81
86
|
"esbuild": "^0.28.1",
|
|
82
87
|
"eslint": "^10.1.0",
|
|
83
88
|
"javy-cli": "^3.0.1",
|
|
84
89
|
"typescript": "^6.0.3",
|
|
85
90
|
"typescript-eslint": "^8.58.0",
|
|
86
|
-
"vitest": "^4.
|
|
91
|
+
"vitest": "^4.1.11"
|
|
87
92
|
},
|
|
88
93
|
"optionalDependencies": {
|
|
89
94
|
"@rolldown/binding-linux-x64-gnu": "1.1.1",
|
|
90
|
-
"@rotifer/playground-darwin-arm64": "0.
|
|
91
|
-
"@rotifer/playground-darwin-x64": "0.
|
|
92
|
-
"@rotifer/playground-linux-x64-gnu": "0.
|
|
93
|
-
"@rotifer/playground-win32-x64-msvc": "0.
|
|
95
|
+
"@rotifer/playground-darwin-arm64": "0.26.0",
|
|
96
|
+
"@rotifer/playground-darwin-x64": "0.26.0",
|
|
97
|
+
"@rotifer/playground-linux-x64-gnu": "0.26.0",
|
|
98
|
+
"@rotifer/playground-win32-x64-msvc": "0.26.0"
|
|
94
99
|
},
|
|
95
100
|
"engines": {
|
|
96
101
|
"node": ">=22.18.0"
|