🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

@papi-ai/shared

Package Overview
Dependencies
Maintainers
1
Versions
9
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@papi-ai/shared - npm Package Compare versions

Comparing version
0.1.6
to
0.1.7
+52
-2
dist/index.d.ts

@@ -32,3 +32,3 @@ /** Valid task statuses on the cycle board. */

/** The value-add capabilities that are switchable from the dashboard (Tier 1). */
type CapabilityKey = 'prReviewer' | 'securityScan' | 'changelog' | 'verifyHealthCheck' | 'gestaltPreBuild' | 'batchBuildRollup' | 'modelRecommendation' | 'discoveredIssues' | 'publishDirective' | 'releaseGate' | 'deployHook' | 'acceptanceGate';
type CapabilityKey = 'prReviewer' | 'securityScan' | 'changelog' | 'verifyHealthCheck' | 'gestaltPreBuild' | 'batchBuildRollup' | 'modelRecommendation' | 'discoveredIssues' | 'publishDirective' | 'releaseGate' | 'deployHook' | 'acceptanceGate' | 'autoBranch' | 'autoCommit' | 'autoPush' | 'papiMetaFraming';
/** A curated capability descriptor rendered by the dashboard toggle surface. */

@@ -120,3 +120,53 @@ interface CapabilityDescriptor {

declare function isSensitiveChangelogLine(line: string): boolean;
/** Why a doc deletion was refused. */
type DocDeletionBlockReason = 'not_found' | 'not_authorized' | 'supersession_dependency' | 'reference_dependency';
/** Facts the deletion guard decides over. All dependency lookups are resolved by
* the caller (adapter or dashboard) and passed in as booleans so this stays pure. */
interface DocDeletionInput {
/** False when no row matched id + project scope. */
docExists: boolean;
/** The acting user's id (config.userId / bearer identity). Null → never authorized. */
requesterUserId: string | null | undefined;
/** doc_registry.owner_user_id — the doc's creator lock. */
creatorUserId: string | null | undefined;
/** projects.user_id — the project owner. */
projectOwnerUserId: string | null | undefined;
/** True when another doc_registry row has superseded_by = this doc's id. */
hasSupersessionDependent: boolean;
/** True when a cycle_task.doc_ref targets this doc, or an action links a task. */
hasReferenceDependent: boolean;
}
type DocDeletionDecision = {
allowed: true;
} | {
allowed: false;
reason: DocDeletionBlockReason;
};
/**
* Evaluate whether a doc may be hard-deleted. Authorization is checked BEFORE
* dependencies so an unauthorized caller never learns a doc's dependency state.
* Fail-closed: a null/blank requester is never the creator or owner.
*/
declare function evaluateDocDeletion(input: DocDeletionInput): DocDeletionDecision;
/** Human-readable explanation for a block reason — reused across MCP + dashboard. */
declare function docDeletionBlockMessage(reason: DocDeletionBlockReason): string;
/**
* The soft Team upsell shown to a non-Team caller who invites someone. Advisory
* ONLY — it accompanies a successful invite, it never blocks one (AD-73).
*/
declare function contributorTeamUpsell(tier: string): string;
/** The contributor-invite decision. `allowed` is always true — see PERMISSIVE note above. */
type ContributorGateDecision = {
allowed: true;
upsell?: string;
};
/**
* Evaluate the contributor-invite gate. PERMISSIVE (AD-73): the invite is ALWAYS
* allowed — this function never returns a block. Non-Team hosted tiers (free/pro)
* receive a soft Team `upsell`; owner/local (null/undefined tier) and team callers
* receive none. Tier is resolved SERVER-SIDE by the caller and passed in — this
* pure function never reads client input.
*/
declare function evaluateContributorGate(tier: string | null | undefined): ContributorGateDecision;
export { CAPABILITY_KEYS, CAPABILITY_REGISTRY, type CapabilityDescriptor, type CapabilityKey, type CapabilityMap, type CapabilityStep, type EffortSize, RETIRED_DECISION_OUTCOMES, type ReviewStage, type ReviewVerdict, SENSITIVE_CHANGELOG_PATTERNS, TASK_STATUSES, type TaskComplexity, type TaskPriority, type TaskStatus, type TaskType, VALID_TRANSITIONS, isCapabilityEnabled, isCapabilityKey, isLiveDecision, isSensitiveChangelogLine, isValidStatus, isValidTransition, validateTransition };
export { CAPABILITY_KEYS, CAPABILITY_REGISTRY, type CapabilityDescriptor, type CapabilityKey, type CapabilityMap, type CapabilityStep, type ContributorGateDecision, type DocDeletionBlockReason, type DocDeletionDecision, type DocDeletionInput, type EffortSize, RETIRED_DECISION_OUTCOMES, type ReviewStage, type ReviewVerdict, SENSITIVE_CHANGELOG_PATTERNS, TASK_STATUSES, type TaskComplexity, type TaskPriority, type TaskStatus, type TaskType, VALID_TRANSITIONS, contributorTeamUpsell, docDeletionBlockMessage, evaluateContributorGate, evaluateDocDeletion, isCapabilityEnabled, isCapabilityKey, isLiveDecision, isSensitiveChangelogLine, isValidStatus, isValidTransition, validateTransition };

@@ -57,3 +57,12 @@ // src/index.ts

// chooses to hold builds to their own acceptance criteria.
{ key: "acceptanceGate", label: "Acceptance-criteria gate", description: "Requires confirming the handoff acceptance criteria before a build completes.", step: "build", defaultEnabled: false }
{ key: "acceptanceGate", label: "Acceptance-criteria gate", description: "Requires confirming the handoff acceptance criteria before a build completes.", step: "build", defaultEnabled: false },
// task-2325 (C344): configurable workflow guardrails — let a user opt out of the
// git/branch/commit/PR ceremony and PAPI-meta framing so PAPI adapts to their
// workflow instead of imposing one. Every toggle DEFAULTS ON (no defaultEnabled)
// so current behaviour is byte-identical until the user flips it off. The no-git
// fallback that these ride on top of is a separate task (task-2353).
{ key: "autoBranch", label: "Auto branch", description: "Creates a feature branch per task/cycle at build start.", step: "build" },
{ key: "autoCommit", label: "Auto commit", description: "Commits your work automatically when a build completes.", step: "build" },
{ key: "autoPush", label: "Auto push & PR", description: "Pushes the branch and opens a pull request on build complete.", step: "build" },
{ key: "papiMetaFraming", label: "PAPI self-referential framing", description: "Includes PAPI-meta build-discipline framing in handoff output.", step: "build" }
];

@@ -114,2 +123,37 @@ var CAPABILITY_KEYS = CAPABILITY_REGISTRY.map((c) => c.key);

}
function normId(v) {
return (v ?? "").trim().toLowerCase();
}
function evaluateDocDeletion(input) {
if (!input.docExists) return { allowed: false, reason: "not_found" };
const requester = normId(input.requesterUserId);
const isCreator = requester.length > 0 && requester === normId(input.creatorUserId);
const isOwner = requester.length > 0 && requester === normId(input.projectOwnerUserId);
if (!isCreator && !isOwner) return { allowed: false, reason: "not_authorized" };
if (input.hasSupersessionDependent) return { allowed: false, reason: "supersession_dependency" };
if (input.hasReferenceDependent) return { allowed: false, reason: "reference_dependency" };
return { allowed: true };
}
function docDeletionBlockMessage(reason) {
switch (reason) {
case "not_found":
return "Doc not found in this project.";
case "not_authorized":
return "Only the doc creator or the project owner may delete this doc.";
case "supersession_dependency":
return "Another doc supersedes this one \u2014 deleting it would orphan the supersession chain. Re-point or remove the dependent first.";
case "reference_dependency":
return "A task references this doc (doc_ref or a linked action) \u2014 resolve the reference before deleting.";
}
}
var CONTRIBUTOR_PRICING_URL = "https://getpapi.ai/pricing";
function contributorTeamUpsell(tier) {
return `**Heads up \u2014 shared projects are a Team feature.**
You're on the ${tier} plan and the invite still went through. Team adds roles and the Quality Gate, and read-only viewer seats are free, so you only pay for who is actually building: ${CONTRIBUTOR_PRICING_URL}`;
}
function evaluateContributorGate(tier) {
if (tier == null || tier === "team") return { allowed: true };
return { allowed: true, upsell: contributorTeamUpsell(tier) };
}
export {

@@ -122,2 +166,6 @@ CAPABILITY_KEYS,

VALID_TRANSITIONS,
contributorTeamUpsell,
docDeletionBlockMessage,
evaluateContributorGate,
evaluateDocDeletion,
isCapabilityEnabled,

@@ -124,0 +172,0 @@ isCapabilityKey,

+1
-1
{
"name": "@papi-ai/shared",
"version": "0.1.6",
"version": "0.1.7",
"description": "Shared types and business rules for PAPI — used by both MCP server and dashboard",

@@ -5,0 +5,0 @@ "license": "Elastic-2.0",