@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.
Files changed (81) hide show
  1. package/dist/commands/build.d.ts +3 -0
  2. package/dist/commands/build.d.ts.map +1 -0
  3. package/dist/commands/build.js +61 -0
  4. package/dist/commands/build.js.map +1 -0
  5. package/dist/commands/deploy.d.ts +3 -0
  6. package/dist/commands/deploy.d.ts.map +1 -0
  7. package/dist/commands/deploy.js +145 -0
  8. package/dist/commands/deploy.js.map +1 -0
  9. package/dist/commands/dev.d.ts +3 -0
  10. package/dist/commands/dev.d.ts.map +1 -0
  11. package/dist/commands/dev.js +418 -0
  12. package/dist/commands/dev.js.map +1 -0
  13. package/dist/commands/init.d.ts +5 -0
  14. package/dist/commands/init.d.ts.map +1 -0
  15. package/dist/commands/init.js +241 -0
  16. package/dist/commands/init.js.map +1 -0
  17. package/dist/commands/login.d.ts +5 -0
  18. package/dist/commands/login.d.ts.map +1 -0
  19. package/dist/commands/login.js +175 -0
  20. package/dist/commands/login.js.map +1 -0
  21. package/dist/commands/logout.d.ts +3 -0
  22. package/dist/commands/logout.d.ts.map +1 -0
  23. package/dist/commands/logout.js +19 -0
  24. package/dist/commands/logout.js.map +1 -0
  25. package/dist/commands/logs.d.ts +3 -0
  26. package/dist/commands/logs.d.ts.map +1 -0
  27. package/dist/commands/logs.js +103 -0
  28. package/dist/commands/logs.js.map +1 -0
  29. package/dist/commands/state.d.ts +3 -0
  30. package/dist/commands/state.d.ts.map +1 -0
  31. package/dist/commands/state.js +71 -0
  32. package/dist/commands/state.js.map +1 -0
  33. package/dist/commands/test.d.ts +3 -0
  34. package/dist/commands/test.d.ts.map +1 -0
  35. package/dist/commands/test.js +188 -0
  36. package/dist/commands/test.js.map +1 -0
  37. package/dist/commands/validate.d.ts +3 -0
  38. package/dist/commands/validate.d.ts.map +1 -0
  39. package/dist/commands/validate.js +71 -0
  40. package/dist/commands/validate.js.map +1 -0
  41. package/dist/commands/whoami.d.ts +3 -0
  42. package/dist/commands/whoami.d.ts.map +1 -0
  43. package/dist/commands/whoami.js +69 -0
  44. package/dist/commands/whoami.js.map +1 -0
  45. package/dist/index.d.ts +3 -0
  46. package/dist/index.d.ts.map +1 -0
  47. package/dist/index.js +74 -46
  48. package/dist/index.js.map +1 -0
  49. package/dist/templates/index.d.ts +13 -0
  50. package/dist/templates/index.d.ts.map +1 -0
  51. package/dist/templates/index.js +246 -0
  52. package/dist/templates/index.js.map +1 -0
  53. package/dist/utils/agent.d.ts +3 -0
  54. package/dist/utils/agent.d.ts.map +1 -0
  55. package/dist/utils/agent.js +25 -0
  56. package/dist/utils/agent.js.map +1 -0
  57. package/dist/utils/api.d.ts +150 -0
  58. package/dist/utils/api.d.ts.map +1 -0
  59. package/dist/utils/api.js +107 -0
  60. package/dist/utils/api.js.map +1 -0
  61. package/dist/utils/config.d.ts +3 -0
  62. package/dist/utils/config.d.ts.map +1 -0
  63. package/dist/utils/config.js +43 -0
  64. package/dist/utils/config.js.map +1 -0
  65. package/dist/utils/credentials.d.ts +23 -0
  66. package/dist/utils/credentials.d.ts.map +1 -0
  67. package/dist/utils/credentials.js +51 -0
  68. package/dist/utils/credentials.js.map +1 -0
  69. package/dist/utils/project.d.ts +12 -0
  70. package/dist/utils/project.d.ts.map +1 -0
  71. package/dist/utils/project.js +24 -0
  72. package/dist/utils/project.js.map +1 -0
  73. package/dist/utils/scaffold.d.ts +17 -0
  74. package/dist/utils/scaffold.d.ts.map +1 -0
  75. package/dist/utils/scaffold.js +106 -0
  76. package/dist/utils/scaffold.js.map +1 -0
  77. package/dist/utils/validate.d.ts +3 -0
  78. package/dist/utils/validate.d.ts.map +1 -0
  79. package/dist/utils/validate.js +79 -0
  80. package/dist/utils/validate.js.map +1 -0
  81. 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://sync.struere.dev";
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
- constructor(baseUrl, token) {
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
- return this.request("/v1/auth/me");
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() + 7 * 24 * 60 * 60 * 1000).toISOString()
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
- return new Promise((resolve) => {
854
- process.stdin.resume();
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
- return new Promise((resolve) => {
869
- process.stdin.resume();
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
- process.stdin.resume();
891
- process.stdin.setEncoding("utf8");
892
- const onData = (data) => {
893
- process.stdin.removeListener("data", onData);
894
- process.stdin.pause();
895
- const num = parseInt(data.trim(), 10);
896
- if (num >= 1 && num <= choices.length) {
897
- resolve(choices[num - 1].value);
898
- } else {
899
- resolve(choices[0].value);
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 Struere Cloud").option("-e, --env <environment>", "Target environment (preview, staging, production)", "preview").option("--dry-run", "Show what would be deployed without deploying").action(async (options) => {
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(options.env)}`);
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 ${options.env}`);
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: options.env,
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 ${options.env}`);
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
- program.name("struere").description("Struere CLI - Build, test, and deploy AI agents").version("0.2.4");
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,3 @@
1
+ import type { AgentConfig } from '@struere/core';
2
+ export declare function loadAgent(cwd: string): Promise<AgentConfig>;
3
+ //# sourceMappingURL=agent.d.ts.map
@@ -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"}