daemora 1.0.0 → 1.0.2
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/config/mcp.json +4 -4
- package/package.json +1 -1
- package/src/cli.js +24 -1
- package/src/config/default.js +5 -2
- package/src/core/TaskRunner.js +3 -2
- package/src/setup/wizard.js +8 -12
package/config/mcp.json
CHANGED
|
@@ -90,10 +90,10 @@
|
|
|
90
90
|
"@modelcontextprotocol/server-slack"
|
|
91
91
|
],
|
|
92
92
|
"env": {
|
|
93
|
-
"SLACK_BOT_TOKEN": "
|
|
94
|
-
"SLACK_TEAM_ID": "
|
|
93
|
+
"SLACK_BOT_TOKEN": "",
|
|
94
|
+
"SLACK_TEAM_ID": ""
|
|
95
95
|
},
|
|
96
|
-
"enabled":
|
|
96
|
+
"enabled": false
|
|
97
97
|
},
|
|
98
98
|
"_comment_postgres": "PostgreSQL database access",
|
|
99
99
|
"postgres": {
|
|
@@ -136,7 +136,7 @@
|
|
|
136
136
|
"enabled": false
|
|
137
137
|
},
|
|
138
138
|
"Umar": {
|
|
139
|
-
"enabled":
|
|
139
|
+
"enabled": false,
|
|
140
140
|
"url": "https://api.example.com/sse",
|
|
141
141
|
"transport": "sse",
|
|
142
142
|
"description": "kajshdkjahskdhaskdh"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "daemora",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "A powerful open-source AI agent that runs on your machine. Connects to any AI model, any MCP server, any channel. Fully autonomous — plans, codes, tests, browses, emails, and manages your tools without asking permission.",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"bin": {
|
package/src/cli.js
CHANGED
|
@@ -17,6 +17,7 @@ import daemonManager from "./daemon/DaemonManager.js";
|
|
|
17
17
|
import secretVault from "./safety/SecretVault.js";
|
|
18
18
|
import { readFileSync, writeFileSync, existsSync } from "fs";
|
|
19
19
|
import { join } from "path";
|
|
20
|
+
import { execSync } from "child_process";
|
|
20
21
|
|
|
21
22
|
const P = {
|
|
22
23
|
brand: "#7C6AFF",
|
|
@@ -168,13 +169,35 @@ function handleDaemon(action) {
|
|
|
168
169
|
console.log(` ${S.bar} Status ${status}`);
|
|
169
170
|
console.log(` ${S.bar} Platform ${t.bold(st.platform)}`);
|
|
170
171
|
if (st.pid) console.log(` ${S.bar} PID ${t.bold(st.pid)}`);
|
|
172
|
+
console.log(` ${S.bar} Logs ${t.muted(daemonManager.logsDir)}`);
|
|
171
173
|
console.log("");
|
|
172
174
|
break;
|
|
173
175
|
}
|
|
174
176
|
|
|
177
|
+
case "logs": {
|
|
178
|
+
const stdoutLog = join(daemonManager.logsDir, "daemon-stdout.log");
|
|
179
|
+
const stderrLog = join(daemonManager.logsDir, "daemon-stderr.log");
|
|
180
|
+
const lines = process.argv[4] || "50";
|
|
181
|
+
console.log(header);
|
|
182
|
+
console.log(` ${S.bar} ${t.muted(stdoutLog)}\n`);
|
|
183
|
+
try {
|
|
184
|
+
const out = execSync(`tail -n ${lines} "${stdoutLog}" 2>/dev/null || echo "(no output log yet)"`).toString();
|
|
185
|
+
console.log(out);
|
|
186
|
+
} catch { console.log(" (no output log yet)\n"); }
|
|
187
|
+
const errExists = existsSync(stderrLog);
|
|
188
|
+
if (errExists) {
|
|
189
|
+
const err = execSync(`tail -n 20 "${stderrLog}" 2>/dev/null`).toString().trim();
|
|
190
|
+
if (err) {
|
|
191
|
+
console.log(` ${S.bar} ${t.muted("stderr:")}\n`);
|
|
192
|
+
console.log(err);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
break;
|
|
196
|
+
}
|
|
197
|
+
|
|
175
198
|
default:
|
|
176
199
|
console.error(`\n ${S.cross} Unknown daemon command: ${action || "(none)"}`);
|
|
177
|
-
console.log(` ${t.muted("Usage:")} daemora daemon ${t.dim("[install|uninstall|start|stop|restart|status]")}\n`);
|
|
200
|
+
console.log(` ${t.muted("Usage:")} daemora daemon ${t.dim("[install|uninstall|start|stop|restart|status|logs]")}\n`);
|
|
178
201
|
process.exit(1);
|
|
179
202
|
}
|
|
180
203
|
}
|
package/src/config/default.js
CHANGED
|
@@ -2,11 +2,14 @@ import { config as loadEnv } from "dotenv";
|
|
|
2
2
|
import { join, dirname } from "path";
|
|
3
3
|
import { fileURLToPath } from "url";
|
|
4
4
|
|
|
5
|
-
loadEnv({ quiet: true });
|
|
6
|
-
|
|
7
5
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
8
6
|
const ROOT_DIR = join(__dirname, "..", "..");
|
|
9
7
|
|
|
8
|
+
// Load .env from the module's install directory (ROOT_DIR), not process.cwd().
|
|
9
|
+
// This ensures `daemora start` always picks up the config written by `daemora setup`,
|
|
10
|
+
// regardless of which directory the user runs the command from.
|
|
11
|
+
loadEnv({ path: join(ROOT_DIR, ".env"), quiet: true });
|
|
12
|
+
|
|
10
13
|
export const config = {
|
|
11
14
|
// Server
|
|
12
15
|
port: parseInt(process.env.PORT || "8081", 10),
|
package/src/core/TaskRunner.js
CHANGED
|
@@ -204,13 +204,14 @@ class TaskRunner {
|
|
|
204
204
|
task.cost = result.cost;
|
|
205
205
|
|
|
206
206
|
// Record cost against tenant lifetime totals
|
|
207
|
+
const estimatedCost = result.cost?.estimatedCost || 0;
|
|
207
208
|
if (tenant) {
|
|
208
|
-
tenantManager.recordCost(tenant.id,
|
|
209
|
+
tenantManager.recordCost(tenant.id, estimatedCost);
|
|
209
210
|
}
|
|
210
211
|
|
|
211
212
|
// Complete the task
|
|
212
213
|
taskQueue.complete(task.id, result.text);
|
|
213
|
-
const costStr =
|
|
214
|
+
const costStr = estimatedCost ? ` cost: $${estimatedCost.toFixed(4)}` : "";
|
|
214
215
|
const tenantStr = tenant ? ` tenant: ${tenant.id}` : "";
|
|
215
216
|
console.log(`[TaskRunner] Task ${task.id} completed (${costStr}${tenantStr})`);
|
|
216
217
|
});
|
package/src/setup/wizard.js
CHANGED
|
@@ -749,15 +749,14 @@ export async function runSetupWizard() {
|
|
|
749
749
|
// ━━━ Next Steps ━━━
|
|
750
750
|
const nextSteps = [
|
|
751
751
|
`${S.arrow} ${t.bold("Start the agent")}`,
|
|
752
|
-
` ${t.cmd("
|
|
752
|
+
` ${t.cmd("daemora start")}`,
|
|
753
753
|
"",
|
|
754
754
|
];
|
|
755
755
|
|
|
756
756
|
if (vaultPassphrase) {
|
|
757
757
|
nextSteps.push(
|
|
758
|
-
`${S.arrow} ${t.bold("Unlock vault
|
|
759
|
-
` ${t.
|
|
760
|
-
` ${t.cmd(` -d '{"passphrase": "<your-passphrase>"}'`)}`,
|
|
758
|
+
`${S.arrow} ${t.bold("Unlock vault")}`,
|
|
759
|
+
` ${t.muted("Enter your passphrase when prompted on start")}`,
|
|
761
760
|
"",
|
|
762
761
|
);
|
|
763
762
|
}
|
|
@@ -765,21 +764,18 @@ export async function runSetupWizard() {
|
|
|
765
764
|
if (daemonMode) {
|
|
766
765
|
nextSteps.push(
|
|
767
766
|
`${S.arrow} ${t.bold("Daemon controls")}`,
|
|
768
|
-
` ${t.cmd("
|
|
769
|
-
` ${t.cmd("
|
|
770
|
-
` ${t.cmd("
|
|
767
|
+
` ${t.cmd("daemora daemon status")}`,
|
|
768
|
+
` ${t.cmd("daemora daemon stop")}`,
|
|
769
|
+
` ${t.cmd("daemora daemon start")}`,
|
|
771
770
|
"",
|
|
772
771
|
);
|
|
773
772
|
}
|
|
774
773
|
|
|
775
774
|
nextSteps.push(
|
|
776
|
-
`${S.arrow} ${t.bold("
|
|
777
|
-
` ${t.cmd(`curl -X POST http://localhost:${port}/chat`)}`,
|
|
778
|
-
` ${t.cmd(` -H "Content-Type: application/json"`)}`,
|
|
779
|
-
` ${t.cmd(` -d '{"message": "Hello!"}'`)}`,
|
|
775
|
+
`${S.arrow} ${t.bold("Message your bot on the channels you configured")}`,
|
|
780
776
|
"",
|
|
781
777
|
`${S.arrow} ${t.bold("All commands")}`,
|
|
782
|
-
` ${t.cmd("
|
|
778
|
+
` ${t.cmd("daemora help")}`,
|
|
783
779
|
);
|
|
784
780
|
|
|
785
781
|
completeBanner(nextSteps);
|