feat: vendor permission system source

This commit is contained in:
云服务部-叶林立
2026-08-19 14:35:19 +08:00
parent 198584daf8
commit 410c50a3e5
809 changed files with 157793 additions and 139 deletions
@@ -0,0 +1,38 @@
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);
}