@cosmicstack/mercury-agent 0.2.5 → 0.2.6
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 +29 -10
- package/dist/index.js.map +1 -1
- package/package.json +3 -6
package/dist/index.js
CHANGED
|
@@ -2304,6 +2304,7 @@ var PermissionManager = class {
|
|
|
2304
2304
|
elevatedCommands = /* @__PURE__ */ new Set();
|
|
2305
2305
|
pendingApprovals = /* @__PURE__ */ new Set();
|
|
2306
2306
|
currentChannelType = "cli";
|
|
2307
|
+
tempScopes = [];
|
|
2307
2308
|
constructor() {
|
|
2308
2309
|
this.cwd = process.cwd();
|
|
2309
2310
|
this.manifest = this.load();
|
|
@@ -2394,12 +2395,18 @@ var PermissionManager = class {
|
|
|
2394
2395
|
}
|
|
2395
2396
|
const resolved = resolve(path3);
|
|
2396
2397
|
const scope = this.findScope(resolved);
|
|
2398
|
+
const tempScope = this.findTempScope(resolved);
|
|
2397
2399
|
if (scope) {
|
|
2398
2400
|
if (mode === "read" && scope.read) return { allowed: true };
|
|
2399
2401
|
if (mode === "write" && scope.write) return { allowed: true };
|
|
2400
2402
|
return { allowed: false, reason: `Permission denied: ${mode} access to ${path3} (scope has ${mode}=false)` };
|
|
2401
2403
|
}
|
|
2402
|
-
|
|
2404
|
+
if (tempScope) {
|
|
2405
|
+
if (mode === "read" && tempScope.read) return { allowed: true };
|
|
2406
|
+
if (mode === "write" && tempScope.write) return { allowed: true };
|
|
2407
|
+
return { allowed: false, reason: `Permission denied: ${mode} access to ${path3}` };
|
|
2408
|
+
}
|
|
2409
|
+
return { allowed: false, reason: `Permission denied for ${mode} access to ${path3}` };
|
|
2403
2410
|
}
|
|
2404
2411
|
async checkShellCommand(command) {
|
|
2405
2412
|
if (this.autoApproveAll) {
|
|
@@ -2430,7 +2437,7 @@ var PermissionManager = class {
|
|
|
2430
2437
|
if (hasPathTraversal) {
|
|
2431
2438
|
const scopeCheck = await this.checkFsAccess(hasPathTraversal, "write");
|
|
2432
2439
|
if (!scopeCheck.allowed) {
|
|
2433
|
-
return { allowed: false, reason:
|
|
2440
|
+
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
2441
|
}
|
|
2435
2442
|
}
|
|
2436
2443
|
}
|
|
@@ -2502,9 +2509,6 @@ var PermissionManager = class {
|
|
|
2502
2509
|
return void 0;
|
|
2503
2510
|
}
|
|
2504
2511
|
async requestScopeExternal(path3, mode) {
|
|
2505
|
-
return this.requestScope(path3, mode);
|
|
2506
|
-
}
|
|
2507
|
-
async requestScope(path3, mode) {
|
|
2508
2512
|
if (!this.askHandler) {
|
|
2509
2513
|
return { allowed: false, reason: `Permission denied for ${mode} access to ${path3}` };
|
|
2510
2514
|
}
|
|
@@ -2517,11 +2521,26 @@ Allow access?`;
|
|
|
2517
2521
|
this.addScope(path3, mode === "read", mode === "write");
|
|
2518
2522
|
return { allowed: true };
|
|
2519
2523
|
}
|
|
2520
|
-
if (response === "yes"
|
|
2524
|
+
if (response === "yes") {
|
|
2525
|
+
this.addTempScope(path3, mode === "read", mode === "write");
|
|
2521
2526
|
return { allowed: true };
|
|
2522
2527
|
}
|
|
2523
2528
|
return { allowed: false, reason: `Permission denied for ${mode} access to ${path3}` };
|
|
2524
2529
|
}
|
|
2530
|
+
addTempScope(path3, read, write) {
|
|
2531
|
+
const resolved = resolve(path3);
|
|
2532
|
+
this.tempScopes.push({ path: resolved, read, write });
|
|
2533
|
+
logger.info({ path: resolved, read, write }, "Temp permission scope added (session only)");
|
|
2534
|
+
}
|
|
2535
|
+
findTempScope(resolvedPath) {
|
|
2536
|
+
for (const scope of this.tempScopes) {
|
|
2537
|
+
const scopeResolved = resolve(scope.path.replace(/^~/, homedir2()));
|
|
2538
|
+
if (resolvedPath === scopeResolved || resolvedPath.startsWith(scopeResolved + sep)) {
|
|
2539
|
+
return scope;
|
|
2540
|
+
}
|
|
2541
|
+
}
|
|
2542
|
+
return void 0;
|
|
2543
|
+
}
|
|
2525
2544
|
matchPattern(command, pattern) {
|
|
2526
2545
|
const regexStr = "^" + pattern.replace(/\*/g, ".*").replace(/\?/g, ".") + "$";
|
|
2527
2546
|
try {
|
|
@@ -2861,18 +2880,18 @@ import { z as z8 } from "zod";
|
|
|
2861
2880
|
import { resolve as resolve9 } from "path";
|
|
2862
2881
|
function createApproveScopeTool(permissions) {
|
|
2863
2882
|
return tool8({
|
|
2864
|
-
description:
|
|
2883
|
+
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
2884
|
parameters: z8.object({
|
|
2866
|
-
path: z8.string().describe("The directory path to
|
|
2885
|
+
path: z8.string().describe("The directory path to request access to"),
|
|
2867
2886
|
mode: z8.enum(["read", "write"]).describe("The access mode needed")
|
|
2868
2887
|
}),
|
|
2869
2888
|
execute: async ({ path: path3, mode }) => {
|
|
2870
2889
|
const resolved = resolve9(path3);
|
|
2871
2890
|
const result = await permissions.requestScopeExternal(resolved, mode);
|
|
2872
2891
|
if (result.allowed) {
|
|
2873
|
-
return `Access approved for ${mode} access to ${resolved}
|
|
2892
|
+
return `Access approved for ${mode} access to ${resolved}. You can now retry the file operation.`;
|
|
2874
2893
|
}
|
|
2875
|
-
return `Access denied for ${mode} access to ${resolved}
|
|
2894
|
+
return `Access denied for ${mode} access to ${resolved}. The user did not approve scope access.`;
|
|
2876
2895
|
}
|
|
2877
2896
|
});
|
|
2878
2897
|
}
|