balchemy 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.
Files changed (67) hide show
  1. package/README.md +59 -0
  2. package/assets/bcrow.png +0 -0
  3. package/dist/agent-store.d.ts +40 -0
  4. package/dist/agent-store.d.ts.map +1 -0
  5. package/dist/agent-store.js +206 -0
  6. package/dist/agent-store.js.map +1 -0
  7. package/dist/config-loader.d.ts +8 -0
  8. package/dist/config-loader.d.ts.map +1 -0
  9. package/dist/config-loader.js +106 -0
  10. package/dist/config-loader.js.map +1 -0
  11. package/dist/docker-gen.d.ts +6 -0
  12. package/dist/docker-gen.d.ts.map +1 -0
  13. package/dist/docker-gen.js +40 -0
  14. package/dist/docker-gen.js.map +1 -0
  15. package/dist/index.d.ts +16 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +143 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/openai-oauth.d.ts +28 -0
  20. package/dist/openai-oauth.d.ts.map +1 -0
  21. package/dist/openai-oauth.js +215 -0
  22. package/dist/openai-oauth.js.map +1 -0
  23. package/dist/runner.d.ts +6 -0
  24. package/dist/runner.d.ts.map +1 -0
  25. package/dist/runner.js +63 -0
  26. package/dist/runner.js.map +1 -0
  27. package/dist/terminal-logo.d.ts +15 -0
  28. package/dist/terminal-logo.d.ts.map +1 -0
  29. package/dist/terminal-logo.js +121 -0
  30. package/dist/terminal-logo.js.map +1 -0
  31. package/dist/tui/AgentBridge.d.ts +35 -0
  32. package/dist/tui/AgentBridge.d.ts.map +1 -0
  33. package/dist/tui/AgentBridge.js +235 -0
  34. package/dist/tui/AgentBridge.js.map +1 -0
  35. package/dist/tui/App.d.ts +8 -0
  36. package/dist/tui/App.d.ts.map +1 -0
  37. package/dist/tui/App.js +118 -0
  38. package/dist/tui/App.js.map +1 -0
  39. package/dist/tui/ChatAgent.d.ts +41 -0
  40. package/dist/tui/ChatAgent.d.ts.map +1 -0
  41. package/dist/tui/ChatAgent.js +312 -0
  42. package/dist/tui/ChatAgent.js.map +1 -0
  43. package/dist/tui/ChatPanel.d.ts +10 -0
  44. package/dist/tui/ChatPanel.d.ts.map +1 -0
  45. package/dist/tui/ChatPanel.js +43 -0
  46. package/dist/tui/ChatPanel.js.map +1 -0
  47. package/dist/tui/StatusPanel.d.ts +8 -0
  48. package/dist/tui/StatusPanel.d.ts.map +1 -0
  49. package/dist/tui/StatusPanel.js +25 -0
  50. package/dist/tui/StatusPanel.js.map +1 -0
  51. package/dist/tui/start.d.ts +3 -0
  52. package/dist/tui/start.d.ts.map +1 -0
  53. package/dist/tui/start.js +14 -0
  54. package/dist/tui/start.js.map +1 -0
  55. package/dist/tui/types.d.ts +61 -0
  56. package/dist/tui/types.d.ts.map +1 -0
  57. package/dist/tui/types.js +3 -0
  58. package/dist/tui/types.js.map +1 -0
  59. package/dist/wizard.d.ts +16 -0
  60. package/dist/wizard.d.ts.map +1 -0
  61. package/dist/wizard.js +716 -0
  62. package/dist/wizard.js.map +1 -0
  63. package/package.json +57 -0
  64. package/templates/.env.example +19 -0
  65. package/templates/Dockerfile +20 -0
  66. package/templates/agent.config.yaml +71 -0
  67. package/templates/docker-compose.yml +27 -0
package/README.md ADDED
@@ -0,0 +1,59 @@
1
+ # create-balchemy-agent
2
+
3
+ Deploy an autonomous AI trading agent on Solana and Base chains in 5 minutes.
4
+
5
+ ## Quick Start
6
+
7
+ ```bash
8
+ npx create-balchemy-agent
9
+ ```
10
+
11
+ The interactive wizard will:
12
+
13
+ 1. Ask you to pick an LLM provider (Anthropic, OpenAI, Gemini, Grok, OpenRouter)
14
+ 2. Set up your agent with trading wallets
15
+ 3. Configure your trading strategy in natural language
16
+ 4. Start an interactive TUI with live chat and status panel
17
+
18
+ ## Features
19
+
20
+ - **Bring Your Own LLM** — your agent, your model, your strategy
21
+ - **Interactive TUI** — split-panel chat + live status (balance, trades, events)
22
+ - **MCP Tool Calling** — your LLM calls Balchemy tools directly (trade, research, portfolio)
23
+ - **5 LLM Providers** — Anthropic, OpenAI, Gemini, Grok, OpenRouter
24
+ - **Encrypted Credentials** — AES-256-GCM at rest, PBKDF2 key derivation
25
+ - **Resume Anytime** — cached agent config, instant restart
26
+
27
+ ## Commands
28
+
29
+ ```bash
30
+ npx create-balchemy-agent # Setup wizard or resume cached agent
31
+ npx create-balchemy-agent init # Force new setup wizard
32
+ npx create-balchemy-agent start # Start from agent.config.yaml
33
+ npx create-balchemy-agent docker # Generate Docker deployment files
34
+ ```
35
+
36
+ ## How It Works
37
+
38
+ ```
39
+ You (strategy) --> Your LLM (decisions) --> Balchemy MCP (execution) --> Solana/Base
40
+ ```
41
+
42
+ Your LLM is the brain. Balchemy provides the infrastructure — wallets, trading, risk checks, and 100+ tools via MCP protocol. You define the strategy in natural language; your LLM decides when and what to trade.
43
+
44
+ ## Requirements
45
+
46
+ - Node.js 18+
47
+ - An LLM API key (from any supported provider)
48
+
49
+ ## Configuration
50
+
51
+ After setup, `agent.config.yaml` and `.env` are generated in the current directory. Edit them to change settings without re-running the wizard.
52
+
53
+ ## Hub Integration
54
+
55
+ When you bind your EVM wallet during setup, the agent appears in your [Balchemy Hub](https://balchemy.ai/hub) dashboard. Use Hub for monitoring, scope management, and key rotation.
56
+
57
+ ## License
58
+
59
+ MIT
Binary file
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Persists agent credentials to ~/.balchemy/agents.enc (AES-256-GCM encrypted).
3
+ *
4
+ * Key derivation: PBKDF2 from machine hostname + username + fixed salt,
5
+ * or from BALCHEMY_MASTER_KEY env var if set.
6
+ *
7
+ * Migration: automatically encrypts plaintext agents.json / agent.json on first read.
8
+ */
9
+ export interface StoredAgent {
10
+ publicId: string;
11
+ mcpEndpoint: string;
12
+ apiKey: string;
13
+ masterKey?: string;
14
+ llmProvider: string;
15
+ llmApiKey: string;
16
+ llmModel?: string;
17
+ llmBaseUrl?: string;
18
+ maxDailyLlmCost?: number;
19
+ strategy: string;
20
+ shadowMode: boolean;
21
+ wallets?: {
22
+ solana?: string;
23
+ base?: string;
24
+ };
25
+ createdAt: string;
26
+ name?: string;
27
+ }
28
+ export declare function saveAgent(agent: StoredAgent): void;
29
+ /** Load the active agent, or null if none. */
30
+ export declare function loadAgent(): StoredAgent | null;
31
+ /** List all saved agents. */
32
+ export declare function listAgents(): StoredAgent[];
33
+ /** Clear the active agent (but keep the list). */
34
+ export declare function clearAgent(): void;
35
+ /** Delete a specific agent from the store. */
36
+ export declare function deleteAgent(publicId: string): void;
37
+ /** Set active agent by publicId. */
38
+ export declare function setActiveAgent(publicId: string): boolean;
39
+ export declare function getStorePath(): string;
40
+ //# sourceMappingURL=agent-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-store.d.ts","sourceRoot":"","sources":["../src/agent-store.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAgBH,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAuJD,wBAAgB,SAAS,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAUlD;AAED,8CAA8C;AAC9C,wBAAgB,SAAS,IAAI,WAAW,GAAG,IAAI,CAQ9C;AAED,6BAA6B;AAC7B,wBAAgB,UAAU,IAAI,WAAW,EAAE,CAE1C;AAED,kDAAkD;AAClD,wBAAgB,UAAU,IAAI,IAAI,CAIjC;AAED,8CAA8C;AAC9C,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAOlD;AAED,oCAAoC;AACpC,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAOxD;AAED,wBAAgB,YAAY,IAAI,MAAM,CAErC"}
@@ -0,0 +1,206 @@
1
+ /**
2
+ * Persists agent credentials to ~/.balchemy/agents.enc (AES-256-GCM encrypted).
3
+ *
4
+ * Key derivation: PBKDF2 from machine hostname + username + fixed salt,
5
+ * or from BALCHEMY_MASTER_KEY env var if set.
6
+ *
7
+ * Migration: automatically encrypts plaintext agents.json / agent.json on first read.
8
+ */
9
+ import * as crypto from "crypto";
10
+ import * as fs from "fs";
11
+ import * as path from "path";
12
+ import * as os from "os";
13
+ const STORE_DIR = path.join(os.homedir(), ".balchemy");
14
+ const ENCRYPTED_STORE_PATH = path.join(STORE_DIR, "agents.enc");
15
+ const LEGACY_STORE_PATH = path.join(STORE_DIR, "agents.json");
16
+ const OLD_STORE_PATH = path.join(STORE_DIR, "agent.json"); // v0.1 single-agent format
17
+ const ALGORITHM = "aes-256-gcm";
18
+ const SALT = "balchemy-agent-store-v1";
19
+ const PBKDF2_ITERATIONS = 100_000;
20
+ // ── Encryption helpers ─────────────────────────────────────────────────────────
21
+ function deriveKey() {
22
+ const passphrase = process.env.BALCHEMY_MASTER_KEY ??
23
+ `${os.hostname()}:${os.userInfo().username}:balchemy`;
24
+ return crypto.pbkdf2Sync(passphrase, SALT, PBKDF2_ITERATIONS, 32, "sha256");
25
+ }
26
+ function encrypt(plaintext) {
27
+ const key = deriveKey();
28
+ const iv = crypto.randomBytes(12);
29
+ const cipher = crypto.createCipheriv(ALGORITHM, key, iv);
30
+ const encrypted = Buffer.concat([
31
+ cipher.update(plaintext, "utf8"),
32
+ cipher.final(),
33
+ ]);
34
+ const tag = cipher.getAuthTag();
35
+ // Format: base64(iv):base64(tag):base64(encrypted)
36
+ return `${iv.toString("base64")}:${tag.toString("base64")}:${encrypted.toString("base64")}`;
37
+ }
38
+ function decrypt(ciphertext) {
39
+ const key = deriveKey();
40
+ const parts = ciphertext.split(":");
41
+ if (parts.length !== 3) {
42
+ throw new Error("Invalid encrypted store format");
43
+ }
44
+ const [ivB64, tagB64, dataB64] = parts;
45
+ const iv = Buffer.from(ivB64, "base64");
46
+ const tag = Buffer.from(tagB64, "base64");
47
+ const data = Buffer.from(dataB64, "base64");
48
+ const decipher = crypto.createDecipheriv(ALGORITHM, key, iv);
49
+ decipher.setAuthTag(tag);
50
+ return decipher.update(data) + decipher.final("utf8");
51
+ }
52
+ // ── Legacy migration ───────────────────────────────────────────────────────────
53
+ /**
54
+ * Attempt to read a plaintext JSON file, parse it as StoreData or single agent.
55
+ * Returns null if the file doesn't exist or is unparseable.
56
+ */
57
+ function readLegacyFile(filePath) {
58
+ try {
59
+ if (!fs.existsSync(filePath))
60
+ return null;
61
+ const raw = fs.readFileSync(filePath, "utf8");
62
+ const data = JSON.parse(raw);
63
+ // Multi-agent format
64
+ if ("agents" in data && Array.isArray(data.agents)) {
65
+ return data;
66
+ }
67
+ // Single-agent format
68
+ const agent = data;
69
+ if (agent.publicId) {
70
+ return { activeId: agent.publicId, agents: [agent] };
71
+ }
72
+ return null;
73
+ }
74
+ catch {
75
+ return null;
76
+ }
77
+ }
78
+ /**
79
+ * Migrate plaintext stores to encrypted format.
80
+ * Reads agents.json and agent.json, merges them, writes agents.enc,
81
+ * then deletes the plaintext files.
82
+ */
83
+ function migrateLegacyStores() {
84
+ const fromMulti = readLegacyFile(LEGACY_STORE_PATH);
85
+ const fromSingle = readLegacyFile(OLD_STORE_PATH);
86
+ if (!fromMulti && !fromSingle)
87
+ return null;
88
+ // Merge: multi-agent store takes precedence, single-agent merged in if not duplicate
89
+ const merged = fromMulti ?? { activeId: null, agents: [] };
90
+ if (fromSingle) {
91
+ for (const agent of fromSingle.agents) {
92
+ if (!merged.agents.some((a) => a.publicId === agent.publicId)) {
93
+ merged.agents.push(agent);
94
+ }
95
+ }
96
+ if (!merged.activeId && fromSingle.activeId) {
97
+ merged.activeId = fromSingle.activeId;
98
+ }
99
+ }
100
+ // Write encrypted
101
+ writeStore(merged);
102
+ // Remove plaintext files
103
+ try {
104
+ if (fs.existsSync(LEGACY_STORE_PATH))
105
+ fs.unlinkSync(LEGACY_STORE_PATH);
106
+ }
107
+ catch { /* best effort */ }
108
+ try {
109
+ if (fs.existsSync(OLD_STORE_PATH))
110
+ fs.unlinkSync(OLD_STORE_PATH);
111
+ }
112
+ catch { /* best effort */ }
113
+ return merged;
114
+ }
115
+ // ── Store read/write ───────────────────────────────────────────────────────────
116
+ function readStore() {
117
+ try {
118
+ // Try encrypted store first
119
+ if (fs.existsSync(ENCRYPTED_STORE_PATH)) {
120
+ const raw = fs.readFileSync(ENCRYPTED_STORE_PATH, "utf8");
121
+ const json = decrypt(raw);
122
+ const data = JSON.parse(json);
123
+ if (Array.isArray(data.agents))
124
+ return data;
125
+ }
126
+ // Attempt migration from plaintext
127
+ const migrated = migrateLegacyStores();
128
+ if (migrated)
129
+ return migrated;
130
+ return { activeId: null, agents: [] };
131
+ }
132
+ catch {
133
+ // Decryption failure (machine changed, key changed, etc.)
134
+ // Try legacy migration as fallback
135
+ try {
136
+ const migrated = migrateLegacyStores();
137
+ if (migrated)
138
+ return migrated;
139
+ }
140
+ catch { /* ignore */ }
141
+ return { activeId: null, agents: [] };
142
+ }
143
+ }
144
+ function writeStore(data) {
145
+ if (!fs.existsSync(STORE_DIR)) {
146
+ fs.mkdirSync(STORE_DIR, { recursive: true, mode: 0o700 });
147
+ }
148
+ const json = JSON.stringify(data, null, 2);
149
+ const encrypted = encrypt(json);
150
+ fs.writeFileSync(ENCRYPTED_STORE_PATH, encrypted, { mode: 0o600 });
151
+ }
152
+ // ── Public API ─────────────────────────────────────────────────────────────────
153
+ export function saveAgent(agent) {
154
+ const store = readStore();
155
+ const idx = store.agents.findIndex((a) => a.publicId === agent.publicId);
156
+ if (idx >= 0) {
157
+ store.agents[idx] = agent;
158
+ }
159
+ else {
160
+ store.agents.push(agent);
161
+ }
162
+ store.activeId = agent.publicId;
163
+ writeStore(store);
164
+ }
165
+ /** Load the active agent, or null if none. */
166
+ export function loadAgent() {
167
+ const store = readStore();
168
+ if (!store.activeId)
169
+ return store.agents[0] ?? null;
170
+ return (store.agents.find((a) => a.publicId === store.activeId) ??
171
+ store.agents[0] ??
172
+ null);
173
+ }
174
+ /** List all saved agents. */
175
+ export function listAgents() {
176
+ return readStore().agents;
177
+ }
178
+ /** Clear the active agent (but keep the list). */
179
+ export function clearAgent() {
180
+ const store = readStore();
181
+ store.activeId = null;
182
+ writeStore(store);
183
+ }
184
+ /** Delete a specific agent from the store. */
185
+ export function deleteAgent(publicId) {
186
+ const store = readStore();
187
+ store.agents = store.agents.filter((a) => a.publicId !== publicId);
188
+ if (store.activeId === publicId) {
189
+ store.activeId = store.agents[0]?.publicId ?? null;
190
+ }
191
+ writeStore(store);
192
+ }
193
+ /** Set active agent by publicId. */
194
+ export function setActiveAgent(publicId) {
195
+ const store = readStore();
196
+ const found = store.agents.find((a) => a.publicId === publicId);
197
+ if (!found)
198
+ return false;
199
+ store.activeId = publicId;
200
+ writeStore(store);
201
+ return true;
202
+ }
203
+ export function getStorePath() {
204
+ return ENCRYPTED_STORE_PATH;
205
+ }
206
+ //# sourceMappingURL=agent-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-store.js","sourceRoot":"","sources":["../src/agent-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Parses agent.config.yaml into AgentLoopConfig.
3
+ * Resolves ${ENV_VAR} references in string values.
4
+ * Validates required fields and throws descriptive errors.
5
+ */
6
+ import type { AgentLoopConfig } from '@balchemyai/agent-sdk';
7
+ export declare function loadConfig(configPath: string): AgentLoopConfig;
8
+ //# sourceMappingURL=config-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-loader.d.ts","sourceRoot":"","sources":["../src/config-loader.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAe,MAAM,uBAAuB,CAAC;AAsE1E,wBAAgB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,eAAe,CAkE9D"}
@@ -0,0 +1,106 @@
1
+ /**
2
+ * Parses agent.config.yaml into AgentLoopConfig.
3
+ * Resolves ${ENV_VAR} references in string values.
4
+ * Validates required fields and throws descriptive errors.
5
+ */
6
+ import * as fs from 'fs';
7
+ import * as yaml from 'js-yaml';
8
+ function resolveEnv(value) {
9
+ return value.replace(/\$\{([^}]+)\}/g, (_, varName) => {
10
+ const envVal = process.env[varName];
11
+ if (envVal === undefined) {
12
+ throw new Error(`Environment variable '${varName}' referenced in config is not set`);
13
+ }
14
+ return envVal;
15
+ });
16
+ }
17
+ function requireString(obj, fieldPath) {
18
+ if (typeof obj !== 'string' || !obj) {
19
+ throw new Error(`Config field '${fieldPath}' is required and must be a non-empty string`);
20
+ }
21
+ return resolveEnv(obj);
22
+ }
23
+ function optionalString(obj) {
24
+ if (typeof obj !== 'string' || !obj)
25
+ return undefined;
26
+ return resolveEnv(obj);
27
+ }
28
+ function optionalNumber(obj, defaultVal) {
29
+ if (obj === undefined || obj === null)
30
+ return defaultVal;
31
+ if (typeof obj === 'number')
32
+ return obj;
33
+ if (typeof obj === 'string') {
34
+ const n = parseFloat(obj);
35
+ if (!isNaN(n))
36
+ return n;
37
+ }
38
+ return defaultVal;
39
+ }
40
+ const VALID_SDK_PROVIDERS = ['anthropic', 'openai', 'custom'];
41
+ function parseLlmProvider(raw) {
42
+ const rawStr = String(raw);
43
+ // Map external provider names to SDK providers
44
+ if (rawStr === 'anthropic')
45
+ return 'anthropic';
46
+ if (['openai', 'gemini', 'grok', 'openrouter'].includes(rawStr))
47
+ return 'openai';
48
+ if (VALID_SDK_PROVIDERS.includes(rawStr))
49
+ return rawStr;
50
+ throw new Error(`Config field 'llm.provider' must be one of: anthropic, openai, gemini, grok, openrouter, custom`);
51
+ }
52
+ export function loadConfig(configPath) {
53
+ if (!fs.existsSync(configPath)) {
54
+ throw new Error(`Config file not found: ${configPath}`);
55
+ }
56
+ const raw = fs.readFileSync(configPath, 'utf8');
57
+ let parsed;
58
+ try {
59
+ parsed = yaml.load(raw);
60
+ }
61
+ catch (err) {
62
+ throw new Error(`Failed to parse YAML config: ${err instanceof Error ? err.message : String(err)}`);
63
+ }
64
+ if (typeof parsed !== 'object' || parsed === null) {
65
+ throw new Error('Config file must be a YAML object');
66
+ }
67
+ const cfg = parsed;
68
+ const mcpEndpoint = requireString(cfg.mcp_endpoint, 'mcp_endpoint');
69
+ const apiKey = requireString(cfg.api_key, 'api_key');
70
+ if (!cfg.llm) {
71
+ throw new Error("Config field 'llm' is required");
72
+ }
73
+ const llmProvider = parseLlmProvider(cfg.llm.provider);
74
+ const llmApiKey = requireString(cfg.llm.api_key, 'llm.api_key');
75
+ const llmModel = optionalString(cfg.llm.model);
76
+ const llmBaseUrl = optionalString(cfg.llm.base_url);
77
+ const maxDailyLlmCost = optionalNumber(cfg.llm.max_daily_usd, 5);
78
+ const llmTimeoutMs = optionalNumber(cfg.llm.timeout_ms, 15_000);
79
+ const webhookPort = cfg.webhook
80
+ ? optionalNumber(cfg.webhook.port, 0) ?? 0
81
+ : 0;
82
+ const webhookSecret = cfg.webhook
83
+ ? optionalString(cfg.webhook.secret)
84
+ : undefined;
85
+ const behaviorRulesPath = typeof cfg.behavior_rules_path === 'string' && cfg.behavior_rules_path
86
+ ? cfg.behavior_rules_path
87
+ : undefined;
88
+ const behaviorRules = typeof cfg.behavior_rules === 'object' && cfg.behavior_rules !== null
89
+ ? cfg.behavior_rules
90
+ : undefined;
91
+ return {
92
+ mcpEndpoint,
93
+ apiKey,
94
+ llmProvider,
95
+ llmApiKey,
96
+ llmModel,
97
+ llmBaseUrl,
98
+ maxDailyLlmCost,
99
+ llmTimeoutMs,
100
+ webhookPort,
101
+ webhookSecret,
102
+ behaviorRulesPath,
103
+ behaviorRules,
104
+ };
105
+ }
106
+ //# sourceMappingURL=config-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-loader.js","sourceRoot":"","sources":["../src/config-loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Generates Dockerfile + docker-compose.yml for the agent.
3
+ * Copies static template files and does not mutate them.
4
+ */
5
+ export declare function generateDocker(outDir: string): Promise<void>;
6
+ //# sourceMappingURL=docker-gen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docker-gen.d.ts","sourceRoot":"","sources":["../src/docker-gen.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAoBH,wBAAsB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAwBlE"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Generates Dockerfile + docker-compose.yml for the agent.
3
+ * Copies static template files and does not mutate them.
4
+ */
5
+ import * as fs from 'fs';
6
+ import * as path from 'path';
7
+ import { fileURLToPath } from 'url';
8
+ const __filename_esm = fileURLToPath(import.meta.url);
9
+ const __dirname_esm = path.dirname(__filename_esm);
10
+ const TEMPLATES_DIR = path.join(__dirname_esm, '..', 'templates');
11
+ function copyTemplate(filename, outDir) {
12
+ const src = path.join(TEMPLATES_DIR, filename);
13
+ const dest = path.join(outDir, filename);
14
+ if (!fs.existsSync(src)) {
15
+ throw new Error(`Template file not found: ${src}`);
16
+ }
17
+ fs.copyFileSync(src, dest);
18
+ process.stdout.write(` wrote ${dest}\n`);
19
+ }
20
+ export async function generateDocker(outDir) {
21
+ if (!fs.existsSync(outDir)) {
22
+ throw new Error(`Output directory does not exist: ${outDir}`);
23
+ }
24
+ process.stdout.write(`Generating Docker files in ${outDir}...\n`);
25
+ copyTemplate('Dockerfile', outDir);
26
+ copyTemplate('docker-compose.yml', outDir);
27
+ // Write .env.example only if not already present (don't overwrite real .env)
28
+ const envExampleDest = path.join(outDir, '.env.example');
29
+ if (!fs.existsSync(envExampleDest)) {
30
+ copyTemplate('.env.example', envExampleDest);
31
+ }
32
+ else {
33
+ process.stdout.write(` skipped .env.example (already exists)\n`);
34
+ }
35
+ process.stdout.write(`\nNext steps:\n` +
36
+ ` 1. Copy .env.example to .env and fill in your credentials\n` +
37
+ ` 2. Place your agent.config.yaml in the same directory\n` +
38
+ ` 3. Run: docker compose up -d\n`);
39
+ }
40
+ //# sourceMappingURL=docker-gen.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docker-gen.js","sourceRoot":"","sources":["../src/docker-gen.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAEpC,MAAM,cAAc,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACtD,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;AACnD,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC;AAElE,SAAS,YAAY,CAAC,QAAgB,EAAE,MAAc;IACpD,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;IAC/C,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACzC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,4BAA4B,GAAG,EAAE,CAAC,CAAC;IACrD,CAAC;IACD,EAAE,CAAC,YAAY,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAC3B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,IAAI,IAAI,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,MAAc;IACjD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,oCAAoC,MAAM,EAAE,CAAC,CAAC;IAChE,CAAC;IAED,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,8BAA8B,MAAM,OAAO,CAAC,CAAC;IAElE,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IACnC,YAAY,CAAC,oBAAoB,EAAE,MAAM,CAAC,CAAC;IAE3C,6EAA6E;IAC7E,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IACzD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;QACnC,YAAY,CAAC,cAAc,EAAE,cAAc,CAAC,CAAC;IAC/C,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAC;IACpE,CAAC;IAED,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,iBAAiB;QACjB,+DAA+D;QAC/D,2DAA2D;QAC3D,kCAAkC,CACnC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * create-balchemy-agent CLI entry point.
4
+ *
5
+ * On launch:
6
+ * - If ~/.balchemy/agent.json exists → offer to resume or start fresh
7
+ * - If no cached agent → run wizard
8
+ *
9
+ * Sub-commands:
10
+ * (no args) Resume cached agent or run wizard
11
+ * init / --init Force run wizard (ignore cache)
12
+ * start [config] Start from agent.config.yaml
13
+ * docker [outDir] Generate Docker files
14
+ */
15
+ export {};
16
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;GAYG"}