@cosmicstack/mercury-agent 0.2.5 → 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/index.js +40 -17
- package/dist/index.js.map +1 -1
- package/package.json +3 -7
package/dist/index.js
CHANGED
|
@@ -7,7 +7,6 @@ import { dirname as dirname3, join as join11 } from "path";
|
|
|
7
7
|
import { Command } from "commander";
|
|
8
8
|
import readline2 from "readline";
|
|
9
9
|
import chalk6 from "chalk";
|
|
10
|
-
import figlet from "figlet";
|
|
11
10
|
|
|
12
11
|
// src/utils/config.ts
|
|
13
12
|
import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
|
|
@@ -2304,6 +2303,7 @@ var PermissionManager = class {
|
|
|
2304
2303
|
elevatedCommands = /* @__PURE__ */ new Set();
|
|
2305
2304
|
pendingApprovals = /* @__PURE__ */ new Set();
|
|
2306
2305
|
currentChannelType = "cli";
|
|
2306
|
+
tempScopes = [];
|
|
2307
2307
|
constructor() {
|
|
2308
2308
|
this.cwd = process.cwd();
|
|
2309
2309
|
this.manifest = this.load();
|
|
@@ -2394,12 +2394,18 @@ var PermissionManager = class {
|
|
|
2394
2394
|
}
|
|
2395
2395
|
const resolved = resolve(path3);
|
|
2396
2396
|
const scope = this.findScope(resolved);
|
|
2397
|
+
const tempScope = this.findTempScope(resolved);
|
|
2397
2398
|
if (scope) {
|
|
2398
2399
|
if (mode === "read" && scope.read) return { allowed: true };
|
|
2399
2400
|
if (mode === "write" && scope.write) return { allowed: true };
|
|
2400
2401
|
return { allowed: false, reason: `Permission denied: ${mode} access to ${path3} (scope has ${mode}=false)` };
|
|
2401
2402
|
}
|
|
2402
|
-
|
|
2403
|
+
if (tempScope) {
|
|
2404
|
+
if (mode === "read" && tempScope.read) return { allowed: true };
|
|
2405
|
+
if (mode === "write" && tempScope.write) return { allowed: true };
|
|
2406
|
+
return { allowed: false, reason: `Permission denied: ${mode} access to ${path3}` };
|
|
2407
|
+
}
|
|
2408
|
+
return { allowed: false, reason: `Permission denied for ${mode} access to ${path3}` };
|
|
2403
2409
|
}
|
|
2404
2410
|
async checkShellCommand(command) {
|
|
2405
2411
|
if (this.autoApproveAll) {
|
|
@@ -2430,7 +2436,7 @@ var PermissionManager = class {
|
|
|
2430
2436
|
if (hasPathTraversal) {
|
|
2431
2437
|
const scopeCheck = await this.checkFsAccess(hasPathTraversal, "write");
|
|
2432
2438
|
if (!scopeCheck.allowed) {
|
|
2433
|
-
return { allowed: false, reason:
|
|
2439
|
+
return { allowed: false, reason: `No permission to access ${hasPathTraversal}. Use approve_scope tool with path="${hasPathTraversal}" and mode="write" to request access.`, needsApproval: false };
|
|
2434
2440
|
}
|
|
2435
2441
|
}
|
|
2436
2442
|
}
|
|
@@ -2502,9 +2508,6 @@ var PermissionManager = class {
|
|
|
2502
2508
|
return void 0;
|
|
2503
2509
|
}
|
|
2504
2510
|
async requestScopeExternal(path3, mode) {
|
|
2505
|
-
return this.requestScope(path3, mode);
|
|
2506
|
-
}
|
|
2507
|
-
async requestScope(path3, mode) {
|
|
2508
2511
|
if (!this.askHandler) {
|
|
2509
2512
|
return { allowed: false, reason: `Permission denied for ${mode} access to ${path3}` };
|
|
2510
2513
|
}
|
|
@@ -2517,11 +2520,26 @@ Allow access?`;
|
|
|
2517
2520
|
this.addScope(path3, mode === "read", mode === "write");
|
|
2518
2521
|
return { allowed: true };
|
|
2519
2522
|
}
|
|
2520
|
-
if (response === "yes"
|
|
2523
|
+
if (response === "yes") {
|
|
2524
|
+
this.addTempScope(path3, mode === "read", mode === "write");
|
|
2521
2525
|
return { allowed: true };
|
|
2522
2526
|
}
|
|
2523
2527
|
return { allowed: false, reason: `Permission denied for ${mode} access to ${path3}` };
|
|
2524
2528
|
}
|
|
2529
|
+
addTempScope(path3, read, write) {
|
|
2530
|
+
const resolved = resolve(path3);
|
|
2531
|
+
this.tempScopes.push({ path: resolved, read, write });
|
|
2532
|
+
logger.info({ path: resolved, read, write }, "Temp permission scope added (session only)");
|
|
2533
|
+
}
|
|
2534
|
+
findTempScope(resolvedPath) {
|
|
2535
|
+
for (const scope of this.tempScopes) {
|
|
2536
|
+
const scopeResolved = resolve(scope.path.replace(/^~/, homedir2()));
|
|
2537
|
+
if (resolvedPath === scopeResolved || resolvedPath.startsWith(scopeResolved + sep)) {
|
|
2538
|
+
return scope;
|
|
2539
|
+
}
|
|
2540
|
+
}
|
|
2541
|
+
return void 0;
|
|
2542
|
+
}
|
|
2525
2543
|
matchPattern(command, pattern) {
|
|
2526
2544
|
const regexStr = "^" + pattern.replace(/\*/g, ".*").replace(/\?/g, ".") + "$";
|
|
2527
2545
|
try {
|
|
@@ -2861,18 +2879,18 @@ import { z as z8 } from "zod";
|
|
|
2861
2879
|
import { resolve as resolve9 } from "path";
|
|
2862
2880
|
function createApproveScopeTool(permissions) {
|
|
2863
2881
|
return tool8({
|
|
2864
|
-
description:
|
|
2882
|
+
description: 'Request user approval to access a directory outside current scopes. Use this when a file tool returns a permission denied error. The user gets an approval prompt (Allow/Always/Deny buttons on Telegram, yes/always/no on CLI). "Allow" grants session-only access. "Always" persists to disk. After approval, retry the original file operation.',
|
|
2865
2883
|
parameters: z8.object({
|
|
2866
|
-
path: z8.string().describe("The directory path to
|
|
2884
|
+
path: z8.string().describe("The directory path to request access to"),
|
|
2867
2885
|
mode: z8.enum(["read", "write"]).describe("The access mode needed")
|
|
2868
2886
|
}),
|
|
2869
2887
|
execute: async ({ path: path3, mode }) => {
|
|
2870
2888
|
const resolved = resolve9(path3);
|
|
2871
2889
|
const result = await permissions.requestScopeExternal(resolved, mode);
|
|
2872
2890
|
if (result.allowed) {
|
|
2873
|
-
return `Access approved for ${mode} access to ${resolved}
|
|
2891
|
+
return `Access approved for ${mode} access to ${resolved}. You can now retry the file operation.`;
|
|
2874
2892
|
}
|
|
2875
|
-
return `Access denied for ${mode} access to ${resolved}
|
|
2893
|
+
return `Access denied for ${mode} access to ${resolved}. The user did not approve scope access.`;
|
|
2876
2894
|
}
|
|
2877
2895
|
});
|
|
2878
2896
|
}
|
|
@@ -4300,11 +4318,17 @@ var pkgVersion = JSON.parse(readFileSync12(join11(__dirname, "..", "package.json
|
|
|
4300
4318
|
function hr() {
|
|
4301
4319
|
console.log(chalk6.dim("\u2500".repeat(50)));
|
|
4302
4320
|
}
|
|
4321
|
+
var MERCURY_ASCII = [
|
|
4322
|
+
" __ _____________ ________ ________ __",
|
|
4323
|
+
" / |/ / ____/ __ \\/ ____/ / / / __ \\/ < /",
|
|
4324
|
+
" / /|_/ / __/ / /_/ / / / / / / /_/ /\\ / ",
|
|
4325
|
+
" / / / / /___/ _, _/ /___/ /_/ / _, _/ / / ",
|
|
4326
|
+
"/_/ /_/_____/_/ |_|\\____/\\____/_/ |_| /_/ "
|
|
4327
|
+
].filter((l) => l.trim());
|
|
4303
4328
|
function banner() {
|
|
4304
4329
|
console.log("");
|
|
4305
|
-
const
|
|
4306
|
-
|
|
4307
|
-
if (line.trim()) console.log(chalk6.bold.cyan(` ${line}`));
|
|
4330
|
+
for (const line of MERCURY_ASCII) {
|
|
4331
|
+
console.log(chalk6.bold.cyan(` ${line}`));
|
|
4308
4332
|
}
|
|
4309
4333
|
console.log("");
|
|
4310
4334
|
console.log(chalk6.white(" an AI agent for personal tasks"));
|
|
@@ -4313,9 +4337,8 @@ function banner() {
|
|
|
4313
4337
|
}
|
|
4314
4338
|
function splashScreen() {
|
|
4315
4339
|
console.log("");
|
|
4316
|
-
const
|
|
4317
|
-
|
|
4318
|
-
if (line.trim()) console.log(chalk6.bold.cyan(` ${line}`));
|
|
4340
|
+
for (const line of MERCURY_ASCII) {
|
|
4341
|
+
console.log(chalk6.bold.cyan(` ${line}`));
|
|
4319
4342
|
}
|
|
4320
4343
|
console.log("");
|
|
4321
4344
|
console.log(chalk6.dim(" an AI agent for personal tasks"));
|