fix(skill): description overran the listing cap; add a real cctab alias - #16
Draft
motin wants to merge 3 commits into
Draft
fix(skill): description overran the listing cap; add a real cctab alias#16motin wants to merge 3 commits into
cctab alias#16motin wants to merge 3 commits into
Conversation
`@types/bun` is declared in package.json devDependencies but was missing from the committed lockfile, so a fresh clone + `bun install` left it unresolved and `npm run typecheck` failed with TS2307 "Cannot find module 'bun:test'" across all 12 test files. Nothing about the dependency changed — only the lockfile catching up to what package.json already asked for. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…rule
A session in another repo was told "open a new cctab to improve the /render-doc
skill". It ran `which cctab`, got nothing, called ListAgents, concluded no such
command existed, and handed the work to an Agent-tool worktree subagent — the
exact substitution this skill's description forbids in bold.
The description was not at fault, and neither was packaging: the transcript
shows `cctabs:cctabs` present in that session's initial skill listing, TRIGGER
list and all. Two separate real problems showed up while proving that.
**The description was being silently truncated.** Claude Code caps a skill
description at 1535 characters in the available-skills listing and appends `…`.
Ours ran 1760, so every listing it ever appeared in was cut mid-sentence at
`"do this in parallel without a new tab", or w…` — amputating the tail of the
anti-substitution rule and the whole `NOT for:` line. Nothing warns about this;
the skill still loads and still works when invoked by name, so the loss is
invisible unless you read a transcript's `skill_listing` attachment.
- Now 1432 chars, ~100 under the cap, and CLAUDE.md records the budget and the
ordering rule so the next edit does not quietly overrun it again.
- The decisive sentence ("a subagent is NOT a tab") moves *above* the TRIGGER
list, so it can no longer be the part that gets dropped.
- Every trigger phrase is preserved verbatim; the list was well-tuned already.
- The opening clause leads with the literal tokens `cctab` / `cctabs` /
`terminal tabs`, because in a project with dozens of its own skills this entry
can land 75% of the way down 80+ entries and the first clause is what reads.
**`cctab` is now a real command.** The skill has always advertised "cctab" as a
singular alias while only `cctabs` was ever installed, so looking the CLI up
under the name the docs use returned nothing. It is now a second bin on the same
entry point. This is the only part of this change that addresses the actual
failure: Claude Code injects the full skill listing **once per session** and does
not re-inject it after a compaction (only single-skill recall deltas). That
session had compacted ~1800 turns before the request, so it had no listing left
and no description wording could have reached it — probing the shell was the one
discovery path still open, and it dead-ended.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
# Conflicts: # CHANGELOG.md
Deploying cctabs with
|
| Latest commit: |
71cd156
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://ad9a0634.cctabs.pages.dev |
| Branch Preview URL: | https://fix-skill-discoverability.cctabs.pages.dev |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What prompted this
A session in
~/Dev/horizonwas told "open a new cctab to improve the /render-doc skill …". It ranwhich cctab/type cctab, grepped~/.zshrcfor an alias, found nothing, calledListAgents, concluded "there is no cctab command and I can't open an interactive tab from inside a session", and handed the work to an Agent-tool worktree subagent — the exact substitution this skill's description forbids in bold.Root cause: not the description, and not packaging
The working theory going in was that the skill was never enumerated. It was.
~/.claude/projects/…-dropoff-ux/<id>.jsonlline 8 holds askill_listingattachment withisInitial: true, skillCount: 82containingcctabs:cctabswith the full TRIGGER list,"open a new cctab" (singular alias)included.What actually happened:
isInitial: false, skillCount: 1) — in that transcript, repeatedlyhorizon-analytics,horizon-next-steps,b2b-triage.isInitial: truelisting is ever emitted.So the handful of skills that session reported as "all I ever saw" (
horizon-analytics,render-doc,b2b-triage,precompact-handoff,conductor-auth-refresh) was an accurate description of its post-compaction context, and the conclusion drawn from it ("it was never in my listing") was wrong.This is harness behavior and cannot be fixed from this repo. Hypotheses ruled out along the way: a skills-only plugin needing its own manifest (the 0.5.0 cache dir has
.claude-plugin/plugin.json, identical in layout tobrowser-automation, which lists fine); two cached versions confusing enumeration (0.4.10 is.orphaned_at-marked and inert); user-scope suppression by project skills — disproved by experiment, see below.What this PR changes
1. The description was being silently truncated
Claude Code caps a skill description at 1535 chars in the listing and appends
…. Ours ran 1760, so every listing it appeared in was cut at"do this in parallel without a new tab", or w…— losing the tail of the anti-substitution rule and the entireNOT for:line. Nothing warns about it; the skill still loads and works when invoked by name.cctab/cctabs/terminal tabs.CLAUDE.mdnow records the budget + ordering rule so the next edit doesn't quietly overrun it.2.
cctabis now a real commandThe skill has always advertised "cctab" as a singular alias while only
cctabswas installed. Added as a second bin on the same entry point.I was asked to weigh this honestly as a possible hack. It is not a fix for the root cause — nothing here is. But it is the only change in this PR that touches the actual failure path: post-compaction there is no listing, so probing the shell is the one discovery route left, and it dead-ended on a name our own docs promise. A stub that merely printed a pointer to the skill would be a hack; a real alias just makes the documented name true.
3. Incidental:
@types/bunmissing frombun.lockDeclared in
package.jsonbut absent from the lockfile, so a fresh clone failsnpm run typecheckwith TS2307 across all 12 test files. Separate commit.How this was verified
Not by reasoning that it should work — by running fresh sessions with
--plugin-dirpointed at this branch.cctabs:cctabslistedcctabs:cctabsstill listed — crowding hypothesis disproved…tmux panes, or screen sessions.; ellipsis present? NO;NOT for:present? YES--allowedTools Skill --disallowedTools "Bash Agent …"TOOL_USE: Skill {"skill": "cctabs:cctabs", "args": "new render-doc-toc --prompt …"}— skill invoked, not the Agent toolcctabs sessionsclean; therender-doc-stylestab predates this work)npm run checkControl worth stating plainly: the old description also triggers correctly under the same crowded conditions. So change 1 is truncation hygiene and listing-position robustness, not demonstrated behavioral repair. I could not reproduce the original failure, because reproducing it requires a compacted long session with no listing — and in that state no description wording is in play at all.
Deliberately left alone
~/Dev/horizon— untouched (read-only inspection of its config and transcript).origin/fix/skill-trigger-open-a-tab— a June attempt at this same symptom, pre-0.5.0 (still containswave.ts). Its substance already landed in main; left abandoned.cctabs-tabby-loginworktree — untouched.chore(release)commit. Note for whoever releases this —SKILL.mdships in both the npm tarball and the marketplace, so this needsnpm run sync-plugin.Also found, not fixed here
Local
mainin the primary checkout is 5 commits behindorigin/main(still at 0.4.10 with Wave-era text, whileorigin/mainis 0.5.1). The worktree I was given was branched from that stale localmain; I reset ontoorigin/mainbefore working. Worth agit pullin the main checkout.🤖 Generated with Claude Code