stacks-session
Interacts with a running stacks2099 instance to read, update, and manage markdown clips.
Install
mkdir -p .claude/skills/stacks-session && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/12269" && unzip -o skill.zip -d .claude/skills/stacks-session && rm skill.zipInstalls to .claude/skills/stacks-session
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Read and edit clips on a running stacks2099 session (the clip manager served over HTTP on a port you choose at startup). Use when asked to put a doc/note/image on a stack, iterate on a markdown clip that's open in the app, update the clip shown in the current stack, or otherwise change what's on the stream without creating a file on disk. Covers the HTTP API (curl) and the direct xs store.Key capabilities
- →Find the currently focused clip in a stacks2099 session
- →Read the content of a specific clip
- →Create a new clip with specified content and mime type
- →Update the content of an existing clip in place
- →Write directly to the event log via xs API
How it works
The skill interacts with a running stacks2099 session via its HTTP API or direct xs store access to manage clips. Clips are content-addressed bytes in an event log, and updates append new bytes while retaining the clip ID.
Inputs & outputs
When to use stacks-session
- →Update content on current stack
- →Read clip content
- →Create new clip note
About this skill
Editing clips on a running stacks2099 session
A clip's content is not a file. It lives in the event log as content-addressed bytes; the clip frame holds a hash. You "edit" a clip by appending an update. The clip keeps the same id, and the pane in the browser refreshes on its own.
So the loop is: find the clip, read its bytes, write new bytes back. The clip stays in place in the stack the whole time.
First you need the server's port. It is not fixed: you pick the port when you
start the server. If the user has not told you the port, ask them for it before
doing anything else. Do not guess or scan. Substitute it for PORT below.
1. Find the clip
/api/state reports the focused (currently shown) clip and stack, plus every
stack with its id, name, and clip count.
curl -s http://127.0.0.1:PORT/api/state | jq .
# .focusedClip -> the clip currently shown in the current stack
# .focusedStack -> its stack
To edit "the clip on my current stack," target .focusedClip.
2. Read a clip's current content
curl -s 'http://127.0.0.1:PORT/clip/blob?clip=CLIP_ID'
A 404 / "not found" means the clip has no stored body yet (a fresh empty note)
or it's a terminal clip (terminals stream over /pty/view, they have no blob).
3. Create a clip (only if one doesn't exist yet)
The body is the content; the mime type comes from the Content-Type header (or
?mime_type=). It lands in the current stack unless you pass ?stack=<id|name>.
The response is the new clip id.
cat notes.md | curl --data-binary @- \
-H 'content-type: text/markdown' http://127.0.0.1:PORT/clip/add
# -> prints the new clip id
4. Update a clip in place (the iterate loop)
Re-post new bytes to an existing clip. Same clip id, same spot in the stack, pane refreshes live. The mime type is unchanged.
curl --data-binary @- 'http://127.0.0.1:PORT/clip/update?clip=CLIP_ID' <<'EOF'
# revised markdown
...
EOF
To iterate on a markdown doc: read with /clip/blob, make your edit, write
back with /clip/update, repeat. No files are created.
Things that will trip you up
- The clip id never changes across updates. Don't create a new clip each time; update the existing one.
- If the clip is open in edit mode in the browser (its textarea is showing), the
server will not repaint it from under you. Your
/clip/updatestill lands in the log, but it won't show until the clip leaves edit mode. If an update seems to "not take," this is usually why. Markdown clips in rendered view repaint immediately. /clip/updatekeeps the existing mime type. To change the type, close the clip and add a new one.
Alternative: write to the store directly (no HTTP)
The store serves an xs API on its socket, so you can append the same frames the
HTTP routes append. This instance's store is the repo's ./store; point xs at
it with XS_ADDR or the path argument. The user's nu helpers in ~/xs/xs.nu
(.append, .cat, .cas, .last) wrap these.
# update a clip's body straight on the log (id = the existing clip id)
cat revised.md | xs append ./store clip.update --ttl forever --meta '{"id":"CLIP_ID"}'
# add a new markdown clip (stack_id from /api/state .focusedStack)
cat notes.md | xs append ./store clip.add --ttl forever \
--meta '{"stack_id":"STACK_ID","kind":"content","mime_type":"text/markdown"}'
In a store-connected nushell the builtin form is the same thing:
open revised.md | .append "clip.update" --meta {id: "CLIP_ID"} --ttl forever
Frames: clip.add {stack_id, kind, mime_type} (body -> new clip), clip.update {id} (body -> replace that clip's bytes), clip.patch {id, label?, view?}
(field change, no body). Use HTTP unless you specifically need to bypass it; the
routes are just sugar over these appends.
When not to use it
- →When the server's port is unknown, as it must be provided by the user
- →When a clip is open in edit mode in the browser, as updates won't repaint immediately
- →When needing to change a clip's mime type, as this requires creating a new clip
Limitations
- →The server port must be explicitly provided by the user.
- →Updates to clips in browser edit mode do not repaint immediately.
- →Changing a clip's mime type requires creating a new clip.
How it compares
This skill allows programmatic manipulation of clips in a live stacks2099 session without creating temporary files, offering a direct way to update content that refreshes in the browser.
Compared to similar skills
stacks-session side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| stacks-session (this skill) | 0 | 2mo | Review | Intermediate |
| obsidian-bases | 11 | 4mo | Review | Intermediate |
| video-transcript-downloader | 4 | 2mo | Review | Intermediate |
| obsidian-clipper-template-creator | 3 | 6mo | No flags | Beginner |
Try saying
Example prompts that trigger this skill in your AI assistant.
You might also like
obsidian-bases
kepano
Create and edit Obsidian Bases (.base files) with views, filters, formulas, and summaries. Use when working with .base files, creating database-like views of notes, or when the user mentions Bases, table views, card views, filters, or formulas in Obsidian.
video-transcript-downloader
steipete
Download videos, audio, subtitles, and clean paragraph-style transcripts from YouTube and any other yt-dlp supported site. Use when asked to “download this video”, “save this clip”, “rip audio”, “get subtitles”, “get transcript”, or to troubleshoot yt-dlp/ffmpeg and formats/playlists.
obsidian-clipper-template-creator
davila7
Guide for creating templates for the Obsidian Web Clipper. Use when you want to create a new clipping template, understand available variables, or format clipped content.
obsidian-vault-ops
ballred
Read and write Obsidian vault files, manage wiki-links, process markdown with YAML frontmatter. Use when working with vault file operations, creating notes, or managing links.
baoyu-danger-x-to-markdown
JimLiu
Converts X (Twitter) tweets and articles to markdown with YAML front matter. Uses reverse-engineered API requiring user consent. Use when user mentions "X to markdown", "tweet to markdown", "save tweet", or provides x.com/twitter.com URLs for conversion.
log-work
pchalasani
Log the work segment that you did after the last work log until now in a