@struere/cli 0.2.4 → 0.2.7
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/dist/commands/build.d.ts +3 -0
- package/dist/commands/build.d.ts.map +1 -0
- package/dist/commands/build.js +61 -0
- package/dist/commands/build.js.map +1 -0
- package/dist/commands/deploy.d.ts +3 -0
- package/dist/commands/deploy.d.ts.map +1 -0
- package/dist/commands/deploy.js +145 -0
- package/dist/commands/deploy.js.map +1 -0
- package/dist/commands/dev.d.ts +3 -0
- package/dist/commands/dev.d.ts.map +1 -0
- package/dist/commands/dev.js +418 -0
- package/dist/commands/dev.js.map +1 -0
- package/dist/commands/init.d.ts +5 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +241 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/login.d.ts +5 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +175 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logout.d.ts +3 -0
- package/dist/commands/logout.d.ts.map +1 -0
- package/dist/commands/logout.js +19 -0
- package/dist/commands/logout.js.map +1 -0
- package/dist/commands/logs.d.ts +3 -0
- package/dist/commands/logs.d.ts.map +1 -0
- package/dist/commands/logs.js +103 -0
- package/dist/commands/logs.js.map +1 -0
- package/dist/commands/state.d.ts +3 -0
- package/dist/commands/state.d.ts.map +1 -0
- package/dist/commands/state.js +71 -0
- package/dist/commands/state.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 +188 -0
- package/dist/commands/test.js.map +1 -0
- package/dist/commands/validate.d.ts +3 -0
- package/dist/commands/validate.d.ts.map +1 -0
- package/dist/commands/validate.js +71 -0
- package/dist/commands/validate.js.map +1 -0
- package/dist/commands/whoami.d.ts +3 -0
- package/dist/commands/whoami.d.ts.map +1 -0
- package/dist/commands/whoami.js +69 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +74 -46
- package/dist/index.js.map +1 -0
- package/dist/templates/index.d.ts +13 -0
- package/dist/templates/index.d.ts.map +1 -0
- package/dist/templates/index.js +246 -0
- package/dist/templates/index.js.map +1 -0
- package/dist/utils/agent.d.ts +3 -0
- package/dist/utils/agent.d.ts.map +1 -0
- package/dist/utils/agent.js +25 -0
- package/dist/utils/agent.js.map +1 -0
- package/dist/utils/api.d.ts +150 -0
- package/dist/utils/api.d.ts.map +1 -0
- package/dist/utils/api.js +107 -0
- package/dist/utils/api.js.map +1 -0
- package/dist/utils/config.d.ts +3 -0
- package/dist/utils/config.d.ts.map +1 -0
- package/dist/utils/config.js +43 -0
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/credentials.d.ts +23 -0
- package/dist/utils/credentials.d.ts.map +1 -0
- package/dist/utils/credentials.js +51 -0
- package/dist/utils/credentials.js.map +1 -0
- package/dist/utils/project.d.ts +12 -0
- package/dist/utils/project.d.ts.map +1 -0
- package/dist/utils/project.js +24 -0
- package/dist/utils/project.js.map +1 -0
- package/dist/utils/scaffold.d.ts +17 -0
- package/dist/utils/scaffold.d.ts.map +1 -0
- package/dist/utils/scaffold.js +106 -0
- package/dist/utils/scaffold.js.map +1 -0
- package/dist/utils/validate.d.ts +3 -0
- package/dist/utils/validate.d.ts.map +1 -0
- package/dist/utils/validate.js +79 -0
- package/dist/utils/validate.js.map +1 -0
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -66,7 +66,7 @@ import ora from "ora";
|
|
|
66
66
|
|
|
67
67
|
// src/utils/api.ts
|
|
68
68
|
var DEFAULT_API_URL = "https://api.struere.dev";
|
|
69
|
-
var DEFAULT_SYNC_URL = "wss://
|
|
69
|
+
var DEFAULT_SYNC_URL = "wss://gateway.struere.dev";
|
|
70
70
|
function getApiUrl() {
|
|
71
71
|
return process.env.STRUERE_API_URL || DEFAULT_API_URL;
|
|
72
72
|
}
|
|
@@ -77,9 +77,11 @@ function getSyncUrl() {
|
|
|
77
77
|
class ApiClient {
|
|
78
78
|
baseUrl;
|
|
79
79
|
tokenOverride;
|
|
80
|
-
|
|
80
|
+
useClerkAuth;
|
|
81
|
+
constructor(baseUrl, token, useClerkAuth = false) {
|
|
81
82
|
this.baseUrl = baseUrl || getApiUrl();
|
|
82
83
|
this.tokenOverride = token;
|
|
84
|
+
this.useClerkAuth = useClerkAuth || !!token;
|
|
83
85
|
}
|
|
84
86
|
async request(path, options = {}) {
|
|
85
87
|
const token = this.tokenOverride || getToken();
|
|
@@ -117,7 +119,8 @@ class ApiClient {
|
|
|
117
119
|
});
|
|
118
120
|
}
|
|
119
121
|
async getMe() {
|
|
120
|
-
|
|
122
|
+
const endpoint = this.useClerkAuth ? "/v1/auth/clerk/me" : "/v1/auth/me";
|
|
123
|
+
return this.request(endpoint);
|
|
121
124
|
}
|
|
122
125
|
async refreshToken() {
|
|
123
126
|
return this.request("/v1/auth/refresh", { method: "POST" });
|
|
@@ -246,9 +249,9 @@ async function browserLoginInternal(spinner) {
|
|
|
246
249
|
const { token } = await authPromise;
|
|
247
250
|
spinner.text = "Fetching user info";
|
|
248
251
|
const api = new ApiClient(undefined, token);
|
|
249
|
-
const { user, organization } = await api.getMe();
|
|
252
|
+
const { user, organization, cliToken } = await api.getMe();
|
|
250
253
|
const credentials = {
|
|
251
|
-
token,
|
|
254
|
+
token: cliToken || token,
|
|
252
255
|
user: {
|
|
253
256
|
id: user.id,
|
|
254
257
|
email: user.email,
|
|
@@ -260,7 +263,7 @@ async function browserLoginInternal(spinner) {
|
|
|
260
263
|
name: organization.name,
|
|
261
264
|
slug: organization.slug
|
|
262
265
|
},
|
|
263
|
-
expiresAt: new Date(Date.now() +
|
|
266
|
+
expiresAt: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString()
|
|
264
267
|
};
|
|
265
268
|
saveCredentials(credentials);
|
|
266
269
|
spinner.succeed("Logged in successfully");
|
|
@@ -850,55 +853,49 @@ function slugify(name) {
|
|
|
850
853
|
}
|
|
851
854
|
async function promptYesNo(message) {
|
|
852
855
|
process.stdout.write(chalk2.gray(`${message} (Y/n) `));
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
process.stdin.setEncoding("utf8");
|
|
856
|
-
const onData = (data) => {
|
|
857
|
-
process.stdin.removeListener("data", onData);
|
|
858
|
-
process.stdin.pause();
|
|
859
|
-
const answer = data.trim().toLowerCase();
|
|
860
|
-
resolve(answer === "" || answer === "y" || answer === "yes");
|
|
861
|
-
};
|
|
862
|
-
process.stdin.on("data", onData);
|
|
863
|
-
});
|
|
856
|
+
const answer = await readLine();
|
|
857
|
+
return answer === "" || answer.toLowerCase() === "y" || answer.toLowerCase() === "yes";
|
|
864
858
|
}
|
|
865
859
|
async function promptText(message, defaultValue) {
|
|
866
860
|
process.stdout.write(chalk2.gray(`${message} `));
|
|
867
861
|
process.stdout.write(chalk2.cyan(`(${defaultValue}) `));
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
process.stdin.setEncoding("utf8");
|
|
871
|
-
const onData = (data) => {
|
|
872
|
-
process.stdin.removeListener("data", onData);
|
|
873
|
-
process.stdin.pause();
|
|
874
|
-
const answer = data.trim();
|
|
875
|
-
resolve(answer || defaultValue);
|
|
876
|
-
};
|
|
877
|
-
process.stdin.on("data", onData);
|
|
878
|
-
});
|
|
862
|
+
const answer = await readLine();
|
|
863
|
+
return answer || defaultValue;
|
|
879
864
|
}
|
|
880
865
|
async function promptChoice(message, choices) {
|
|
881
866
|
console.log(chalk2.gray(message));
|
|
882
867
|
console.log();
|
|
883
868
|
for (let i = 0;i < choices.length; i++) {
|
|
884
869
|
const prefix = i === 0 ? chalk2.cyan("\u276F") : chalk2.gray(" ");
|
|
885
|
-
console.log(`${prefix} ${choices[i].label}`);
|
|
870
|
+
console.log(`${prefix} ${i + 1}. ${choices[i].label}`);
|
|
886
871
|
}
|
|
887
872
|
console.log();
|
|
888
873
|
process.stdout.write(chalk2.gray("Enter choice (1-" + choices.length + "): "));
|
|
874
|
+
const answer = await readLine();
|
|
875
|
+
const num = parseInt(answer, 10);
|
|
876
|
+
if (num >= 1 && num <= choices.length) {
|
|
877
|
+
return choices[num - 1].value;
|
|
878
|
+
}
|
|
879
|
+
return choices[0].value;
|
|
880
|
+
}
|
|
881
|
+
function readLine() {
|
|
889
882
|
return new Promise((resolve) => {
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
resolve(
|
|
883
|
+
let buffer = "";
|
|
884
|
+
const onData = (chunk) => {
|
|
885
|
+
const str = chunk.toString();
|
|
886
|
+
buffer += str;
|
|
887
|
+
if (str.includes(`
|
|
888
|
+
`) || str.includes("\r")) {
|
|
889
|
+
process.stdin.removeListener("data", onData);
|
|
890
|
+
process.stdin.pause();
|
|
891
|
+
process.stdin.setRawMode?.(false);
|
|
892
|
+
resolve(buffer.replace(/[\r\n]/g, "").trim());
|
|
900
893
|
}
|
|
901
894
|
};
|
|
895
|
+
if (process.stdin.isTTY) {
|
|
896
|
+
process.stdin.setRawMode?.(false);
|
|
897
|
+
}
|
|
898
|
+
process.stdin.resume();
|
|
902
899
|
process.stdin.on("data", onData);
|
|
903
900
|
});
|
|
904
901
|
}
|
|
@@ -979,7 +976,7 @@ async function loadAgent(cwd) {
|
|
|
979
976
|
}
|
|
980
977
|
|
|
981
978
|
// src/commands/dev.ts
|
|
982
|
-
var devCommand = new Command3("dev").description("Start development server with cloud sync").option("-p, --port <port>", "Port to run on", "3000").option("-c, --channel <channel>", "Channel to open (web, api)", "web").option("--no-open", "Do not open browser").action(async (options) => {
|
|
979
|
+
var devCommand = new Command3("dev").description("Start development server with cloud sync").option("-p, --port <port>", "Port to run on", "3000").option("-c, --channel <channel>", "Channel to open (web, api)", "web").option("--no-open", "Do not open browser").option("--local", "Run locally without cloud sync").action(async (options) => {
|
|
983
980
|
const spinner = ora3();
|
|
984
981
|
const cwd = process.cwd();
|
|
985
982
|
console.log();
|
|
@@ -1690,7 +1687,8 @@ import { Command as Command6 } from "commander";
|
|
|
1690
1687
|
import chalk6 from "chalk";
|
|
1691
1688
|
import ora6 from "ora";
|
|
1692
1689
|
import { join as join10 } from "path";
|
|
1693
|
-
var deployCommand = new Command6("deploy").description("Deploy agent to
|
|
1690
|
+
var deployCommand = new Command6("deploy").description("Deploy agent to production").option("--dry-run", "Show what would be deployed without deploying").action(async (options) => {
|
|
1691
|
+
const environment = "production";
|
|
1694
1692
|
const spinner = ora6();
|
|
1695
1693
|
const cwd = process.cwd();
|
|
1696
1694
|
console.log();
|
|
@@ -1735,7 +1733,7 @@ var deployCommand = new Command6("deploy").description("Deploy agent to Struere
|
|
|
1735
1733
|
console.log("Would deploy:");
|
|
1736
1734
|
console.log(chalk6.gray(" -"), `Agent: ${chalk6.cyan(agent.name)}`);
|
|
1737
1735
|
console.log(chalk6.gray(" -"), `Version: ${chalk6.cyan(agent.version)}`);
|
|
1738
|
-
console.log(chalk6.gray(" -"), `Environment: ${chalk6.cyan(
|
|
1736
|
+
console.log(chalk6.gray(" -"), `Environment: ${chalk6.cyan(environment)}`);
|
|
1739
1737
|
console.log(chalk6.gray(" -"), `Agent ID: ${chalk6.cyan(project.agentId)}`);
|
|
1740
1738
|
console.log();
|
|
1741
1739
|
return;
|
|
@@ -1767,13 +1765,13 @@ var deployCommand = new Command6("deploy").description("Deploy agent to Struere
|
|
|
1767
1765
|
}
|
|
1768
1766
|
const bundle = await result.outputs[0].text();
|
|
1769
1767
|
spinner.succeed(`Bundle created (${formatBytes(bundle.length)})`);
|
|
1770
|
-
spinner.start(`Deploying to ${
|
|
1768
|
+
spinner.start(`Deploying to ${environment}`);
|
|
1771
1769
|
try {
|
|
1772
1770
|
const api = new ApiClient;
|
|
1773
1771
|
const { deployment } = await api.deployAgent(project.agentId, {
|
|
1774
1772
|
bundle,
|
|
1775
1773
|
version: agent.version,
|
|
1776
|
-
environment
|
|
1774
|
+
environment,
|
|
1777
1775
|
metadata: {
|
|
1778
1776
|
modelProvider: agent.model?.provider || "anthropic",
|
|
1779
1777
|
modelName: agent.model?.name || "claude-sonnet-4-20250514",
|
|
@@ -1781,7 +1779,7 @@ var deployCommand = new Command6("deploy").description("Deploy agent to Struere
|
|
|
1781
1779
|
bundleSize: bundle.length
|
|
1782
1780
|
}
|
|
1783
1781
|
});
|
|
1784
|
-
spinner.succeed(`Deployed to ${
|
|
1782
|
+
spinner.succeed(`Deployed to ${environment}`);
|
|
1785
1783
|
console.log();
|
|
1786
1784
|
console.log(chalk6.green("Success!"), "Agent deployed");
|
|
1787
1785
|
console.log();
|
|
@@ -2116,7 +2114,37 @@ var whoamiCommand = new Command11("whoami").description("Show current logged in
|
|
|
2116
2114
|
});
|
|
2117
2115
|
|
|
2118
2116
|
// src/index.ts
|
|
2119
|
-
|
|
2117
|
+
var CURRENT_VERSION = "0.2.7";
|
|
2118
|
+
async function checkForUpdates() {
|
|
2119
|
+
try {
|
|
2120
|
+
const response = await fetch("https://registry.npmjs.org/@struere/cli/latest", {
|
|
2121
|
+
signal: AbortSignal.timeout(2000)
|
|
2122
|
+
});
|
|
2123
|
+
if (response.ok) {
|
|
2124
|
+
const data = await response.json();
|
|
2125
|
+
if (data.version !== CURRENT_VERSION) {
|
|
2126
|
+
const semverCompare = (a, b) => {
|
|
2127
|
+
const pa = a.split(".").map(Number);
|
|
2128
|
+
const pb = b.split(".").map(Number);
|
|
2129
|
+
for (let i = 0;i < 3; i++) {
|
|
2130
|
+
if (pa[i] > pb[i])
|
|
2131
|
+
return 1;
|
|
2132
|
+
if (pa[i] < pb[i])
|
|
2133
|
+
return -1;
|
|
2134
|
+
}
|
|
2135
|
+
return 0;
|
|
2136
|
+
};
|
|
2137
|
+
if (semverCompare(data.version, CURRENT_VERSION) > 0) {
|
|
2138
|
+
console.log(`\x1B[33m\u26A0 Update available: ${CURRENT_VERSION} \u2192 ${data.version}\x1B[0m`);
|
|
2139
|
+
console.log(`\x1B[90m Run: npm install -g @struere/cli@${data.version}\x1B[0m`);
|
|
2140
|
+
console.log();
|
|
2141
|
+
}
|
|
2142
|
+
}
|
|
2143
|
+
}
|
|
2144
|
+
} catch {}
|
|
2145
|
+
}
|
|
2146
|
+
checkForUpdates();
|
|
2147
|
+
program.name("struere").description("Struere CLI - Build, test, and deploy AI agents").version(CURRENT_VERSION);
|
|
2120
2148
|
program.addCommand(initCommand);
|
|
2121
2149
|
program.addCommand(loginCommand);
|
|
2122
2150
|
program.addCommand(logoutCommand);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare function getPackageJson(name: string): string;
|
|
2
|
+
export declare function getTsConfig(): string;
|
|
3
|
+
export declare function getStruereConfig(): string;
|
|
4
|
+
export declare function getAgentTs(name: string): string;
|
|
5
|
+
export declare function getContextTs(): string;
|
|
6
|
+
export declare function getToolsTs(): string;
|
|
7
|
+
export declare function getBasicTestYaml(): string;
|
|
8
|
+
export declare function getEnvExample(): string;
|
|
9
|
+
export declare function getGitignore(): string;
|
|
10
|
+
export declare function getVercelApiHandler(): string;
|
|
11
|
+
export declare function getStruereJson(agentId: string, team: string, slug: string, name: string): string;
|
|
12
|
+
export declare function getEnvLocal(deploymentUrl: string): string;
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/templates/index.ts"],"names":[],"mappings":"AAAA,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAyBnD;AAED,wBAAgB,WAAW,IAAI,MAAM,CAsBpC;AAED,wBAAgB,gBAAgB,IAAI,MAAM,CAgBzC;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAoC/C;AAED,wBAAgB,YAAY,IAAI,MAAM,CAkBrC;AAED,wBAAgB,UAAU,IAAI,MAAM,CAoDnC;AAED,wBAAgB,gBAAgB,IAAI,MAAM,CAmBzC;AAED,wBAAgB,aAAa,IAAI,MAAM,CAatC;AAED,wBAAgB,YAAY,IAAI,MAAM,CAgBrC;AAED,wBAAgB,mBAAmB,IAAI,MAAM,CAa5C;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAahG;AAED,wBAAgB,WAAW,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAGzD"}
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
export function getPackageJson(name) {
|
|
2
|
+
return JSON.stringify({
|
|
3
|
+
name,
|
|
4
|
+
version: '0.1.0',
|
|
5
|
+
type: 'module',
|
|
6
|
+
scripts: {
|
|
7
|
+
dev: 'struere dev',
|
|
8
|
+
build: 'struere build',
|
|
9
|
+
test: 'struere test',
|
|
10
|
+
deploy: 'struere deploy',
|
|
11
|
+
},
|
|
12
|
+
dependencies: {
|
|
13
|
+
'@struere/core': '^0.1.0',
|
|
14
|
+
'@struere/runtime': '^0.1.0',
|
|
15
|
+
},
|
|
16
|
+
devDependencies: {
|
|
17
|
+
'@struere/cli': '^0.1.0',
|
|
18
|
+
'bun-types': '^1.0.0',
|
|
19
|
+
typescript: '^5.3.0',
|
|
20
|
+
},
|
|
21
|
+
}, null, 2);
|
|
22
|
+
}
|
|
23
|
+
export function getTsConfig() {
|
|
24
|
+
return JSON.stringify({
|
|
25
|
+
compilerOptions: {
|
|
26
|
+
target: 'ES2022',
|
|
27
|
+
module: 'ESNext',
|
|
28
|
+
moduleResolution: 'bundler',
|
|
29
|
+
lib: ['ES2022'],
|
|
30
|
+
strict: true,
|
|
31
|
+
esModuleInterop: true,
|
|
32
|
+
skipLibCheck: true,
|
|
33
|
+
forceConsistentCasingInFileNames: true,
|
|
34
|
+
outDir: 'dist',
|
|
35
|
+
rootDir: 'src',
|
|
36
|
+
types: ['bun-types'],
|
|
37
|
+
},
|
|
38
|
+
include: ['src/**/*'],
|
|
39
|
+
exclude: ['node_modules', 'dist'],
|
|
40
|
+
}, null, 2);
|
|
41
|
+
}
|
|
42
|
+
export function getStruereConfig() {
|
|
43
|
+
return `import { defineConfig } from '@struere/core'
|
|
44
|
+
|
|
45
|
+
export default defineConfig({
|
|
46
|
+
port: 3000,
|
|
47
|
+
host: 'localhost',
|
|
48
|
+
cors: {
|
|
49
|
+
origins: ['http://localhost:3000'],
|
|
50
|
+
credentials: true,
|
|
51
|
+
},
|
|
52
|
+
logging: {
|
|
53
|
+
level: 'info',
|
|
54
|
+
format: 'pretty',
|
|
55
|
+
},
|
|
56
|
+
})
|
|
57
|
+
`;
|
|
58
|
+
}
|
|
59
|
+
export function getAgentTs(name) {
|
|
60
|
+
const displayName = name
|
|
61
|
+
.split('-')
|
|
62
|
+
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
|
|
63
|
+
.join(' ');
|
|
64
|
+
return `import { defineAgent } from '@struere/core'
|
|
65
|
+
import { context } from './context'
|
|
66
|
+
import { tools } from './tools'
|
|
67
|
+
|
|
68
|
+
export default defineAgent({
|
|
69
|
+
name: '${name}',
|
|
70
|
+
version: '0.1.0',
|
|
71
|
+
description: '${displayName} Agent',
|
|
72
|
+
model: {
|
|
73
|
+
provider: 'anthropic',
|
|
74
|
+
name: 'claude-sonnet-4-20250514',
|
|
75
|
+
temperature: 0.7,
|
|
76
|
+
maxTokens: 4096,
|
|
77
|
+
},
|
|
78
|
+
systemPrompt: \`You are ${displayName}, a helpful AI assistant.
|
|
79
|
+
|
|
80
|
+
Your capabilities:
|
|
81
|
+
- Answer questions accurately and helpfully
|
|
82
|
+
- Use available tools when appropriate
|
|
83
|
+
- Maintain conversation context
|
|
84
|
+
|
|
85
|
+
Always be concise, accurate, and helpful.\`,
|
|
86
|
+
tools,
|
|
87
|
+
context,
|
|
88
|
+
state: {
|
|
89
|
+
storage: 'memory',
|
|
90
|
+
ttl: 3600,
|
|
91
|
+
},
|
|
92
|
+
})
|
|
93
|
+
`;
|
|
94
|
+
}
|
|
95
|
+
export function getContextTs() {
|
|
96
|
+
return `import { defineContext } from '@struere/core'
|
|
97
|
+
|
|
98
|
+
export const context = defineContext(async (request) => {
|
|
99
|
+
const { conversationId, userId, channel, state } = request
|
|
100
|
+
|
|
101
|
+
return {
|
|
102
|
+
additionalContext: \`
|
|
103
|
+
Current conversation: \${conversationId}
|
|
104
|
+
Channel: \${channel}
|
|
105
|
+
\`,
|
|
106
|
+
variables: {
|
|
107
|
+
userId,
|
|
108
|
+
timestamp: new Date().toISOString(),
|
|
109
|
+
},
|
|
110
|
+
}
|
|
111
|
+
})
|
|
112
|
+
`;
|
|
113
|
+
}
|
|
114
|
+
export function getToolsTs() {
|
|
115
|
+
return `import { defineTools } from '@struere/core'
|
|
116
|
+
|
|
117
|
+
export const tools = defineTools([
|
|
118
|
+
{
|
|
119
|
+
name: 'get_current_time',
|
|
120
|
+
description: 'Get the current date and time',
|
|
121
|
+
parameters: {
|
|
122
|
+
type: 'object',
|
|
123
|
+
properties: {
|
|
124
|
+
timezone: {
|
|
125
|
+
type: 'string',
|
|
126
|
+
description: 'Timezone (e.g., "America/New_York", "UTC")',
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
},
|
|
130
|
+
handler: async (params) => {
|
|
131
|
+
const timezone = (params.timezone as string) || 'UTC'
|
|
132
|
+
const now = new Date()
|
|
133
|
+
return {
|
|
134
|
+
timestamp: now.toISOString(),
|
|
135
|
+
formatted: now.toLocaleString('en-US', { timeZone: timezone }),
|
|
136
|
+
timezone,
|
|
137
|
+
}
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
name: 'calculate',
|
|
142
|
+
description: 'Perform a mathematical calculation',
|
|
143
|
+
parameters: {
|
|
144
|
+
type: 'object',
|
|
145
|
+
properties: {
|
|
146
|
+
expression: {
|
|
147
|
+
type: 'string',
|
|
148
|
+
description: 'Mathematical expression to evaluate (e.g., "2 + 2")',
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
required: ['expression'],
|
|
152
|
+
},
|
|
153
|
+
handler: async (params) => {
|
|
154
|
+
const expression = params.expression as string
|
|
155
|
+
const sanitized = expression.replace(/[^0-9+*/().\\s-]/g, '')
|
|
156
|
+
try {
|
|
157
|
+
const result = new Function(\`return \${sanitized}\`)()
|
|
158
|
+
return { expression, result }
|
|
159
|
+
} catch {
|
|
160
|
+
return { expression, error: 'Invalid expression' }
|
|
161
|
+
}
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
])
|
|
165
|
+
`;
|
|
166
|
+
}
|
|
167
|
+
export function getBasicTestYaml() {
|
|
168
|
+
return `name: Basic conversation test
|
|
169
|
+
description: Verify the agent responds correctly to basic queries
|
|
170
|
+
|
|
171
|
+
conversation:
|
|
172
|
+
- role: user
|
|
173
|
+
content: Hello, what can you do?
|
|
174
|
+
- role: assistant
|
|
175
|
+
assertions:
|
|
176
|
+
- type: contains
|
|
177
|
+
value: help
|
|
178
|
+
|
|
179
|
+
- role: user
|
|
180
|
+
content: What time is it?
|
|
181
|
+
- role: assistant
|
|
182
|
+
assertions:
|
|
183
|
+
- type: toolCalled
|
|
184
|
+
value: get_current_time
|
|
185
|
+
`;
|
|
186
|
+
}
|
|
187
|
+
export function getEnvExample() {
|
|
188
|
+
return `# Anthropic API Key (default provider)
|
|
189
|
+
ANTHROPIC_API_KEY=your_api_key_here
|
|
190
|
+
|
|
191
|
+
# Optional: OpenAI API Key (if using OpenAI models)
|
|
192
|
+
# OPENAI_API_KEY=your_openai_api_key
|
|
193
|
+
|
|
194
|
+
# Optional: Google AI API Key (if using Gemini models)
|
|
195
|
+
# GOOGLE_GENERATIVE_AI_API_KEY=your_google_api_key
|
|
196
|
+
|
|
197
|
+
# Optional: Custom API endpoint
|
|
198
|
+
# STRUERE_API_URL=https://api.struere.dev
|
|
199
|
+
`;
|
|
200
|
+
}
|
|
201
|
+
export function getGitignore() {
|
|
202
|
+
return `node_modules/
|
|
203
|
+
dist/
|
|
204
|
+
.env
|
|
205
|
+
.env.local
|
|
206
|
+
.env.*.local
|
|
207
|
+
.idea/
|
|
208
|
+
.vscode/
|
|
209
|
+
*.swp
|
|
210
|
+
*.swo
|
|
211
|
+
.DS_Store
|
|
212
|
+
Thumbs.db
|
|
213
|
+
*.log
|
|
214
|
+
logs/
|
|
215
|
+
.vercel/
|
|
216
|
+
`;
|
|
217
|
+
}
|
|
218
|
+
export function getVercelApiHandler() {
|
|
219
|
+
return `import agent from '../src/agent'
|
|
220
|
+
import { createVercelHandler } from '@struere/runtime/serverless/vercel'
|
|
221
|
+
|
|
222
|
+
export default createVercelHandler(agent, {
|
|
223
|
+
streaming: true,
|
|
224
|
+
corsOrigins: ['*'],
|
|
225
|
+
})
|
|
226
|
+
|
|
227
|
+
export const config = {
|
|
228
|
+
runtime: 'edge',
|
|
229
|
+
}
|
|
230
|
+
`;
|
|
231
|
+
}
|
|
232
|
+
export function getStruereJson(agentId, team, slug, name) {
|
|
233
|
+
return JSON.stringify({
|
|
234
|
+
agentId,
|
|
235
|
+
team,
|
|
236
|
+
agent: {
|
|
237
|
+
slug,
|
|
238
|
+
name,
|
|
239
|
+
},
|
|
240
|
+
}, null, 2);
|
|
241
|
+
}
|
|
242
|
+
export function getEnvLocal(deploymentUrl) {
|
|
243
|
+
return `STRUERE_DEPLOYMENT_URL=${deploymentUrl}
|
|
244
|
+
`;
|
|
245
|
+
}
|
|
246
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/templates/index.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,OAAO,IAAI,CAAC,SAAS,CACnB;QACE,IAAI;QACJ,OAAO,EAAE,OAAO;QAChB,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE;YACP,GAAG,EAAE,aAAa;YAClB,KAAK,EAAE,eAAe;YACtB,IAAI,EAAE,cAAc;YACpB,MAAM,EAAE,gBAAgB;SACzB;QACD,YAAY,EAAE;YACZ,eAAe,EAAE,QAAQ;YACzB,kBAAkB,EAAE,QAAQ;SAC7B;QACD,eAAe,EAAE;YACf,cAAc,EAAE,QAAQ;YACxB,WAAW,EAAE,QAAQ;YACrB,UAAU,EAAE,QAAQ;SACrB;KACF,EACD,IAAI,EACJ,CAAC,CACF,CAAA;AACH,CAAC;AAED,MAAM,UAAU,WAAW;IACzB,OAAO,IAAI,CAAC,SAAS,CACnB;QACE,eAAe,EAAE;YACf,MAAM,EAAE,QAAQ;YAChB,MAAM,EAAE,QAAQ;YAChB,gBAAgB,EAAE,SAAS;YAC3B,GAAG,EAAE,CAAC,QAAQ,CAAC;YACf,MAAM,EAAE,IAAI;YACZ,eAAe,EAAE,IAAI;YACrB,YAAY,EAAE,IAAI;YAClB,gCAAgC,EAAE,IAAI;YACtC,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,CAAC,WAAW,CAAC;SACrB;QACD,OAAO,EAAE,CAAC,UAAU,CAAC;QACrB,OAAO,EAAE,CAAC,cAAc,EAAE,MAAM,CAAC;KAClC,EACD,IAAI,EACJ,CAAC,CACF,CAAA;AACH,CAAC;AAED,MAAM,UAAU,gBAAgB;IAC9B,OAAO;;;;;;;;;;;;;;CAcR,CAAA;AACD,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,MAAM,WAAW,GAAG,IAAI;SACrB,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;SAC3D,IAAI,CAAC,GAAG,CAAC,CAAA;IAEZ,OAAO;;;;;WAKE,IAAI;;kBAEG,WAAW;;;;;;;4BAOD,WAAW;;;;;;;;;;;;;;;CAetC,CAAA;AACD,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,OAAO;;;;;;;;;;;;;;;;CAgBR,CAAA;AACD,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkDR,CAAA;AACD,CAAC;AAED,MAAM,UAAU,gBAAgB;IAC9B,OAAO;;;;;;;;;;;;;;;;;CAiBR,CAAA;AACD,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,OAAO;;;;;;;;;;;CAWR,CAAA;AACD,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,OAAO;;;;;;;;;;;;;;CAcR,CAAA;AACD,CAAC;AAED,MAAM,UAAU,mBAAmB;IACjC,OAAO;;;;;;;;;;;CAWR,CAAA;AACD,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,OAAe,EAAE,IAAY,EAAE,IAAY,EAAE,IAAY;IACtF,OAAO,IAAI,CAAC,SAAS,CACnB;QACE,OAAO;QACP,IAAI;QACJ,KAAK,EAAE;YACL,IAAI;YACJ,IAAI;SACL;KACF,EACD,IAAI,EACJ,CAAC,CACF,CAAA;AACH,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,aAAqB;IAC/C,OAAO,0BAA0B,aAAa;CAC/C,CAAA;AACD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/utils/agent.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAEhD,wBAAsB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CA0BjE"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { join } from 'path';
|
|
2
|
+
export async function loadAgent(cwd) {
|
|
3
|
+
const agentPath = join(cwd, 'src/agent.ts');
|
|
4
|
+
try {
|
|
5
|
+
const module = await import(agentPath);
|
|
6
|
+
const agent = module.default || module;
|
|
7
|
+
if (!agent.name) {
|
|
8
|
+
throw new Error('Agent must have a name');
|
|
9
|
+
}
|
|
10
|
+
if (!agent.version) {
|
|
11
|
+
throw new Error('Agent must have a version');
|
|
12
|
+
}
|
|
13
|
+
if (!agent.systemPrompt) {
|
|
14
|
+
throw new Error('Agent must have a systemPrompt');
|
|
15
|
+
}
|
|
16
|
+
return agent;
|
|
17
|
+
}
|
|
18
|
+
catch (error) {
|
|
19
|
+
if (error instanceof Error && error.message.includes('Cannot find module')) {
|
|
20
|
+
throw new Error(`Agent not found at ${agentPath}`);
|
|
21
|
+
}
|
|
22
|
+
throw error;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../../src/utils/agent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAG3B,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,GAAW;IACzC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAA;IAE3C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,CAAA;QACtC,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,IAAI,MAAM,CAAA;QAEtC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAA;QAC3C,CAAC;QAED,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAA;QAC9C,CAAC;QAED,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAA;QACnD,CAAC;QAED,OAAO,KAAoB,CAAA;IAC7B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAC,EAAE,CAAC;YAC3E,MAAM,IAAI,KAAK,CAAC,sBAAsB,SAAS,EAAE,CAAC,CAAA;QACpD,CAAC;QACD,MAAM,KAAK,CAAA;IACb,CAAC;AACH,CAAC"}
|