mirror of
https://bitbucket.org/siakitem/my-pi.git
synced 2026-10-27 03:05:22 +00:00
feat: add pure ssh2 remote operations
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
import type { ShellToolsConfig } from "#src/config-schema";
|
||||
import type { PermissionCheckResult } from "#src/types";
|
||||
|
||||
/** Synthetic rule marker recorded when a shell alias raises allow to ask. */
|
||||
export const SHELL_TOOL_DECISION_FLOOR_PATTERN = "<shell-tool-decision-floor>";
|
||||
|
||||
type ShellDecisionFloor = ShellToolsConfig[string]["decisionFloor"];
|
||||
|
||||
/**
|
||||
* Enforce the minimum review decision configured for a shell alias.
|
||||
*
|
||||
* The only supported floor is `ask`: it raises an allow to ask while preserving
|
||||
* existing asks and hard denies. The synthetic result no longer reports a
|
||||
* session source, so a prior Bash session approval cannot bypass an alias whose
|
||||
* contract requires every invocation to enter the authorizer chain.
|
||||
*/
|
||||
export function applyShellDecisionFloor(
|
||||
check: PermissionCheckResult,
|
||||
floor: ShellDecisionFloor,
|
||||
): PermissionCheckResult {
|
||||
if (floor !== "ask" || check.state !== "allow") return check;
|
||||
|
||||
return {
|
||||
...check,
|
||||
state: "ask",
|
||||
source: "bash",
|
||||
matchedPattern: SHELL_TOOL_DECISION_FLOOR_PATTERN,
|
||||
reason: undefined,
|
||||
};
|
||||
}
|
||||
@@ -25,6 +25,7 @@ import { describePathGate } from "./path";
|
||||
import type { GateRunner } from "./runner";
|
||||
import { describeSkillReadGate } from "./skill-read";
|
||||
import { describeToolGate } from "./tool";
|
||||
import { applyShellDecisionFloor } from "./shell-decision-floor";
|
||||
import type { GateOutcome, ToolCallContext } from "./types";
|
||||
|
||||
/**
|
||||
@@ -164,25 +165,27 @@ export class ToolCallGatePipeline {
|
||||
): { toolCheck: PermissionCheckResult; accessPath?: AccessPath } {
|
||||
if (shell) {
|
||||
if (bashProgram) {
|
||||
const check = resolveBashCommandCheck(
|
||||
bashProgram.commandText(),
|
||||
bashProgram.commands(),
|
||||
tcc.agentName ?? undefined,
|
||||
this.resolver,
|
||||
);
|
||||
return {
|
||||
toolCheck: resolveBashCommandCheck(
|
||||
bashProgram.commandText(),
|
||||
bashProgram.commands(),
|
||||
tcc.agentName ?? undefined,
|
||||
this.resolver,
|
||||
),
|
||||
toolCheck: applyShellDecisionFloor(check, shell.decisionFloor),
|
||||
};
|
||||
}
|
||||
// A shell invocation whose command did not parse (e.g. empty) still
|
||||
// resolves on the `bash` surface, so an aliased tool never falls through
|
||||
// to its own extension-tool surface.
|
||||
const check = this.resolver.resolve({
|
||||
kind: "tool",
|
||||
surface: "bash",
|
||||
input: { command: shell.command },
|
||||
agentName: tcc.agentName ?? undefined,
|
||||
});
|
||||
return {
|
||||
toolCheck: this.resolver.resolve({
|
||||
kind: "tool",
|
||||
surface: "bash",
|
||||
input: { command: shell.command },
|
||||
agentName: tcc.agentName ?? undefined,
|
||||
}),
|
||||
toolCheck: applyShellDecisionFloor(check, shell.decisionFloor),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -65,6 +65,10 @@ export function describeToolGate(
|
||||
tcc.input,
|
||||
PATH_BEARING_TOOLS,
|
||||
);
|
||||
if (shell && tcc.toolName !== check.toolName) {
|
||||
permissionLogContext.toolInputPreview =
|
||||
formatter.formatToolInputForPrompt(tcc.toolName, tcc.input) || undefined;
|
||||
}
|
||||
|
||||
// Compute session approval suggestion for the "for this session" option.
|
||||
const suggestion = suggestSessionPattern(
|
||||
|
||||
Reference in New Issue
Block a user