Pinned and named clips — persistent credential-friendly history entries
Problem
teeclip's clipboard history uses FIFO eviction: when max_entries is reached (default 50), the oldest entry is silently deleted. This works well for general clipboard content but creates a problem for users who rely on teeclip as a lightweight credential store.
Consider this workflow:
# User copies API key from password manager → saved to encrypted history as entry #1
# User does 50 more clipboard operations...
# API key is silently evicted from history
teeclip --get 50 # error: no clip at index 50 — the key is gone
Additionally, retrieving credentials by numeric index (--get 3) is fragile — the index shifts every time a new clip is added. Users need a stable way to reference important entries.
Proposed solution
Two complementary features that make teeclip viable as a simple encrypted credential helper:
Pinned clips
Pin entries to protect them from FIFO eviction:
teeclip --pin 3 # pin entry #3 (exempt from eviction)
teeclip --unpin 3 # unpin entry #3 (returns to normal FIFO)
teeclip --list # pinned entries show [P] marker
Pinned entries remain in history indefinitely regardless of max_entries. FIFO eviction only applies to unpinned entries.
Named clips
Save and retrieve clips by name instead of numeric index:
# Save with a name
teeclip --save-as "aws-key" # save clipboard as named clip
echo "sk-abc123" | teeclip --name "openai-key" # pipe content into named clip
# Retrieve by name
teeclip --get aws-key | deploy-tool --key-stdin
teeclip --get openai-key # also copies back to clipboard
# List shows names
teeclip --list
# 1 2026-02-18 09:30 [P] aws-key: AKIA...
# 2 2026-02-18 09:28 [P] openai-key: sk-a...
Named clips are implicitly pinned (exempt from eviction). The name provides stable, human-readable retrieval.
Schema changes
-- Add to clips table:
ALTER TABLE clips ADD COLUMN pinned INTEGER NOT NULL DEFAULT 0;
ALTER TABLE clips ADD COLUMN name TEXT DEFAULT NULL;
-- Unique constraint on names:
CREATE UNIQUE INDEX IF NOT EXISTS idx_clips_name ON clips(name) WHERE name IS NOT NULL;
Implementation approach
Phase 1 — Pinned clips:
- Add
pinned column to schema (v3 migration)
- Modify FIFO eviction query:
DELETE FROM clips WHERE pinned = 0 AND id NOT IN (SELECT id FROM clips WHERE pinned = 0 ORDER BY id DESC LIMIT ?)
- Add
--pin N and --unpin N CLI flags
- Show
[P] marker in --list output (alongside existing [E] for encrypted)
Phase 2 — Named clips:
- Add
name column to schema (same v3 migration)
- Add
--save-as NAME and --name NAME CLI flags
- Extend
--get to accept a string name in addition to integer index
- Show name in
--list preview when present
Design considerations
- Named clips are implicitly pinned: If you took the time to name something, you don't want it evicted. This avoids the confusing state of a named clip that disappears.
--get overloading: --get 3 (integer → index) vs --get aws-key (string → name). Disambiguation: try integer parse first. Names that are pure digits would need quoting or a prefix convention — but this edge case is rare enough to handle later.
max_entries interaction: The limit applies to unpinned entries only. If a user pins 100 entries, the database holds 100 + max_entries. This is acceptable for a developer workstation tool.
- Selective clear interaction:
--clear should skip pinned entries by default. --clear --force or explicit --unpin + --clear to remove pinned entries.
- Encryption: Pinned/named clips follow the same encryption rules as regular clips. Names are stored in plaintext (they're user-chosen labels, not secret content).
Acceptance criteria
Related issues
Analysis
See notes/ideas/2026-02-18__09-18-22__both_secure-credential-piping-via-clipboard.md for the original observation and discussion about teeclip as a credential helper.
Pinned and named clips — persistent credential-friendly history entries
Problem
teeclip's clipboard history uses FIFO eviction: when
max_entriesis reached (default 50), the oldest entry is silently deleted. This works well for general clipboard content but creates a problem for users who rely on teeclip as a lightweight credential store.Consider this workflow:
Additionally, retrieving credentials by numeric index (
--get 3) is fragile — the index shifts every time a new clip is added. Users need a stable way to reference important entries.Proposed solution
Two complementary features that make teeclip viable as a simple encrypted credential helper:
Pinned clips
Pin entries to protect them from FIFO eviction:
Pinned entries remain in history indefinitely regardless of
max_entries. FIFO eviction only applies to unpinned entries.Named clips
Save and retrieve clips by name instead of numeric index:
Named clips are implicitly pinned (exempt from eviction). The name provides stable, human-readable retrieval.
Schema changes
Implementation approach
Phase 1 — Pinned clips:
pinnedcolumn to schema (v3 migration)DELETE FROM clips WHERE pinned = 0 AND id NOT IN (SELECT id FROM clips WHERE pinned = 0 ORDER BY id DESC LIMIT ?)--pin Nand--unpin NCLI flags[P]marker in--listoutput (alongside existing[E]for encrypted)Phase 2 — Named clips:
namecolumn to schema (same v3 migration)--save-as NAMEand--name NAMECLI flags--getto accept a string name in addition to integer index--listpreview when presentDesign considerations
--getoverloading:--get 3(integer → index) vs--get aws-key(string → name). Disambiguation: try integer parse first. Names that are pure digits would need quoting or a prefix convention — but this edge case is rare enough to handle later.max_entriesinteraction: The limit applies to unpinned entries only. If a user pins 100 entries, the database holds 100 + max_entries. This is acceptable for a developer workstation tool.--clearshould skip pinned entries by default.--clear --forceor explicit--unpin+--clearto remove pinned entries.Acceptance criteria
pinnedcolumn exists in clips table (schema v3)namecolumn exists in clips table with unique constraint (schema v3)--pin Npins an entry;--unpin Nunpins it--listshows[P]marker for pinned entries--save-as NAMEsaves clipboard contents with a name--name NAMEduring pipe saves piped content with a name--get NAMEretrieves by name;--get Nretrieves by index--clearskips pinned entries by defaultRelated issues
Analysis
See
notes/ideas/2026-02-18__09-18-22__both_secure-credential-piping-via-clipboard.mdfor the original observation and discussion about teeclip as a credential helper.