metadata

package
v1.6.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 26, 2026 License: MIT Imports: 4 Imported by: 0

Documentation

Overview

Package metadata provides HTML-based metadata storage for Linear issues and projects.

Linear doesn't provide native custom fields, so this package implements metadata storage by embedding HTML comment blocks in markdown descriptions. The metadata is invisible in Linear's UI but accessible via the API.

Metadata Format

Metadata is stored as JSON in an HTML comment block:

<!-- linear-metadata
{
  "customField1": "value",
  "customField2": 42,
  "nested": {"key": "value"}
}
-->

Extraction

Extract metadata from a description:

description := "Issue description\n<!-- linear-metadata\n{\"key\":\"value\"}\n-->"
metadata, cleanDesc := metadata.ExtractMetadataFromDescription(description)
// metadata = map[string]interface{}{"key": "value"}
// cleanDesc = "Issue description"

Injection

Inject metadata into a description:

metadata := map[string]interface{}{"priority": "high", "customer": "Acme Corp"}
newDesc := metadata.InjectMetadataIntoDescription("User description", metadata)
// Adds HTML comment block with metadata to description

Preservation During Updates

When updating descriptions, preserve existing metadata:

oldDesc := "Old text\n<!-- linear-metadata\n{\"key\":\"value\"}\n-->"
newDesc := "New text"
finalDesc := metadata.UpdateDescriptionPreservingMetadata(oldDesc, newDesc)
// finalDesc = "New text\n<!-- linear-metadata\n{\"key\":\"value\"}\n-->"

Use Cases

Common metadata use cases:

  • Custom priority systems
  • Customer/stakeholder tracking
  • External system IDs
  • AI agent state tracking
  • Custom workflow flags

Design Rationale

This approach has several advantages:

  • Works within Linear's existing API (no schema changes needed)
  • Invisible to users in Linear's UI (clean UX)
  • Survives copy/paste operations
  • Compatible with Linear's markdown rendering
  • Type-safe JSON storage

The HTML comment format was chosen because:

  • Linear renders it invisibly (unlike code blocks)
  • It's valid markdown
  • It doesn't interfere with descriptions
  • It's easily parsable and detectable

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ExtractMetadataFromDescription

func ExtractMetadataFromDescription(description string) (map[string]interface{}, string)

extractMetadataFromDescription extracts metadata JSON from a description and returns both the metadata and the description without the metadata section.

Why this approach: We store metadata as a hidden collapsible section in descriptions to avoid cluttering the UI while preserving structured data. This allows metadata to travel with issues and projects without requiring separate API calls.

func InjectMetadataIntoDescription

func InjectMetadataIntoDescription(description string, metadata map[string]interface{}) string

injectMetadataIntoDescription adds metadata to a description as a collapsible section. If the description already contains metadata, it will be replaced.

Why this approach: By always replacing existing metadata, we ensure there's only one metadata section and it's always up-to-date. The collapsible format keeps the description readable while preserving the data.

func UpdateDescriptionPreservingMetadata

func UpdateDescriptionPreservingMetadata(oldDescription, newDescription string) string

updateDescriptionPreservingMetadata updates a description while preserving any existing metadata. This is useful when updating description content without losing metadata.

Why: Users often want to update the human-readable description without worrying about preserving technical metadata. This function handles that automatically.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL