@clepit/core 0.4.0 → 0.5.0-beta.350

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  export declare const inputStylesKey = "embed-input";
2
2
  export declare const outputStylesKey = "embed-output";
3
- export declare const sharedStyle = "\n.clepit-embed {\n border: 1px solid rgba(127, 127, 127, 0.35);\n border-radius: 8px;\n overflow: hidden;\n}\n.clepit-embed__frame {\n display: block;\n width: 100%;\n border: 0;\n}\n.clepit-embed-card {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n padding: 12px;\n border: 1px solid rgba(127, 127, 127, 0.35);\n border-radius: 8px;\n color: inherit;\n text-decoration: none;\n}\n.clepit-embed-card:hover {\n background: rgba(127, 127, 127, 0.08);\n}\n.clepit-embed-card__title {\n font-weight: 600;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.clepit-embed-card__description {\n opacity: 0.7;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n";
4
- export declare const inputStyle = "\n.clepit-embed {\n border: 1px solid rgba(127, 127, 127, 0.35);\n border-radius: 8px;\n overflow: hidden;\n}\n.clepit-embed__frame {\n display: block;\n width: 100%;\n border: 0;\n}\n.clepit-embed-card {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n padding: 12px;\n border: 1px solid rgba(127, 127, 127, 0.35);\n border-radius: 8px;\n color: inherit;\n text-decoration: none;\n}\n.clepit-embed-card:hover {\n background: rgba(127, 127, 127, 0.08);\n}\n.clepit-embed-card__title {\n font-weight: 600;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.clepit-embed-card__description {\n opacity: 0.7;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n";
5
- export declare const outputStyle = "\n.clepit-embed {\n border: 1px solid rgba(127, 127, 127, 0.35);\n border-radius: 8px;\n overflow: hidden;\n}\n.clepit-embed__frame {\n display: block;\n width: 100%;\n border: 0;\n}\n.clepit-embed-card {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n padding: 12px;\n border: 1px solid rgba(127, 127, 127, 0.35);\n border-radius: 8px;\n color: inherit;\n text-decoration: none;\n}\n.clepit-embed-card:hover {\n background: rgba(127, 127, 127, 0.08);\n}\n.clepit-embed-card__title {\n font-weight: 600;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.clepit-embed-card__description {\n opacity: 0.7;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n";
3
+ export declare const sharedStyle = "\n.clepit-embed {\n border: 1px solid rgba(127, 127, 127, 0.35);\n border-radius: 8px;\n overflow: hidden;\n}\n.clepit-embed__frame {\n display: block;\n width: 100%;\n border: 0;\n}\n.clepit-embed-card {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n padding: 12px;\n border: 1px solid rgba(127, 127, 127, 0.35);\n border-radius: 8px;\n color: inherit;\n text-decoration: none;\n}\n.clepit-embed-card:hover {\n background: rgba(127, 127, 127, 0.08);\n}\n.clepit-embed-card__title {\n font-weight: 600;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.clepit-embed-card__description {\n opacity: 0.7;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n.clepit-embed-card--with-reason {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 12px;\n border: 1px solid rgba(127, 127, 127, 0.35);\n border-radius: 8px;\n}\n.clepit-embed-card--with-reason > .clepit-embed-card {\n padding: 0;\n border: 0;\n}\n.clepit-embed-card__reason {\n display: flex;\n flex-wrap: wrap;\n gap: 6px 14px;\n align-items: center;\n font-size: 0.9em;\n opacity: 0.85;\n}\n.clepit-embed-card__action {\n padding: 0;\n font: inherit;\n color: inherit;\n text-decoration: underline;\n background: none;\n border: 0;\n cursor: pointer;\n}\n.clepit-embed--gist-frame .clepit-embed__frame {\n height: 552px;\n}\n.clepit-embed-gist {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n.clepit-embed-gist__file {\n display: flex;\n gap: 10px;\n align-items: baseline;\n font-size: 0.9em;\n}\n.clepit-embed-gist__file b {\n font-weight: 600;\n}\n.clepit-embed-gist__file a {\n margin-left: auto;\n color: inherit;\n opacity: 0.7;\n}\n.clepit-embed-offer {\n position: absolute;\n z-index: 20;\n display: inline-flex;\n gap: 6px;\n align-items: center;\n padding: 4px 4px 4px 10px;\n font-size: 12px;\n background: var(--clepit-surface, #fff);\n border: 1px solid rgba(127, 127, 127, 0.35);\n border-radius: 999px;\n box-shadow: 0 8px 24px rgba(0, 0, 0, 0.16);\n}\n.clepit-embed-offer button {\n padding: 3px 9px;\n font: inherit;\n font-weight: 600;\n color: #fff;\n background: var(--clepit-primary, #5b5bff);\n border: 0;\n border-radius: 999px;\n cursor: pointer;\n}\n";
4
+ export declare const inputStyle = "\n.clepit-embed {\n border: 1px solid rgba(127, 127, 127, 0.35);\n border-radius: 8px;\n overflow: hidden;\n}\n.clepit-embed__frame {\n display: block;\n width: 100%;\n border: 0;\n}\n.clepit-embed-card {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n padding: 12px;\n border: 1px solid rgba(127, 127, 127, 0.35);\n border-radius: 8px;\n color: inherit;\n text-decoration: none;\n}\n.clepit-embed-card:hover {\n background: rgba(127, 127, 127, 0.08);\n}\n.clepit-embed-card__title {\n font-weight: 600;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.clepit-embed-card__description {\n opacity: 0.7;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n.clepit-embed-card--with-reason {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 12px;\n border: 1px solid rgba(127, 127, 127, 0.35);\n border-radius: 8px;\n}\n.clepit-embed-card--with-reason > .clepit-embed-card {\n padding: 0;\n border: 0;\n}\n.clepit-embed-card__reason {\n display: flex;\n flex-wrap: wrap;\n gap: 6px 14px;\n align-items: center;\n font-size: 0.9em;\n opacity: 0.85;\n}\n.clepit-embed-card__action {\n padding: 0;\n font: inherit;\n color: inherit;\n text-decoration: underline;\n background: none;\n border: 0;\n cursor: pointer;\n}\n.clepit-embed--gist-frame .clepit-embed__frame {\n height: 552px;\n}\n.clepit-embed-gist {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n.clepit-embed-gist__file {\n display: flex;\n gap: 10px;\n align-items: baseline;\n font-size: 0.9em;\n}\n.clepit-embed-gist__file b {\n font-weight: 600;\n}\n.clepit-embed-gist__file a {\n margin-left: auto;\n color: inherit;\n opacity: 0.7;\n}\n.clepit-embed-offer {\n position: absolute;\n z-index: 20;\n display: inline-flex;\n gap: 6px;\n align-items: center;\n padding: 4px 4px 4px 10px;\n font-size: 12px;\n background: var(--clepit-surface, #fff);\n border: 1px solid rgba(127, 127, 127, 0.35);\n border-radius: 999px;\n box-shadow: 0 8px 24px rgba(0, 0, 0, 0.16);\n}\n.clepit-embed-offer button {\n padding: 3px 9px;\n font: inherit;\n font-weight: 600;\n color: #fff;\n background: var(--clepit-primary, #5b5bff);\n border: 0;\n border-radius: 999px;\n cursor: pointer;\n}\n";
5
+ export declare const outputStyle = "\n.clepit-embed {\n border: 1px solid rgba(127, 127, 127, 0.35);\n border-radius: 8px;\n overflow: hidden;\n}\n.clepit-embed__frame {\n display: block;\n width: 100%;\n border: 0;\n}\n.clepit-embed-card {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n padding: 12px;\n border: 1px solid rgba(127, 127, 127, 0.35);\n border-radius: 8px;\n color: inherit;\n text-decoration: none;\n}\n.clepit-embed-card:hover {\n background: rgba(127, 127, 127, 0.08);\n}\n.clepit-embed-card__title {\n font-weight: 600;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.clepit-embed-card__description {\n opacity: 0.7;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n}\n.clepit-embed-card--with-reason {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 12px;\n border: 1px solid rgba(127, 127, 127, 0.35);\n border-radius: 8px;\n}\n.clepit-embed-card--with-reason > .clepit-embed-card {\n padding: 0;\n border: 0;\n}\n.clepit-embed-card__reason {\n display: flex;\n flex-wrap: wrap;\n gap: 6px 14px;\n align-items: center;\n font-size: 0.9em;\n opacity: 0.85;\n}\n.clepit-embed-card__action {\n padding: 0;\n font: inherit;\n color: inherit;\n text-decoration: underline;\n background: none;\n border: 0;\n cursor: pointer;\n}\n.clepit-embed--gist-frame .clepit-embed__frame {\n height: 552px;\n}\n.clepit-embed-gist {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n.clepit-embed-gist__file {\n display: flex;\n gap: 10px;\n align-items: baseline;\n font-size: 0.9em;\n}\n.clepit-embed-gist__file b {\n font-weight: 600;\n}\n.clepit-embed-gist__file a {\n margin-left: auto;\n color: inherit;\n opacity: 0.7;\n}\n.clepit-embed-offer {\n position: absolute;\n z-index: 20;\n display: inline-flex;\n gap: 6px;\n align-items: center;\n padding: 4px 4px 4px 10px;\n font-size: 12px;\n background: var(--clepit-surface, #fff);\n border: 1px solid rgba(127, 127, 127, 0.35);\n border-radius: 999px;\n box-shadow: 0 8px 24px rgba(0, 0, 0, 0.16);\n}\n.clepit-embed-offer button {\n padding: 3px 9px;\n font: inherit;\n font-weight: 600;\n color: #fff;\n background: var(--clepit-primary, #5b5bff);\n border: 0;\n border-radius: 999px;\n cursor: pointer;\n}\n";
6
6
  //# sourceMappingURL=css.d.ts.map
@@ -1,4 +1,4 @@
1
- import { EmbedData, InputConfig } from '../../../types';
1
+ import { EmbedData, InputConfig, IssueSnapshot } from '../../../types';
2
2
  export declare class EmbedInput {
3
3
  static placeholder: string;
4
4
  private static eventListenersMap;
@@ -6,6 +6,15 @@ export declare class EmbedInput {
6
6
  static render(containerId: string, data?: EmbedData, config?: InputConfig<'embed'>): HTMLElement;
7
7
  static isEmpty(blockElement: HTMLElement): boolean;
8
8
  static isEmptyData(data: EmbedData): boolean;
9
+ /** The block menu's four embed operations (Task B4 of the embed plan). */
10
+ static handleOperation(operation: string, block: HTMLElement, containerId: string): void;
11
+ /** A refresh redraws an issue card from a fresh snapshot without writing the
12
+ * document: the snapshot is remembered for the next save, and the card is
13
+ * redrawn in place. */
14
+ static refreshIssue(block: HTMLElement, containerId: string, snapshot: IssueSnapshot): void;
9
15
  static destroy(containerId: string): void;
16
+ /** The fix beside a reason. `retry` the core runs itself; `connectGoogle` goes
17
+ * to the host, which owns the routes. */
18
+ private static listenForActions;
10
19
  }
11
20
  //# sourceMappingURL=input.d.ts.map
@@ -0,0 +1,17 @@
1
+ import { Backing, ClepitElement } from '../../../core/element';
2
+ import { IssueLabel, IssueSnapshot } from '../../../types';
3
+ type Labels = Partial<Record<IssueLabel, string>> | undefined;
4
+ /**
5
+ * An issue as a card: the embed block's drawing when its snapshot is an issue.
6
+ * Key and title on the first line with the status pill, the holder and when it
7
+ * changed on the second. A card that could not be read says why, and in the
8
+ * editor offers the connect; a page drawn with no browser names the fix and
9
+ * offers nothing, since no handler exists there.
10
+ */
11
+ export declare class IssueCard {
12
+ static render(issue: IssueSnapshot, labels: Labels): HTMLElement;
13
+ static draw(issue: IssueSnapshot, backing: Backing, labels: Labels, withAction: boolean): ClepitElement;
14
+ private static drawReason;
15
+ }
16
+ export {};
17
+ //# sourceMappingURL=issue-card.d.ts.map
@@ -0,0 +1,9 @@
1
+ import { EmbedResolution } from '../../../types';
2
+ /** The `offer` paste preference: the link pastes as text, and a small chip
3
+ * under the caret offers to show it live for one keystroke. Enter or the chip
4
+ * converts; any other key, a click elsewhere or a moved selection dismisses. */
5
+ export declare const EmbedOffer: {
6
+ dismiss(containerId: string): void;
7
+ show(containerId: string, blockElement: HTMLElement, url: string, resolution: EmbedResolution): void;
8
+ };
9
+ //# sourceMappingURL=offer.d.ts.map
@@ -1,5 +1,14 @@
1
1
  import { Backing, ClepitElement, DrawContext } from '../../../core/element';
2
- import { BlockClassNames, BlockStyles, EmbedData, OutputConfig } from '../../../types';
2
+ import { BlockClassNames, BlockStyles, CodeLanguage, EmbedData, EmbedLabel, EmbedProvider, OutputConfig } from '../../../types';
3
+ /** The English this package ships for the embed block. A host replaces any of
4
+ * these through `embedLabels`. */
5
+ export declare const EMBED_ENGLISH: Record<EmbedLabel, string>;
6
+ /** Proper nouns stay themselves in every locale. */
7
+ export declare const EMBED_TOOL_NAMES: Partial<Record<EmbedProvider, string>>;
8
+ export declare function embedLabel(labels: Partial<Record<EmbedLabel, string>> | undefined, key: EmbedLabel, replacements?: Record<string, string>): string;
9
+ /** GitHub's language name as the code block's language, or undefined for one
10
+ * the code block does not know, which then renders as plain text. */
11
+ export declare function toCodeLanguage(name: string | null): CodeLanguage | undefined;
3
12
  export declare class EmbedOutput {
4
13
  static render(data: EmbedData, config?: OutputConfig & {
5
14
  mapsEmbedKey?: string;
@@ -11,11 +20,16 @@ export declare class EmbedOutput {
11
20
  * A string builder has no live element to hold a property, so `draw` sets the
12
21
  * attributes they reflect, and the parity tests prove the two serialise the
13
22
  * same. The aspect ratio moves from `style.aspectRatio` to the `style`
14
- * attribute for the same reason.
23
+ * attribute for the same reason. A gist never loads GitHub's script here:
24
+ * without a browser the snapshot is drawn as code, one block per file.
15
25
  */
16
26
  static draw(data: EmbedData, backing?: Backing, context?: DrawContext): ClepitElement | null;
27
+ private static drawGist;
17
28
  private static drawFrame;
29
+ /** `standalone` marks the block root; a card inside the reason wrapper is not
30
+ * the root, and the wrapper carries the mark instead. */
18
31
  private static drawCard;
32
+ private static gistFrame;
19
33
  private static frame;
20
34
  private static card;
21
35
  private static validate;
@@ -0,0 +1,16 @@
1
+ import { Block, EditorConfig, EmbedResolution, PasteEmbeds } from '../../../types';
2
+ /** The resolution of a pasted link that a provider renders, or null for text
3
+ * that is not a URL, a plain link, and anything the image and video paths own.
4
+ * A switched-off provider still resolves, so the card can say why. */
5
+ export declare function pasteEmbedTarget(text: string, disabled?: readonly string[]): EmbedResolution | null;
6
+ export declare function embedBlockFor(url: string, mode: PasteEmbeds): Block<'embed'>;
7
+ /** Puts the embed where the paste landed: in place of an empty block, or after
8
+ * a full one, the image precedent. Then asks the host's lookup to fill the
9
+ * snapshot, if the host wired one. Answers the new block's id. */
10
+ export declare function placeEmbed(containerId: string, blockIndex: number, replace: boolean, url: string): Promise<string | null>;
11
+ /** The snapshot arrives after the block does. The url is the identity and never
12
+ * changes hands: a lookup answering a different url is ignored on that field. A
13
+ * lookup that throws leaves the card saying the tool did not answer, with Try
14
+ * again beside it. */
15
+ export declare function fillEmbed(containerId: string, blockId: string, resolveLink: EditorConfig['resolveLink']): Promise<void>;
16
+ //# sourceMappingURL=paste.d.ts.map
@@ -1,5 +1,10 @@
1
- import { EmbedResolution, EmbedResolveOptions } from '../../../types';
1
+ import { EmbedProvider, EmbedResolution, EmbedResolveOptions } from '../../../types';
2
+ /** The server's wire names for the providers a workspace can switch off. YouTube,
3
+ * Airtable, draw.io and Maps have no switch: they are not in the catalogue. */
4
+ export declare const EMBED_WIRE_KEYS: Partial<Record<EmbedProvider, string>>;
5
+ export declare function isEmbedProviderDisabled(provider: EmbedProvider, disabled?: readonly string[]): boolean;
2
6
  /** Resolves a URL to what it should render as. Pure — no network, no state, so
3
- * the editor, the public renderer, exports and the Flutter app all agree. */
7
+ * the editor, the public renderer, exports and the Flutter app all agree. A
8
+ * provider the workspace switched off resolves to a card that says so. */
4
9
  export declare function resolveEmbed(raw: string, options?: EmbedResolveOptions): EmbedResolution;
5
10
  //# sourceMappingURL=providers.d.ts.map
@@ -1,5 +1,5 @@
1
1
  export declare const inputStylesKey = "clepit-header-input-styles";
2
2
  export declare const inputStyle = "\n/* Header block styles */\n.clepit-header {\n outline: none;\n margin: 0;\n margin-block-start: 0;\n margin-block-end: 0;\n margin-inline-start: 0;\n margin-inline-end: 0;\n padding: 0 20px;\n}\n\n.clepit-block[data-tool=\"header\"] .clepit-block-content {\n font-weight: bold;\n margin: 16px 0 8px 0;\n}\n\n.clepit-block[data-tool=\"header\"] .clepit-block-content h1 {\n font-size: 32px;\n margin: 0;\n color: inherit;\n}\n\n.clepit-block[data-tool=\"header\"] .clepit-block-content h2 {\n font-size: 24px;\n margin: 0;\n color: inherit;\n}\n\n.clepit-block[data-tool=\"header\"] .clepit-block-content h3 {\n font-size: 20px;\n margin: 0;\n color: inherit;\n}\n\n.clepit-block[data-tool=\"header\"] .clepit-block-content h4 {\n font-size: 18px;\n margin: 0;\n color: inherit;\n}\n\n.clepit-block[data-tool=\"header\"] .clepit-block-content h5 {\n font-size: 16px;\n margin: 0;\n color: inherit;\n}\n\n.clepit-block[data-tool=\"header\"] .clepit-block-content h6 {\n font-size: 14px;\n margin: 0;\n color: inherit;\n}\n\n/* Header placeholder styles */\n.clepit-header[data-placeholder]:empty::before {\n content: attr(data-placeholder);\n color: var(--clepit-text-subtle);\n pointer-events: none;\n font-style: italic;\n}\n\n/* Header link styles */\n.clepit-header a {\n color: var(--clepit-primary);\n text-decoration: none;\n cursor: pointer;\n transition: color 0.2s ease;\n}\n\n.clepit-header a:hover {\n color: var(--clepit-primary-hover);\n text-decoration: none;\n}\n\n/* Header inline code styling */\n.clepit-header code {\n background: var(--clepit-error-bg);\n color: var(--clepit-error);\n padding: 0 4px;\n border-radius: 4px;\n}\n\n/* Header marker brush effect */\n.clepit-header mark {\n background: none;\n position: relative;\n color: inherit;\n display: inline-block;\n z-index: 0; /* create stacking context so ::before sits behind text, not page */\n white-space: pre-wrap; /* ensure leading/trailing spaces inside mark render */\n}\n\n.clepit-header mark::before {\n content: '';\n position: absolute;\n left: 0;\n right: 0;\n top: 0.15em;\n height: 1.25em;\n transform: rotate(-0.4deg);\n background: url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 20' preserveAspectRatio='none'><path d='M0,8 C5,2 15,1 25,3 35,5 45,2 55,4 65,6 75,5 85,7 95,9 100,8 100,8 100,14 95,18 85,17 75,16 65,19 55,17 45,15 35,18 25,16 15,14 5,15 0,12 Z' fill='%23FFE047'/></svg>\") no-repeat center / 100% 100%;\n z-index: -1; /* behind text but within mark's stacking context */\n}\n\n";
3
3
  export declare const outputStylesKey = "clepit-header-output-styles";
4
- export declare const outputStyle = "\n/* Output header styles */\n.clepit-output-header {\n margin: 0 0 1rem 0;\n font-weight: 600;\n color: var(--clepit-text);\n}\n\n.clepit-output-header[data-level=\"1\"] {\n font-size: 2.5rem;\n line-height: 1.2;\n}\n\n.clepit-output-header[data-level=\"2\"] {\n font-size: 2rem;\n line-height: 1.3;\n}\n\n.clepit-output-header[data-level=\"3\"] {\n font-size: 1.75rem;\n line-height: 1.4;\n}\n\n.clepit-output-header[data-level=\"4\"] {\n font-size: 1.5rem;\n line-height: 1.4;\n}\n\n.clepit-output-header[data-level=\"5\"] {\n font-size: 1.25rem;\n line-height: 1.4;\n}\n\n.clepit-output-header[data-level=\"6\"] {\n font-size: 1rem;\n line-height: 1.4;\n}\n\n/* Output header inline code styling */\n.clepit-output-header code {\n background: var(--clepit-error-bg);\n color: var(--clepit-error);\n padding: 0 4px;\n border-radius: 4px;\n}\n\n/* Output header marker brush effect */\n.clepit-output-header mark {\n background: none;\n position: relative;\n color: inherit;\n display: inline-block;\n z-index: 0;\n white-space: pre-wrap;\n}\n\n.clepit-output-header mark::before {\n content: '';\n position: absolute;\n left: 0;\n right: 0;\n top: 0.15em;\n height: 1.25em;\n transform: rotate(-0.4deg);\n background: url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 20' preserveAspectRatio='none'><path d='M0,8 C5,2 15,1 25,3 35,5 45,2 55,4 65,6 75,5 85,7 95,9 100,8 100,8 100,14 95,18 85,17 75,16 65,19 55,17 45,15 35,18 25,16 15,14 5,15 0,12 Z' fill='%23FFE047'/></svg>\") no-repeat center / 100% 100%;\n z-index: -1;\n}\n\n/* Output header link styles */\n.clepit-output-header a {\n color: var(--clepit-primary);\n text-decoration: none;\n cursor: pointer;\n transition: color 0.2s ease;\n}\n\n.clepit-output-header a:hover {\n color: var(--clepit-primary-hover);\n text-decoration: none;\n}\n\n/* Responsive Design */\n@media (max-width: 768px) {\n .clepit-output-header[data-level=\"1\"] {\n font-size: 2rem;\n }\n\n .clepit-output-header[data-level=\"2\"] {\n font-size: 1.75rem;\n }\n\n .clepit-output-header[data-level=\"3\"] {\n font-size: 1.5rem;\n }\n}\n";
4
+ export declare const outputStyle = "\n/* Output header styles */\n.clepit-output-header {\n margin: 0 0 1rem 0;\n font-weight: 600;\n color: var(--clepit-text);\n}\n\nh1.clepit-output-header {\n font-size: 2.5rem;\n line-height: 1.2;\n}\n\nh2.clepit-output-header {\n font-size: 2rem;\n line-height: 1.3;\n}\n\nh3.clepit-output-header {\n font-size: 1.75rem;\n line-height: 1.4;\n}\n\nh4.clepit-output-header {\n font-size: 1.5rem;\n line-height: 1.4;\n}\n\nh5.clepit-output-header {\n font-size: 1.25rem;\n line-height: 1.4;\n}\n\nh6.clepit-output-header {\n font-size: 1rem;\n line-height: 1.4;\n}\n\n/* Output header inline code styling */\n.clepit-output-header code {\n background: var(--clepit-error-bg);\n color: var(--clepit-error);\n padding: 0 4px;\n border-radius: 4px;\n}\n\n/* Output header marker brush effect */\n.clepit-output-header mark {\n background: none;\n position: relative;\n color: inherit;\n display: inline-block;\n z-index: 0;\n white-space: pre-wrap;\n}\n\n.clepit-output-header mark::before {\n content: '';\n position: absolute;\n left: 0;\n right: 0;\n top: 0.15em;\n height: 1.25em;\n transform: rotate(-0.4deg);\n background: url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 20' preserveAspectRatio='none'><path d='M0,8 C5,2 15,1 25,3 35,5 45,2 55,4 65,6 75,5 85,7 95,9 100,8 100,8 100,14 95,18 85,17 75,16 65,19 55,17 45,15 35,18 25,16 15,14 5,15 0,12 Z' fill='%23FFE047'/></svg>\") no-repeat center / 100% 100%;\n z-index: -1;\n}\n\n/* Output header link styles */\n.clepit-output-header a {\n color: var(--clepit-primary);\n text-decoration: none;\n cursor: pointer;\n transition: color 0.2s ease;\n}\n\n.clepit-output-header a:hover {\n color: var(--clepit-primary-hover);\n text-decoration: none;\n}\n\n/* Responsive Design */\n@media (max-width: 768px) {\n h1.clepit-output-header {\n font-size: 2rem;\n }\n\n h2.clepit-output-header {\n font-size: 1.75rem;\n }\n\n h3.clepit-output-header {\n font-size: 1.5rem;\n }\n}\n";
5
5
  //# sourceMappingURL=css.d.ts.map
@@ -0,0 +1,7 @@
1
+ export declare const inputStylesKey = "issues-input";
2
+ export declare const outputStylesKey = "issues-output";
3
+ /** The table shares the chip's stylesheet: its status pill is the chip's, and
4
+ * the page stylesheet carries the block's rules through the chip's sheet. */
5
+ export declare const inputStyle = "\n.clepit-issue {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n max-width: 100%;\n padding: 1px 8px 1px 6px;\n vertical-align: baseline;\n font-size: 0.92em;\n line-height: 1.5;\n color: inherit;\n text-decoration: none;\n white-space: nowrap;\n background: rgba(127, 127, 127, 0.1);\n border: 1px solid rgba(127, 127, 127, 0.25);\n border-radius: 999px;\n cursor: pointer;\n}\n.clepit-issue:hover {\n background: rgba(127, 127, 127, 0.16);\n}\n.clepit-issue__key {\n font-weight: 600;\n font-variant-numeric: tabular-nums;\n}\n.clepit-issue__title {\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 28ch;\n}\n.clepit-issue__state {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 0 7px;\n font-size: 12px;\n line-height: 18px;\n border-radius: 999px;\n background: rgba(127, 127, 127, 0.16);\n}\n.clepit-issue__state::before {\n content: '';\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: currentColor;\n}\n.clepit-issue__state[data-issue-category=\"todo\"] {\n color: var(--clepit-text-muted, #6b7280);\n}\n.clepit-issue__state[data-issue-category=\"started\"] {\n color: var(--clepit-primary, #5b5bff);\n background: var(--clepit-primary-bg, rgba(91, 91, 255, 0.16));\n}\n.clepit-issue__state[data-issue-category=\"done\"] {\n color: var(--clepit-success, #15803d);\n background: var(--clepit-success-bg, rgba(21, 128, 61, 0.16));\n}\n.clepit-issue__state[data-issue-category=\"cancelled\"] {\n color: var(--clepit-text-muted, #6b7280);\n text-decoration: line-through;\n}\n.clepit-issue__assignee {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 18px;\n height: 18px;\n font-size: 10px;\n font-weight: 600;\n letter-spacing: 0.02em;\n color: #fff;\n background: var(--clepit-primary, #5b5bff);\n border-radius: 50%;\n}\n.clepit-issue__reason {\n color: var(--clepit-text-muted, #6b7280);\n}\n.clepit-issue--reason {\n border-style: dashed;\n}\n[data-issue-chip-status=\"off\"] .clepit-issue__state,\n[data-issue-chip-assignee=\"off\"] .clepit-issue__assignee {\n display: none;\n}\n.clepit-issue-menu {\n position: absolute;\n z-index: 20;\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 180px;\n padding: 4px;\n font-size: 13px;\n background: var(--clepit-surface, #fff);\n border: 1px solid rgba(127, 127, 127, 0.35);\n border-radius: 8px;\n box-shadow: 0 8px 24px rgba(0, 0, 0, 0.16);\n}\n.clepit-issue-menu a,\n.clepit-issue-menu button {\n display: block;\n width: 100%;\n padding: 6px 10px;\n font: inherit;\n color: inherit;\n text-align: left;\n text-decoration: none;\n background: none;\n border: 0;\n border-radius: 6px;\n cursor: pointer;\n}\n.clepit-issue-menu a:hover,\n.clepit-issue-menu button:hover {\n background: rgba(127, 127, 127, 0.1);\n}\n.clepit-issue-menu__reason {\n padding: 6px 10px 2px;\n font-size: 12px;\n color: var(--clepit-text-muted, #6b7280);\n}\n.clepit-issue-card {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 12px;\n color: inherit;\n text-decoration: none;\n border: 1px solid rgba(127, 127, 127, 0.35);\n border-radius: 8px;\n}\n.clepit-issue-card:hover {\n background: rgba(127, 127, 127, 0.08);\n}\n.clepit-issue-card__head {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 8px;\n}\n.clepit-issue-card__key {\n font-weight: 600;\n font-variant-numeric: tabular-nums;\n}\n.clepit-issue-card__title {\n font-weight: 600;\n}\n.clepit-issue-card__meta {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 6px 12px;\n font-size: 0.9em;\n opacity: 0.85;\n}\n.clepit-issue-card__assignee {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n}\n.clepit-issue-card__reason {\n display: flex;\n flex-wrap: wrap;\n gap: 6px 14px;\n align-items: center;\n font-size: 0.9em;\n opacity: 0.85;\n}\n.clepit-issue-card__action {\n padding: 0;\n font: inherit;\n color: inherit;\n text-decoration: underline;\n background: none;\n border: 0;\n cursor: pointer;\n}\n.clepit-issues {\n width: 100%;\n border-collapse: collapse;\n font-size: 0.95em;\n}\n.clepit-issues th,\n.clepit-issues td {\n padding: 6px 10px;\n text-align: left;\n border-bottom: 1px solid rgba(127, 127, 127, 0.25);\n}\n.clepit-issues th {\n font-size: 12px;\n font-weight: 600;\n letter-spacing: 0.02em;\n text-transform: uppercase;\n opacity: 0.7;\n}\n.clepit-issues a {\n color: inherit;\n font-weight: 600;\n text-decoration: none;\n}\n.clepit-issues a:hover {\n text-decoration: underline;\n}\n.clepit-issues__empty {\n opacity: 0.55;\n}\n";
6
+ export declare const outputStyle = "\n.clepit-issue {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n max-width: 100%;\n padding: 1px 8px 1px 6px;\n vertical-align: baseline;\n font-size: 0.92em;\n line-height: 1.5;\n color: inherit;\n text-decoration: none;\n white-space: nowrap;\n background: rgba(127, 127, 127, 0.1);\n border: 1px solid rgba(127, 127, 127, 0.25);\n border-radius: 999px;\n cursor: pointer;\n}\n.clepit-issue:hover {\n background: rgba(127, 127, 127, 0.16);\n}\n.clepit-issue__key {\n font-weight: 600;\n font-variant-numeric: tabular-nums;\n}\n.clepit-issue__title {\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 28ch;\n}\n.clepit-issue__state {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 0 7px;\n font-size: 12px;\n line-height: 18px;\n border-radius: 999px;\n background: rgba(127, 127, 127, 0.16);\n}\n.clepit-issue__state::before {\n content: '';\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: currentColor;\n}\n.clepit-issue__state[data-issue-category=\"todo\"] {\n color: var(--clepit-text-muted, #6b7280);\n}\n.clepit-issue__state[data-issue-category=\"started\"] {\n color: var(--clepit-primary, #5b5bff);\n background: var(--clepit-primary-bg, rgba(91, 91, 255, 0.16));\n}\n.clepit-issue__state[data-issue-category=\"done\"] {\n color: var(--clepit-success, #15803d);\n background: var(--clepit-success-bg, rgba(21, 128, 61, 0.16));\n}\n.clepit-issue__state[data-issue-category=\"cancelled\"] {\n color: var(--clepit-text-muted, #6b7280);\n text-decoration: line-through;\n}\n.clepit-issue__assignee {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 18px;\n height: 18px;\n font-size: 10px;\n font-weight: 600;\n letter-spacing: 0.02em;\n color: #fff;\n background: var(--clepit-primary, #5b5bff);\n border-radius: 50%;\n}\n.clepit-issue__reason {\n color: var(--clepit-text-muted, #6b7280);\n}\n.clepit-issue--reason {\n border-style: dashed;\n}\n[data-issue-chip-status=\"off\"] .clepit-issue__state,\n[data-issue-chip-assignee=\"off\"] .clepit-issue__assignee {\n display: none;\n}\n.clepit-issue-menu {\n position: absolute;\n z-index: 20;\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 180px;\n padding: 4px;\n font-size: 13px;\n background: var(--clepit-surface, #fff);\n border: 1px solid rgba(127, 127, 127, 0.35);\n border-radius: 8px;\n box-shadow: 0 8px 24px rgba(0, 0, 0, 0.16);\n}\n.clepit-issue-menu a,\n.clepit-issue-menu button {\n display: block;\n width: 100%;\n padding: 6px 10px;\n font: inherit;\n color: inherit;\n text-align: left;\n text-decoration: none;\n background: none;\n border: 0;\n border-radius: 6px;\n cursor: pointer;\n}\n.clepit-issue-menu a:hover,\n.clepit-issue-menu button:hover {\n background: rgba(127, 127, 127, 0.1);\n}\n.clepit-issue-menu__reason {\n padding: 6px 10px 2px;\n font-size: 12px;\n color: var(--clepit-text-muted, #6b7280);\n}\n.clepit-issue-card {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 12px;\n color: inherit;\n text-decoration: none;\n border: 1px solid rgba(127, 127, 127, 0.35);\n border-radius: 8px;\n}\n.clepit-issue-card:hover {\n background: rgba(127, 127, 127, 0.08);\n}\n.clepit-issue-card__head {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 8px;\n}\n.clepit-issue-card__key {\n font-weight: 600;\n font-variant-numeric: tabular-nums;\n}\n.clepit-issue-card__title {\n font-weight: 600;\n}\n.clepit-issue-card__meta {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 6px 12px;\n font-size: 0.9em;\n opacity: 0.85;\n}\n.clepit-issue-card__assignee {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n}\n.clepit-issue-card__reason {\n display: flex;\n flex-wrap: wrap;\n gap: 6px 14px;\n align-items: center;\n font-size: 0.9em;\n opacity: 0.85;\n}\n.clepit-issue-card__action {\n padding: 0;\n font: inherit;\n color: inherit;\n text-decoration: underline;\n background: none;\n border: 0;\n cursor: pointer;\n}\n.clepit-issues {\n width: 100%;\n border-collapse: collapse;\n font-size: 0.95em;\n}\n.clepit-issues th,\n.clepit-issues td {\n padding: 6px 10px;\n text-align: left;\n border-bottom: 1px solid rgba(127, 127, 127, 0.25);\n}\n.clepit-issues th {\n font-size: 12px;\n font-weight: 600;\n letter-spacing: 0.02em;\n text-transform: uppercase;\n opacity: 0.7;\n}\n.clepit-issues a {\n color: inherit;\n font-weight: 600;\n text-decoration: none;\n}\n.clepit-issues a:hover {\n text-decoration: underline;\n}\n.clepit-issues__empty {\n opacity: 0.55;\n}\n";
7
+ //# sourceMappingURL=css.d.ts.map
@@ -0,0 +1,13 @@
1
+ import { IssuesInput } from './input';
2
+ import { IssuesOutput } from './output';
3
+ import { ToolType } from '../../../types';
4
+ export declare const IssuesTool: {
5
+ icon: string;
6
+ readonly input: typeof IssuesInput;
7
+ label: string;
8
+ readonly output: typeof IssuesOutput;
9
+ shortcut: string;
10
+ testId: string;
11
+ type: ToolType;
12
+ };
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,14 @@
1
+ import { InputConfig, IssueSnapshot, IssuesData } from '../../../types';
2
+ export declare class IssuesInput {
3
+ static placeholder: string;
4
+ private static eventListenersMap;
5
+ static save(_element: HTMLElement): IssuesData;
6
+ static render(containerId: string, _data?: IssuesData, config?: InputConfig<'issues'>): HTMLElement;
7
+ /** A refresh hands the table its fresh set and redraws every table in the
8
+ * editor without touching the document. */
9
+ static refresh(containerId: string, issues: Record<string, IssueSnapshot>): void;
10
+ static isEmpty(_blockElement: HTMLElement): boolean;
11
+ static isEmptyData(_data: IssuesData): boolean;
12
+ static destroy(containerId: string): void;
13
+ }
14
+ //# sourceMappingURL=input.d.ts.map
@@ -0,0 +1,24 @@
1
+ import { Backing, ClepitElement, DrawContext } from '../../../core/element';
2
+ import { Block, BlockClassNames, BlockStyles, IssueLabel, IssueSnapshot, IssuesData, OutputConfig } from '../../../types';
3
+ type Labels = Partial<Record<IssueLabel, string>> | undefined;
4
+ type IssuesContext = {
5
+ documentBlocks?: readonly Block[];
6
+ issues?: Record<string, IssueSnapshot>;
7
+ issueLabels?: Labels;
8
+ };
9
+ /**
10
+ * The Linked issues block: derived from the document like the table of
11
+ * contents. Every chip in any text a block stores and every issue card, once
12
+ * each by URL, in document order, each row carrying the freshest snapshot the
13
+ * renderer was handed and the stored one otherwise.
14
+ */
15
+ export declare class IssuesOutput {
16
+ static collect(documentBlocks: readonly Block[] | undefined, issues?: Record<string, IssueSnapshot>): IssueSnapshot[];
17
+ static render(_data: IssuesData, config?: OutputConfig & IssuesContext, styles?: BlockStyles['issues'], classNames?: BlockClassNames['issues']): HTMLElement;
18
+ /** Where `render` shows "no issues linked yet", this draws nothing: a
19
+ * published page has no author to reassure. */
20
+ static draw(data: IssuesData, backing?: Backing, context?: DrawContext): ClepitElement | null;
21
+ private static table;
22
+ }
23
+ export {};
24
+ //# sourceMappingURL=output.d.ts.map
@@ -0,0 +1,10 @@
1
+ export declare const stylesKey = "inline-issue";
2
+ /** The status tool's pill grown into a chip: one line, the key set, the title
3
+ * plain, the status a 6px dot and a 12px word on a 16% tint, the holder's
4
+ * initials in a 18px circle. A reason chip keeps the key and says why, muted.
5
+ * The two per-person switches hide a part from any ancestor that carries
6
+ * them, in the editor and on a rendered page alike. */
7
+ export declare const style = "\n.clepit-issue {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n max-width: 100%;\n padding: 1px 8px 1px 6px;\n vertical-align: baseline;\n font-size: 0.92em;\n line-height: 1.5;\n color: inherit;\n text-decoration: none;\n white-space: nowrap;\n background: rgba(127, 127, 127, 0.1);\n border: 1px solid rgba(127, 127, 127, 0.25);\n border-radius: 999px;\n cursor: pointer;\n}\n.clepit-issue:hover {\n background: rgba(127, 127, 127, 0.16);\n}\n.clepit-issue__key {\n font-weight: 600;\n font-variant-numeric: tabular-nums;\n}\n.clepit-issue__title {\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 28ch;\n}\n.clepit-issue__state {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 0 7px;\n font-size: 12px;\n line-height: 18px;\n border-radius: 999px;\n background: rgba(127, 127, 127, 0.16);\n}\n.clepit-issue__state::before {\n content: '';\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: currentColor;\n}\n.clepit-issue__state[data-issue-category=\"todo\"] {\n color: var(--clepit-text-muted, #6b7280);\n}\n.clepit-issue__state[data-issue-category=\"started\"] {\n color: var(--clepit-primary, #5b5bff);\n background: var(--clepit-primary-bg, rgba(91, 91, 255, 0.16));\n}\n.clepit-issue__state[data-issue-category=\"done\"] {\n color: var(--clepit-success, #15803d);\n background: var(--clepit-success-bg, rgba(21, 128, 61, 0.16));\n}\n.clepit-issue__state[data-issue-category=\"cancelled\"] {\n color: var(--clepit-text-muted, #6b7280);\n text-decoration: line-through;\n}\n.clepit-issue__assignee {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 18px;\n height: 18px;\n font-size: 10px;\n font-weight: 600;\n letter-spacing: 0.02em;\n color: #fff;\n background: var(--clepit-primary, #5b5bff);\n border-radius: 50%;\n}\n.clepit-issue__reason {\n color: var(--clepit-text-muted, #6b7280);\n}\n.clepit-issue--reason {\n border-style: dashed;\n}\n[data-issue-chip-status=\"off\"] .clepit-issue__state,\n[data-issue-chip-assignee=\"off\"] .clepit-issue__assignee {\n display: none;\n}\n.clepit-issue-menu {\n position: absolute;\n z-index: 20;\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 180px;\n padding: 4px;\n font-size: 13px;\n background: var(--clepit-surface, #fff);\n border: 1px solid rgba(127, 127, 127, 0.35);\n border-radius: 8px;\n box-shadow: 0 8px 24px rgba(0, 0, 0, 0.16);\n}\n.clepit-issue-menu a,\n.clepit-issue-menu button {\n display: block;\n width: 100%;\n padding: 6px 10px;\n font: inherit;\n color: inherit;\n text-align: left;\n text-decoration: none;\n background: none;\n border: 0;\n border-radius: 6px;\n cursor: pointer;\n}\n.clepit-issue-menu a:hover,\n.clepit-issue-menu button:hover {\n background: rgba(127, 127, 127, 0.1);\n}\n.clepit-issue-menu__reason {\n padding: 6px 10px 2px;\n font-size: 12px;\n color: var(--clepit-text-muted, #6b7280);\n}\n.clepit-issue-card {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 12px;\n color: inherit;\n text-decoration: none;\n border: 1px solid rgba(127, 127, 127, 0.35);\n border-radius: 8px;\n}\n.clepit-issue-card:hover {\n background: rgba(127, 127, 127, 0.08);\n}\n.clepit-issue-card__head {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 8px;\n}\n.clepit-issue-card__key {\n font-weight: 600;\n font-variant-numeric: tabular-nums;\n}\n.clepit-issue-card__title {\n font-weight: 600;\n}\n.clepit-issue-card__meta {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 6px 12px;\n font-size: 0.9em;\n opacity: 0.85;\n}\n.clepit-issue-card__assignee {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n}\n.clepit-issue-card__reason {\n display: flex;\n flex-wrap: wrap;\n gap: 6px 14px;\n align-items: center;\n font-size: 0.9em;\n opacity: 0.85;\n}\n.clepit-issue-card__action {\n padding: 0;\n font: inherit;\n color: inherit;\n text-decoration: underline;\n background: none;\n border: 0;\n cursor: pointer;\n}\n.clepit-issues {\n width: 100%;\n border-collapse: collapse;\n font-size: 0.95em;\n}\n.clepit-issues th,\n.clepit-issues td {\n padding: 6px 10px;\n text-align: left;\n border-bottom: 1px solid rgba(127, 127, 127, 0.25);\n}\n.clepit-issues th {\n font-size: 12px;\n font-weight: 600;\n letter-spacing: 0.02em;\n text-transform: uppercase;\n opacity: 0.7;\n}\n.clepit-issues a {\n color: inherit;\n font-weight: 600;\n text-decoration: none;\n}\n.clepit-issues a:hover {\n text-decoration: underline;\n}\n.clepit-issues__empty {\n opacity: 0.55;\n}\n";
8
+ export declare const inputStyle = "\n.clepit-issue {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n max-width: 100%;\n padding: 1px 8px 1px 6px;\n vertical-align: baseline;\n font-size: 0.92em;\n line-height: 1.5;\n color: inherit;\n text-decoration: none;\n white-space: nowrap;\n background: rgba(127, 127, 127, 0.1);\n border: 1px solid rgba(127, 127, 127, 0.25);\n border-radius: 999px;\n cursor: pointer;\n}\n.clepit-issue:hover {\n background: rgba(127, 127, 127, 0.16);\n}\n.clepit-issue__key {\n font-weight: 600;\n font-variant-numeric: tabular-nums;\n}\n.clepit-issue__title {\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 28ch;\n}\n.clepit-issue__state {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 0 7px;\n font-size: 12px;\n line-height: 18px;\n border-radius: 999px;\n background: rgba(127, 127, 127, 0.16);\n}\n.clepit-issue__state::before {\n content: '';\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: currentColor;\n}\n.clepit-issue__state[data-issue-category=\"todo\"] {\n color: var(--clepit-text-muted, #6b7280);\n}\n.clepit-issue__state[data-issue-category=\"started\"] {\n color: var(--clepit-primary, #5b5bff);\n background: var(--clepit-primary-bg, rgba(91, 91, 255, 0.16));\n}\n.clepit-issue__state[data-issue-category=\"done\"] {\n color: var(--clepit-success, #15803d);\n background: var(--clepit-success-bg, rgba(21, 128, 61, 0.16));\n}\n.clepit-issue__state[data-issue-category=\"cancelled\"] {\n color: var(--clepit-text-muted, #6b7280);\n text-decoration: line-through;\n}\n.clepit-issue__assignee {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 18px;\n height: 18px;\n font-size: 10px;\n font-weight: 600;\n letter-spacing: 0.02em;\n color: #fff;\n background: var(--clepit-primary, #5b5bff);\n border-radius: 50%;\n}\n.clepit-issue__reason {\n color: var(--clepit-text-muted, #6b7280);\n}\n.clepit-issue--reason {\n border-style: dashed;\n}\n[data-issue-chip-status=\"off\"] .clepit-issue__state,\n[data-issue-chip-assignee=\"off\"] .clepit-issue__assignee {\n display: none;\n}\n.clepit-issue-menu {\n position: absolute;\n z-index: 20;\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 180px;\n padding: 4px;\n font-size: 13px;\n background: var(--clepit-surface, #fff);\n border: 1px solid rgba(127, 127, 127, 0.35);\n border-radius: 8px;\n box-shadow: 0 8px 24px rgba(0, 0, 0, 0.16);\n}\n.clepit-issue-menu a,\n.clepit-issue-menu button {\n display: block;\n width: 100%;\n padding: 6px 10px;\n font: inherit;\n color: inherit;\n text-align: left;\n text-decoration: none;\n background: none;\n border: 0;\n border-radius: 6px;\n cursor: pointer;\n}\n.clepit-issue-menu a:hover,\n.clepit-issue-menu button:hover {\n background: rgba(127, 127, 127, 0.1);\n}\n.clepit-issue-menu__reason {\n padding: 6px 10px 2px;\n font-size: 12px;\n color: var(--clepit-text-muted, #6b7280);\n}\n.clepit-issue-card {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 12px;\n color: inherit;\n text-decoration: none;\n border: 1px solid rgba(127, 127, 127, 0.35);\n border-radius: 8px;\n}\n.clepit-issue-card:hover {\n background: rgba(127, 127, 127, 0.08);\n}\n.clepit-issue-card__head {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 8px;\n}\n.clepit-issue-card__key {\n font-weight: 600;\n font-variant-numeric: tabular-nums;\n}\n.clepit-issue-card__title {\n font-weight: 600;\n}\n.clepit-issue-card__meta {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 6px 12px;\n font-size: 0.9em;\n opacity: 0.85;\n}\n.clepit-issue-card__assignee {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n}\n.clepit-issue-card__reason {\n display: flex;\n flex-wrap: wrap;\n gap: 6px 14px;\n align-items: center;\n font-size: 0.9em;\n opacity: 0.85;\n}\n.clepit-issue-card__action {\n padding: 0;\n font: inherit;\n color: inherit;\n text-decoration: underline;\n background: none;\n border: 0;\n cursor: pointer;\n}\n.clepit-issues {\n width: 100%;\n border-collapse: collapse;\n font-size: 0.95em;\n}\n.clepit-issues th,\n.clepit-issues td {\n padding: 6px 10px;\n text-align: left;\n border-bottom: 1px solid rgba(127, 127, 127, 0.25);\n}\n.clepit-issues th {\n font-size: 12px;\n font-weight: 600;\n letter-spacing: 0.02em;\n text-transform: uppercase;\n opacity: 0.7;\n}\n.clepit-issues a {\n color: inherit;\n font-weight: 600;\n text-decoration: none;\n}\n.clepit-issues a:hover {\n text-decoration: underline;\n}\n.clepit-issues__empty {\n opacity: 0.55;\n}\n";
9
+ export declare const outputStyle = "\n.clepit-issue {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n max-width: 100%;\n padding: 1px 8px 1px 6px;\n vertical-align: baseline;\n font-size: 0.92em;\n line-height: 1.5;\n color: inherit;\n text-decoration: none;\n white-space: nowrap;\n background: rgba(127, 127, 127, 0.1);\n border: 1px solid rgba(127, 127, 127, 0.25);\n border-radius: 999px;\n cursor: pointer;\n}\n.clepit-issue:hover {\n background: rgba(127, 127, 127, 0.16);\n}\n.clepit-issue__key {\n font-weight: 600;\n font-variant-numeric: tabular-nums;\n}\n.clepit-issue__title {\n overflow: hidden;\n text-overflow: ellipsis;\n max-width: 28ch;\n}\n.clepit-issue__state {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 0 7px;\n font-size: 12px;\n line-height: 18px;\n border-radius: 999px;\n background: rgba(127, 127, 127, 0.16);\n}\n.clepit-issue__state::before {\n content: '';\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: currentColor;\n}\n.clepit-issue__state[data-issue-category=\"todo\"] {\n color: var(--clepit-text-muted, #6b7280);\n}\n.clepit-issue__state[data-issue-category=\"started\"] {\n color: var(--clepit-primary, #5b5bff);\n background: var(--clepit-primary-bg, rgba(91, 91, 255, 0.16));\n}\n.clepit-issue__state[data-issue-category=\"done\"] {\n color: var(--clepit-success, #15803d);\n background: var(--clepit-success-bg, rgba(21, 128, 61, 0.16));\n}\n.clepit-issue__state[data-issue-category=\"cancelled\"] {\n color: var(--clepit-text-muted, #6b7280);\n text-decoration: line-through;\n}\n.clepit-issue__assignee {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 18px;\n height: 18px;\n font-size: 10px;\n font-weight: 600;\n letter-spacing: 0.02em;\n color: #fff;\n background: var(--clepit-primary, #5b5bff);\n border-radius: 50%;\n}\n.clepit-issue__reason {\n color: var(--clepit-text-muted, #6b7280);\n}\n.clepit-issue--reason {\n border-style: dashed;\n}\n[data-issue-chip-status=\"off\"] .clepit-issue__state,\n[data-issue-chip-assignee=\"off\"] .clepit-issue__assignee {\n display: none;\n}\n.clepit-issue-menu {\n position: absolute;\n z-index: 20;\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 180px;\n padding: 4px;\n font-size: 13px;\n background: var(--clepit-surface, #fff);\n border: 1px solid rgba(127, 127, 127, 0.35);\n border-radius: 8px;\n box-shadow: 0 8px 24px rgba(0, 0, 0, 0.16);\n}\n.clepit-issue-menu a,\n.clepit-issue-menu button {\n display: block;\n width: 100%;\n padding: 6px 10px;\n font: inherit;\n color: inherit;\n text-align: left;\n text-decoration: none;\n background: none;\n border: 0;\n border-radius: 6px;\n cursor: pointer;\n}\n.clepit-issue-menu a:hover,\n.clepit-issue-menu button:hover {\n background: rgba(127, 127, 127, 0.1);\n}\n.clepit-issue-menu__reason {\n padding: 6px 10px 2px;\n font-size: 12px;\n color: var(--clepit-text-muted, #6b7280);\n}\n.clepit-issue-card {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 12px;\n color: inherit;\n text-decoration: none;\n border: 1px solid rgba(127, 127, 127, 0.35);\n border-radius: 8px;\n}\n.clepit-issue-card:hover {\n background: rgba(127, 127, 127, 0.08);\n}\n.clepit-issue-card__head {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 8px;\n}\n.clepit-issue-card__key {\n font-weight: 600;\n font-variant-numeric: tabular-nums;\n}\n.clepit-issue-card__title {\n font-weight: 600;\n}\n.clepit-issue-card__meta {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 6px 12px;\n font-size: 0.9em;\n opacity: 0.85;\n}\n.clepit-issue-card__assignee {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n}\n.clepit-issue-card__reason {\n display: flex;\n flex-wrap: wrap;\n gap: 6px 14px;\n align-items: center;\n font-size: 0.9em;\n opacity: 0.85;\n}\n.clepit-issue-card__action {\n padding: 0;\n font: inherit;\n color: inherit;\n text-decoration: underline;\n background: none;\n border: 0;\n cursor: pointer;\n}\n.clepit-issues {\n width: 100%;\n border-collapse: collapse;\n font-size: 0.95em;\n}\n.clepit-issues th,\n.clepit-issues td {\n padding: 6px 10px;\n text-align: left;\n border-bottom: 1px solid rgba(127, 127, 127, 0.25);\n}\n.clepit-issues th {\n font-size: 12px;\n font-weight: 600;\n letter-spacing: 0.02em;\n text-transform: uppercase;\n opacity: 0.7;\n}\n.clepit-issues a {\n color: inherit;\n font-weight: 600;\n text-decoration: none;\n}\n.clepit-issues a:hover {\n text-decoration: underline;\n}\n.clepit-issues__empty {\n opacity: 0.55;\n}\n";
10
+ //# sourceMappingURL=css.d.ts.map
@@ -0,0 +1,58 @@
1
+ import { Backing, ClepitElement } from '../../../core/element';
2
+ import { IssueChipParts, IssueLabel, IssueSnapshot } from '../../../types';
3
+ export declare const ISSUE_CHIP_CLASS = "clepit-issue";
4
+ type Labels = Partial<Record<IssueLabel, string>> | undefined;
5
+ /** The first letters of the first two words: `Amina Diallo` is `AD`. */
6
+ export declare const initials: (name: string) => string;
7
+ /** The date a timestamp falls on, which is what the card says under "updated". */
8
+ export declare const dayOf: (iso: string) => string;
9
+ /** The sentence a chip or a card explains itself with when it has no snapshot. */
10
+ export declare const reasonText: (snapshot: Pick<IssueSnapshot, "reason" | "tool">, labels: Labels) => string | null;
11
+ /** The word for a status: the tool's own when it gave one, the category
12
+ * otherwise (Asana has only a done flag). */
13
+ export declare const stateText: (snapshot: Pick<IssueSnapshot, "category" | "stateName">, labels: Labels) => string;
14
+ /** A snapshot with every optional part absent: what a chip is before its lookup answers. */
15
+ export declare const bareIssue: (url: string, tool: string, key?: string) => IssueSnapshot;
16
+ /**
17
+ * The inline chip. One drawing for both backings; the DOM path wraps it.
18
+ *
19
+ * Everything the chip knows rides on `data-issue-*` attributes so the stored
20
+ * HTML carries the last known state (a page opened offline still shows it) and
21
+ * a refresh can rewrite the chip in place. The parts a member switched off are
22
+ * hidden by CSS from an ancestor's `data-issue-chip-*` attribute rather than
23
+ * omitted, so the stored document is the same for every reader.
24
+ */
25
+ export declare class IssueChip {
26
+ static build(snapshot: IssueSnapshot, labels: Labels, backing?: Backing): ClepitElement;
27
+ /** The chip as markup, for a document drawn with no browser. */
28
+ static markup(snapshot: IssueSnapshot, labels: Labels, sanitize: (html: string) => string): string;
29
+ static create(snapshot: IssueSnapshot, labels: Labels): HTMLAnchorElement;
30
+ /** Rewrites a chip in place from a fresh snapshot: attributes and children,
31
+ * the node itself kept so the caret and the paragraph around it are untouched. */
32
+ static refresh(anchor: Element, snapshot: IssueSnapshot, labels: Labels): void;
33
+ /** What a chip knows, read back off its attributes. */
34
+ static read(anchor: Element): IssueSnapshot;
35
+ static collect(root: ParentNode): HTMLAnchorElement[];
36
+ /** Every chip under `root` rewritten from the snapshots the host resolved,
37
+ * keyed by URL; a chip with no answer keeps what it stored. */
38
+ static refreshAll(root: ParentNode, issues: Record<string, IssueSnapshot>, labels: Labels): void;
39
+ /** Stamps the two per-person switches on a root so its chips hide the parts
40
+ * the member asked to hide. */
41
+ static applyParts(root: Element, parts: IssueChipParts | undefined): void;
42
+ /** Inserts a chip at the caret, the mention precedent, with a space after it
43
+ * so typing continues outside the chip. Null with no selection to insert into. */
44
+ static insertAtCaret(snapshot: IssueSnapshot, labels: Labels): HTMLAnchorElement | null;
45
+ private static attributes;
46
+ }
47
+ /** A chip's snapshot read off its markup, the string twin of `IssueChip.read`. */
48
+ export declare const readChipMarkup: (chip: string) => IssueSnapshot;
49
+ /** Every chip in a stored HTML string, as stored. */
50
+ export declare const chipsInHtml: (html: string) => IssueSnapshot[];
51
+ /**
52
+ * Every chip in a rendered HTML string redrawn from the snapshots the host
53
+ * resolved, with the parts a reader switched off omitted: the string path has
54
+ * no ancestor to hang the CSS switches on, so it draws what the DOM path hides.
55
+ */
56
+ export declare const refreshChipsInHtml: (html: string, issues: Record<string, IssueSnapshot> | undefined, parts: IssueChipParts | undefined, labels: Labels, sanitize: (html: string) => string) => string;
57
+ export {};
58
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,11 @@
1
+ import { IssueCategory, IssueLabel, IssueTool } from '../../../types';
2
+ /** The English this package ships for issue chips, cards and the Linked
3
+ * issues table. A host replaces any of these through `issueLabels`. */
4
+ export declare const ISSUE_ENGLISH: Record<IssueLabel, string>;
5
+ /** Proper nouns stay themselves in every locale. The group word ("GitHub
6
+ * issues") belongs to the catalogue; a sentence names the tool alone. */
7
+ export declare const ISSUE_TOOL_NAMES: Record<IssueTool, string>;
8
+ export declare const CATEGORY_LABEL: Record<IssueCategory, IssueLabel>;
9
+ export declare function issueLabel(labels: Partial<Record<IssueLabel, string>> | undefined, key: IssueLabel, replacements?: Record<string, string>): string;
10
+ export declare const issueToolName: (tool: string) => string;
11
+ //# sourceMappingURL=labels.d.ts.map
@@ -0,0 +1,14 @@
1
+ /**
2
+ * What a click on a chip offers while editing: open the issue in its tool, or
3
+ * show it as a card; a chip that could not be read says why and offers the
4
+ * connect. Outside the editor a chip is a plain link and no menu exists.
5
+ */
6
+ export declare const IssueChipMenu: {
7
+ dismiss(containerId: string): void;
8
+ show(containerId: string, anchor: HTMLAnchorElement): void;
9
+ /** The chip leaves the sentence and an issue card takes the next slot: a
10
+ * card is a block, so it cannot sit where a chip sat. A sentence left empty
11
+ * gives its slot to the card instead. */
12
+ showAsCard(containerId: string, anchor: HTMLAnchorElement): void;
13
+ };
14
+ //# sourceMappingURL=menu.d.ts.map
@@ -0,0 +1,22 @@
1
+ import { IssueSnapshot, IssueTarget } from '../../../types';
2
+ /** The tracker a pasted link belongs to, or null for any other text. */
3
+ export declare function pasteIssueTarget(text: string, jiraSites?: readonly string[]): IssueTarget | null;
4
+ /**
5
+ * The host's lookup for a set of links, never throwing: a lookup that fails
6
+ * answers every link with "did not answer" so the chips say so instead of
7
+ * staying blank. Without a host lookup, nothing is known and nothing changes.
8
+ */
9
+ export declare function lookupIssues(containerId: string, urls: readonly string[]): Promise<Record<string, IssueSnapshot>>;
10
+ /**
11
+ * Puts a pasted issue link where the paste landed (picks 2026-09-06): a chip
12
+ * at the caret always, except on an empty line for a member who asked for
13
+ * cards, where the line becomes an issue card. Then asks the host's lookup to
14
+ * fill it. The paste preference for embeds does not apply to an issue link.
15
+ */
16
+ export declare function placeIssue(containerId: string, blockElement: HTMLElement, blockIndex: number, isEmpty: boolean, url: string, target: IssueTarget): Promise<void>;
17
+ /** The snapshot arrives after the chip does and is written into the chip and,
18
+ * through the block's save, into the document. */
19
+ export declare function fillIssueChip(containerId: string, chip: HTMLAnchorElement, url: string): Promise<void>;
20
+ /** The card's snapshot, written into the block's data so the document carries it. */
21
+ export declare function fillIssueCard(containerId: string, blockId: string, url: string): Promise<void>;
22
+ //# sourceMappingURL=paste.d.ts.map
@@ -0,0 +1,9 @@
1
+ import { IssueTarget } from '../../../types';
2
+ /**
3
+ * Which tracker a URL belongs to, by host and path shape alone, or null for
4
+ * any other link. `jiraSites` are the site URLs the reader's connections reach,
5
+ * so a Jira site on its own domain is recognised. Every match is on the whole
6
+ * host, so a lookalike (`linear.app.evil.example`) is null.
7
+ */
8
+ export declare function classifyIssueUrl(url: string, jiraSites?: readonly string[]): IssueTarget | null;
9
+ //# sourceMappingURL=providers.d.ts.map