import type { ExternalWorkItemSource } from '../storage/domains/work-items/base.js'; export type WorkItemSource = 'github-issue' | 'github-pr' | 'linear-issue' | 'manual'; /** The source label that holds an issue at rest until a maintainer decides; compared lowercased. */ export declare const NEEDS_APPROVAL_LABEL = "status: needs approval"; export declare const AUTO_TRIAGED_LABEL = "status: auto-triaged"; export declare function needsApproval(item: { metadata: Record | null; stages?: readonly string[]; acceptedAt?: Date | string | null; }): boolean; export declare function workItemSource(source: ExternalWorkItemSource | null): WorkItemSource; export declare function externallyAuthored(item: { source: string; metadata: Record | null; }): boolean; export declare function knownExternalAuthor(item: { source: string; metadata: Record | null; }): boolean; export declare function externallyAuthoredWorkItem(item: { externalSource: ExternalWorkItemSource | null; metadata: Record | null; }): boolean; export declare const FACTORY_RULE_STAGES: readonly ["intake", "triage", "planning", "execute", "review", "done", "canceled"]; export type FactoryRuleStage = (typeof FACTORY_RULE_STAGES)[number] | (string & {}); export declare const FACTORY_ROLE_STAGES: { readonly triage: "triage"; readonly plan: "planning"; readonly work: "execute"; readonly review: "review"; }; export type FactoryRole = keyof typeof FACTORY_ROLE_STAGES; export declare function isFactoryRole(value: string): value is FactoryRole; export declare const FACTORY_TRIAGE_TYPES: readonly ["bug", "feature request", "docs", "question/support", "maintenance", "duplicate", "resolved", "invalid", "spam", "out-of-scope", "other"]; export type FactoryTriageType = (typeof FACTORY_TRIAGE_TYPES)[number]; export declare function isFactoryTriageType(value: unknown): value is FactoryTriageType; export declare function isFactoryRuleStage(value: unknown): value is FactoryRuleStage; export declare function factoryRuleStage(stages: readonly string[]): FactoryRuleStage | undefined; export declare function isTerminalFactoryRuleStage(stages: readonly string[]): boolean; /** Working lanes hold cards with a seat engaged; Intake, Done and Canceled rest them. */ export declare function isWorkingFactoryRuleStage(stage: FactoryRuleStage): boolean; export declare function factoryLaneForRole(role: string): FactoryRuleStage | undefined; export declare const FACTORY_RULE_BOARDS: readonly ["work", "review"]; export type FactoryRuleBoard = (typeof FACTORY_RULE_BOARDS)[number] | (string & {}); export declare const FACTORY_RULE_SOURCES: readonly ["issue", "pullRequest", "linearIssue", "manual"]; export type FactoryRuleSource = (typeof FACTORY_RULE_SOURCES)[number]; export declare const FACTORY_GITHUB_EVENTS: readonly ["issueOpened", "issueEdited", "issueClosed", "issueCommentCreated", "issueCommentEdited", "issueCommentDeleted", "pullRequestOpened", "pullRequestUpdated", "pullRequestCommentCreated", "pullRequestReviewRequested", "pullRequestReviewSubmitted", "pullRequestMerged", "pullRequestClosed"]; export type FactoryGithubEventName = (typeof FACTORY_GITHUB_EVENTS)[number]; export declare const FACTORY_LINEAR_EVENTS: readonly ["issueObserved", "issueClosed"]; export type FactoryLinearEventName = (typeof FACTORY_LINEAR_EVENTS)[number]; export type FactoryRuleJsonValue = null | boolean | number | string | FactoryRuleJsonValue[] | { [key: string]: FactoryRuleJsonValue; }; export interface FactoryRuleItemContext { id: string; source: WorkItemSource; sourceKey: string | null; parentWorkItemId: string | null; title: string; url: string | null; stages: readonly string[]; acceptedAt: Date | null; /** Intake-stamped facts about the source — repository id, reporter login, labels. */ metadata: Record | null; } export type FactoryRuleActor = { type: 'human'; id: string; } | { type: 'agent'; bindingId: string; role: string; } | { type: 'github'; login: string; trusted: boolean; factoryAuthored: boolean; } | { type: 'system'; id: string; }; export interface FactoryRuleIngressIdentity { type: 'human' | 'agent' | 'toolResult' | 'github' | 'linear' | 'rule'; id: string; } export interface FactoryRuleCausalEntry { ingressId: string; decisionType: FactoryCommitDecision['type']; } export interface FactoryRuleContextBase { tenant: { orgId: string; projectId: string; }; actor: FactoryRuleActor; ingress: FactoryRuleIngressIdentity; cause: string; causalChain: readonly FactoryRuleCausalEntry[]; configVersion: string; } export interface FactoryBoundRuleContext extends FactoryRuleContextBase { item: FactoryRuleItemContext; board: FactoryRuleBoard; itemRevision: number; } export interface FactoryStageRuleContext extends FactoryBoundRuleContext { source: FactoryRuleSource; stage: FactoryRuleStage; fromStage: FactoryRuleStage; toStage: FactoryRuleStage; } export interface FactoryToolResultRuleContext extends FactoryBoundRuleContext { toolName: string; threadId: string; assistantMessageId: string; toolCallId: string; result: { status: 'success' | 'error'; value: FactoryRuleJsonValue; }; } export interface FactoryGithubRuleContext extends FactoryRuleContextBase { item?: FactoryRuleItemContext; board?: FactoryRuleBoard; itemRevision?: number; /** * Board an issue's labels route it to, when the project has a matching label route and that board * is installed. Absent for pull requests and for issues whose labels select nothing. */ intake?: FactoryRuleIntakeTarget; event: FactoryGithubEventName; deliveryId: string; factory: { createdAt: string; }; repository: { id: number; fullName: string; }; issue?: { number: number; title: string; url: string; createdAt?: string; updatedAt?: string; assignees?: string[]; labels?: string[]; state?: 'open' | 'closed'; /** GitHub close reason: `completed`, `not_planned`, or `duplicate`. */ stateReason?: string; }; issueChange?: { title: boolean; body: boolean; }; issueComment?: { id: number; body?: string; url?: string; author?: string; authorType?: string; createdAt?: string; updatedAt?: string; }; pullRequest?: { number: number; title: string; url: string; createdAt?: string; state: 'open' | 'closed'; draft: boolean; merged: boolean; assignees?: string[]; requestedReviewers?: string[]; labels?: string[]; author?: string; factoryAuthored: boolean; headBranch: string; baseBranch: string; }; /** Present on `pullRequestReviewRequested`: who review was (re-)requested from. */ reviewRequest?: { reviewer: string; factoryReviewer: boolean; }; /** Present when a PR comment uses Factory's exact review command. */ reviewCommand?: { command: 'review' | 're-review'; target: string; }; /** Present on `pullRequestReviewSubmitted`: the review that was just posted. */ review?: { id: number; state: string; url: string; }; } /** * Where an intake source binding says new items from this source should land. * Absent when the source is unbound or bound without a board (built-in routing). */ export interface FactoryRuleIntakeTarget { board: string; initialPhase: string; } export interface FactoryLinearRuleContext extends FactoryRuleContextBase { item?: FactoryRuleItemContext; board?: FactoryRuleBoard; itemRevision?: number; /** Bound board for the source this issue came from, when one is configured and installed. */ intake?: FactoryRuleIntakeTarget; event: FactoryLinearEventName; issue: { id: string; identifier: string; title: string; url: string; state: string; stateType: string; priorityLabel: string; assignee: string | null; creator: string | null; team: string | null; labels: readonly string[]; createdAt: string; updatedAt: string; }; } export type FactoryRuleHandler = (context: Readonly) => FactoryRuleDecision | void | Promise; export interface FactoryBoardRuleLeaf { onEnter?: FactoryRuleHandler; onExit?: FactoryRuleHandler; } export type FactoryRuleRejectionCode = 'forbidden' | 'invalid_transition' | 'missing_binding' | 'stale' | 'timeout' | 'rule_error' | 'causal_depth_exceeded' | 'repeated_transition' | 'approval_required'; export interface FactoryRuleRejectDecision { type: 'reject'; code: FactoryRuleRejectionCode; reason: string; } interface FactoryCommitDecisionBase { idempotencyKey: string; } export interface FactoryTransitionDecision extends FactoryCommitDecisionBase { type: 'transition'; board: FactoryRuleBoard; stage: FactoryRuleStage; /** * Delivered to the item's active session (waking it if idle) after the * transition commits. Skipped when the item has no active run binding, so * informational messages never fail the transition. */ message?: { text: string; role?: string; }; /** * Runs the stage's entry rules even when the item is already in that stage. * A transition to the current stage is normally inert, because most callers * are correcting a board into a state it already holds. Re-entry is for the * opposite case: the stage's work is in flight and has been invalidated, so * it has to start over. */ reenter?: boolean; } export interface FactoryUpsertLinkedWorkItemDecision extends FactoryCommitDecisionBase { type: 'upsertLinkedWorkItem'; board: FactoryRuleBoard; source: WorkItemSource; sourceKey: string; title: string; url: string | null; stage: FactoryRuleStage; metadata?: Record; } interface FactoryInvokeSkillDecisionBase extends FactoryCommitDecisionBase { type: 'invokeSkill'; role: string; arguments?: string; precedingMessage?: string; cancelInFlight?: boolean; } /** * Starting an agent run. Most runs activate a skill, because the skill carries * the handoff contract later rules match on. A run whose completion is already * signalled some other way — Building finishes by opening a pull request, which * arrives as its own event — needs no contract, so it can carry a plain prompt * instead of an otherwise empty skill. */ export type FactoryInvokeSkillDecision = FactoryInvokeSkillDecisionBase & ({ skillName: string; prompt?: never; } | { prompt: string; skillName?: never; }); export interface FactorySendMessageDecision extends FactoryCommitDecisionBase { type: 'sendMessage'; /** Omitted: the card's live session, whichever seat holds it. Required with `prepareBinding`. */ role?: string; message: string; priority?: 'medium' | 'high' | 'urgent'; idleBehavior?: 'persist' | 'wake'; prepareBinding?: boolean; } export interface FactoryNotifyDecision extends FactoryCommitDecisionBase { type: 'notify'; title: string; body?: string; level?: 'info' | 'warning' | 'error'; } export type FactoryCommitDecision = FactoryTransitionDecision | FactoryUpsertLinkedWorkItemDecision | FactoryInvokeSkillDecision | FactorySendMessageDecision | FactoryNotifyDecision; export type FactoryRuleDecision = FactoryRuleRejectDecision | FactoryCommitDecision; export interface FactoryTransitionResultAccepted { status: 'accepted'; transitionId: string; itemId: string; revision: number; stage: FactoryRuleStage; decisions: FactoryCommitDecision[]; } export interface FactoryTransitionResultRejected { status: 'rejected'; transitionId: string; itemId: string; code: FactoryRuleRejectionCode; reason: string; } export type FactoryTransitionResult = FactoryTransitionResultAccepted | FactoryTransitionResultRejected; export declare function factoryRuleSourceForWorkItem(source: WorkItemSource): FactoryRuleSource; export {}; //# sourceMappingURL=types.d.ts.map