dsh-home-hosted 0.1.3 → 0.1.4
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/docs/DESIGN.md +10 -0
- package/lib/index.js +17 -3
- package/lib/index.js.map +2 -2
- package/package.json +1 -1
package/docs/DESIGN.md
CHANGED
|
@@ -31,6 +31,16 @@ node_modules (flat or pnpm), then PATH — and forwards its argv, so the entry
|
|
|
31
31
|
survives plugin upgrades and profile reinstalls. The plugin preflights the
|
|
32
32
|
launcher the way the unit invokes it and shows the version it answers.
|
|
33
33
|
|
|
34
|
+
## Approvals follow the session's sandbox
|
|
35
|
+
|
|
36
|
+
A mutating agent tool asks the approval service only when the calling session is
|
|
37
|
+
*not* already `danger-full-access` (`ctx.sandboxPolicy.resolve({ session })`).
|
|
38
|
+
Asking anyway made a Full-access run fail whenever the deployment's approvals
|
|
39
|
+
auto-reject — the session had already granted exactly what the tool was asking
|
|
40
|
+
about. Below full access the tool still asks and still fails closed, and the
|
|
41
|
+
refusal names the mode and the remedy (Full access, or an answerable approval
|
|
42
|
+
channel).
|
|
43
|
+
|
|
34
44
|
## Config compatibility
|
|
35
45
|
|
|
36
46
|
`onPortConflict: kill` did not exist before home-hosted 0.6.0, and an older panel
|
package/lib/index.js
CHANGED
|
@@ -3591,6 +3591,17 @@ var SettingsStore = class {
|
|
|
3591
3591
|
|
|
3592
3592
|
// src/tools.ts
|
|
3593
3593
|
import { defineTool } from "@deepseek-ai/dsh-tools";
|
|
3594
|
+
function sandboxMode(ctx, exec) {
|
|
3595
|
+
const policy = ctx.get("sandboxPolicy");
|
|
3596
|
+
if (policy?.resolve === void 0)
|
|
3597
|
+
return null;
|
|
3598
|
+
const session = exec?.agent?.session;
|
|
3599
|
+
try {
|
|
3600
|
+
return policy.resolve({ ...session === void 0 ? {} : { session } })?.mode ?? null;
|
|
3601
|
+
} catch {
|
|
3602
|
+
return null;
|
|
3603
|
+
}
|
|
3604
|
+
}
|
|
3594
3605
|
var TOOL_SPECS = {
|
|
3595
3606
|
status: {
|
|
3596
3607
|
endpoint: "status",
|
|
@@ -3663,17 +3674,20 @@ function registerOne(ctx, service, name2) {
|
|
|
3663
3674
|
},
|
|
3664
3675
|
async execute(args, exec) {
|
|
3665
3676
|
const input = args ?? {};
|
|
3666
|
-
|
|
3677
|
+
const mode = sandboxMode(ctx, exec);
|
|
3678
|
+
const fullAccess = mode === "danger-full-access";
|
|
3679
|
+
if (mutating && !fullAccess) {
|
|
3667
3680
|
const approval = ctx.get("approval");
|
|
3681
|
+
const remedy = "Set the session to Full access (danger-full-access), or use a session where approvals can be answered.";
|
|
3668
3682
|
if (approval?.request === void 0)
|
|
3669
|
-
return
|
|
3683
|
+
return `refused: this session runs in ${mode ?? "an unknown"} sandbox and the deployment has no approval service. ${remedy}`;
|
|
3670
3684
|
const outcome = await approval.request({
|
|
3671
3685
|
agent: exec?.agent,
|
|
3672
3686
|
toolName,
|
|
3673
3687
|
reason: `${spec.description} (${JSON.stringify(input)})`
|
|
3674
3688
|
});
|
|
3675
3689
|
if (outcome !== "allowed-once")
|
|
3676
|
-
return `refused: approval answered "${outcome}"
|
|
3690
|
+
return `refused: approval answered "${outcome}" (session sandbox: ${mode ?? "unknown"}). ${remedy}`;
|
|
3677
3691
|
}
|
|
3678
3692
|
try {
|
|
3679
3693
|
const payload = name2 === "servers_create" ? { entry: input.entry } : name2 === "servers_update" ? { id: input.id, patch: input.patch } : name2 === "status" || name2 === "servers_list" ? {} : { id: input.id, mechanism: input.mechanism };
|