import type { WriteOrigin } from './origin.js'; /** * Work-item labels — the shared tag registry and per-Todo label sets (Todos v2 * slice 3). * * Semantics (design decisions, locked): * - Label names are normalized to lowercase kebab-case and UNIQUE; `department` * NULL = company-wide. Creation authority (operator or a manager) lives at the * route layer; this module is the storage truth. * - NO implicit label creation: `setWorkItemLabels` accepts existing label ids * or names only — an unknown name throws listing the valid labels. * - Changing a Todo's set appends ONE `label_changed` event with the resulting * names (`versionEffect: 'state'`), and only on an actual change. * - A set can be REPLACED, or one label added or removed without re-sending the * others. Replace is the destructive one and every caller that has a whole set * in hand uses it; add/remove exist because a caller that only wants to drop * one label should not have to reconstruct the rest from memory to do it. */ export interface Label { id: string; name: string; color: string | null; department: string | null; createdAt: string; } /** The most labels one Todo may carry. It lives here rather than at the route * because `add` only learns the resulting size once it has read the current * set, so this is the only layer that can refuse the write that overflows. */ export declare const TODO_LABELS_MAX = 100; /** How a write changes a Todo's set: the whole set at once, or only the labels * named, leaving every other label in place. */ export type LabelChangeMode = 'replace' | 'add' | 'remove'; /** Normalize a label name to lowercase kebab-case: runs of anything that is not * a letter or digit collapse to single dashes. Throws when nothing survives. */ export declare function normalizeLabelName(name: string): string; /** * Create a label. The name is normalized to kebab-case; a normalized-name * collision (including a lost UNIQUE race) returns the existing label unchanged * rather than erroring or overwriting. */ export declare function createLabel(input: { name: string; color?: string | null; department?: string | null; }): Label; /** All labels, ordered by name. */ export declare function listLabels(): Label[]; /** Replace a Todo's whole label set. Every label not named is dropped. */ export declare function setWorkItemLabels(workItemId: string, labelRefs: string[], actor: string, origin?: WriteOrigin): Label[]; /** Add labels without re-sending the ones already there. Labels already on the * Todo are not duplicated, and an add that changes nothing writes nothing. */ export declare function addWorkItemLabels(workItemId: string, labelRefs: string[], actor: string, origin?: WriteOrigin): Label[]; /** Remove the labels named, leaving every other label on the Todo in place. */ export declare function removeWorkItemLabels(workItemId: string, labelRefs: string[], actor: string, origin?: WriteOrigin): Label[]; /** A Todo's labels, ordered by name. An unknown Todo reads as empty — existence * 404s belong to the route layer. */ export declare function getWorkItemLabels(workItemId: string): Label[]; /** Batch form of `getWorkItemLabels` for list payloads: ONE query for the whole * page, never per-item. Every requested id is present in the Map (empty array * when unlabelled). */ export declare function labelSets(workItemIds: string[]): Map; //# sourceMappingURL=labels.d.ts.map