Skills part 4: editing skills in Settings, with the built-ins as examples - #93
Open
shanforge wants to merge 2 commits into
Open
Skills part 4: editing skills in Settings, with the built-ins as examples#93shanforge wants to merge 2 commits into
shanforge wants to merge 2 commits into
Conversation
… examples Part of #56. Closes #87 — the last box of #64, which this closes too. ## The built-ins are the documentation #64 asks that they be "readable as examples", so they are listed first, opening one shows exactly what it says to the model, and each is written the way someone's own skill should be: a short summary, instructions that say what to *do* rather than what to be, and a tool list that is narrow — because narrowing is the normal case, not an advanced option. **Editing one copies it.** That is `SkillStore`'s decision rather than this screen's, and the form says so before you save. "Restore" appears only on the ones that have been changed, because a button that undoes nothing is a button that teaches you not to trust it. ## What the form has to get right - **The invocation is shown as you type the name**, because what you read and what you type are different strings and this is where that becomes obvious. - **"Limit which tools" is a switch, not an empty field.** Absent and empty mean different things — see `AgentSkill.allowedToolNames` — and inferring "narrows to nothing" from an empty text field would take every tool from a skill the moment someone cleared it to retype. - **The tool list splits on commas or whitespace**, because someone will use either and a list that accepts one silently drops half of what was typed. - **Validation is the store's.** The form shows `SkillName.Rejection`'s message and keeps what was typed; a second copy of the name rules is a second copy that can disagree. - The three tool states read as words in the list — "Any tool the agent has", "No tools", "Only: …" — because they are easy to confuse and the difference matters. ## Export and import `SkillTransfer` presents a panel rather than inventing a path: this is the user's filesystem, and a silent write into Documents is how a feature becomes something people cannot find again. `MessageActions.exportMarkdown` already makes that argument. A file that cannot be read costs that file and nothing else — picking six and losing all of them to one bad encoding would be the worst possible reading of "import". The result is said out loud **including when it is zero**, because an import that quietly does nothing is indistinguishable from one that worked. The wording is pure and tested at every count, since "1 skills" is the kind of thing nobody notices until it ships. The log names the *file*, never the path — the project rule, and the filename is what the user recognises anyway. ## Two size caps, split rather than suppressed `AISettingsTab` went one line past the 450-line type-body cap, so the per-tool switches and their static group list moved to `AISettingsTab+Tools.swift` — static data rather than logic, which is exactly what the extension-file rule is for. Three members widened to internal to make that work, each carrying the project's `// Extension-visible: +Tools` marker so the wider access reads as deliberate. Verified: build succeeds, 1877 tests in 170 suites pass, SwiftFormat --lint clean over 573 files, SwiftLint --strict 0 violations in 732 files. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M3Wpnj9ZmWPKYdFPB1AVY3
**Instructions past the prompt budget were stored and never sent, with nothing saying so.** Only `AgentSkill.maxInstructionCharacters` of a skill ever reaches the model — it is layered on top of the system prompt and everything else the turn needs, so it spends context the conversation would otherwise have. Paste a long document into a skill and it saves, appears complete, and the agent quietly acts on the first part of it. The way you find out is an answer that ignored half of what you wrote. The count is now said while it is still editable, and the two limits are distinguished because they mean different things: past the prompt budget the extra is saved but never used; past the file limit it will not save at all — refused rather than silently cut, since losing what someone typed on save is the one failure here that cannot be undone. Verified: build succeeds, 1877 tests in 170 suites pass, SwiftFormat --lint clean over 573 files, SwiftLint --strict 0 violations in 732 files. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M3Wpnj9ZmWPKYdFPB1AVY3
39 tasks
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.
Part of #56. Closes #87 — the last box of #64, which this closes too.
Stacked on #92 — review that first; this branch contains it.
The built-ins are the documentation
#64 asks that they be "readable as examples", so they are listed first, opening one shows
exactly what it says to the model, and each is written the way someone's own skill should be:
a short summary, instructions that say what to do rather than what to be, and a tool list
that is narrow — because narrowing is the normal case, not an advanced option.
Editing one copies it. That is
SkillStore's decision rather than this screen's, and theform says so before you save. "Restore" appears only on the ones that have been changed,
because a button that undoes nothing teaches you not to trust it.
What the form has to get right
different strings, and this is where that becomes obvious.
things, and inferring "narrows to nothing" from an empty text field would take every tool
from a skill the moment someone cleared it to retype.
list that accepts one silently drops half of what was typed.
SkillName.Rejection's message and keeps whatwas typed; a second copy of the name rules is a second copy that can disagree.
because they are easy to confuse and the difference matters.
Export and import
SkillTransferpresents a panel rather than inventing a path: this is the user's filesystem,and a silent write into Documents is how a feature becomes something people cannot find
again. A file that cannot be read costs that file and nothing else — picking six and losing
all of them to one bad encoding would be the worst possible reading of "import".
The result is said out loud including when it is zero: an import that quietly does
nothing is indistinguishable from one that worked. The wording is pure and tested at every
count, because "1 skills" is the kind of thing nobody notices until it ships. The log names
the file, never the path.
What the review found
Instructions past the prompt budget were stored and never sent, with nothing saying so.
Only a bounded amount of a skill reaches the model — it is layered on top of the system
prompt and everything else the turn needs. Paste a long document into a skill and it saves,
looks complete, and the agent quietly acts on the first part. The way you find out is an
answer that ignored half of what you wrote.
The count is now shown while it is still editable, and the two limits are distinguished
because they mean different things: past the prompt budget the extra is saved but never used;
past the file limit it will not save at all — refused rather than silently cut, since losing
what someone typed on save is the one failure here that cannot be undone.
Verification
xcodebuild build— succeeds./scripts/test-no-llm.sh— 1877 tests in 170 suites pass--lint— 0/573 files require formatting--strict— 0 violations in 732 filesAISettingsTabwent one line past the 450-line type-body cap, so the per-tool switches andtheir static group list moved to
AISettingsTab+Tools.swift— static data rather than logic,which is what the extension-file rule is for. Three members widened to internal, each
carrying the project's
// Extension-visible: +Toolsmarker so the wider access reads asdeliberate.
The click-through for the whole skills feature
This is where it can be driven end to end, so this is the PR carrying the evidence request.
/nameand a "built-in" badge.Open one: the instructions are readable, and are what the model is actually given.
+→ Skills. A chip appears sayingwhich. Send: the answer follows the skill.
that is the point of Ask Logue part 1: one assistant on both surfaces #61 and the reason this box was cheap.
/tighten-thisand a document name — no chip needed.typed, on both surfaces.
something needing a different tool. It should decline rather than call the other tool.
away and never add one.
original comes back.
says "Imported 1 skill of 2".
actually sent.
🤖 Generated with Claude Code
https://claude.ai/code/session_01M3Wpnj9ZmWPKYdFPB1AVY3