@langwatch/better-agents 0.1.19 → 0.1.20
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/index.js +382 -40
- package/dist/index.js.map +1 -1
- package/package.json +2 -3
package/dist/index.js
CHANGED
|
@@ -224,7 +224,7 @@ var ConsoleLogger = class {
|
|
|
224
224
|
*/
|
|
225
225
|
detectDebugMode() {
|
|
226
226
|
return Boolean(
|
|
227
|
-
process.env.
|
|
227
|
+
process.env.BETTERAGENTS_DEBUG || process.argv.includes("--debug") || process.argv.includes("-d")
|
|
228
228
|
);
|
|
229
229
|
}
|
|
230
230
|
/**
|
|
@@ -565,7 +565,7 @@ var MastraFrameworkProvider = {
|
|
|
565
565
|
language: "typescript",
|
|
566
566
|
getKnowledge: getKnowledge2,
|
|
567
567
|
getMCPConfig: getMCPConfig2,
|
|
568
|
-
setup: async (
|
|
568
|
+
setup: async () => {
|
|
569
569
|
}
|
|
570
570
|
};
|
|
571
571
|
|
|
@@ -621,7 +621,7 @@ var LangGraphPyFrameworkProvider = {
|
|
|
621
621
|
language: "python",
|
|
622
622
|
getKnowledge: getKnowledge3,
|
|
623
623
|
getMCPConfig: getMCPConfig3,
|
|
624
|
-
setup: async (
|
|
624
|
+
setup: async () => {
|
|
625
625
|
}
|
|
626
626
|
};
|
|
627
627
|
|
|
@@ -683,7 +683,7 @@ var LangGraphTSFrameworkProvider = {
|
|
|
683
683
|
language: "typescript",
|
|
684
684
|
getKnowledge: getKnowledge4,
|
|
685
685
|
getMCPConfig: getMCPConfig4,
|
|
686
|
-
setup: async (
|
|
686
|
+
setup: async () => {
|
|
687
687
|
}
|
|
688
688
|
};
|
|
689
689
|
|
|
@@ -790,7 +790,70 @@ var GoogleAdkFrameworkProvider = {
|
|
|
790
790
|
getKnowledge: getKnowledge5,
|
|
791
791
|
getMCPConfig: getMCPConfig5,
|
|
792
792
|
// setup,
|
|
793
|
-
setup: async (
|
|
793
|
+
setup: async () => {
|
|
794
|
+
}
|
|
795
|
+
};
|
|
796
|
+
|
|
797
|
+
// src/providers/frameworks/vercel-ai/knowledge.ts
|
|
798
|
+
var getKnowledge6 = () => ({
|
|
799
|
+
setupInstructions: "TypeScript w/pnpm + vitest",
|
|
800
|
+
toolingInstructions: "Use the Vercel MCP to learn about Vercel AI SDK and how to build agents",
|
|
801
|
+
agentsGuideSection: `## Framework-Specific Guidelines
|
|
802
|
+
|
|
803
|
+
### Vercel AI SDK Framework
|
|
804
|
+
|
|
805
|
+
**Always use the Vercel MCP for learning:**
|
|
806
|
+
|
|
807
|
+
- The Vercel MCP server provides real-time documentation for Vercel AI SDK
|
|
808
|
+
- Ask it questions about Vercel AI SDK APIs and best practices
|
|
809
|
+
- Follow Vercel AI SDK's recommended patterns for agent development
|
|
810
|
+
|
|
811
|
+
**When implementing agent features:**
|
|
812
|
+
1. Consult the Vercel MCP: "How do I [do X] in Vercel AI SDK?"
|
|
813
|
+
2. Use Vercel AI SDK's unified provider architecture
|
|
814
|
+
3. Follow Vercel AI SDK's TypeScript patterns and conventions
|
|
815
|
+
4. Leverage Vercel AI SDK's framework integrations (Next.js, React, Svelte, Vue, Node.js)
|
|
816
|
+
|
|
817
|
+
**Initial setup:**
|
|
818
|
+
1. Use \`pnpm init\` to create a new project
|
|
819
|
+
2. Install dependencies: \`pnpm add ai @ai-sdk/openai\` (or other provider packages like \`@ai-sdk/anthropic\`, \`@ai-sdk/google\`)
|
|
820
|
+
3. Set up TypeScript configuration
|
|
821
|
+
4. Proceed with the user definition request to implement the agent and test it out
|
|
822
|
+
5. Run the agent using \`pnpm tsx src/index.ts\` or integrate with your chosen framework
|
|
823
|
+
|
|
824
|
+
**Key Concepts:**
|
|
825
|
+
- **Unified Provider Architecture**: Consistent interface across multiple AI model providers
|
|
826
|
+
- **generateText**: Generate text using any supported model
|
|
827
|
+
- **streamText**: Stream text responses for real-time interactions
|
|
828
|
+
- **Framework Integration**: Works with Next.js, React, Svelte, Vue, and Node.js
|
|
829
|
+
|
|
830
|
+
---
|
|
831
|
+
`
|
|
832
|
+
});
|
|
833
|
+
|
|
834
|
+
// src/providers/frameworks/vercel-ai/mcp-config.ts
|
|
835
|
+
var getMCPConfig6 = () => ({
|
|
836
|
+
type: "stdio",
|
|
837
|
+
command: "uvx",
|
|
838
|
+
args: [
|
|
839
|
+
"--from",
|
|
840
|
+
"mcpdoc",
|
|
841
|
+
"mcpdoc",
|
|
842
|
+
"--urls",
|
|
843
|
+
"Vercel:https://ai-sdk.dev/docs/introduction",
|
|
844
|
+
"--transport",
|
|
845
|
+
"stdio"
|
|
846
|
+
]
|
|
847
|
+
});
|
|
848
|
+
|
|
849
|
+
// src/providers/frameworks/vercel-ai/index.ts
|
|
850
|
+
var VercelAIFrameworkProvider = {
|
|
851
|
+
id: "vercel-ai",
|
|
852
|
+
displayName: "Vercel AI SDK",
|
|
853
|
+
language: "typescript",
|
|
854
|
+
getKnowledge: getKnowledge6,
|
|
855
|
+
getMCPConfig: getMCPConfig6,
|
|
856
|
+
setup: async () => {
|
|
794
857
|
}
|
|
795
858
|
};
|
|
796
859
|
|
|
@@ -800,7 +863,8 @@ var PROVIDERS = {
|
|
|
800
863
|
mastra: MastraFrameworkProvider,
|
|
801
864
|
"langgraph-py": LangGraphPyFrameworkProvider,
|
|
802
865
|
"langgraph-ts": LangGraphTSFrameworkProvider,
|
|
803
|
-
"google-adk": GoogleAdkFrameworkProvider
|
|
866
|
+
"google-adk": GoogleAdkFrameworkProvider,
|
|
867
|
+
"vercel-ai": VercelAIFrameworkProvider
|
|
804
868
|
};
|
|
805
869
|
var getFrameworkProvider = ({
|
|
806
870
|
framework
|
|
@@ -879,7 +943,7 @@ var CliUtils = class {
|
|
|
879
943
|
};
|
|
880
944
|
|
|
881
945
|
// src/providers/languages/python/knowledge.ts
|
|
882
|
-
var
|
|
946
|
+
var getKnowledge7 = () => ({
|
|
883
947
|
setupInstructions: "Python with uv + pytest (install uv for them if they don't have it)",
|
|
884
948
|
sourceExtensions: [".py"],
|
|
885
949
|
testFramework: "pytest"
|
|
@@ -889,11 +953,11 @@ var getKnowledge6 = () => ({
|
|
|
889
953
|
var PythonLanguageProvider = {
|
|
890
954
|
id: "python",
|
|
891
955
|
displayName: "Python",
|
|
892
|
-
getKnowledge:
|
|
956
|
+
getKnowledge: getKnowledge7
|
|
893
957
|
};
|
|
894
958
|
|
|
895
959
|
// src/providers/languages/typescript/knowledge.ts
|
|
896
|
-
var
|
|
960
|
+
var getKnowledge8 = () => ({
|
|
897
961
|
setupInstructions: "TypeScript with pnpm + vitest (install pnpm for them if they don't have it)",
|
|
898
962
|
sourceExtensions: [".ts", ".tsx"],
|
|
899
963
|
testFramework: "vitest"
|
|
@@ -903,7 +967,7 @@ var getKnowledge7 = () => ({
|
|
|
903
967
|
var TypeScriptLanguageProvider = {
|
|
904
968
|
id: "typescript",
|
|
905
969
|
displayName: "TypeScript",
|
|
906
|
-
getKnowledge:
|
|
970
|
+
getKnowledge: getKnowledge8
|
|
907
971
|
};
|
|
908
972
|
|
|
909
973
|
// src/providers/languages/index.ts
|
|
@@ -1023,7 +1087,12 @@ var ClaudeCodingAssistantProvider = {
|
|
|
1023
1087
|
cwd: projectPath
|
|
1024
1088
|
});
|
|
1025
1089
|
logger.userSuccess("Session complete!");
|
|
1026
|
-
} catch {
|
|
1090
|
+
} catch (error) {
|
|
1091
|
+
if (error instanceof Error) {
|
|
1092
|
+
logger.error(error, { step: "claude-launch-failed" });
|
|
1093
|
+
} else {
|
|
1094
|
+
logger.debug("claude-launch-failed", { error: String(error) });
|
|
1095
|
+
}
|
|
1027
1096
|
logger.userWarning(`Could not auto-launch ${this.displayName}.`);
|
|
1028
1097
|
showManualLaunchInstructions({
|
|
1029
1098
|
targetPath,
|
|
@@ -1035,35 +1104,84 @@ var ClaudeCodingAssistantProvider = {
|
|
|
1035
1104
|
}
|
|
1036
1105
|
}
|
|
1037
1106
|
};
|
|
1107
|
+
var OSUtils = class {
|
|
1108
|
+
/**
|
|
1109
|
+
* Checks if we're running on a Unix platform (Mac/Linux/WSL).
|
|
1110
|
+
*
|
|
1111
|
+
* @returns true if running on Unix platform, false otherwise
|
|
1112
|
+
*
|
|
1113
|
+
* @example
|
|
1114
|
+
* ```ts
|
|
1115
|
+
* if (OSUtils.isUnix) {
|
|
1116
|
+
* // Unix-specific code
|
|
1117
|
+
* }
|
|
1118
|
+
* ```
|
|
1119
|
+
*/
|
|
1120
|
+
static get isUnix() {
|
|
1121
|
+
return os.platform() !== "win32";
|
|
1122
|
+
}
|
|
1123
|
+
/**
|
|
1124
|
+
* Checks if we're running on macOS.
|
|
1125
|
+
*
|
|
1126
|
+
* @returns true if running on macOS, false otherwise
|
|
1127
|
+
*
|
|
1128
|
+
* @example
|
|
1129
|
+
* ```ts
|
|
1130
|
+
* if (OSUtils.isMac) {
|
|
1131
|
+
* // macOS-specific code
|
|
1132
|
+
* }
|
|
1133
|
+
* ```
|
|
1134
|
+
*/
|
|
1135
|
+
static get isMac() {
|
|
1136
|
+
return os.platform() === "darwin";
|
|
1137
|
+
}
|
|
1138
|
+
};
|
|
1038
1139
|
|
|
1039
1140
|
// src/providers/coding-assistants/cursor/index.ts
|
|
1040
1141
|
var CursorCodingAssistantProvider = {
|
|
1041
1142
|
id: "cursor",
|
|
1042
|
-
displayName: "Cursor",
|
|
1043
|
-
command: "",
|
|
1143
|
+
displayName: "Cursor Agent",
|
|
1144
|
+
command: "cursor-agent",
|
|
1044
1145
|
async isAvailable() {
|
|
1045
1146
|
return { installed: true };
|
|
1046
1147
|
},
|
|
1047
1148
|
async launch({
|
|
1048
|
-
|
|
1149
|
+
projectPath,
|
|
1150
|
+
targetPath,
|
|
1151
|
+
prompt
|
|
1049
1152
|
}) {
|
|
1153
|
+
if (OSUtils.isMac) {
|
|
1154
|
+
try {
|
|
1155
|
+
logger.userInfo(`\u{1F916} Launching ${this.displayName}...`);
|
|
1156
|
+
ProcessUtils.launchWithTerminalControl("cursor-agent", [prompt], {
|
|
1157
|
+
cwd: projectPath
|
|
1158
|
+
});
|
|
1159
|
+
logger.userSuccess("Session complete!");
|
|
1160
|
+
return;
|
|
1161
|
+
} catch (error) {
|
|
1162
|
+
if (error instanceof Error) {
|
|
1163
|
+
logger.error(error, { step: "cursor-launch-failed" });
|
|
1164
|
+
} else {
|
|
1165
|
+
logger.debug("cursor-launch-failed", { error: String(error) });
|
|
1166
|
+
}
|
|
1167
|
+
logger.userWarning(`Could not auto-launch ${this.displayName}.`);
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1050
1170
|
const isCurrentDir = targetPath === ".";
|
|
1171
|
+
const path14 = isCurrentDir ? "." : targetPath;
|
|
1172
|
+
const composerShortcut = OSUtils.isMac ? "Cmd+I" : "Ctrl+I";
|
|
1051
1173
|
logger.userPlain("");
|
|
1052
|
-
logger.userPlain("
|
|
1174
|
+
logger.userPlain("\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510");
|
|
1175
|
+
logger.userPlain("\u2502 \u{1F680} Next Steps \u2502");
|
|
1176
|
+
logger.userPlain("\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518");
|
|
1053
1177
|
logger.userPlain("");
|
|
1054
|
-
|
|
1055
|
-
logger.userPlain(" 1. Open the current folder in Cursor:");
|
|
1056
|
-
logger.userPlain("");
|
|
1057
|
-
logger.userPlain(" cursor .");
|
|
1058
|
-
} else {
|
|
1059
|
-
logger.userPlain(" 1. Open the project in Cursor:");
|
|
1060
|
-
logger.userPlain("");
|
|
1061
|
-
logger.userPlain(` cursor ${targetPath}`);
|
|
1062
|
-
}
|
|
1178
|
+
logger.userPlain(` 1. Launch Cursor with your project:`);
|
|
1063
1179
|
logger.userPlain("");
|
|
1064
|
-
logger.userPlain(
|
|
1180
|
+
logger.userPlain(` cursor-agent ${path14}`);
|
|
1065
1181
|
logger.userPlain("");
|
|
1066
|
-
logger.userPlain(
|
|
1182
|
+
logger.userPlain(` 2. Open Cursor (${composerShortcut})`);
|
|
1183
|
+
logger.userPlain("");
|
|
1184
|
+
logger.userPlain(" 3. Paste the prompt above and start building!");
|
|
1067
1185
|
logger.userPlain("");
|
|
1068
1186
|
}
|
|
1069
1187
|
};
|
|
@@ -1145,6 +1263,11 @@ var KilocodeCodingAssistantProvider = {
|
|
|
1145
1263
|
});
|
|
1146
1264
|
logger.userSuccess("Session complete!");
|
|
1147
1265
|
} catch (error) {
|
|
1266
|
+
if (error instanceof Error) {
|
|
1267
|
+
logger.error(error, { step: "kilocode-launch-failed" });
|
|
1268
|
+
} else {
|
|
1269
|
+
logger.debug("kilocode-launch-failed", { error: String(error) });
|
|
1270
|
+
}
|
|
1148
1271
|
logger.userWarning(`Could not auto-launch ${this.displayName}.`);
|
|
1149
1272
|
showManualLaunchInstructions({
|
|
1150
1273
|
targetPath,
|
|
@@ -1172,12 +1295,127 @@ var NoneCodingAssistantProvider = {
|
|
|
1172
1295
|
}
|
|
1173
1296
|
};
|
|
1174
1297
|
|
|
1298
|
+
// src/providers/coding-assistants/crush/index.ts
|
|
1299
|
+
var CrushCodingAssistantProvider = {
|
|
1300
|
+
id: "crush",
|
|
1301
|
+
displayName: "Crush",
|
|
1302
|
+
command: "crush",
|
|
1303
|
+
async isAvailable() {
|
|
1304
|
+
const installed = await CliUtils.isCommandAvailable("crush");
|
|
1305
|
+
return {
|
|
1306
|
+
installed,
|
|
1307
|
+
installCommand: installed ? void 0 : "npm install -g @charmland/crush"
|
|
1308
|
+
};
|
|
1309
|
+
},
|
|
1310
|
+
async launch({ targetPath }) {
|
|
1311
|
+
const isCurrentDir = targetPath === ".";
|
|
1312
|
+
logger.userPlain("");
|
|
1313
|
+
logger.userPlain("\u{1F498} Launch Crush");
|
|
1314
|
+
logger.userPlain("");
|
|
1315
|
+
if (isCurrentDir) {
|
|
1316
|
+
logger.userPlain(" Run:");
|
|
1317
|
+
logger.userPlain("");
|
|
1318
|
+
logger.userPlain(" crush");
|
|
1319
|
+
} else {
|
|
1320
|
+
logger.userPlain(" Navigate to project and run via the following commands:");
|
|
1321
|
+
logger.userPlain("");
|
|
1322
|
+
logger.userPlain(` cd ${targetPath}`);
|
|
1323
|
+
logger.userPlain(" crush");
|
|
1324
|
+
}
|
|
1325
|
+
logger.userPlain("");
|
|
1326
|
+
logger.userPlain(" Then paste the prompt above when Crush starts.");
|
|
1327
|
+
logger.userPlain("");
|
|
1328
|
+
}
|
|
1329
|
+
};
|
|
1330
|
+
|
|
1331
|
+
// src/providers/coding-assistants/gemini-cli/index.ts
|
|
1332
|
+
var GeminiCLICodingAssistantProvider = {
|
|
1333
|
+
id: "gemini-cli",
|
|
1334
|
+
displayName: "Gemini CLI",
|
|
1335
|
+
command: "gemini",
|
|
1336
|
+
async isAvailable() {
|
|
1337
|
+
const installed = await CliUtils.isCommandAvailable("gemini");
|
|
1338
|
+
return {
|
|
1339
|
+
installed,
|
|
1340
|
+
installCommand: installed ? void 0 : "npm install -g @google/gemini-cli"
|
|
1341
|
+
};
|
|
1342
|
+
},
|
|
1343
|
+
async launch({ projectPath, targetPath, prompt }) {
|
|
1344
|
+
if (OSUtils.isUnix) {
|
|
1345
|
+
try {
|
|
1346
|
+
logger.userInfo(`\u{1F916} Launching ${this.displayName}...`);
|
|
1347
|
+
ProcessUtils.launchWithTerminalControl("gemini", ["-p", prompt], { cwd: projectPath });
|
|
1348
|
+
logger.userSuccess("Session complete!");
|
|
1349
|
+
return;
|
|
1350
|
+
} catch (error) {
|
|
1351
|
+
if (error instanceof Error) {
|
|
1352
|
+
logger.error(error, { step: "gemini-launch-failed" });
|
|
1353
|
+
} else {
|
|
1354
|
+
logger.debug("gemini-launch-failed", { error: String(error) });
|
|
1355
|
+
}
|
|
1356
|
+
logger.userWarning(`Could not auto-launch ${this.displayName}.`);
|
|
1357
|
+
}
|
|
1358
|
+
}
|
|
1359
|
+
const isCurrentDir = targetPath === ".";
|
|
1360
|
+
logger.userPlain("");
|
|
1361
|
+
logger.userPlain("To get started with Gemini CLI:");
|
|
1362
|
+
logger.userPlain("");
|
|
1363
|
+
if (isCurrentDir) {
|
|
1364
|
+
logger.userPlain(" Run:");
|
|
1365
|
+
logger.userPlain("");
|
|
1366
|
+
logger.userPlain(` gemini -p "${prompt}"`);
|
|
1367
|
+
} else {
|
|
1368
|
+
logger.userPlain(" Navigate to project and run:");
|
|
1369
|
+
logger.userPlain("");
|
|
1370
|
+
logger.userPlain(` cd ${targetPath}`);
|
|
1371
|
+
logger.userPlain(` gemini -p "${prompt}"`);
|
|
1372
|
+
}
|
|
1373
|
+
logger.userPlain("");
|
|
1374
|
+
}
|
|
1375
|
+
};
|
|
1376
|
+
|
|
1377
|
+
// src/providers/coding-assistants/qwen-code/index.ts
|
|
1378
|
+
var QwenCodeCodingAssistantProvider = {
|
|
1379
|
+
id: "qwen-code",
|
|
1380
|
+
displayName: "Qwen Code",
|
|
1381
|
+
command: "qwen",
|
|
1382
|
+
async isAvailable() {
|
|
1383
|
+
const installed = await CliUtils.isCommandAvailable("qwen");
|
|
1384
|
+
return {
|
|
1385
|
+
installed,
|
|
1386
|
+
installCommand: installed ? void 0 : "npm install -g @qwenlm/qwen-code"
|
|
1387
|
+
};
|
|
1388
|
+
},
|
|
1389
|
+
async launch({ targetPath }) {
|
|
1390
|
+
const isCurrentDir = targetPath === ".";
|
|
1391
|
+
logger.userPlain("");
|
|
1392
|
+
logger.userPlain("To get started with Qwen Code:");
|
|
1393
|
+
logger.userPlain("");
|
|
1394
|
+
if (isCurrentDir) {
|
|
1395
|
+
logger.userPlain(" Run:");
|
|
1396
|
+
logger.userPlain("");
|
|
1397
|
+
logger.userPlain(" qwen");
|
|
1398
|
+
} else {
|
|
1399
|
+
logger.userPlain(" Navigate to project and run:");
|
|
1400
|
+
logger.userPlain("");
|
|
1401
|
+
logger.userPlain(` cd ${targetPath}`);
|
|
1402
|
+
logger.userPlain(" qwen");
|
|
1403
|
+
}
|
|
1404
|
+
logger.userPlain("");
|
|
1405
|
+
logger.userPlain(" Then paste the prompt above when Qwen Code starts.");
|
|
1406
|
+
logger.userPlain("");
|
|
1407
|
+
}
|
|
1408
|
+
};
|
|
1409
|
+
|
|
1175
1410
|
// src/providers/coding-assistants/index.ts
|
|
1176
1411
|
var PROVIDERS3 = {
|
|
1177
1412
|
kilocode: KilocodeCodingAssistantProvider,
|
|
1178
1413
|
"claude-code": ClaudeCodingAssistantProvider,
|
|
1179
1414
|
cursor: CursorCodingAssistantProvider,
|
|
1180
1415
|
antigravity: AntigravityCodingAssistantProvider,
|
|
1416
|
+
crush: CrushCodingAssistantProvider,
|
|
1417
|
+
"gemini-cli": GeminiCLICodingAssistantProvider,
|
|
1418
|
+
"qwen-code": QwenCodeCodingAssistantProvider,
|
|
1181
1419
|
none: NoneCodingAssistantProvider
|
|
1182
1420
|
};
|
|
1183
1421
|
var getCodingAssistantProvider = ({
|
|
@@ -1450,6 +1688,13 @@ var collectConfig = async () => {
|
|
|
1450
1688
|
}
|
|
1451
1689
|
}
|
|
1452
1690
|
}
|
|
1691
|
+
logger.userInfo("To get your LangWatch API key, visit:");
|
|
1692
|
+
logger.userInfo("https://app.langwatch.ai/authorize");
|
|
1693
|
+
const langwatchApiKey = await password({
|
|
1694
|
+
message: "Enter your LangWatch API key (for prompt management, scenarios, evaluations and observability):",
|
|
1695
|
+
mask: "*",
|
|
1696
|
+
validate: validateLangWatchKey
|
|
1697
|
+
});
|
|
1453
1698
|
const codingAssistant = await select({
|
|
1454
1699
|
message: "What is your preferred coding assistant for building the agent?",
|
|
1455
1700
|
choices: await buildCodingAssistantChoices()
|
|
@@ -1507,14 +1752,24 @@ var collectConfig = async () => {
|
|
|
1507
1752
|
}
|
|
1508
1753
|
}
|
|
1509
1754
|
}
|
|
1755
|
+
if (codingAssistant === "gemini-cli") {
|
|
1756
|
+
if (!process.env.GEMINI_API_KEY) {
|
|
1757
|
+
logger.userInfo("When using Gemini API, you must specify the GEMINI_API_KEY environment variable.");
|
|
1758
|
+
const geminiApiKey = await password({
|
|
1759
|
+
message: "Enter your Gemini API key:",
|
|
1760
|
+
mask: "*",
|
|
1761
|
+
validate: (value) => {
|
|
1762
|
+
if (!value || value.length < 5) {
|
|
1763
|
+
return "API key is required and must be at least 5 characters";
|
|
1764
|
+
}
|
|
1765
|
+
return true;
|
|
1766
|
+
}
|
|
1767
|
+
});
|
|
1768
|
+
process.env.GEMINI_API_KEY = geminiApiKey;
|
|
1769
|
+
logger.userInfo("GEMINI_API_KEY has been set for this session.");
|
|
1770
|
+
}
|
|
1771
|
+
}
|
|
1510
1772
|
logger.userInfo("\u2714\uFE0E Your coding assistant will finish setup later if needed\n");
|
|
1511
|
-
logger.userInfo("To get your LangWatch API key, visit:");
|
|
1512
|
-
logger.userInfo("https://app.langwatch.ai/authorize");
|
|
1513
|
-
const langwatchApiKey = await password({
|
|
1514
|
-
message: "Enter your LangWatch API key (for prompt management, scenarios, evaluations and observability):",
|
|
1515
|
-
mask: "*",
|
|
1516
|
-
validate: validateLangWatchKey
|
|
1517
|
-
});
|
|
1518
1773
|
const projectGoal = await input({
|
|
1519
1774
|
message: "What is your agent going to do?",
|
|
1520
1775
|
validate: validateProjectGoal
|
|
@@ -1780,7 +2035,7 @@ var buildOverviewSection = ({ config }) => {
|
|
|
1780
2035
|
**Framework:** ${framework === "agno" ? "Agno" : framework === "langgraph-py" ? "LangGraph (Python)" : framework === "langgraph-ts" ? "LangGraph (TypeScript)" : framework === "google-adk" ? "Google ADK" : "Mastra"}
|
|
1781
2036
|
**Language:** ${language === "python" ? "Python" : "TypeScript"}
|
|
1782
2037
|
|
|
1783
|
-
This project follows
|
|
2038
|
+
This project follows the Better Agents standard for building production-ready AI agents.
|
|
1784
2039
|
|
|
1785
2040
|
---
|
|
1786
2041
|
`;
|
|
@@ -2018,9 +2273,95 @@ var buildMCPConfig = ({
|
|
|
2018
2273
|
}
|
|
2019
2274
|
return mcpConfig;
|
|
2020
2275
|
};
|
|
2021
|
-
var
|
|
2276
|
+
var setupCLIConfigs = async ({
|
|
2022
2277
|
projectPath,
|
|
2278
|
+
config,
|
|
2023
2279
|
mcpConfig
|
|
2280
|
+
}) => {
|
|
2281
|
+
const assistant = config.codingAssistant;
|
|
2282
|
+
if (assistant === "gemini-cli") {
|
|
2283
|
+
const geminiConfigDir = path11.join(os.homedir(), ".gemini");
|
|
2284
|
+
await fs11.mkdir(geminiConfigDir, { recursive: true });
|
|
2285
|
+
const geminiConfigPath = path11.join(geminiConfigDir, "settings.json");
|
|
2286
|
+
let geminiConfig = {};
|
|
2287
|
+
try {
|
|
2288
|
+
const existingContent = await fs11.readFile(geminiConfigPath, "utf-8");
|
|
2289
|
+
geminiConfig = JSON.parse(existingContent);
|
|
2290
|
+
} catch {
|
|
2291
|
+
}
|
|
2292
|
+
geminiConfig.mcpServers = structuredClone(mcpConfig.mcpServers);
|
|
2293
|
+
await fs11.writeFile(
|
|
2294
|
+
geminiConfigPath,
|
|
2295
|
+
JSON.stringify(geminiConfig, null, 2)
|
|
2296
|
+
);
|
|
2297
|
+
}
|
|
2298
|
+
if (assistant === "crush") {
|
|
2299
|
+
const crushConfigPath = path11.join(projectPath, "crush.json");
|
|
2300
|
+
let crushConfig = {
|
|
2301
|
+
$schema: "https://charm.land/crush.json"
|
|
2302
|
+
};
|
|
2303
|
+
try {
|
|
2304
|
+
const existingContent = await fs11.readFile(crushConfigPath, "utf-8");
|
|
2305
|
+
crushConfig = JSON.parse(existingContent);
|
|
2306
|
+
} catch {
|
|
2307
|
+
}
|
|
2308
|
+
if (!crushConfig.mcp) {
|
|
2309
|
+
crushConfig.mcp = {};
|
|
2310
|
+
}
|
|
2311
|
+
const crushMCP = crushConfig.mcp;
|
|
2312
|
+
for (const [key, server] of Object.entries(mcpConfig.mcpServers)) {
|
|
2313
|
+
if (typeof server === "object" && server !== null) {
|
|
2314
|
+
const serverConfig = server;
|
|
2315
|
+
if ("type" in serverConfig && serverConfig.type === "http") {
|
|
2316
|
+
crushMCP[key] = {
|
|
2317
|
+
type: "http",
|
|
2318
|
+
transport: serverConfig.transport || "http",
|
|
2319
|
+
url: serverConfig.url
|
|
2320
|
+
};
|
|
2321
|
+
} else {
|
|
2322
|
+
crushMCP[key] = {
|
|
2323
|
+
type: "stdio",
|
|
2324
|
+
command: serverConfig.command,
|
|
2325
|
+
args: serverConfig.args || []
|
|
2326
|
+
};
|
|
2327
|
+
}
|
|
2328
|
+
}
|
|
2329
|
+
}
|
|
2330
|
+
if (!crushConfig.projectContext) {
|
|
2331
|
+
crushConfig.projectContext = {
|
|
2332
|
+
framework: config.framework,
|
|
2333
|
+
language: config.language,
|
|
2334
|
+
goal: config.projectGoal
|
|
2335
|
+
};
|
|
2336
|
+
}
|
|
2337
|
+
await fs11.writeFile(
|
|
2338
|
+
crushConfigPath,
|
|
2339
|
+
JSON.stringify(crushConfig, null, 2)
|
|
2340
|
+
);
|
|
2341
|
+
}
|
|
2342
|
+
if (assistant === "qwen-code") {
|
|
2343
|
+
const geminiConfigDir = path11.join(os.homedir(), ".gemini");
|
|
2344
|
+
await fs11.mkdir(geminiConfigDir, { recursive: true });
|
|
2345
|
+
const geminiConfigPath = path11.join(geminiConfigDir, "settings.json");
|
|
2346
|
+
let geminiConfig = {};
|
|
2347
|
+
try {
|
|
2348
|
+
const existingContent = await fs11.readFile(geminiConfigPath, "utf-8");
|
|
2349
|
+
geminiConfig = JSON.parse(existingContent);
|
|
2350
|
+
} catch {
|
|
2351
|
+
}
|
|
2352
|
+
geminiConfig.mcpServers = JSON.parse(JSON.stringify(mcpConfig.mcpServers));
|
|
2353
|
+
await fs11.writeFile(
|
|
2354
|
+
geminiConfigPath,
|
|
2355
|
+
JSON.stringify(geminiConfig, null, 2)
|
|
2356
|
+
);
|
|
2357
|
+
}
|
|
2358
|
+
};
|
|
2359
|
+
|
|
2360
|
+
// src/builders/editor-setup-builder.ts
|
|
2361
|
+
var setupEditorConfigs = async ({
|
|
2362
|
+
projectPath,
|
|
2363
|
+
mcpConfig,
|
|
2364
|
+
config
|
|
2024
2365
|
}) => {
|
|
2025
2366
|
const mcpConfigPath = path11.join(projectPath, ".mcp.json");
|
|
2026
2367
|
await fs11.writeFile(mcpConfigPath, JSON.stringify(mcpConfig, null, 2));
|
|
@@ -2038,6 +2379,7 @@ var setupEditorConfigs = async ({
|
|
|
2038
2379
|
const claudeMdContent = `@AGENTS.md
|
|
2039
2380
|
`;
|
|
2040
2381
|
await fs11.writeFile(claudeMdPath, claudeMdContent);
|
|
2382
|
+
await setupCLIConfigs({ projectPath, config, mcpConfig });
|
|
2041
2383
|
};
|
|
2042
2384
|
|
|
2043
2385
|
// src/commands/init.ts
|
|
@@ -2060,7 +2402,7 @@ var showBanner = () => {
|
|
|
2060
2402
|
};
|
|
2061
2403
|
var initCommand = async (targetPath, debug = false) => {
|
|
2062
2404
|
if (debug) {
|
|
2063
|
-
process.env.
|
|
2405
|
+
process.env.BETTERAGENTS_DEBUG = "true";
|
|
2064
2406
|
}
|
|
2065
2407
|
const logger2 = new LoggerFacade();
|
|
2066
2408
|
try {
|
|
@@ -2101,7 +2443,7 @@ var initCommand = async (targetPath, debug = false) => {
|
|
|
2101
2443
|
await ensureGitignore({ projectPath: absolutePath });
|
|
2102
2444
|
const editorTimer = projectLogger.startTimer("editor-setup");
|
|
2103
2445
|
const mcpConfig = buildMCPConfig({ config });
|
|
2104
|
-
await setupEditorConfigs({ projectPath: absolutePath, mcpConfig });
|
|
2446
|
+
await setupEditorConfigs({ projectPath: absolutePath, mcpConfig, config });
|
|
2105
2447
|
if (config.codingAssistant === "antigravity") {
|
|
2106
2448
|
await setupAntigravityMCPConfig(mcpConfig);
|
|
2107
2449
|
}
|
|
@@ -2143,15 +2485,15 @@ var packageJson = JSON.parse(
|
|
|
2143
2485
|
);
|
|
2144
2486
|
var program = new Command();
|
|
2145
2487
|
program.name("better-agents").description(
|
|
2146
|
-
"CLI for kicking off production-ready agent projects with
|
|
2488
|
+
"CLI for kicking off production-ready agent projects with the Better Agents standard"
|
|
2147
2489
|
).version(packageJson.version).option("-d, --debug", "Enable debug logging with structured JSON output");
|
|
2148
2490
|
program.command("init").description("Initialize a new agent project").argument(
|
|
2149
2491
|
"[path]",
|
|
2150
2492
|
"Path to initialize the project (defaults to current directory)",
|
|
2151
2493
|
"."
|
|
2152
|
-
).action((
|
|
2494
|
+
).action((path14, options) => {
|
|
2153
2495
|
const debug = options.parent?.debug || false;
|
|
2154
|
-
return initCommand(
|
|
2496
|
+
return initCommand(path14, debug);
|
|
2155
2497
|
});
|
|
2156
2498
|
program.parse();
|
|
2157
2499
|
//# sourceMappingURL=index.js.map
|