grexal 0.1.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/LICENSE +21 -0
- package/README.md +180 -0
- package/dist/commands/deploy.d.ts +2 -0
- package/dist/commands/deploy.d.ts.map +1 -0
- package/dist/commands/deploy.js +161 -0
- package/dist/commands/deploy.js.map +1 -0
- package/dist/commands/dev.d.ts +4 -0
- package/dist/commands/dev.d.ts.map +1 -0
- package/dist/commands/dev.js +232 -0
- package/dist/commands/dev.js.map +1 -0
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +76 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/login.d.ts +2 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +96 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logout.d.ts +2 -0
- package/dist/commands/logout.d.ts.map +1 -0
- package/dist/commands/logout.js +12 -0
- package/dist/commands/logout.js.map +1 -0
- package/dist/commands/validate.d.ts +2 -0
- package/dist/commands/validate.d.ts.map +1 -0
- package/dist/commands/validate.js +55 -0
- package/dist/commands/validate.js.map +1 -0
- package/dist/dev-server/server.d.ts +31 -0
- package/dist/dev-server/server.d.ts.map +1 -0
- package/dist/dev-server/server.js +89 -0
- package/dist/dev-server/server.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +63 -0
- package/dist/index.js.map +1 -0
- package/dist/manifest/constants.d.ts +31 -0
- package/dist/manifest/constants.d.ts.map +1 -0
- package/dist/manifest/constants.js +54 -0
- package/dist/manifest/constants.js.map +1 -0
- package/dist/manifest/types.d.ts +66 -0
- package/dist/manifest/types.d.ts.map +1 -0
- package/dist/manifest/types.js +3 -0
- package/dist/manifest/types.js.map +1 -0
- package/dist/manifest/validator.d.ts +7 -0
- package/dist/manifest/validator.d.ts.map +1 -0
- package/dist/manifest/validator.js +435 -0
- package/dist/manifest/validator.js.map +1 -0
- package/dist/templates/python.d.ts +4 -0
- package/dist/templates/python.d.ts.map +1 -0
- package/dist/templates/python.js +35 -0
- package/dist/templates/python.js.map +1 -0
- package/dist/templates/shared.d.ts +3 -0
- package/dist/templates/shared.d.ts.map +1 -0
- package/dist/templates/shared.js +29 -0
- package/dist/templates/shared.js.map +1 -0
- package/dist/templates/typescript.d.ts +5 -0
- package/dist/templates/typescript.d.ts.map +1 -0
- package/dist/templates/typescript.js +55 -0
- package/dist/templates/typescript.js.map +1 -0
- package/dist/utils/api.d.ts +12 -0
- package/dist/utils/api.d.ts.map +1 -0
- package/dist/utils/api.js +23 -0
- package/dist/utils/api.js.map +1 -0
- package/dist/utils/auth.d.ts +10 -0
- package/dist/utils/auth.d.ts.map +1 -0
- package/dist/utils/auth.js +46 -0
- package/dist/utils/auth.js.map +1 -0
- package/dist/utils/manifest.d.ts +3 -0
- package/dist/utils/manifest.d.ts.map +1 -0
- package/dist/utils/manifest.js +32 -0
- package/dist/utils/manifest.js.map +1 -0
- package/dist/utils/process.d.ts +18 -0
- package/dist/utils/process.d.ts.map +1 -0
- package/dist/utils/process.js +30 -0
- package/dist/utils/process.js.map +1 -0
- package/package.json +29 -0
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { mkdir, writeFile, access } from "node:fs/promises";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { createInterface } from "node:readline/promises";
|
|
4
|
+
import { NAME_REGEX, NAME_MAX_LENGTH } from "../manifest/constants.js";
|
|
5
|
+
import { tsManifest, tsEntrypoint, tsPackageJson, tsTsconfig, } from "../templates/typescript.js";
|
|
6
|
+
import { pyManifest, pyEntrypoint, pyRequirements } from "../templates/python.js";
|
|
7
|
+
import { gitignore, connectionsJson } from "../templates/shared.js";
|
|
8
|
+
export async function runInit() {
|
|
9
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
10
|
+
try {
|
|
11
|
+
// Prompt for language
|
|
12
|
+
const langInput = await rl.question(" Language (typescript/python) [typescript]: ");
|
|
13
|
+
const language = langInput.trim().toLowerCase() === "python" ? "python" : "typescript";
|
|
14
|
+
// Prompt for agent name
|
|
15
|
+
let name = "";
|
|
16
|
+
while (!name) {
|
|
17
|
+
const nameInput = await rl.question(" Agent name: ");
|
|
18
|
+
const trimmed = nameInput.trim();
|
|
19
|
+
if (!trimmed) {
|
|
20
|
+
console.log(" Name cannot be empty");
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
if (trimmed.length > NAME_MAX_LENGTH) {
|
|
24
|
+
console.log(` Maximum ${NAME_MAX_LENGTH} characters`);
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
if (!NAME_REGEX.test(trimmed)) {
|
|
28
|
+
console.log(" Must be lowercase alphanumeric, hyphens, and underscores (start with alphanumeric)");
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
name = trimmed;
|
|
32
|
+
}
|
|
33
|
+
rl.close();
|
|
34
|
+
// Check if directory already exists
|
|
35
|
+
const dir = join(process.cwd(), name);
|
|
36
|
+
try {
|
|
37
|
+
await access(dir);
|
|
38
|
+
console.error(`\n Error: Directory '${name}' already exists`);
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
// Directory doesn't exist — good
|
|
43
|
+
}
|
|
44
|
+
// Create project structure
|
|
45
|
+
await mkdir(dir, { recursive: true });
|
|
46
|
+
await mkdir(join(dir, ".grexal"), { recursive: true });
|
|
47
|
+
if (language === "typescript") {
|
|
48
|
+
await writeFile(join(dir, "grexal.json"), tsManifest(name));
|
|
49
|
+
await writeFile(join(dir, "index.ts"), tsEntrypoint());
|
|
50
|
+
await writeFile(join(dir, "package.json"), tsPackageJson(name));
|
|
51
|
+
await writeFile(join(dir, "tsconfig.json"), tsTsconfig());
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
await writeFile(join(dir, "grexal.json"), pyManifest(name));
|
|
55
|
+
await writeFile(join(dir, "agent.py"), pyEntrypoint());
|
|
56
|
+
await writeFile(join(dir, "requirements.txt"), pyRequirements());
|
|
57
|
+
}
|
|
58
|
+
await writeFile(join(dir, ".gitignore"), gitignore(language));
|
|
59
|
+
await writeFile(join(dir, ".grexal", "connections.json"), connectionsJson());
|
|
60
|
+
console.log(`\n Created ${name}/ (${language})`);
|
|
61
|
+
console.log("");
|
|
62
|
+
console.log(` cd ${name}`);
|
|
63
|
+
if (language === "typescript") {
|
|
64
|
+
console.log(" npm install");
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
console.log(" pip install -r requirements.txt");
|
|
68
|
+
}
|
|
69
|
+
console.log(" npx grexal dev");
|
|
70
|
+
console.log("");
|
|
71
|
+
}
|
|
72
|
+
finally {
|
|
73
|
+
rl.close();
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AA8BA,wBAAsB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CA8F9C"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { createInterface } from "node:readline/promises";
|
|
2
|
+
import { exec } from "node:child_process";
|
|
3
|
+
import { platform } from "node:os";
|
|
4
|
+
import { loadCredentials, saveCredentials } from "../utils/auth.js";
|
|
5
|
+
import { platformFetch, getPlatformUrl } from "../utils/api.js";
|
|
6
|
+
function openBrowser(url) {
|
|
7
|
+
const os = platform();
|
|
8
|
+
let cmd;
|
|
9
|
+
if (os === "darwin") {
|
|
10
|
+
cmd = `open "${url}"`;
|
|
11
|
+
}
|
|
12
|
+
else if (os === "win32") {
|
|
13
|
+
cmd = `start "${url}"`;
|
|
14
|
+
}
|
|
15
|
+
else {
|
|
16
|
+
cmd = `xdg-open "${url}"`;
|
|
17
|
+
}
|
|
18
|
+
exec(cmd, (err) => {
|
|
19
|
+
if (err) {
|
|
20
|
+
console.log(` Could not open browser automatically.`);
|
|
21
|
+
console.log(` Please visit: ${url}\n`);
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
function sleep(ms) {
|
|
26
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
27
|
+
}
|
|
28
|
+
export async function runLogin() {
|
|
29
|
+
// Check if already logged in
|
|
30
|
+
const existing = await loadCredentials();
|
|
31
|
+
if (existing) {
|
|
32
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
33
|
+
const answer = await rl.question(` Already logged in as ${existing.email}. Re-authenticate? [y/N] `);
|
|
34
|
+
rl.close();
|
|
35
|
+
if (answer.trim().toLowerCase() !== "y") {
|
|
36
|
+
console.log(" Keeping existing credentials.");
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
// Generate auth code
|
|
41
|
+
console.log(" Generating authentication code...\n");
|
|
42
|
+
let code;
|
|
43
|
+
try {
|
|
44
|
+
const resp = await platformFetch("/api/cli/auth/code", {
|
|
45
|
+
method: "POST",
|
|
46
|
+
});
|
|
47
|
+
if (!resp.ok) {
|
|
48
|
+
const text = await resp.text();
|
|
49
|
+
console.error(` Error: Failed to generate auth code — ${text}`);
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
52
|
+
const data = (await resp.json());
|
|
53
|
+
code = data.code;
|
|
54
|
+
}
|
|
55
|
+
catch (e) {
|
|
56
|
+
console.error(` Error: Could not connect to platform at ${getPlatformUrl()}`);
|
|
57
|
+
console.error(` Set GREXAL_API_URL if you're using a custom deployment.\n`);
|
|
58
|
+
process.exit(1);
|
|
59
|
+
}
|
|
60
|
+
// Show code and open browser
|
|
61
|
+
const webUrl = process.env.GREXAL_WEB_URL ?? "https://grexal.ai";
|
|
62
|
+
const authUrl = `${webUrl}/auth/cli?code=${code}`;
|
|
63
|
+
console.log(` Your code is: ${code}\n`);
|
|
64
|
+
console.log(` Opening browser to confirm...`);
|
|
65
|
+
console.log(` ${authUrl}\n`);
|
|
66
|
+
openBrowser(authUrl);
|
|
67
|
+
// Poll for confirmation
|
|
68
|
+
console.log(" Waiting for confirmation...");
|
|
69
|
+
const maxAttempts = 150; // 5 minutes at 2-second intervals
|
|
70
|
+
for (let i = 0; i < maxAttempts; i++) {
|
|
71
|
+
await sleep(2000);
|
|
72
|
+
try {
|
|
73
|
+
const resp = await platformFetch(`/api/cli/auth/poll?code=${encodeURIComponent(code)}`, { method: "GET" });
|
|
74
|
+
if (!resp.ok)
|
|
75
|
+
continue;
|
|
76
|
+
const data = (await resp.json());
|
|
77
|
+
if (data.status === "confirmed" && data.token && data.email) {
|
|
78
|
+
await saveCredentials({ token: data.token, email: data.email });
|
|
79
|
+
console.log(`\n Authenticated as ${data.email}`);
|
|
80
|
+
console.log(` Credentials saved to ~/.grexal/credentials.json\n`);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
if (data.status === "expired" || data.status === "not_found") {
|
|
84
|
+
console.error("\n Authentication code expired. Please try again.");
|
|
85
|
+
process.exit(1);
|
|
86
|
+
}
|
|
87
|
+
// status === "pending" — keep polling
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
// Network error — keep trying
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
console.error("\n Authentication timed out. Please try again.");
|
|
94
|
+
process.exit(1);
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=login.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logout.d.ts","sourceRoot":"","sources":["../../src/commands/logout.ts"],"names":[],"mappings":"AAEA,wBAAsB,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAW/C"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { clearCredentials, loadCredentials } from "../utils/auth.js";
|
|
2
|
+
export async function runLogout() {
|
|
3
|
+
const creds = await loadCredentials();
|
|
4
|
+
if (!creds) {
|
|
5
|
+
console.log(" Not currently logged in.");
|
|
6
|
+
return;
|
|
7
|
+
}
|
|
8
|
+
await clearCredentials();
|
|
9
|
+
console.log(` Logged out (was ${creds.email}).`);
|
|
10
|
+
console.log(" Credentials removed from ~/.grexal/credentials.json");
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=logout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logout.js","sourceRoot":"","sources":["../../src/commands/logout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAErE,MAAM,CAAC,KAAK,UAAU,SAAS;IAC7B,MAAM,KAAK,GAAG,MAAM,eAAe,EAAE,CAAC;IAEtC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;QAC1C,OAAO;IACT,CAAC;IAED,MAAM,gBAAgB,EAAE,CAAC;IACzB,OAAO,CAAC,GAAG,CAAC,qBAAqB,KAAK,CAAC,KAAK,IAAI,CAAC,CAAC;IAClD,OAAO,CAAC,GAAG,CAAC,uDAAuD,CAAC,CAAC;AACvE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"AAIA,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAyDjD"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { readFile, access } from "node:fs/promises";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import { validateManifest } from "../manifest/validator.js";
|
|
4
|
+
export async function runValidate() {
|
|
5
|
+
const manifestPath = resolve("grexal.json");
|
|
6
|
+
// Check manifest exists
|
|
7
|
+
let raw;
|
|
8
|
+
try {
|
|
9
|
+
raw = await readFile(manifestPath, "utf-8");
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
console.error(" Error: grexal.json not found in current directory");
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
// Parse JSON
|
|
16
|
+
let parsed;
|
|
17
|
+
try {
|
|
18
|
+
parsed = JSON.parse(raw);
|
|
19
|
+
}
|
|
20
|
+
catch (err) {
|
|
21
|
+
console.error(` Error: grexal.json contains invalid JSON — ${err instanceof Error ? err.message : err}`);
|
|
22
|
+
process.exit(1);
|
|
23
|
+
}
|
|
24
|
+
// Run schema validation
|
|
25
|
+
const errors = validateManifest(parsed);
|
|
26
|
+
// Check entrypoint file exists on disk
|
|
27
|
+
if (typeof parsed === "object" &&
|
|
28
|
+
parsed !== null &&
|
|
29
|
+
typeof parsed.entrypoint === "string") {
|
|
30
|
+
const entrypoint = parsed.entrypoint;
|
|
31
|
+
const entrypointPath = resolve(entrypoint);
|
|
32
|
+
try {
|
|
33
|
+
await access(entrypointPath);
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
errors.push({
|
|
37
|
+
path: "entrypoint",
|
|
38
|
+
message: `File '${entrypoint}' not found in project`,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
// Report results
|
|
43
|
+
if (errors.length === 0) {
|
|
44
|
+
console.log(" Manifest valid ✓");
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
console.error(" Validation failed:\n");
|
|
48
|
+
for (const err of errors) {
|
|
49
|
+
const path = err.path ? `${err.path} — ` : "";
|
|
50
|
+
console.error(` ${path}${err.message}`);
|
|
51
|
+
}
|
|
52
|
+
console.error("");
|
|
53
|
+
process.exit(1);
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,OAAO,EAAW,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAE5D,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,MAAM,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IAE5C,wBAAwB;IACxB,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IAC9C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,KAAK,CAAC,qDAAqD,CAAC,CAAC;QACrE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,aAAa;IACb,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CACX,gDAAgD,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,CAC3F,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,wBAAwB;IACxB,MAAM,MAAM,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC;IAExC,uCAAuC;IACvC,IACE,OAAO,MAAM,KAAK,QAAQ;QAC1B,MAAM,KAAK,IAAI;QACf,OAAQ,MAAkC,CAAC,UAAU,KAAK,QAAQ,EAClE,CAAC;QACD,MAAM,UAAU,GAAI,MAAkC,CAAC,UAAoB,CAAC;QAC5E,MAAM,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;QAC3C,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;QAC/B,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI,EAAE,YAAY;gBAClB,OAAO,EAAE,SAAS,UAAU,wBAAwB;aACrD,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,iBAAiB;IACjB,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;QAClC,OAAO;IACT,CAAC;IAED,OAAO,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;IACxC,KAAK,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9C,OAAO,CAAC,KAAK,CAAC,OAAO,IAAI,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;IAC7C,CAAC;IACD,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAClB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export interface DevServerCallbacks {
|
|
2
|
+
onSubmit: (result: unknown) => void;
|
|
3
|
+
onLog: (entries: LogEntryPayload[]) => void;
|
|
4
|
+
}
|
|
5
|
+
export interface LogEntryPayload {
|
|
6
|
+
type: "log" | "progress";
|
|
7
|
+
message?: string;
|
|
8
|
+
value?: number;
|
|
9
|
+
timestamp?: number;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* A local HTTP server that mimics the Grexal platform API.
|
|
13
|
+
* Handles submit and log endpoints from the SDK running inside the agent process.
|
|
14
|
+
*/
|
|
15
|
+
export declare class DevServer {
|
|
16
|
+
private _server;
|
|
17
|
+
private _callbacks;
|
|
18
|
+
private _submitted;
|
|
19
|
+
constructor(callbacks: DevServerCallbacks);
|
|
20
|
+
/** Start listening on the given port. */
|
|
21
|
+
listen(port: number): Promise<void>;
|
|
22
|
+
/** Reset state for a new run. */
|
|
23
|
+
reset(): void;
|
|
24
|
+
/** Close the server. */
|
|
25
|
+
close(): Promise<void>;
|
|
26
|
+
private _handleRequest;
|
|
27
|
+
private _handleSubmit;
|
|
28
|
+
private _handleLog;
|
|
29
|
+
private _readBody;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/dev-server/server.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IACpC,KAAK,EAAE,CAAC,OAAO,EAAE,eAAe,EAAE,KAAK,IAAI,CAAC;CAC7C;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,KAAK,GAAG,UAAU,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,UAAU,CAAqB;IACvC,OAAO,CAAC,UAAU,CAAS;gBAEf,SAAS,EAAE,kBAAkB;IAKzC,yCAAyC;IACzC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMnC,iCAAiC;IACjC,KAAK,IAAI,IAAI;IAIb,wBAAwB;IACxB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAMtB,OAAO,CAAC,cAAc;IAmBtB,OAAO,CAAC,aAAa;IAqBrB,OAAO,CAAC,UAAU;IAgBlB,OAAO,CAAC,SAAS;CAOlB"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { createServer } from "node:http";
|
|
2
|
+
/**
|
|
3
|
+
* A local HTTP server that mimics the Grexal platform API.
|
|
4
|
+
* Handles submit and log endpoints from the SDK running inside the agent process.
|
|
5
|
+
*/
|
|
6
|
+
export class DevServer {
|
|
7
|
+
_server;
|
|
8
|
+
_callbacks;
|
|
9
|
+
_submitted = false;
|
|
10
|
+
constructor(callbacks) {
|
|
11
|
+
this._callbacks = callbacks;
|
|
12
|
+
this._server = createServer((req, res) => this._handleRequest(req, res));
|
|
13
|
+
}
|
|
14
|
+
/** Start listening on the given port. */
|
|
15
|
+
listen(port) {
|
|
16
|
+
return new Promise((resolve) => {
|
|
17
|
+
this._server.listen(port, "127.0.0.1", () => resolve());
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
/** Reset state for a new run. */
|
|
21
|
+
reset() {
|
|
22
|
+
this._submitted = false;
|
|
23
|
+
}
|
|
24
|
+
/** Close the server. */
|
|
25
|
+
close() {
|
|
26
|
+
return new Promise((resolve, reject) => {
|
|
27
|
+
this._server.close((err) => (err ? reject(err) : resolve()));
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
_handleRequest(req, res) {
|
|
31
|
+
const url = req.url ?? "";
|
|
32
|
+
// Match POST /runs/:id/submit
|
|
33
|
+
if (req.method === "POST" && /^\/runs\/[^/]+\/submit$/.test(url)) {
|
|
34
|
+
this._handleSubmit(req, res);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
// Match POST /runs/:id/log
|
|
38
|
+
if (req.method === "POST" && /^\/runs\/[^/]+\/log$/.test(url)) {
|
|
39
|
+
this._handleLog(req, res);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
res.writeHead(404);
|
|
43
|
+
res.end("Not found");
|
|
44
|
+
}
|
|
45
|
+
_handleSubmit(req, res) {
|
|
46
|
+
if (this._submitted) {
|
|
47
|
+
res.writeHead(409, { "Content-Type": "application/json" });
|
|
48
|
+
res.end(JSON.stringify({ error: "Already submitted" }));
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
this._readBody(req).then((body) => {
|
|
52
|
+
try {
|
|
53
|
+
const parsed = JSON.parse(body);
|
|
54
|
+
this._submitted = true;
|
|
55
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
56
|
+
res.end(JSON.stringify({ ok: true }));
|
|
57
|
+
this._callbacks.onSubmit(parsed.result);
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
res.writeHead(400);
|
|
61
|
+
res.end("Invalid JSON");
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
_handleLog(req, res) {
|
|
66
|
+
this._readBody(req).then((body) => {
|
|
67
|
+
try {
|
|
68
|
+
const parsed = JSON.parse(body);
|
|
69
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
70
|
+
res.end(JSON.stringify({ ok: true }));
|
|
71
|
+
if (Array.isArray(parsed.entries)) {
|
|
72
|
+
this._callbacks.onLog(parsed.entries);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
res.writeHead(400);
|
|
77
|
+
res.end("Invalid JSON");
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
_readBody(req) {
|
|
82
|
+
return new Promise((resolve) => {
|
|
83
|
+
const chunks = [];
|
|
84
|
+
req.on("data", (chunk) => chunks.push(chunk));
|
|
85
|
+
req.on("end", () => resolve(Buffer.concat(chunks).toString()));
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/dev-server/server.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
3
|
+
import { resolve } from "node:path";
|
|
4
|
+
import { Command } from "commander";
|
|
5
|
+
import { runValidate } from "./commands/validate.js";
|
|
6
|
+
// Load .env from the current working directory (if it exists)
|
|
7
|
+
try {
|
|
8
|
+
const envPath = resolve(".env");
|
|
9
|
+
const envContent = readFileSync(envPath, "utf-8");
|
|
10
|
+
for (const line of envContent.split("\n")) {
|
|
11
|
+
const trimmed = line.trim();
|
|
12
|
+
if (!trimmed || trimmed.startsWith("#"))
|
|
13
|
+
continue;
|
|
14
|
+
const eqIndex = trimmed.indexOf("=");
|
|
15
|
+
if (eqIndex === -1)
|
|
16
|
+
continue;
|
|
17
|
+
const key = trimmed.slice(0, eqIndex).trim();
|
|
18
|
+
const value = trimmed.slice(eqIndex + 1).trim().replace(/^["']|["']$/g, "");
|
|
19
|
+
if (!process.env[key]) {
|
|
20
|
+
process.env[key] = value;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
// No .env file — that's fine
|
|
26
|
+
}
|
|
27
|
+
import { runInit } from "./commands/init.js";
|
|
28
|
+
import { runDev } from "./commands/dev.js";
|
|
29
|
+
import { runLogin } from "./commands/login.js";
|
|
30
|
+
import { runLogout } from "./commands/logout.js";
|
|
31
|
+
import { runDeploy } from "./commands/deploy.js";
|
|
32
|
+
const program = new Command();
|
|
33
|
+
program
|
|
34
|
+
.name("grexal")
|
|
35
|
+
.description("Grexal CLI — build and deploy agents")
|
|
36
|
+
.version("0.1.0");
|
|
37
|
+
program
|
|
38
|
+
.command("validate")
|
|
39
|
+
.description("Validate grexal.json manifest")
|
|
40
|
+
.action(runValidate);
|
|
41
|
+
program
|
|
42
|
+
.command("init")
|
|
43
|
+
.description("Scaffold a new agent project")
|
|
44
|
+
.action(runInit);
|
|
45
|
+
program
|
|
46
|
+
.command("dev")
|
|
47
|
+
.description("Run the agent locally in a simulated environment")
|
|
48
|
+
.option("--input <json>", "Task input JSON (skips interactive prompt for first run)")
|
|
49
|
+
.action(runDev);
|
|
50
|
+
program
|
|
51
|
+
.command("login")
|
|
52
|
+
.description("Authenticate with the Grexal platform")
|
|
53
|
+
.action(runLogin);
|
|
54
|
+
program
|
|
55
|
+
.command("logout")
|
|
56
|
+
.description("Clear stored credentials")
|
|
57
|
+
.action(runLogout);
|
|
58
|
+
program
|
|
59
|
+
.command("deploy")
|
|
60
|
+
.description("Deploy the agent to the Grexal platform")
|
|
61
|
+
.action(runDeploy);
|
|
62
|
+
program.parse();
|
|
63
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAErD,8DAA8D;AAC9D,IAAI,CAAC;IACH,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAChC,MAAM,UAAU,GAAG,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAClD,KAAK,MAAM,IAAI,IAAI,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1C,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QAClD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACrC,IAAI,OAAO,KAAK,CAAC,CAAC;YAAE,SAAS;QAC7B,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;QAC7C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;QAC5E,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACtB,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QAC3B,CAAC;IACH,CAAC;AACH,CAAC;AAAC,MAAM,CAAC;IACP,6BAA6B;AAC/B,CAAC;AACD,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEjD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,QAAQ,CAAC;KACd,WAAW,CAAC,sCAAsC,CAAC;KACnD,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO;KACJ,OAAO,CAAC,UAAU,CAAC;KACnB,WAAW,CAAC,+BAA+B,CAAC;KAC5C,MAAM,CAAC,WAAW,CAAC,CAAC;AAEvB,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,8BAA8B,CAAC;KAC3C,MAAM,CAAC,OAAO,CAAC,CAAC;AAEnB,OAAO;KACJ,OAAO,CAAC,KAAK,CAAC;KACd,WAAW,CAAC,kDAAkD,CAAC;KAC/D,MAAM,CAAC,gBAAgB,EAAE,0DAA0D,CAAC;KACpF,MAAM,CAAC,MAAM,CAAC,CAAC;AAElB,OAAO;KACJ,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,uCAAuC,CAAC;KACpD,MAAM,CAAC,QAAQ,CAAC,CAAC;AAEpB,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,0BAA0B,CAAC;KACvC,MAAM,CAAC,SAAS,CAAC,CAAC;AAErB,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,yCAAyC,CAAC;KACtD,MAAM,CAAC,SAAS,CAAC,CAAC;AAErB,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/** Agent name: lowercase alphanumeric, hyphens, underscores. Must start with alphanumeric. */
|
|
2
|
+
export declare const NAME_REGEX: RegExp;
|
|
3
|
+
export declare const NAME_MAX_LENGTH = 64;
|
|
4
|
+
/** Connection ID: lowercase alphanumeric and underscores. Must start with letter. */
|
|
5
|
+
export declare const CONNECTION_ID_REGEX: RegExp;
|
|
6
|
+
export declare const CONNECTION_ID_MAX_LENGTH = 64;
|
|
7
|
+
/** Field name for secret_input fields. Same pattern as connection ID. */
|
|
8
|
+
export declare const FIELD_NAME_REGEX: RegExp;
|
|
9
|
+
/** Tag: lowercase alphanumeric and hyphens. */
|
|
10
|
+
export declare const TAG_REGEX: RegExp;
|
|
11
|
+
export declare const TAG_MAX_LENGTH = 32;
|
|
12
|
+
export declare const MAX_TAGS = 10;
|
|
13
|
+
/** Description max length. */
|
|
14
|
+
export declare const DESCRIPTION_MAX_LENGTH = 2000;
|
|
15
|
+
export declare const CATEGORIES: readonly ["finance", "productivity", "data", "communication", "development", "research", "media", "commerce", "travel", "other"];
|
|
16
|
+
export type Category = (typeof CATEGORIES)[number];
|
|
17
|
+
export declare const LANGUAGES: readonly ["python", "typescript"];
|
|
18
|
+
export declare const CPU_OPTIONS: readonly [1, 2, 4, 8];
|
|
19
|
+
export declare const SANDBOX_TEMPLATES: readonly ["standard", "desktop"];
|
|
20
|
+
export declare const MEMORY_MIN = 512;
|
|
21
|
+
export declare const MEMORY_MAX = 8192;
|
|
22
|
+
export declare const TIMEOUT_MIN = 10;
|
|
23
|
+
export declare const TIMEOUT_MAX = 86400;
|
|
24
|
+
export declare const PRICE_MIN = 0;
|
|
25
|
+
export declare const PRICE_MAX = 100;
|
|
26
|
+
export declare const AUTH_MODES: readonly ["secret_input", "oauth_redirect", "file_upload", "browser_login"];
|
|
27
|
+
export declare const DELIVERY_MODES: readonly ["runtime_object", "env_vars", "file"];
|
|
28
|
+
export declare const MAX_SECRET_INPUT_FIELDS = 20;
|
|
29
|
+
export declare const MAX_FILE_UPLOAD_BYTES = 1048576;
|
|
30
|
+
export declare const LANGUAGE_EXTENSIONS: Record<string, string[]>;
|
|
31
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/manifest/constants.ts"],"names":[],"mappings":"AAEA,8FAA8F;AAC9F,eAAO,MAAM,UAAU,QAA0B,CAAC;AAClD,eAAO,MAAM,eAAe,KAAK,CAAC;AAElC,qFAAqF;AACrF,eAAO,MAAM,mBAAmB,QAAsB,CAAC;AACvD,eAAO,MAAM,wBAAwB,KAAK,CAAC;AAE3C,yEAAyE;AACzE,eAAO,MAAM,gBAAgB,QAAsB,CAAC;AAEpD,+CAA+C;AAC/C,eAAO,MAAM,SAAS,QAAiB,CAAC;AACxC,eAAO,MAAM,cAAc,KAAK,CAAC;AACjC,eAAO,MAAM,QAAQ,KAAK,CAAC;AAE3B,8BAA8B;AAC9B,eAAO,MAAM,sBAAsB,OAAO,CAAC;AAI3C,eAAO,MAAM,UAAU,kIAWb,CAAC;AAEX,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;AAInD,eAAO,MAAM,SAAS,mCAAoC,CAAC;AAC3D,eAAO,MAAM,WAAW,uBAAwB,CAAC;AACjD,eAAO,MAAM,iBAAiB,kCAAmC,CAAC;AAElE,eAAO,MAAM,UAAU,MAAM,CAAC;AAC9B,eAAO,MAAM,UAAU,OAAO,CAAC;AAC/B,eAAO,MAAM,WAAW,KAAK,CAAC;AAC9B,eAAO,MAAM,WAAW,QAAQ,CAAC;AACjC,eAAO,MAAM,SAAS,IAAI,CAAC;AAC3B,eAAO,MAAM,SAAS,MAAM,CAAC;AAI7B,eAAO,MAAM,UAAU,6EAKb,CAAC;AAEX,eAAO,MAAM,cAAc,iDAAkD,CAAC;AAE9E,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAC1C,eAAO,MAAM,qBAAqB,UAAY,CAAC;AAI/C,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAGxD,CAAC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// --- Regex patterns ---
|
|
2
|
+
/** Agent name: lowercase alphanumeric, hyphens, underscores. Must start with alphanumeric. */
|
|
3
|
+
export const NAME_REGEX = /^[a-z0-9][a-z0-9_-]*$/;
|
|
4
|
+
export const NAME_MAX_LENGTH = 64;
|
|
5
|
+
/** Connection ID: lowercase alphanumeric and underscores. Must start with letter. */
|
|
6
|
+
export const CONNECTION_ID_REGEX = /^[a-z][a-z0-9_]*$/;
|
|
7
|
+
export const CONNECTION_ID_MAX_LENGTH = 64;
|
|
8
|
+
/** Field name for secret_input fields. Same pattern as connection ID. */
|
|
9
|
+
export const FIELD_NAME_REGEX = /^[a-z][a-z0-9_]*$/;
|
|
10
|
+
/** Tag: lowercase alphanumeric and hyphens. */
|
|
11
|
+
export const TAG_REGEX = /^[a-z0-9-]+$/;
|
|
12
|
+
export const TAG_MAX_LENGTH = 32;
|
|
13
|
+
export const MAX_TAGS = 10;
|
|
14
|
+
/** Description max length. */
|
|
15
|
+
export const DESCRIPTION_MAX_LENGTH = 2000;
|
|
16
|
+
// --- Categories ---
|
|
17
|
+
export const CATEGORIES = [
|
|
18
|
+
"finance",
|
|
19
|
+
"productivity",
|
|
20
|
+
"data",
|
|
21
|
+
"communication",
|
|
22
|
+
"development",
|
|
23
|
+
"research",
|
|
24
|
+
"media",
|
|
25
|
+
"commerce",
|
|
26
|
+
"travel",
|
|
27
|
+
"other",
|
|
28
|
+
];
|
|
29
|
+
// --- Runtime constraints ---
|
|
30
|
+
export const LANGUAGES = ["python", "typescript"];
|
|
31
|
+
export const CPU_OPTIONS = [1, 2, 4, 8];
|
|
32
|
+
export const SANDBOX_TEMPLATES = ["standard", "desktop"];
|
|
33
|
+
export const MEMORY_MIN = 512;
|
|
34
|
+
export const MEMORY_MAX = 8192;
|
|
35
|
+
export const TIMEOUT_MIN = 10;
|
|
36
|
+
export const TIMEOUT_MAX = 86400;
|
|
37
|
+
export const PRICE_MIN = 0;
|
|
38
|
+
export const PRICE_MAX = 100;
|
|
39
|
+
// --- Connection constraints ---
|
|
40
|
+
export const AUTH_MODES = [
|
|
41
|
+
"secret_input",
|
|
42
|
+
"oauth_redirect",
|
|
43
|
+
"file_upload",
|
|
44
|
+
"browser_login",
|
|
45
|
+
];
|
|
46
|
+
export const DELIVERY_MODES = ["runtime_object", "env_vars", "file"];
|
|
47
|
+
export const MAX_SECRET_INPUT_FIELDS = 20;
|
|
48
|
+
export const MAX_FILE_UPLOAD_BYTES = 1_048_576; // 1 MB
|
|
49
|
+
// --- Entrypoint extensions ---
|
|
50
|
+
export const LANGUAGE_EXTENSIONS = {
|
|
51
|
+
python: [".py"],
|
|
52
|
+
typescript: [".ts", ".js"],
|
|
53
|
+
};
|
|
54
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/manifest/constants.ts"],"names":[],"mappings":"AAAA,yBAAyB;AAEzB,8FAA8F;AAC9F,MAAM,CAAC,MAAM,UAAU,GAAG,uBAAuB,CAAC;AAClD,MAAM,CAAC,MAAM,eAAe,GAAG,EAAE,CAAC;AAElC,qFAAqF;AACrF,MAAM,CAAC,MAAM,mBAAmB,GAAG,mBAAmB,CAAC;AACvD,MAAM,CAAC,MAAM,wBAAwB,GAAG,EAAE,CAAC;AAE3C,yEAAyE;AACzE,MAAM,CAAC,MAAM,gBAAgB,GAAG,mBAAmB,CAAC;AAEpD,+CAA+C;AAC/C,MAAM,CAAC,MAAM,SAAS,GAAG,cAAc,CAAC;AACxC,MAAM,CAAC,MAAM,cAAc,GAAG,EAAE,CAAC;AACjC,MAAM,CAAC,MAAM,QAAQ,GAAG,EAAE,CAAC;AAE3B,8BAA8B;AAC9B,MAAM,CAAC,MAAM,sBAAsB,GAAG,IAAI,CAAC;AAE3C,qBAAqB;AAErB,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,SAAS;IACT,cAAc;IACd,MAAM;IACN,eAAe;IACf,aAAa;IACb,UAAU;IACV,OAAO;IACP,UAAU;IACV,QAAQ;IACR,OAAO;CACC,CAAC;AAIX,8BAA8B;AAE9B,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,QAAQ,EAAE,YAAY,CAAU,CAAC;AAC3D,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAU,CAAC;AACjD,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,UAAU,EAAE,SAAS,CAAU,CAAC;AAElE,MAAM,CAAC,MAAM,UAAU,GAAG,GAAG,CAAC;AAC9B,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,CAAC;AAC/B,MAAM,CAAC,MAAM,WAAW,GAAG,EAAE,CAAC;AAC9B,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,CAAC;AACjC,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,CAAC;AAC3B,MAAM,CAAC,MAAM,SAAS,GAAG,GAAG,CAAC;AAE7B,iCAAiC;AAEjC,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,cAAc;IACd,gBAAgB;IAChB,aAAa;IACb,eAAe;CACP,CAAC;AAEX,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,gBAAgB,EAAE,UAAU,EAAE,MAAM,CAAU,CAAC;AAE9E,MAAM,CAAC,MAAM,uBAAuB,GAAG,EAAE,CAAC;AAC1C,MAAM,CAAC,MAAM,qBAAqB,GAAG,SAAS,CAAC,CAAC,OAAO;AAEvD,gCAAgC;AAEhC,MAAM,CAAC,MAAM,mBAAmB,GAA6B;IAC3D,MAAM,EAAE,CAAC,KAAK,CAAC;IACf,UAAU,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC;CAC3B,CAAC"}
|