@zibby/skills 0.1.41 → 0.1.43

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.
@@ -1,4 +1,4 @@
1
- export namespace reviewMemorySkill {
1
+ export namespace kvMemorySkill {
2
2
  let id: string;
3
3
  let serverName: string;
4
4
  let allowedTools: string[];
@@ -26,18 +26,13 @@ export namespace reviewMemorySkill {
26
26
  input_schema: {
27
27
  type: string;
28
28
  properties: {
29
- scope: {
29
+ key: {
30
30
  type: string;
31
31
  description: string;
32
32
  };
33
- query: {
34
- type: string;
35
- description: string;
36
- };
37
- scopePrefix?: undefined;
33
+ keyPrefix?: undefined;
38
34
  content?: undefined;
39
35
  metadata?: undefined;
40
- headSha?: undefined;
41
36
  };
42
37
  required: string[];
43
38
  };
@@ -47,15 +42,13 @@ export namespace reviewMemorySkill {
47
42
  input_schema: {
48
43
  type: string;
49
44
  properties: {
50
- scopePrefix: {
45
+ keyPrefix: {
51
46
  type: string;
52
47
  description: string;
53
48
  };
54
- scope?: undefined;
55
- query?: undefined;
49
+ key?: undefined;
56
50
  content?: undefined;
57
51
  metadata?: undefined;
58
- headSha?: undefined;
59
52
  };
60
53
  required: string[];
61
54
  };
@@ -65,7 +58,7 @@ export namespace reviewMemorySkill {
65
58
  input_schema: {
66
59
  type: string;
67
60
  properties: {
68
- scope: {
61
+ key: {
69
62
  type: string;
70
63
  description: string;
71
64
  };
@@ -77,12 +70,7 @@ export namespace reviewMemorySkill {
77
70
  type: string;
78
71
  description: string;
79
72
  };
80
- headSha: {
81
- type: string;
82
- description: string;
83
- };
84
- query?: undefined;
85
- scopePrefix?: undefined;
73
+ keyPrefix?: undefined;
86
74
  };
87
75
  required: string[];
88
76
  };
@@ -0,0 +1,16 @@
1
+ import{existsSync as a,readFileSync as p}from"node:fs";import{homedir as l}from"node:os";import{join as y,dirname as u,resolve as d}from"node:path";import{fileURLToPath as m}from"node:url";function f(){if(process.env.MCP_SKILL_PATH)return process.env.MCP_SKILL_PATH;let r=u(m(import.meta.url)),e=d(r,"..","bin","mcp-skill.mjs");return a(e)?e:null}function k(){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=y(l(),".zibby","config.json");return a(r)&&JSON.parse(p(r,"utf-8")).sessionToken||null}catch{return null}}function _(){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 v(){return(typeof process.env.WORKFLOW_TYPE=="string"?process.env.WORKFLOW_TYPE.trim():"")||"agent"}function s(r){return`${v()}:${r}`}async function i(r,e){let t=k();if(!t)throw new Error("No backend credential (PROJECT_API_TOKEN). KV memory is only available inside a Zibby run.");let n=`${_()}/credits/review-memory`,o=await fetch(n,{method:"POST",headers:{Authorization:`Bearer ${t}`,"Content-Type":"application/json"},body:JSON.stringify({op:r,...e})});if(!o.ok){let c=await o.text().catch(()=>"");throw new Error(`KV memory ${r} failed (${o.status}): ${c.slice(0,300)}`)}return o.json()}var T={id:"kv-memory",serverName:"kv_memory",allowedTools:["mcp__kv_memory__*"],description:"KV memory \u2014 a private, per-agent persistent key\u2192value store across stateless runs (auto-namespaced)",promptFragment:`## KV Memory (private, per-agent, persistent key-value store)
2
+ You have a PRIVATE per-agent key-value memory that survives across your
3
+ stateless runs. It is automatically namespaced to YOU (this agent type) \u2014 other
4
+ agents cannot see or collide with your entries, and you don't need to prefix
5
+ anything. Just use plain keys.
6
+
7
+ Tools:
8
+ - kv_recall: Recall the value stored under a plain \`key\` (exact match).
9
+ Use at the START of a run to pick up what a prior run of yours recorded.
10
+ - kv_recall_prefix: List entries whose plain \`keyPrefix\` matches
11
+ (e.g. "seen#" to list everything you've marked seen). Capped at 25.
12
+ - kv_store: Store (overwrite) a concise value under a plain \`key\`.
13
+ Use to record durable facts \u2014 e.g. dedup markers, prior decisions, summaries.
14
+
15
+ Your namespace is added for you automatically; pass plain keys like
16
+ "seen#owner/repo#42" or "lastRun".`,resolve(){let r=f();if(!r)return{command:null,args:[],env:{},description:this.description};let e={};for(let t of["PROJECT_API_TOKEN","ZIBBY_ACCOUNT_API_URL","ZIBBY_ENV","ZIBBY_PROD_ACCOUNT_API_URL","ZIBBY_USER_TOKEN","WORKFLOW_TYPE"])process.env[t]&&(e[t]=process.env[t]);return{type:"stdio",command:"node",args:[r,"../dist/kvMemory.js","kvMemorySkill"],env:e,description:this.description,alwaysLoad:!0}},async handleToolCall(r,e){try{switch(r){case"kv_recall":{let t=typeof e?.key=="string"?e.key.trim():"";if(!t)return JSON.stringify({error:"key is required"});let n=await i("recall",{scope:s(t)});return JSON.stringify(n)}case"kv_recall_prefix":{let t=typeof e?.keyPrefix=="string"?e.keyPrefix.trim():"";if(!t)return JSON.stringify({error:"keyPrefix is required"});let n=await i("recall-prefix",{scopePrefix:s(t)});return JSON.stringify(n)}case"kv_store":{let t=typeof e?.key=="string"?e.key.trim():"";if(!t)return JSON.stringify({error:"key is required"});if(typeof e?.content!="string"||e.content.length===0)return JSON.stringify({error:"content is required (non-empty string)"});let n={scope:s(t),content:e.content};e.metadata!=null&&(n.metadata=e.metadata);let o=await i("store",n);return JSON.stringify(o)}default:return JSON.stringify({error:`Unknown tool: ${r}`})}}catch(t){return JSON.stringify({error:t.message})}},tools:[{name:"kv_recall",description:'Recall the value you stored under a plain key (exact match). Your per-agent namespace is added automatically \u2014 pass a plain key like "seen#owner/repo#42".',input_schema:{type:"object",properties:{key:{type:"string",description:'Plain storage key (no namespace prefix needed) \u2014 e.g. "seen#owner/repo#42" or "lastRun".'}},required:["key"]}},{name:"kv_recall_prefix",description:'List your entries whose plain key STARTS WITH a prefix (e.g. "seen#"). Your per-agent namespace is added automatically. Capped at 25.',input_schema:{type:"object",properties:{keyPrefix:{type:"string",description:'Plain key prefix to match (no namespace prefix needed) \u2014 e.g. "seen#".'}},required:["keyPrefix"]}},{name:"kv_store",description:"Store (overwrite) a value under a plain key so a later run of yours can recall it. Your per-agent namespace is added automatically.",input_schema:{type:"object",properties:{key:{type:"string",description:"Plain storage key (no namespace prefix needed). Same key you recall by."},content:{type:"string",description:"The value to persist. Free-form markdown/text."},metadata:{type:"object",description:"Optional structured metadata."}},required:["key","content"]}}]};export{T as kvMemorySkill};
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zibby/skills",
3
- "version": "0.1.41",
3
+ "version": "0.1.43",
4
4
  "description": "Built-in skill definitions for the Zibby agent-workflow framework",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -0,0 +1,79 @@
1
+ ---
2
+ sidebar_position: 6
3
+ title: Editing node prompts
4
+ ---
5
+
6
+ # Editing node prompts
7
+
8
+ Every node in an agent has a **prompt** — the instructions handed to the
9
+ coding agent when that step runs. In the graph editor (both the deploy modal
10
+ and a deployed agent's **Overview** tab) each prompt is tagged with a badge:
11
+
12
+ | Badge | What it means |
13
+ |---|---|
14
+ | <span style={{color:'#34d399',fontWeight:600}}>EDITABLE</span> | The prompt is a stored text template. You can change it right here. |
15
+ | <span style={{color:'#d4b483',fontWeight:600}}>READ-ONLY</span> | The prompt is generated by the node's code at runtime. It can't be edited in the UI. |
16
+
17
+ The `!` next to the badge explains the same thing on hover.
18
+
19
+ ## Editable prompts
20
+
21
+ A prompt is editable when the node declares it as a plain text template (a
22
+ string, optionally with `{{variables}}`).
23
+
24
+ The graph shown in the marketplace **deploy modal is a read-only preview** —
25
+ you pick the name and model there, not edit prompts. You edit editable
26
+ prompts **after you deploy**:
27
+
28
+ - Open the deployed agent's **Overview** tab.
29
+ - Click the node, edit the prompt, and save.
30
+ - The change applies to the next run **live — no redeploy needed**.
31
+
32
+ This is the right choice when you want non-developers to tune wording,
33
+ tone, or rules without touching code.
34
+
35
+ ## Read-only prompts
36
+
37
+ A prompt is read-only when the node builds it **in code** — a function that
38
+ assembles the text from state, fetched context, or conditionals at runtime.
39
+ There's no fixed string to edit, so the editor shows a rendered preview only.
40
+
41
+ To change a read-only prompt you edit the agent's source and redeploy. You
42
+ don't need to leave your AI coding agent to do it — the
43
+ [Zibby MCP](../packages/mcp-cli) drives the whole loop from chat:
44
+
45
+ 1. **Download the agent** — pull the deployed sources back to your machine.
46
+
47
+ ```bash
48
+ zibby agent download <uuid>
49
+ ```
50
+
51
+ Or, from an MCP-aware agent (Claude Code / Cursor / Codex / Gemini),
52
+ ask it to call `zibby_download_agent`.
53
+
54
+ 2. **Edit the node's code** — open the node file under
55
+ `.zibby/workflows/<name>/nodes/` and change how the prompt is built. Your
56
+ coding agent can do this directly.
57
+
58
+ 3. **Redeploy to update** — ship the change back to the same agent.
59
+
60
+ ```bash
61
+ zibby agent deploy <name>
62
+ ```
63
+
64
+ Or have the agent call `zibby_deploy_agent`. The deployed agent updates in
65
+ place; its UUID and trigger config stay the same.
66
+
67
+ :::tip Want it editable instead?
68
+ If a prompt would be better tuned by non-developers, convert the node from a
69
+ function prompt to a **string template**. Once it's a stored template, the
70
+ badge flips to **Editable** and it gains live-update from Overview.
71
+ :::
72
+
73
+ ## Why the split exists
74
+
75
+ Function prompts exist for a reason: some nodes need to assemble instructions
76
+ from things only known at runtime — the linked ticket, the diff, prior
77
+ reviews, whether an integration is connected. A fixed text box can't express
78
+ that logic, so those nodes keep their prompt in code. Simpler, static prompts
79
+ stay as editable templates so anyone can adjust them.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zibby/skills",
3
- "version": "0.1.41",
3
+ "version": "0.1.43",
4
4
  "description": "Built-in skill definitions for the Zibby agent-workflow framework",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1,19 +0,0 @@
1
- import{existsSync as a,readFileSync as u,mkdirSync as w,writeFileSync as h,renameSync as y}from"node:fs";import{homedir as _}from"node:os";import{join as d,dirname as m,resolve as f}from"node:path";import{fileURLToPath as v}from"node:url";function S(){if(process.env.MCP_SKILL_PATH)return process.env.MCP_SKILL_PATH;let e=m(v(import.meta.url)),t=f(e,"..","bin","mcp-skill.mjs");return a(t)?t:null}function g(){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 e=d(_(),".zibby","config.json");return a(e)&&JSON.parse(u(e,"utf-8")).sessionToken||null}catch{return null}}function P(){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"}async function O(e,t){let r=g();if(!r)throw new Error("No backend credential (PROJECT_API_TOKEN). Review memory is only available inside a Zibby run.");let o=`${P()}/credits/review-memory`,n=await fetch(o,{method:"POST",headers:{Authorization:`Bearer ${r}`,"Content-Type":"application/json"},body:JSON.stringify({op:e,...t})});if(!n.ok){let s=await n.text().catch(()=>"");throw new Error(`Review memory ${e} failed (${n.status}): ${s.slice(0,300)}`)}return n.json()}function R(){let e=process.env.ZIBBY_SELF_HOST;return e!=null&&e!==""&&e!=="0"&&e.toLowerCase()!=="false"}function A(){if(!R()||(process.env.ZIBBY_REVIEW_MEMORY_BACKEND||"").trim().toLowerCase()==="none")return null;let t=process.env.ZIBBY_REVIEW_MEMORY_PATH,r=t&&t.trim()?t.trim():d(".zibby","review-memory.json");return f(process.cwd(),r)}function i(e){try{if(!a(e))return{};let t=u(e,"utf-8");if(!t.trim())return{};let r=JSON.parse(t);return r&&typeof r=="object"&&!Array.isArray(r)?r:{}}catch{return{}}}function b(e,t){let r=m(e);w(r,{recursive:!0});let o=`${e}.tmp-${process.pid}-${Date.now()}`;h(o,`${JSON.stringify(t,null,2)}
2
- `,"utf-8"),y(o,e)}function l(e){return!e||typeof e!="object"?null:{scope:e.scope,content:e.content,metadata:e.metadata||null,headSha:e.headSha||null,createdAt:e.createdAt||null,updatedAt:e.updatedAt||null}}function T(e,t,r){if(t==="store"){let o=i(e),n=new Date().toISOString(),s=o[r.scope],p={scope:r.scope,content:r.content,metadata:r.metadata!=null?r.metadata:void 0,headSha:r.headSha!=null?r.headSha:void 0,createdAt:s&&s.createdAt||n,updatedAt:n};return o[r.scope]=p,b(e,o),{stored:!0,scope:r.scope,headSha:p.headSha||null,updatedAt:n}}if(t==="recall"){let n=i(e)[r.scope];return n?{found:!0,memory:l(n)}:{found:!1,memory:null}}if(t==="recall-prefix"){let o=i(e),n=Object.values(o).filter(s=>s&&typeof s.scope=="string"&&s.scope.startsWith(r.scopePrefix)).map(l).slice(0,25);return{count:n.length,truncated:!1,memories:n}}return{error:`Unknown op: ${t}`}}async function c(e,t){let r=A();return r?T(r,e,t):O(e,t)}var k={id:"review-memory",serverName:"review_memory",allowedTools:["mcp__review_memory__*"],description:"Review memory \u2014 persist & recall per-PR (configurable-scope) review notes across stateless runs",promptFragment:`## Review Memory (per-PR, configurable scope)
3
- Persist what you pulled, found, and reasoned during a review so a FOLLOW-UP
4
- run (a fresh stateless task replying on the same PR) can recall it. Storage is
5
- keyed by a \`scope\` STRING you choose \u2014 nothing is hardcoded to per-PR:
6
- - per-PR: scope = "review:owner/repo#<prNumber>" (the usual choice)
7
- - per-repo: scope = "repo:owner/repo"
8
- - per-org: scope = "org:owner"
9
- Same tools, different scope string \u2014 pick the granularity you need.
10
-
11
- Tools:
12
- - review_memory_recall: At the START of a review, recall any prior note for
13
- this PR's scope (e.g. "review:owner/repo#42"). If found, build on it instead
14
- of re-deriving everything.
15
- - review_memory_recall_prefix: List notes whose scope starts with a prefix
16
- (e.g. "review:owner/repo#") \u2014 e.g. to see prior reviews across a repo.
17
- - review_memory_store: At the END (or when you learn something durable), store
18
- a concise note under the PR's scope. Pass headSha so a later run knows which
19
- commit the note describes. Overwrites the prior note for that exact scope.`,resolve(){let e=S();if(!e)return{command:null,args:[],env:{},description:this.description};let t={};for(let r of["PROJECT_API_TOKEN","ZIBBY_ACCOUNT_API_URL","ZIBBY_ENV","ZIBBY_PROD_ACCOUNT_API_URL","ZIBBY_USER_TOKEN","ZIBBY_SELF_HOST","ZIBBY_REVIEW_MEMORY_BACKEND","ZIBBY_REVIEW_MEMORY_PATH"])process.env[r]&&(t[r]=process.env[r]);return{type:"stdio",command:"node",args:[e,"../dist/reviewMemory.js","reviewMemorySkill"],env:t,description:this.description,alwaysLoad:!0}},async handleToolCall(e,t){try{switch(e){case"review_memory_recall":{let r=typeof t?.scope=="string"?t.scope.trim():"";if(!r)return JSON.stringify({error:"scope is required"});let o=await c("recall",{scope:r});return JSON.stringify(o)}case"review_memory_recall_prefix":{let r=typeof t?.scopePrefix=="string"?t.scopePrefix.trim():"";if(!r)return JSON.stringify({error:"scopePrefix is required"});let o=await c("recall-prefix",{scopePrefix:r});return JSON.stringify(o)}case"review_memory_store":{let r=typeof t?.scope=="string"?t.scope.trim():"";if(!r)return JSON.stringify({error:"scope is required"});if(typeof t?.content!="string"||t.content.length===0)return JSON.stringify({error:"content is required (non-empty string)"});let o={scope:r,content:t.content};t.metadata!=null&&(o.metadata=t.metadata),t.headSha!=null&&(o.headSha=String(t.headSha));let n=await c("store",o);return JSON.stringify(n)}default:return JSON.stringify({error:`Unknown tool: ${e}`})}}catch(r){return JSON.stringify({error:r.message})}},tools:[{name:"review_memory_recall",description:'Recall the prior review note for a scope (exact match). Use at the start of a review to build on what an earlier run pulled/found/reasoned. scope is the storage key \u2014 e.g. "review:owner/repo#42" for per-PR.',input_schema:{type:"object",properties:{scope:{type:"string",description:'Storage key. Per-PR: "review:owner/repo#<prNumber>". Per-repo: "repo:owner/repo". Per-org: "org:owner". Or any custom string.'},query:{type:"string",description:"Optional free-text hint (reserved for future semantic recall; v1 ignores it \u2014 recall is exact-scope)."}},required:["scope"]}},{name:"review_memory_recall_prefix",description:'List review notes whose scope STARTS WITH a prefix (e.g. "review:owner/repo#" to see all prior PR reviews in a repo). Capped at 25 most-relevant.',input_schema:{type:"object",properties:{scopePrefix:{type:"string",description:'Scope prefix to match, e.g. "review:owner/repo#" or "repo:owner/".'}},required:["scopePrefix"]}},{name:"review_memory_store",description:"Store (overwrite) the review note for a scope so a follow-up run can recall it. Write a concise summary of what you pulled, found, and reasoned. Pass headSha so a later run knows which commit the note describes.",input_schema:{type:"object",properties:{scope:{type:"string",description:'Storage key. Per-PR: "review:owner/repo#<prNumber>". Or per-repo/per-org/custom. Same key you recall by.'},content:{type:"string",description:"The note: what was pulled, what was found, the reasoning. Free-form markdown/text."},metadata:{type:"object",description:"Optional structured metadata (e.g. {filesReviewed, verdict, severity})."},headSha:{type:"string",description:"Optional PR head commit SHA this note describes \u2014 lets a later run detect new commits."}},required:["scope","content"]}}]};export{k as reviewMemorySkill};