diff --git a/COPY.md b/COPY.md index 6b7ae011..bea4a98a 100644 --- a/COPY.md +++ b/COPY.md @@ -46,6 +46,8 @@ These exact strings. Do not paraphrase them per page. The Agent request uses `Fork this Skill: `. The Skill page's Markdown explains how to copy the source and install the local path. Keep run as the default. Fork is the opt-in for an editable local copy. +The HTML page links to that Markdown with `Fork this Skill`. +Its description uses `A fork creates an editable local Skill with its original author and licence.` ### Watch and weekly promotions diff --git a/layers/registry/app/components/_SkillCommandPanel.vue b/layers/registry/app/components/_SkillCommandPanel.vue index 92bcbd5c..e24c2cf5 100644 --- a/layers/registry/app/components/_SkillCommandPanel.vue +++ b/layers/registry/app/components/_SkillCommandPanel.vue @@ -212,6 +212,18 @@ function copyFrom(next: CommandMode) { +
+ + Fork this Skill + +

+ A fork creates an editable local Skill with its original author and licence. +

+
+

This session only. Nothing lands on disk.

+
+ + Fork this Skill + +

+ A fork creates an editable local Skill with its original author and licence. +

+
+

{ + it.each(['stacked', 'tabs'] as const)('offers the fork workflow in the %s layout', async (layout) => { + const wrapper = await mountSuspended(SkillCommandPanel, { props: { ...props, layout } }) + const forkLink = wrapper.findAll('a').find(link => link.text() === 'Fork this Skill') + + expect(forkLink?.attributes('href')).toBe(`${props.runUrl}.md`) + expect(wrapper.text()).toContain('A fork creates an editable local Skill with its original author and licence.') + }) + it('points each install tab at the matching developers setup', async () => { const wrapper = await mountSuspended(SkillCommandPanel, { props }) const setupHref = () => wrapper.findAll('a').map(a => a.attributes('href')).find(href => href?.startsWith('/developers'))