@rotifer/playground 0.1.0-alpha.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.
- package/CHANGELOG.md +62 -0
- package/LICENSE +31 -0
- package/README.md +230 -0
- package/dist/commands/agent-create.d.ts +3 -0
- package/dist/commands/agent-create.d.ts.map +1 -0
- package/dist/commands/agent-create.js +86 -0
- package/dist/commands/agent-create.js.map +1 -0
- package/dist/commands/agent-list.d.ts +3 -0
- package/dist/commands/agent-list.d.ts.map +1 -0
- package/dist/commands/agent-list.js +83 -0
- package/dist/commands/agent-list.js.map +1 -0
- package/dist/commands/arena-list.d.ts +3 -0
- package/dist/commands/arena-list.d.ts.map +1 -0
- package/dist/commands/arena-list.js +116 -0
- package/dist/commands/arena-list.js.map +1 -0
- package/dist/commands/arena-submit.d.ts +3 -0
- package/dist/commands/arena-submit.d.ts.map +1 -0
- package/dist/commands/arena-submit.js +106 -0
- package/dist/commands/arena-submit.js.map +1 -0
- package/dist/commands/arena-watch.d.ts +3 -0
- package/dist/commands/arena-watch.d.ts.map +1 -0
- package/dist/commands/arena-watch.js +56 -0
- package/dist/commands/arena-watch.js.map +1 -0
- package/dist/commands/compile.d.ts +3 -0
- package/dist/commands/compile.d.ts.map +1 -0
- package/dist/commands/compile.js +107 -0
- package/dist/commands/compile.js.map +1 -0
- package/dist/commands/init.d.ts +3 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +215 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/scan.d.ts +3 -0
- package/dist/commands/scan.d.ts.map +1 -0
- package/dist/commands/scan.js +106 -0
- package/dist/commands/scan.js.map +1 -0
- package/dist/commands/test.d.ts +3 -0
- package/dist/commands/test.d.ts.map +1 -0
- package/dist/commands/test.js +155 -0
- package/dist/commands/test.js.map +1 -0
- package/dist/commands/wrap.d.ts +3 -0
- package/dist/commands/wrap.d.ts.map +1 -0
- package/dist/commands/wrap.js +94 -0
- package/dist/commands/wrap.js.map +1 -0
- package/dist/errors/formatter.d.ts +25 -0
- package/dist/errors/formatter.d.ts.map +1 -0
- package/dist/errors/formatter.js +43 -0
- package/dist/errors/formatter.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +36 -0
- package/dist/index.js.map +1 -0
- package/dist/utils/config.d.ts +12 -0
- package/dist/utils/config.d.ts.map +1 -0
- package/dist/utils/config.js +40 -0
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/display.d.ts +16 -0
- package/dist/utils/display.d.ts.map +1 -0
- package/dist/utils/display.js +56 -0
- package/dist/utils/display.js.map +1 -0
- package/genes/genesis-code-format/index.ts +42 -0
- package/genes/genesis-code-format/phenotype.json +29 -0
- package/genes/genesis-file-read/index.ts +33 -0
- package/genes/genesis-file-read/phenotype.json +29 -0
- package/genes/genesis-l0-constraint/index.ts +62 -0
- package/genes/genesis-l0-constraint/phenotype.json +37 -0
- package/genes/genesis-web-search/index.ts +39 -0
- package/genes/genesis-web-search/phenotype.json +40 -0
- package/genes/genesis-web-search-lite/index.ts +22 -0
- package/genes/genesis-web-search-lite/phenotype.json +27 -0
- package/package.json +72 -0
- package/templates/composition/par-example.json +11 -0
- package/templates/composition/seq-example.json +9 -0
- package/templates/gene/index.ts +13 -0
- package/templates/gene/phenotype.json +21 -0
- package/templates/gene/test.ts +15 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.success = success;
|
|
7
|
+
exports.error = error;
|
|
8
|
+
exports.info = info;
|
|
9
|
+
exports.warn = warn;
|
|
10
|
+
exports.header = header;
|
|
11
|
+
exports.keyValue = keyValue;
|
|
12
|
+
exports.geneId = geneId;
|
|
13
|
+
exports.rustStyleError = rustStyleError;
|
|
14
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
15
|
+
function success(message) {
|
|
16
|
+
console.log(chalk_1.default.green("✓") + " " + message);
|
|
17
|
+
}
|
|
18
|
+
function error(message, detail) {
|
|
19
|
+
console.error(chalk_1.default.red("✗") + " " + chalk_1.default.red(message));
|
|
20
|
+
if (detail) {
|
|
21
|
+
console.error(chalk_1.default.dim(" → " + detail));
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function info(message) {
|
|
25
|
+
console.log(chalk_1.default.blue("ℹ") + " " + message);
|
|
26
|
+
}
|
|
27
|
+
function warn(message) {
|
|
28
|
+
console.log(chalk_1.default.yellow("⚠") + " " + message);
|
|
29
|
+
}
|
|
30
|
+
function header(title) {
|
|
31
|
+
console.log();
|
|
32
|
+
console.log(chalk_1.default.bold.cyan(` ${title}`));
|
|
33
|
+
console.log(chalk_1.default.dim(" " + "─".repeat(title.length + 2)));
|
|
34
|
+
}
|
|
35
|
+
function keyValue(key, value) {
|
|
36
|
+
console.log(` ${chalk_1.default.dim(key + ":")} ${value}`);
|
|
37
|
+
}
|
|
38
|
+
function geneId(id) {
|
|
39
|
+
return chalk_1.default.yellow(id.slice(0, 12) + "…");
|
|
40
|
+
}
|
|
41
|
+
function rustStyleError(opts) {
|
|
42
|
+
console.error();
|
|
43
|
+
console.error(chalk_1.default.red.bold(`error[${opts.code}]`) + chalk_1.default.bold(`: ${opts.message}`));
|
|
44
|
+
if (opts.file) {
|
|
45
|
+
console.error(chalk_1.default.blue(" --> ") + opts.file + (opts.line ? `:${opts.line}` : ""));
|
|
46
|
+
}
|
|
47
|
+
if (opts.suggestion) {
|
|
48
|
+
console.error();
|
|
49
|
+
console.error(chalk_1.default.green("help") + `: ${opts.suggestion}`);
|
|
50
|
+
}
|
|
51
|
+
if (opts.docsUrl) {
|
|
52
|
+
console.error(chalk_1.default.dim("docs") + `: ${opts.docsUrl}`);
|
|
53
|
+
}
|
|
54
|
+
console.error();
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=display.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"display.js","sourceRoot":"","sources":["../../src/utils/display.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
interface CodeFormatInput {
|
|
2
|
+
code: string;
|
|
3
|
+
language: "typescript" | "javascript" | "json" | "markdown" | "rust";
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
interface CodeFormatOutput {
|
|
7
|
+
formatted: string;
|
|
8
|
+
changed: boolean;
|
|
9
|
+
language: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Genesis Gene: Code Format
|
|
14
|
+
*
|
|
15
|
+
* Formats source code. MVP uses simple heuristic formatting.
|
|
16
|
+
* Production binding would delegate to prettier/rustfmt/etc.
|
|
17
|
+
*/
|
|
18
|
+
export async function express(input: CodeFormatInput): Promise<CodeFormatOutput> {
|
|
19
|
+
let formatted: string;
|
|
20
|
+
|
|
21
|
+
switch (input.language) {
|
|
22
|
+
case "json":
|
|
23
|
+
try {
|
|
24
|
+
formatted = JSON.stringify(JSON.parse(input.code), null, 2);
|
|
25
|
+
} catch {
|
|
26
|
+
formatted = input.code;
|
|
27
|
+
}
|
|
28
|
+
break;
|
|
29
|
+
default:
|
|
30
|
+
formatted = input.code
|
|
31
|
+
.replace(/\t/g, " ")
|
|
32
|
+
.replace(/[ \t]+$/gm, "")
|
|
33
|
+
.replace(/\n{3,}/g, "\n\n");
|
|
34
|
+
break;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return {
|
|
38
|
+
formatted,
|
|
39
|
+
changed: formatted !== input.code,
|
|
40
|
+
language: input.language,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"domain": "tooling",
|
|
3
|
+
"inputSchema": {
|
|
4
|
+
"type": "object",
|
|
5
|
+
"properties": {
|
|
6
|
+
"code": { "type": "string", "description": "Source code to format" },
|
|
7
|
+
"language": { "type": "string", "description": "Programming language", "enum": ["typescript", "javascript", "json", "markdown", "rust"] }
|
|
8
|
+
},
|
|
9
|
+
"required": ["code", "language"]
|
|
10
|
+
},
|
|
11
|
+
"outputSchema": {
|
|
12
|
+
"type": "object",
|
|
13
|
+
"properties": {
|
|
14
|
+
"formatted": { "type": "string" },
|
|
15
|
+
"changed": { "type": "boolean" },
|
|
16
|
+
"language": { "type": "string" }
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"dependencies": [],
|
|
20
|
+
"version": "0.1.0",
|
|
21
|
+
"author": "rotifer-genesis",
|
|
22
|
+
"fidelity": "Native",
|
|
23
|
+
"transparency": "Open",
|
|
24
|
+
"semantic_requirements": {
|
|
25
|
+
"timeModel": "Sync",
|
|
26
|
+
"concurrencyModel": "Stateless",
|
|
27
|
+
"failureSemantics": "Fail"
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
|
|
3
|
+
interface FileReadInput {
|
|
4
|
+
path: string;
|
|
5
|
+
encoding?: "utf-8" | "base64";
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
interface FileReadOutput {
|
|
9
|
+
content: string;
|
|
10
|
+
size: number;
|
|
11
|
+
encoding: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Genesis Gene: File Read
|
|
16
|
+
*
|
|
17
|
+
* Reads a local file and returns its contents.
|
|
18
|
+
* Restricted by L0 sandbox constraints (path allowlist).
|
|
19
|
+
*/
|
|
20
|
+
export async function express(input: FileReadInput): Promise<FileReadOutput> {
|
|
21
|
+
const encoding = input.encoding ?? "utf-8";
|
|
22
|
+
const buffer = readFileSync(input.path);
|
|
23
|
+
|
|
24
|
+
const content = encoding === "base64"
|
|
25
|
+
? buffer.toString("base64")
|
|
26
|
+
: buffer.toString("utf-8");
|
|
27
|
+
|
|
28
|
+
return {
|
|
29
|
+
content,
|
|
30
|
+
size: buffer.length,
|
|
31
|
+
encoding,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"domain": "filesystem",
|
|
3
|
+
"inputSchema": {
|
|
4
|
+
"type": "object",
|
|
5
|
+
"properties": {
|
|
6
|
+
"path": { "type": "string", "description": "File path to read" },
|
|
7
|
+
"encoding": { "type": "string", "default": "utf-8", "enum": ["utf-8", "base64"] }
|
|
8
|
+
},
|
|
9
|
+
"required": ["path"]
|
|
10
|
+
},
|
|
11
|
+
"outputSchema": {
|
|
12
|
+
"type": "object",
|
|
13
|
+
"properties": {
|
|
14
|
+
"content": { "type": "string" },
|
|
15
|
+
"size": { "type": "integer" },
|
|
16
|
+
"encoding": { "type": "string" }
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"dependencies": [],
|
|
20
|
+
"version": "0.1.0",
|
|
21
|
+
"author": "rotifer-genesis",
|
|
22
|
+
"fidelity": "Native",
|
|
23
|
+
"transparency": "Open",
|
|
24
|
+
"semantic_requirements": {
|
|
25
|
+
"timeModel": "Sync",
|
|
26
|
+
"concurrencyModel": "Stateless",
|
|
27
|
+
"failureSemantics": "Fail"
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
interface ConstraintCheckInput {
|
|
2
|
+
geneId: string;
|
|
3
|
+
constraints?: {
|
|
4
|
+
maxMemoryBytes?: number;
|
|
5
|
+
maxFuel?: number;
|
|
6
|
+
allowedHostFunctions?: string[];
|
|
7
|
+
deniedHostFunctions?: string[];
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
interface ConstraintCheckOutput {
|
|
12
|
+
compliant: boolean;
|
|
13
|
+
violations: string[];
|
|
14
|
+
constraintSet: {
|
|
15
|
+
maxMemoryBytes: number;
|
|
16
|
+
maxFuel: number;
|
|
17
|
+
allowedHostFunctions: string[];
|
|
18
|
+
deniedHostFunctions: string[];
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const DEFAULT_MAX_MEMORY = 16 * 1024 * 1024; // 16 MiB
|
|
23
|
+
const DEFAULT_MAX_FUEL = 1_000_000;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Genesis Gene: L0 Constraint Checker
|
|
27
|
+
*
|
|
28
|
+
* Validates that a gene's resource usage profile conforms to L0 sandbox
|
|
29
|
+
* constraints. This is a meta-gene used by the Arena admission process
|
|
30
|
+
* and the testing framework.
|
|
31
|
+
*/
|
|
32
|
+
export async function express(input: ConstraintCheckInput): Promise<ConstraintCheckOutput> {
|
|
33
|
+
const maxMem = input.constraints?.maxMemoryBytes ?? DEFAULT_MAX_MEMORY;
|
|
34
|
+
const maxFuel = input.constraints?.maxFuel ?? DEFAULT_MAX_FUEL;
|
|
35
|
+
const allowed = input.constraints?.allowedHostFunctions ?? [];
|
|
36
|
+
const denied = input.constraints?.deniedHostFunctions ?? ["fs.write", "net.listen", "process.exit"];
|
|
37
|
+
|
|
38
|
+
const violations: string[] = [];
|
|
39
|
+
|
|
40
|
+
if (!input.geneId || input.geneId.length !== 64) {
|
|
41
|
+
violations.push("Invalid gene ID format (expected 64-char hex)");
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (maxMem > 256 * 1024 * 1024) {
|
|
45
|
+
violations.push(`Memory limit ${maxMem} exceeds protocol maximum (256 MiB)`);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (maxFuel > 100_000_000) {
|
|
49
|
+
violations.push(`Fuel limit ${maxFuel} exceeds protocol maximum (100M)`);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return {
|
|
53
|
+
compliant: violations.length === 0,
|
|
54
|
+
violations,
|
|
55
|
+
constraintSet: {
|
|
56
|
+
maxMemoryBytes: maxMem,
|
|
57
|
+
maxFuel: maxFuel,
|
|
58
|
+
allowedHostFunctions: allowed,
|
|
59
|
+
deniedHostFunctions: denied,
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"domain": "safety",
|
|
3
|
+
"inputSchema": {
|
|
4
|
+
"type": "object",
|
|
5
|
+
"properties": {
|
|
6
|
+
"geneId": { "type": "string", "description": "Gene ID (hex) to check" },
|
|
7
|
+
"constraints": {
|
|
8
|
+
"type": "object",
|
|
9
|
+
"properties": {
|
|
10
|
+
"maxMemoryBytes": { "type": "integer", "default": 16777216 },
|
|
11
|
+
"maxFuel": { "type": "integer", "default": 1000000 },
|
|
12
|
+
"allowedHostFunctions": { "type": "array", "items": { "type": "string" } },
|
|
13
|
+
"deniedHostFunctions": { "type": "array", "items": { "type": "string" } }
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"required": ["geneId"]
|
|
18
|
+
},
|
|
19
|
+
"outputSchema": {
|
|
20
|
+
"type": "object",
|
|
21
|
+
"properties": {
|
|
22
|
+
"compliant": { "type": "boolean" },
|
|
23
|
+
"violations": { "type": "array", "items": { "type": "string" } },
|
|
24
|
+
"constraintSet": { "type": "object" }
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"dependencies": [],
|
|
28
|
+
"version": "0.1.0",
|
|
29
|
+
"author": "rotifer-genesis",
|
|
30
|
+
"fidelity": "Native",
|
|
31
|
+
"transparency": "Open",
|
|
32
|
+
"semantic_requirements": {
|
|
33
|
+
"timeModel": "Sync",
|
|
34
|
+
"concurrencyModel": "Stateless",
|
|
35
|
+
"failureSemantics": "Fail"
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
interface SearchInput {
|
|
2
|
+
query: string;
|
|
3
|
+
maxResults?: number;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
interface SearchResult {
|
|
7
|
+
title: string;
|
|
8
|
+
url: string;
|
|
9
|
+
snippet: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
interface SearchOutput {
|
|
13
|
+
results: SearchResult[];
|
|
14
|
+
totalResults: number;
|
|
15
|
+
searchTime: number;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Genesis Gene: Web Search
|
|
20
|
+
*
|
|
21
|
+
* Full-featured web search gene. In MVP, returns simulated results.
|
|
22
|
+
* Production binding would connect to a real search API.
|
|
23
|
+
*/
|
|
24
|
+
export async function express(input: SearchInput): Promise<SearchOutput> {
|
|
25
|
+
const start = Date.now();
|
|
26
|
+
const max = input.maxResults ?? 5;
|
|
27
|
+
|
|
28
|
+
const results: SearchResult[] = Array.from({ length: max }, (_, i) => ({
|
|
29
|
+
title: `Result ${i + 1} for "${input.query}"`,
|
|
30
|
+
url: `https://example.com/search?q=${encodeURIComponent(input.query)}&p=${i + 1}`,
|
|
31
|
+
snippet: `This is a simulated search result #${i + 1} for the query "${input.query}". In production, this gene binds to a real search provider.`,
|
|
32
|
+
}));
|
|
33
|
+
|
|
34
|
+
return {
|
|
35
|
+
results,
|
|
36
|
+
totalResults: results.length,
|
|
37
|
+
searchTime: Date.now() - start,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"domain": "search",
|
|
3
|
+
"inputSchema": {
|
|
4
|
+
"type": "object",
|
|
5
|
+
"properties": {
|
|
6
|
+
"query": { "type": "string", "description": "Search query string" },
|
|
7
|
+
"maxResults": { "type": "integer", "default": 5, "minimum": 1, "maximum": 20 }
|
|
8
|
+
},
|
|
9
|
+
"required": ["query"]
|
|
10
|
+
},
|
|
11
|
+
"outputSchema": {
|
|
12
|
+
"type": "object",
|
|
13
|
+
"properties": {
|
|
14
|
+
"results": {
|
|
15
|
+
"type": "array",
|
|
16
|
+
"items": {
|
|
17
|
+
"type": "object",
|
|
18
|
+
"properties": {
|
|
19
|
+
"title": { "type": "string" },
|
|
20
|
+
"url": { "type": "string" },
|
|
21
|
+
"snippet": { "type": "string" }
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"totalResults": { "type": "integer" },
|
|
26
|
+
"searchTime": { "type": "number" }
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"dependencies": [],
|
|
30
|
+
"version": "0.1.0",
|
|
31
|
+
"author": "rotifer-genesis",
|
|
32
|
+
"fidelity": "Native",
|
|
33
|
+
"transparency": "Open",
|
|
34
|
+
"streaming_capability": null,
|
|
35
|
+
"semantic_requirements": {
|
|
36
|
+
"timeModel": "Async",
|
|
37
|
+
"concurrencyModel": "Stateless",
|
|
38
|
+
"failureSemantics": "Retry"
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
interface LiteSearchInput {
|
|
2
|
+
query: string;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
interface LiteSearchOutput {
|
|
6
|
+
answer: string;
|
|
7
|
+
source: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Genesis Gene: Web Search Lite
|
|
12
|
+
*
|
|
13
|
+
* Lightweight single-answer search gene — returns a concise answer
|
|
14
|
+
* instead of a list. Lower resource cost, suitable for Par composition
|
|
15
|
+
* with deadline constraints.
|
|
16
|
+
*/
|
|
17
|
+
export async function express(input: LiteSearchInput): Promise<LiteSearchOutput> {
|
|
18
|
+
return {
|
|
19
|
+
answer: `[Simulated] Quick answer for "${input.query}": This is a placeholder response from genesis-web-search-lite. In production, this returns a concise answer from a search provider.`,
|
|
20
|
+
source: "https://example.com/instant?q=" + encodeURIComponent(input.query),
|
|
21
|
+
};
|
|
22
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"domain": "search",
|
|
3
|
+
"inputSchema": {
|
|
4
|
+
"type": "object",
|
|
5
|
+
"properties": {
|
|
6
|
+
"query": { "type": "string", "description": "Search query string" }
|
|
7
|
+
},
|
|
8
|
+
"required": ["query"]
|
|
9
|
+
},
|
|
10
|
+
"outputSchema": {
|
|
11
|
+
"type": "object",
|
|
12
|
+
"properties": {
|
|
13
|
+
"answer": { "type": "string" },
|
|
14
|
+
"source": { "type": "string" }
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"dependencies": [],
|
|
18
|
+
"version": "0.1.0",
|
|
19
|
+
"author": "rotifer-genesis",
|
|
20
|
+
"fidelity": "Native",
|
|
21
|
+
"transparency": "Open",
|
|
22
|
+
"semantic_requirements": {
|
|
23
|
+
"timeModel": "Async",
|
|
24
|
+
"concurrencyModel": "Stateless",
|
|
25
|
+
"failureSemantics": "Fallback"
|
|
26
|
+
}
|
|
27
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@rotifer/playground",
|
|
3
|
+
"version": "0.1.0-alpha.1",
|
|
4
|
+
"description": "Rotifer Protocol Playground — local development environment for gene development, Arena competition, and protocol simulation",
|
|
5
|
+
"license": "AGPL-3.0-or-later",
|
|
6
|
+
"author": "Rotifer Protocol Contributors",
|
|
7
|
+
"homepage": "https://github.com/rotifer-protocol/rotifer-playground#readme",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/rotifer-protocol/rotifer-playground.git"
|
|
11
|
+
},
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/rotifer-protocol/rotifer-playground/issues"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"rotifer",
|
|
17
|
+
"protocol",
|
|
18
|
+
"gene",
|
|
19
|
+
"arena",
|
|
20
|
+
"agent",
|
|
21
|
+
"wasm",
|
|
22
|
+
"sandbox",
|
|
23
|
+
"evolution",
|
|
24
|
+
"ai",
|
|
25
|
+
"web3",
|
|
26
|
+
"decentralized",
|
|
27
|
+
"autonomous",
|
|
28
|
+
"digital-life",
|
|
29
|
+
"cli"
|
|
30
|
+
],
|
|
31
|
+
"bin": {
|
|
32
|
+
"rotifer": "./dist/index.js"
|
|
33
|
+
},
|
|
34
|
+
"main": "./dist/index.js",
|
|
35
|
+
"types": "./dist/index.d.ts",
|
|
36
|
+
"scripts": {
|
|
37
|
+
"build": "tsc",
|
|
38
|
+
"build:napi": "cd crates/rotifer-napi && napi build --release",
|
|
39
|
+
"dev": "tsc --watch",
|
|
40
|
+
"start": "node dist/index.js",
|
|
41
|
+
"test": "vitest run",
|
|
42
|
+
"test:watch": "vitest",
|
|
43
|
+
"test:coverage": "vitest run --coverage",
|
|
44
|
+
"lint": "tsc --noEmit",
|
|
45
|
+
"clean": "rm -rf dist",
|
|
46
|
+
"prepublishOnly": "npm run lint && npm run test && npm run build",
|
|
47
|
+
"prepack": "npm run build"
|
|
48
|
+
},
|
|
49
|
+
"dependencies": {
|
|
50
|
+
"commander": "^13.0.0",
|
|
51
|
+
"chalk": "^4.1.2",
|
|
52
|
+
"cli-table3": "^0.6.5",
|
|
53
|
+
"ajv": "^8.17.0",
|
|
54
|
+
"ajv-formats": "^3.0.0"
|
|
55
|
+
},
|
|
56
|
+
"devDependencies": {
|
|
57
|
+
"@types/node": "^22.0.0",
|
|
58
|
+
"typescript": "^5.7.0",
|
|
59
|
+
"vitest": "^3.0.0"
|
|
60
|
+
},
|
|
61
|
+
"engines": {
|
|
62
|
+
"node": ">=20.0.0"
|
|
63
|
+
},
|
|
64
|
+
"files": [
|
|
65
|
+
"dist/",
|
|
66
|
+
"templates/",
|
|
67
|
+
"genes/",
|
|
68
|
+
"LICENSE",
|
|
69
|
+
"README.md",
|
|
70
|
+
"CHANGELOG.md"
|
|
71
|
+
]
|
|
72
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://rotifer.dev/schemas/algebra-expr.json",
|
|
3
|
+
"type": "Par",
|
|
4
|
+
"branches": [
|
|
5
|
+
{ "type": "Gene", "id": "{{gene_a_id}}" },
|
|
6
|
+
{ "type": "Gene", "id": "{{gene_b_id}}" }
|
|
7
|
+
],
|
|
8
|
+
"merge": "FirstSuccess",
|
|
9
|
+
"deadline": "5s",
|
|
10
|
+
"_comment": "Parallel composition: run both genes, take first success within 5s deadline"
|
|
11
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://rotifer.dev/schemas/algebra-expr.json",
|
|
3
|
+
"type": "Seq",
|
|
4
|
+
"steps": [
|
|
5
|
+
{ "type": "Gene", "id": "{{gene_a_id}}" },
|
|
6
|
+
{ "type": "Gene", "id": "{{gene_b_id}}" }
|
|
7
|
+
],
|
|
8
|
+
"_comment": "Sequential composition: gene_a output feeds into gene_b input"
|
|
9
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"domain": "{{domain}}",
|
|
3
|
+
"inputSchema": {
|
|
4
|
+
"type": "object",
|
|
5
|
+
"properties": {
|
|
6
|
+
"input": { "type": "string", "description": "Primary input" }
|
|
7
|
+
},
|
|
8
|
+
"required": ["input"]
|
|
9
|
+
},
|
|
10
|
+
"outputSchema": {
|
|
11
|
+
"type": "object",
|
|
12
|
+
"properties": {
|
|
13
|
+
"output": { "type": "string" }
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"dependencies": [],
|
|
17
|
+
"version": "0.1.0",
|
|
18
|
+
"author": "{{author}}",
|
|
19
|
+
"fidelity": "Wrapped",
|
|
20
|
+
"transparency": "Open"
|
|
21
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { express } from "./index.js";
|
|
3
|
+
|
|
4
|
+
describe("{{name}}", () => {
|
|
5
|
+
it("should process input and return output", async () => {
|
|
6
|
+
const result = await express({ input: "hello" });
|
|
7
|
+
expect(result).toHaveProperty("output");
|
|
8
|
+
expect(typeof result.output).toBe("string");
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
it("should handle empty input", async () => {
|
|
12
|
+
const result = await express({ input: "" });
|
|
13
|
+
expect(result).toHaveProperty("output");
|
|
14
|
+
});
|
|
15
|
+
});
|