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,54 @@
import type { ForwardedSessionApproval } from "#src/authority/permission-forwarding";
/**
* Value object for a session-scoped approval: one surface, one-or-more patterns.
*
* Owned by gate descriptors and passed to the session store — the runner never
* needs to know whether there is one pattern or many.
*/
export class SessionApproval {
private constructor(
readonly surface: string,
readonly patterns: readonly string[],
) {}
/** Create an approval for a single pattern (the common case). */
static single(surface: string, pattern: string): SessionApproval {
return new SessionApproval(surface, [pattern]);
}
/**
* Create an approval for multiple patterns (e.g. bash external-directory
* gates that cover several uncovered paths in one prompt).
*/
static multiple(
surface: string,
patterns: readonly string[],
): SessionApproval {
return new SessionApproval(surface, [...patterns]);
}
/** Representative pattern for the interactive prompt — the first, if any. */
get representativePattern(): string | undefined {
return this.patterns[0];
}
/**
* Single-pattern shape `applyPermissionGate` echoes back to the caller.
* Returns `undefined` when patterns is empty (degenerate case).
*/
toGateApproval(): { surface: string; pattern: string } | undefined {
const pattern = this.representativePattern;
if (pattern === undefined) return undefined;
return { surface: this.surface, pattern };
}
/**
* Plain data shape for relaying this approval on a forwarded request, so the
* serving node can record the same pattern(s) as a whole-session grant.
* Returns a defensive copy of the patterns.
*/
toForwardedData(): ForwardedSessionApproval {
return { surface: this.surface, patterns: [...this.patterns] };
}
}