mirror of
https://bitbucket.org/siakitem/my-pi.git
synced 2026-10-26 10:45:22 +00:00
39 lines
1.6 KiB
TypeScript
39 lines
1.6 KiB
TypeScript
import { parseBashCommandsSync } from "#src/access-intent/bash/sync-commands";
|
|
import { resolveBashCommandCheck } from "#src/handlers/gates/bash-command";
|
|
import type { ScopedPermissionResolver } from "#src/permission-resolver";
|
|
import type { PermissionCheckResult } from "#src/types";
|
|
|
|
/**
|
|
* Resolve an advisory bash query at the gate's decomposed fidelity.
|
|
*
|
|
* When the tree-sitter parser is warm, the command is decomposed into its
|
|
* command-pattern units and routed through the same shared orchestrator the
|
|
* enforcement gate uses (`resolveBashCommandCheck`) — so a chained/nested
|
|
* command returns the most-restrictive decision (`deny > ask > allow`) and
|
|
* inherits the opaque-wrapper floor (#481) and the fail-closed
|
|
* `<unparseable-bash-command>` sentinel (#452), at parity with the gate.
|
|
*
|
|
* In the pre-warm window (`parseBashCommandsSync` returns `null`) it falls back
|
|
* to the pre-#309 whole-string match, so the advisory answer is never *weaker*
|
|
* than before — only strengthened once warm.
|
|
*
|
|
* Synchronous, preserving `PermissionsService.checkPermission`'s sync contract:
|
|
* the only async step (parser init) happens earlier, at `before_agent_start`.
|
|
*/
|
|
export function resolveBashAdvisoryCheck(
|
|
command: string,
|
|
agentName: string | undefined,
|
|
resolver: ScopedPermissionResolver,
|
|
): PermissionCheckResult {
|
|
const commands = parseBashCommandsSync(command);
|
|
if (commands === null) {
|
|
return resolver.resolve({
|
|
kind: "tool",
|
|
surface: "bash",
|
|
input: { command },
|
|
agentName,
|
|
});
|
|
}
|
|
return resolveBashCommandCheck(command, commands, agentName, resolver);
|
|
}
|