Files
my-pi/pi-permission-system/src/session-approval.ts
T

55 lines
1.8 KiB
TypeScript

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] };
}
}