@zibby/skills 0.2.14 → 0.2.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/artifact.d.ts +2 -0
- package/dist/artifact.js +37 -11
- package/dist/index.js +146 -120
- package/dist/package.json +1 -1
- package/package.json +1 -1
package/dist/artifact.d.ts
CHANGED
package/dist/artifact.js
CHANGED
|
@@ -1,10 +1,35 @@
|
|
|
1
|
-
import{SKILL_META as
|
|
1
|
+
import{SKILL_META as v}from"@zibby/skill-ids";import{existsSync as k,readFileSync as S}from"node:fs";import{homedir as N}from"node:os";import{join as E,dirname as _,resolve as R}from"node:path";import{fileURLToPath as A}from"node:url";function I(){if(process.env.MCP_SKILL_PATH)return process.env.MCP_SKILL_PATH;let r=_(A(import.meta.url)),t=R(r,"..","bin","mcp-skill.mjs");return k(t)?t:null}function m(){if(process.env.PROJECT_API_TOKEN)return process.env.PROJECT_API_TOKEN;if(process.env.ZIBBY_USER_TOKEN)return process.env.ZIBBY_USER_TOKEN;try{let r=E(N(),".zibby","config.json");return k(r)&&JSON.parse(S(r,"utf-8")).sessionToken||null}catch{return null}}function f(){return process.env.ZIBBY_ACCOUNT_API_URL?process.env.ZIBBY_ACCOUNT_API_URL.replace(/\/$/,""):(process.env.ZIBBY_ENV||"prod")==="local"?"http://localhost:3001":process.env.ZIBBY_PROD_ACCOUNT_API_URL||"https://api-prod.zibby.app"}function P(){return(typeof process.env.WORKFLOW_TYPE=="string"?process.env.WORKFLOW_TYPE.trim():"")||"agent"}function O(r){return`${P()}:artifact:${r}`}var u="headings, paragraphs, **bold**, *italic*, `inline code`, fenced code blocks, bullet + numbered lists, blockquotes, horizontal rules, links, and GitHub-style pipe tables (including |---:| alignment)",h="raw HTML (tags are escaped and print as literal text), images, nested lists, footnotes and strikethrough",p=2,c=0;function j(){c=0}function y(r,t){return JSON.stringify({published:!1,stop:!0,attemptsUsed:p,defects:t||[],error:r,instruction:`STOP. You have used both publish attempts and the page is still rejected. Do NOT call artifact_publish or artifact_update again in this turn. Tell the user plainly that you could not produce a clean page, say in one line what was wrong, and give them the content directly in the chat instead. A broken link is worse than an honest "I couldn't".`})}function U(r,t,e){return JSON.stringify({published:!1,stop:!1,attemptsRemaining:p-c,defects:e||[],error:t,instruction:"The page was NOT published and no URL exists. Fix EXACTLY the defects listed above and call once more \u2014 you get ONE more attempt, then this tool will stop you."+(r==="html"?` You are on the \`html\` path, where you author the entire document and every mistake ships. Unless this page genuinely needs a custom visual layout, the fastest and most reliable fix is to re-send the SAME content as \`markdown\` \u2014 Zibby then generates the document skeleton, CSS and tables for you and these defects become impossible. Markdown supports ${u}.`:` Markdown supports ${u}; it does NOT support ${h}.`)})}async function x(r){let t=m();if(!t)throw new Error("No backend credential (PROJECT_API_TOKEN). Artifacts are only available inside a Zibby run.");let e=await fetch(`${f()}/credits/artifacts`,{method:"POST",headers:{Authorization:`Bearer ${t}`,"Content-Type":"application/json"},body:JSON.stringify(r)});if(!e.ok){let a=await e.text().catch(()=>""),n=null;try{n=JSON.parse(a)}catch{}let i=new Error(e.status===422&&n?.error?n.error:`artifact write failed (${e.status}): ${a.slice(0,300)}`);throw i.status=e.status,Array.isArray(n?.defects)&&(i.defects=n.defects),i}return e.json()}async function g(r,t){try{let e=await x(r);return c=0,e}catch(e){if(e?.status!==422)throw e;return c+=1,{__rejected:!0,payload:c>=p?y(e.message,e.defects):U(t,e.message,e.defects)}}}async function L(r){let t=m();if(!t)throw new Error("No backend credential (PROJECT_API_TOKEN). Artifacts are only available inside a Zibby run.");let e=await fetch(`${f()}/credits/artifacts/${encodeURIComponent(r)}`,{method:"GET",headers:{Authorization:`Bearer ${t}`}});if(!e.ok){let a=await e.text().catch(()=>"");throw new Error(`artifact get failed (${e.status}): ${a.slice(0,300)}`)}return e.json()}async function b(r,t){let e=m();if(!e)return;let a=await fetch(`${f()}/credits/review-memory`,{method:"POST",headers:{Authorization:`Bearer ${e}`,"Content-Type":"application/json"},body:JSON.stringify({op:"store",scope:O(r),content:JSON.stringify(t)})});if(!a.ok){let n=await a.text().catch(()=>"");throw new Error(`artifact index write failed (${a.status}): ${n.slice(0,200)}`)}}async function C(r){let t=m();if(!t)return null;let e=await fetch(`${f()}/credits/review-memory`,{method:"POST",headers:{Authorization:`Bearer ${t}`,"Content-Type":"application/json"},body:JSON.stringify({op:"recall",scope:O(r)})});if(!e.ok)return null;let a=await e.json().catch(()=>null);if(!a?.found||!a?.memory?.content)return null;try{return JSON.parse(a.memory.content)}catch{return null}}function w(r){let t=typeof r?.html=="string"&&r.html.length>0,e=typeof r?.markdown=="string"&&r.markdown.length>0;return t&&e?{error:"Pass EITHER markdown OR html, not both \u2014 they are different rendering paths. Use markdown unless the page needs a custom visual layout."}:e?{format:"markdown",content:r.markdown}:t?{format:"html",content:r.html}:null}var H={id:"artifact",callsBackend:!0,meta:v.artifact,serverName:"artifact",allowedTools:["mcp__artifact__*"],description:"Artifacts \u2014 publish a self-contained, shareable HTML/Markdown page to Zibby and get back a URL; the index of what you published is your memory.",promptFragment:`## Artifacts (publish a shareable page, remember what you made)
|
|
2
2
|
You can PUBLISH a standalone page \u2014 a status report, a plan, a comparison table,
|
|
3
3
|
a dashboard-y summary, a diagram, a "here's what I found" write-up \u2014 and get back
|
|
4
|
-
a shareable URL.
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
a shareable URL.
|
|
5
|
+
|
|
6
|
+
### WRITE IT AS MARKDOWN. That is the default, and it is not a stylistic hint.
|
|
7
|
+
Pass \`markdown\` and Zibby generates the whole document for you \u2014 doctype, head,
|
|
8
|
+
CSS, typography, dark mode, table styling. You supply only the CONTENT. Markdown
|
|
9
|
+
supports ${u}. It does NOT support ${h}.
|
|
10
|
+
|
|
11
|
+
Pass \`html\` ONLY when the page genuinely needs a visual layout Markdown cannot
|
|
12
|
+
express \u2014 a bar chart, a gauge, a custom grid, an SVG diagram. On the html path
|
|
13
|
+
YOU author the entire document and every mistake ships: a table left in Markdown
|
|
14
|
+
syntax, an escaped \`<!doctype\`, a bar with no width. If the page is a report,
|
|
15
|
+
a plan, a list, a table or a write-up, it is markdown. No exceptions worth taking.
|
|
16
|
+
|
|
17
|
+
Whichever path: the page is sandboxed when viewed (no network at all, no ambient
|
|
18
|
+
credentials), so on the html path keep ALL CSS/JS/images INLINE (inline
|
|
19
|
+
<style>/<script>, data: URIs) \u2014 every external URL is blocked and will simply not
|
|
20
|
+
load. NEVER escape the document: send real tags, not \`<div>\`.
|
|
21
|
+
|
|
22
|
+
### Every number on the page must come from a tool result or this transcript.
|
|
23
|
+
Do not do arithmetic in prose and then print the answer \u2014 that is how a page ends
|
|
24
|
+
up saying 42 in one place and 45 in another. If you need a total, compute it with
|
|
25
|
+
a tool (or restate the figures exactly as your tools returned them) and cite the
|
|
26
|
+
same figure everywhere it appears.
|
|
27
|
+
|
|
28
|
+
### The page is validated BEFORE a URL exists.
|
|
29
|
+
If the content is broken you get back the exact defects and their line numbers,
|
|
30
|
+
and no page is created. You get ONE retry. After that the tool STOPS you \u2014 at
|
|
31
|
+
which point say plainly that you could not produce a clean page and put the
|
|
32
|
+
content in the chat instead. Do not keep trying.
|
|
8
33
|
|
|
9
34
|
THE CONTENT COMES FROM THIS CONVERSATION \u2014 NEVER FROM YOUR IMAGINATION.
|
|
10
35
|
When someone says "make me a page / an artifact / a report", they mean THE THING
|
|
@@ -23,16 +48,17 @@ link, buries the real answer, and reads as if you ignored them. There is no
|
|
|
23
48
|
situation in which "\u793A\u4F8B / sample / demo" belongs in a title you publish.
|
|
24
49
|
|
|
25
50
|
Tools:
|
|
26
|
-
- artifact_publish: Publish a NEW page. Pass a \`title\` and EITHER \`
|
|
27
|
-
\`
|
|
28
|
-
\`favicon\` (an emoji), and \`summary\` (one line
|
|
29
|
-
{ id, url }. Share the url; keep the id if you'll
|
|
51
|
+
- artifact_publish: Publish a NEW page. Pass a \`title\` and EITHER \`markdown\`
|
|
52
|
+
(the default \u2014 prefer this) OR \`html\` (never both). Optional \`kind\` (e.g.
|
|
53
|
+
"report", "plan", "dashboard"), \`favicon\` (an emoji), and \`summary\` (one line
|
|
54
|
+
for your own index). Returns { id, url }. Share the url; keep the id if you'll
|
|
55
|
+
update it later.
|
|
30
56
|
- artifact_update: Revise an EXISTING page by \`id\` (same url, new version). Pass
|
|
31
|
-
the fields to change (\`title\`, \`html
|
|
57
|
+
the fields to change (\`title\`, \`markdown\`|\`html\`).
|
|
32
58
|
- artifact_get: Fetch one artifact by \`id\` \u2192 { metadata, content } so you can
|
|
33
59
|
reuse / edit / re-publish it.
|
|
34
60
|
|
|
35
61
|
To recall WHAT YOU HAVE ALREADY PUBLISHED, use your kv-memory tool
|
|
36
62
|
kv_recall_prefix with keyPrefix "artifact:" \u2014 each entry is the index record
|
|
37
63
|
{ id, title, url, kind, createdAt, summary } for a page you made. (Publishing
|
|
38
|
-
records this automatically; you don't store it yourself.)`,resolve(){let
|
|
64
|
+
records this automatically; you don't store it yourself.)`,resolve(){let r=I();if(!r)return{command:null,args:[],env:{},description:this.description};let t={};for(let e of["PROJECT_API_TOKEN","ZIBBY_ACCOUNT_API_URL","ZIBBY_ENV","ZIBBY_PROD_ACCOUNT_API_URL","ZIBBY_USER_TOKEN","WORKFLOW_TYPE"])process.env[e]&&(t[e]=process.env[e]);return{type:"stdio",command:"node",args:[r,"../dist/artifact.js","artifactSkill"],env:t,description:this.description,alwaysLoad:!0}},async handleToolCall(r,t){try{switch(r){case"artifact_publish":{if(c>=p)return y("Publish budget already spent this turn.",[]);let e=typeof t?.title=="string"?t.title.trim():"";if(!e)return JSON.stringify({error:"title is required"});let a=w(t);if(!a)return JSON.stringify({error:"provide exactly one of markdown (preferred) or html (non-empty string)"});if(a.error)return JSON.stringify({error:a.error});let n={title:e,[a.format]:a.content};typeof t?.kind=="string"&&t.kind.trim()&&(n.kind=t.kind.trim()),typeof t?.favicon=="string"&&t.favicon.trim()&&(n.favicon=t.favicon.trim());let i=await g(n,a.format);if(i?.__rejected)return i.payload;let o=i?.id,s=i?.url;if(!o||!s)return JSON.stringify({error:"artifact write returned no id/url",response:i});let l={id:o,title:e,url:s,kind:n.kind||null,createdAt:i.createdAt||new Date().toISOString(),summary:typeof t?.summary=="string"&&t.summary.trim()?t.summary.trim():e};try{await b(o,l)}catch(d){return JSON.stringify({id:o,url:s,indexWarning:d.message})}return JSON.stringify({id:o,url:s})}case"artifact_update":{if(c>=p)return y("Publish budget already spent this turn.",[]);let e=typeof t?.id=="string"?t.id.trim():"";if(!e)return JSON.stringify({error:"id is required"});let a=w(t);if(a?.error)return JSON.stringify({error:a.error});let n=typeof t?.title=="string"?t.title.trim():"";if(!a&&!n)return JSON.stringify({error:"nothing to update \u2014 pass a new title and/or markdown|html"});let i={id:e};n&&(i.title=n),a&&(i[a.format]=a.content),typeof t?.kind=="string"&&t.kind.trim()&&(i.kind=t.kind.trim()),typeof t?.favicon=="string"&&t.favicon.trim()&&(i.favicon=t.favicon.trim());let o=await g(i,a?.format);if(o?.__rejected)return o.payload;let s=o?.url;if(!s)return JSON.stringify({error:"artifact update returned no url",response:o});let l=await C(e)||{},d={...l,id:e,url:s,title:n||l.title||"Untitled",kind:i.kind||l.kind||null,createdAt:l.createdAt||o.createdAt||new Date().toISOString(),updatedAt:o.updatedAt||new Date().toISOString()};typeof t?.summary=="string"&&t.summary.trim()?d.summary=t.summary.trim():d.summary||(d.summary=d.title);try{await b(e,d)}catch(T){return JSON.stringify({id:e,url:s,indexWarning:T.message})}return JSON.stringify({id:e,url:s})}case"artifact_get":{let e=typeof t?.id=="string"?t.id.trim():"";if(!e)return JSON.stringify({error:"id is required"});let a=await L(e);return JSON.stringify(a)}default:return JSON.stringify({error:`Unknown tool: ${r}`})}}catch(e){return JSON.stringify({error:e.message})}},tools:[{name:"artifact_publish",description:`Publish a NEW self-contained, shareable page (report/plan/table/dashboard/diagram/write-up) and get back a shareable URL. USE \`markdown\` \u2014 it is the default path and Zibby generates the entire document for you (doctype, head, CSS, dark mode, table styling); you supply only the content, so the page cannot come out malformed. Markdown supports ${u}; it does NOT support ${h}. Use \`html\` ONLY when the page needs a visual layout Markdown cannot express (a bar chart, a gauge, a custom grid, an SVG diagram) \u2014 on that path you author the whole document and every mistake ships verbatim. Never pass both. Every figure on the page must come from a tool result or this conversation \u2014 do not do arithmetic in prose and print the result, and use the same number everywhere it appears. The content MUST come from the current conversation or data you fetched this turn; if you are not sure what the page should be about, ASK instead of calling this tool, and never publish a demo/sample/placeholder or an account-overview page as a stand-in. On the html path keep all CSS/JS/images INLINE (inline <style>/<script>, data: URIs) and send real tags (never <escaped> markup) \u2014 the page is sandboxed on view with no network at all, so every external URL is dead. The content is VALIDATED before any URL exists: if it is broken you get the exact defects and line numbers back, you get ONE retry, and then the tool stops you. Returns { id, url }.`,input_schema:{type:"object",properties:{title:{type:"string",description:"The page title (also the browser tab title)."},markdown:{type:"string",description:`PREFERRED. The page content as Markdown \u2014 Zibby renders it into a styled, self-contained document, so you never author a skeleton. Supports ${u}. Does NOT support ${h}. Provide this OR html, never both.`},html:{type:"string",description:"The EXCEPTION path \u2014 only for a layout Markdown cannot express (bar chart, gauge, custom grid, SVG diagram). A self-contained HTML document or fragment, served VERBATIM: you own the doctype, head, CSS and every tag. All assets must be inline (<style>/<script>, data: URIs). Provide this OR markdown, never both."},kind:{type:"string",description:'Optional label for what this is, e.g. "report", "plan", "dashboard", "diagram". Stored in your index.'},favicon:{type:"string",description:'Optional emoji used as the browser-tab icon, e.g. "\u{1F4CA}".'},summary:{type:"string",description:"Optional one-line summary for your own index (defaults to the title). Helps you recall later what this page was."}},required:["title"]}},{name:"artifact_update",description:"Revise an EXISTING artifact by id \u2014 the shareable URL stays the same, the content is replaced (new version). Pass the fields to change (title and/or markdown|html). Prefer `markdown` for the same reason artifact_publish does: Zibby generates the document, so it cannot come out malformed. An update is validated exactly like a publish \u2014 if the new content is broken it is REFUSED and the page keeps its last good version. Returns { id, url }.",input_schema:{type:"object",properties:{id:{type:"string",description:'The id of the artifact to update (from a prior artifact_publish, or your kv-memory "artifact:" index).'},title:{type:"string",description:"New title (optional)."},markdown:{type:"string",description:`PREFERRED. New Markdown content (optional) \u2014 Zibby renders the document skeleton. Supports ${u}. Provide this OR html.`},html:{type:"string",description:"New HTML content (optional), served verbatim \u2014 only for layouts Markdown cannot express. Provide this OR markdown."},kind:{type:"string",description:"Optional updated kind label."},favicon:{type:"string",description:"Optional updated emoji favicon."},summary:{type:"string",description:"Optional updated one-line index summary."}},required:["id"]}},{name:"artifact_get",description:'Fetch ONE artifact you published, by id \u2192 { metadata, content }. Use to reuse / edit / re-publish a page. To LIST what you have published, use your kv-memory tool kv_recall_prefix with keyPrefix "artifact:".',input_schema:{type:"object",properties:{id:{type:"string",description:"The artifact id."}},required:["id"]}}]};export{j as __resetPublishBudget,H as artifactSkill};
|