@synadia-ai/agent-fabric-claude-code 0.1.0 → 0.3.0
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/.claude-plugin/plugin.json +4 -4
- package/.mcp.json +14 -0
- package/BUILD +4 -0
- package/LICENSE +18 -17
- package/README.md +54 -441
- package/hooks/hooks.json +53 -0
- package/hooks/session-event.js +14 -0
- package/package.json +23 -72
- package/runtime/chunk-5ke4ws7r.js +38 -0
- package/runtime/fabric.js +7 -0
- package/runtime/server.js +66 -0
- package/skills/configure/SKILL.md +190 -0
- package/skills/configure/list-contexts.sh +22 -0
- package/skills/scratchpad/SKILL.md +87 -6
- package/skills/scratchpad/scripts/sp +13 -7
- package/CHANGELOG.md +0 -18
- package/dist/index.cjs +0 -277
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.cts +0 -63
- package/dist/index.d.ts +0 -63
- package/dist/index.js +0 -248
- package/dist/index.js.map +0 -1
package/hooks/hooks.json
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"hooks": {
|
|
3
3
|
"SessionStart": [
|
|
4
|
+
{
|
|
5
|
+
"hooks": [
|
|
6
|
+
{
|
|
7
|
+
"type": "command",
|
|
8
|
+
"command": "bun \"${CLAUDE_PLUGIN_ROOT}/hooks/session-event.js\"",
|
|
9
|
+
"timeout": 10
|
|
10
|
+
}
|
|
11
|
+
]
|
|
12
|
+
},
|
|
4
13
|
{
|
|
5
14
|
"hooks": [
|
|
6
15
|
{
|
|
@@ -10,6 +19,50 @@
|
|
|
10
19
|
}
|
|
11
20
|
]
|
|
12
21
|
}
|
|
22
|
+
],
|
|
23
|
+
"Stop": [
|
|
24
|
+
{
|
|
25
|
+
"hooks": [
|
|
26
|
+
{
|
|
27
|
+
"type": "command",
|
|
28
|
+
"command": "bun \"${CLAUDE_PLUGIN_ROOT}/hooks/session-event.js\"",
|
|
29
|
+
"timeout": 10
|
|
30
|
+
}
|
|
31
|
+
]
|
|
32
|
+
}
|
|
33
|
+
],
|
|
34
|
+
"UserPromptSubmit": [
|
|
35
|
+
{
|
|
36
|
+
"hooks": [
|
|
37
|
+
{
|
|
38
|
+
"type": "command",
|
|
39
|
+
"command": "bun \"${CLAUDE_PLUGIN_ROOT}/hooks/session-event.js\"",
|
|
40
|
+
"timeout": 10
|
|
41
|
+
}
|
|
42
|
+
]
|
|
43
|
+
}
|
|
44
|
+
],
|
|
45
|
+
"StopFailure": [
|
|
46
|
+
{
|
|
47
|
+
"hooks": [
|
|
48
|
+
{
|
|
49
|
+
"type": "command",
|
|
50
|
+
"command": "bun \"${CLAUDE_PLUGIN_ROOT}/hooks/session-event.js\"",
|
|
51
|
+
"timeout": 10
|
|
52
|
+
}
|
|
53
|
+
]
|
|
54
|
+
}
|
|
55
|
+
],
|
|
56
|
+
"PreToolUse": [
|
|
57
|
+
{
|
|
58
|
+
"hooks": [
|
|
59
|
+
{
|
|
60
|
+
"type": "command",
|
|
61
|
+
"command": "bun \"${CLAUDE_PLUGIN_ROOT}/hooks/session-event.js\"",
|
|
62
|
+
"timeout": 10
|
|
63
|
+
}
|
|
64
|
+
]
|
|
65
|
+
}
|
|
13
66
|
]
|
|
14
67
|
}
|
|
15
68
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
// @bun
|
|
3
|
+
import{writeSync as _n}from"fs";import{homedir as yn}from"os";import{join as bn}from"path";import{appendFileSync as Z,existsSync as hn,mkdirSync as y,readdirSync as kn,readFileSync as A,renameSync as z,rmSync as B,writeFileSync as G}from"fs";import{join as a}from"path";var X=/^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/,W=/^[A-Za-z0-9][A-Za-z0-9_-]{0,127}$/,Q=["discover_agents","prompt_agent","wait_agent","answer_agent","cancel_agent","list_agent_calls"];function l(n){return typeof n==="string"&&X.test(n)}function K(n){return typeof n==="string"&&W.test(n)}function f(n){return a(n,"sessions")}function V(n,t){return a(f(n),String(t))}function w(n,t){return a(f(n),`${t}.stop`)}function E(n,t){return a(f(n),`${t}.nudge`)}function M(n,t){return a(f(n),`${t}.turn`)}function Y(n,t){return a(f(n),`${t}.open`)}function nn(n,t){return a(f(n),`${t}.tools`)}function T(n,t){return a(f(n),`${t}.events`)}function I(n,t){let e=`${n}.${process.pid}.tmp`;G(e,t),z(e,n)}var en=new RegExp(`^mcp__.+__(${Q.join("|")})$`);function tn(n){return en.test(n)}function q(n){if(!("background_tasks"in n)&&!("session_crons"in n))return;return N(n.background_tasks)||N(n.session_crons)}function N(n){if(n===void 0||n===null||n===!1||n===0||n==="")return!1;if(Array.isArray(n))return n.length>0;if(typeof n==="object")return Object.keys(n).length>0;return!0}var P=/^plugin:[^"]+:nats$/,v=/^[A-Za-z0-9_-]{1,64}$/,rn=1024,sn=/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{1,3})?Z$/,J=64,U=200;function on(n){if(typeof n!=="string"||!n.startsWith("<channel "))return;let t=n.indexOf(">");if(t<0||t>rn)return;let e=n.slice(0,t),r=/\ssource="([^"]*)"/.exec(e)?.[1],o=/\srequest_id="([^"]*)"/.exec(e)?.[1];if(r===void 0||o===void 0)return;if(!P.test(r)||!v.test(o))return;let s=/\sts="([^"]*)"/.exec(e)?.[1];return{requestId:o,source:r,...s!==void 0&&j(s)!==void 0?{ts:s}:{}}}function j(n){if(typeof n!=="string"||!sn.test(n))return;let t=Date.parse(n);return Number.isFinite(t)?t:void 0}function k(n,t){if(typeof n!=="string")return;let e=Array.from(n.replace(/[\u0000-\u001f\u007f]+/g," ").trim()).slice(0,t).join("");return e.length>0?e:void 0}function R(n,t,e){y(f(n),{recursive:!0}),Z(T(n,t),`${JSON.stringify(e)}
|
|
4
|
+
`)}function F(n,t,e,r=Date.now()){let o=e.hook_event_name,s=l(e.session_id)?e.session_id:void 0,i=l(e.prompt_id)?e.prompt_id:void 0;if(o==="UserPromptSubmit"){let d=on(e.prompt);return R(n,t,{event:"submit",...s?{session_id:s}:{},...i?{prompt_id:i}:{},...d?{request_id:d.requestId,source:d.source}:{},...d?.ts!==void 0?{ts:d.ts}:{},at_ms:r}),"submit"}if(o==="StopFailure"){let d=k(e.error,J),u=k(e.error_details,U);return R(n,t,{event:"failure",...s?{session_id:s}:{},...i?{prompt_id:i}:{},...d!==void 0?{error:d}:{},...u!==void 0?{error_details:u}:{},at_ms:r}),"failure"}if(o==="SessionStart"){if(s===void 0)return;let d=typeof e.source==="string"?e.source:"unknown";return y(f(n),{recursive:!0}),I(V(n,t),`${JSON.stringify({session_id:s,source:d,at_ms:r})}
|
|
5
|
+
`),"session"}if(o==="Stop"){let d=q(e),u=D(n,t,e),c=u===void 0||u.length>0?un(n,t)??H(e):void 0,m={...s?{session_id:s}:{},...d!==void 0?{background:d}:{},...c!==void 0?{final_text:c}:{},at_ms:r};return y(f(n),{recursive:!0}),I(w(n,t),`${JSON.stringify(m)}
|
|
6
|
+
`),R(n,t,{event:"stop",...i?{prompt_id:i}:{},...m}),ln(E(n,t)),"stop"}if(o==="PreToolUse"){let{tool_use_id:d,tool_name:u}=e;if(typeof u!=="string"||u.length===0)return;if(y(f(n),{recursive:!0}),dn(n,t,e.prompt_id,r),!tn(u)||!K(d))return"turn";let c=nn(n,t);return y(c,{recursive:!0}),I(a(c,d),`${JSON.stringify({tool_use_id:d,tool_name:u,tool_input:e.tool_input??null,...i?{prompt_id:i}:{},at_ms:r})}
|
|
7
|
+
`),"tool"}return}function dn(n,t,e,r){let o=l(e)?e:void 0,s=x(M(n,t)),i=g(s?.at_ms),d=g(s?.first_ms),u=g(x(w(n,t))?.at_ms),c=s!==void 0&&s.prompt_id===o&&i!==void 0&&d!==void 0&&(u===void 0||i>u);I(M(n,t),`${JSON.stringify({...o!==void 0?{prompt_id:o}:{},first_ms:c?d:r,at_ms:r})}
|
|
8
|
+
`)}function L(n,t,e){if(e.hook_event_name!=="Stop"||e.stop_hook_active===!0)return;if(q(e)!==!1)return;let r=D(n,t,e);if(r===void 0||r.length===0)return;let o=r.map((s)=>`"${s}"`).join(", ");return`The NATS channel ${r.length===1?"request":"requests"} ${o} ${r.length===1?"is":"are"} still open: the sender has not received an answer, and cannot see this session's own output. Send your answer with the reply tool (load it with ToolSearch if it is deferred), with the request_id and done: true.`}function C(n,t,e,r=Date.now()){let o=H(e);y(f(n),{recursive:!0}),I(E(n,t),`${JSON.stringify({...o!==void 0?{final_text:o}:{},at_ms:r})}
|
|
9
|
+
`)}function un(n,t){let e=x(E(n,t)),r=g(e?.at_ms);if(e===void 0||r===void 0)return;let o=g(x(w(n,t))?.at_ms);if(o!==void 0&&r<=o)return;let s=e.final_text;return typeof s==="string"&&s.length>0?s:void 0}function cn(n,t){let e=x(Y(n,t));if(!e)return;let r=e.server_pid,o=O(e.request_ids),s=e.open_ids===void 0?o:O(e.open_ids);if(typeof r!=="number"||!Number.isSafeInteger(r)||r<=0)return;if(o===void 0||s===void 0)return;if(!mn(r))return;let i=g(e.since_ms);return{requestIds:o,openIds:s,...i!==void 0?{sinceMs:i}:{}}}function O(n){return Array.isArray(n)&&n.every((t)=>typeof t==="string"&&v.test(t))?n:void 0}function D(n,t,e){let r=cn(n,t);if(r===void 0)return;let o=l(e.prompt_id)?e.prompt_id:void 0;if(o===void 0)return r.requestIds;let s=gn(n,t);if(!s.some((u)=>u.kind==="submit"&&u.submit.promptId!==void 0))return r.requestIds;let i=new Map,d;for(let u of s){if(u.kind!=="submit"||u.submit.requestId===void 0){d=void 0;continue}let{requestId:c,promptId:m,atMs:b,sentAtMs:_}=u.submit,S=d!==void 0&&b-d.atMs<=fn?d.promptIds:new Set;S.add(m);let p=r.sinceMs;if(p===void 0||b>=p&&(_??p)>=p)i.set(c,S);d={atMs:b,promptIds:S}}return r.openIds.filter((u)=>i.get(u)?.has(o)===!0)}var fn=30000;function H(n){if("last_assistant_message"in n){let i=n.last_assistant_message;return typeof i==="string"&&i.trim().length>0?i.trim():void 0}let t=n.transcript_path;if(typeof t!=="string"||t.length===0)return;let e;try{e=A(t,"utf8")}catch{return}let r,o=[];for(let i of e.split(`
|
|
10
|
+
`)){if(i.trim().length===0)continue;let d;try{d=JSON.parse(i)}catch{continue}if(typeof d!=="object"||d===null)continue;let{type:u,message:c,uuid:m}=d;if(u!=="assistant"||typeof c!=="object"||c===null)continue;let{id:b,content:_}=c,h=b??m;if(h===void 0||h!==r)r=h,o=[];if(typeof _==="string")o.push(_);else if(Array.isArray(_))for(let S of _){let p=S;if(p?.type==="text"&&typeof p.text==="string")o.push(p.text)}}let s=o.join(`
|
|
11
|
+
`).trim();return s.length>0?s:void 0}function x(n){let t;try{t=A(n,"utf8")}catch{return}try{let e=JSON.parse(t);return typeof e==="object"&&e!==null&&!Array.isArray(e)?e:void 0}catch{return}}function g(n){return typeof n==="number"&&Number.isSafeInteger(n)&&n>=0?n:void 0}function an(n){if(!n)return;let t=g(n.at_ms);if(t===void 0)return;return{...l(n.session_id)?{sessionId:n.session_id}:{},...l(n.prompt_id)?{promptId:n.prompt_id}:{},...typeof n.background==="boolean"?{background:n.background}:{},...typeof n.final_text==="string"&&n.final_text.length>0?{finalText:n.final_text}:{},atMs:t}}function pn(n){let t;try{t=JSON.parse(n)}catch{return}if(typeof t!=="object"||t===null||Array.isArray(t))return;let e=t,r=g(e.at_ms);if(r===void 0)return;let o={...l(e.session_id)?{sessionId:e.session_id}:{},...l(e.prompt_id)?{promptId:e.prompt_id}:{}};switch(e.event){case"submit":{let s=typeof e.request_id==="string"&&v.test(e.request_id)&&typeof e.source==="string"&&P.test(e.source)?{requestId:e.request_id,source:e.source}:{},i=s.requestId!==void 0?j(e.ts):void 0;return{kind:"submit",submit:{...o,...s,...i!==void 0?{sentAtMs:i}:{},atMs:r}}}case"stop":{let s=an(e);return s?{kind:"stop",stop:s}:void 0}case"failure":{let s=k(e.error,J),i=k(e.error_details,U);return{kind:"failure",failure:{...o,...s!==void 0?{error:s}:{},...i!==void 0?{errorDetails:i}:{},atMs:r}}}default:return}}function gn(n,t){let e;try{e=A(T(n,t),"utf8")}catch{return[]}let r=[],o=e.lastIndexOf(`
|
|
12
|
+
`);for(let s of e.slice(0,o+1).split(`
|
|
13
|
+
`)){if(s.length===0)continue;let i=pn(s);if(i)r.push(i)}return r}function ln(n){try{B(n,{recursive:!0,force:!0})}catch{}}function mn(n){try{return process.kill(n,0),!0}catch(t){return t.code==="EPERM"}}var Sn=5000;setTimeout(()=>process.exit(0),Sn).unref();async function In(){let n=[];for await(let t of process.stdin)n.push(Buffer.from(t));return Buffer.concat(n).toString("utf8")}try{let n=process.env.CLAUDE_PID;if(n!==void 0&&/^\d+$/.test(n)){let t=JSON.parse(await In());if(typeof t==="object"&&t!==null&&!Array.isArray(t)){let e=process.env.NATS_STATE_DIR??bn(yn(),".claude","channels","nats"),r=t,o=L(e,n,r);if(o!==void 0){try{C(e,n,r)}catch{}_n(1,`${JSON.stringify({decision:"block",reason:o})}
|
|
14
|
+
`)}else F(e,n,r)}}}catch{}process.exit(0);
|
package/package.json
CHANGED
|
@@ -1,58 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@synadia-ai/agent-fabric-claude-code",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
5
|
-
"type": "module",
|
|
6
|
-
"main": "./dist/index.cjs",
|
|
7
|
-
"module": "./dist/index.js",
|
|
8
|
-
"types": "./dist/index.d.ts",
|
|
9
|
-
"exports": {
|
|
10
|
-
".": {
|
|
11
|
-
"types": "./dist/index.d.ts",
|
|
12
|
-
"import": "./dist/index.js",
|
|
13
|
-
"require": "./dist/index.cjs",
|
|
14
|
-
"default": "./dist/index.js"
|
|
15
|
-
},
|
|
16
|
-
"./package.json": "./package.json"
|
|
17
|
-
},
|
|
18
|
-
"files": [
|
|
19
|
-
"dist",
|
|
20
|
-
".claude-plugin",
|
|
21
|
-
"hooks",
|
|
22
|
-
"skills",
|
|
23
|
-
"README.md",
|
|
24
|
-
"CHANGELOG.md",
|
|
25
|
-
"LICENSE"
|
|
26
|
-
],
|
|
27
|
-
"sideEffects": false,
|
|
28
|
-
"engines": {
|
|
29
|
-
"node": ">=20.0.0"
|
|
30
|
-
},
|
|
31
|
-
"scripts": {
|
|
32
|
-
"build": "tsup",
|
|
33
|
-
"build:sp": "sh ../scratchpad-skill/install.sh --dest skills/scratchpad --allowed-tools 'Bash(${CLAUDE_SKILL_DIR}/scripts/sp *)'",
|
|
34
|
-
"typecheck": "tsc --noEmit",
|
|
35
|
-
"lint": "eslint .",
|
|
36
|
-
"lint:fix": "eslint . --fix",
|
|
37
|
-
"format": "prettier --write .",
|
|
38
|
-
"format:check": "prettier --check .",
|
|
39
|
-
"test": "vitest run",
|
|
40
|
-
"test:unit": "vitest run test/unit",
|
|
41
|
-
"test:integration": "vitest run test/integration",
|
|
42
|
-
"test:watch": "vitest",
|
|
43
|
-
"check": "npm run typecheck && npm run lint && npm run format:check && npm run test",
|
|
44
|
-
"prepack": "npm run build:sp",
|
|
45
|
-
"prepublishOnly": "npm run build"
|
|
46
|
-
},
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "Claude Code on the Synadia Agent Fabric: the NATS channel plugin for Claude Code with the fabric's tracing and ScratchPad, in one plugin",
|
|
47
5
|
"keywords": [
|
|
48
|
-
"nats",
|
|
49
|
-
"ai",
|
|
50
|
-
"agents",
|
|
51
|
-
"agent-fabric",
|
|
52
|
-
"tracing",
|
|
53
6
|
"claude-code",
|
|
54
|
-
"
|
|
55
|
-
"
|
|
7
|
+
"claude-code-plugin",
|
|
8
|
+
"nats",
|
|
9
|
+
"agent",
|
|
10
|
+
"channel",
|
|
11
|
+
"synadia-agent-protocol",
|
|
12
|
+
"synadia-agent-fabric"
|
|
56
13
|
],
|
|
57
14
|
"license": "Apache-2.0",
|
|
58
15
|
"author": "Synadia Communications",
|
|
@@ -61,29 +18,23 @@
|
|
|
61
18
|
"url": "git+https://github.com/synadia-ai/agent-fabric-sdk.git",
|
|
62
19
|
"directory": "plugins/claude-code"
|
|
63
20
|
},
|
|
64
|
-
"
|
|
65
|
-
"
|
|
66
|
-
|
|
21
|
+
"type": "module",
|
|
22
|
+
"main": "./runtime/fabric.js",
|
|
23
|
+
"exports": {
|
|
24
|
+
".": "./runtime/fabric.js",
|
|
25
|
+
"./package.json": "./package.json"
|
|
67
26
|
},
|
|
27
|
+
"files": [
|
|
28
|
+
".claude-plugin",
|
|
29
|
+
".mcp.json",
|
|
30
|
+
"runtime",
|
|
31
|
+
"hooks",
|
|
32
|
+
"skills",
|
|
33
|
+
"BUILD",
|
|
34
|
+
"README.md",
|
|
35
|
+
"LICENSE"
|
|
36
|
+
],
|
|
68
37
|
"publishConfig": {
|
|
69
38
|
"access": "public"
|
|
70
|
-
},
|
|
71
|
-
"dependencies": {
|
|
72
|
-
"@synadia-ai/agent-fabric": "^0.1.0",
|
|
73
|
-
"@synadia-ai/agent-service": "^0.6.0",
|
|
74
|
-
"@synadia-ai/agents": "^0.6.0"
|
|
75
|
-
},
|
|
76
|
-
"devDependencies": {
|
|
77
|
-
"@nats-io/nats-core": "^3.4.0",
|
|
78
|
-
"@nats-io/transport-node": "^3.4.0",
|
|
79
|
-
"@types/node": "^20.16.0",
|
|
80
|
-
"ajv": "^8.17.0",
|
|
81
|
-
"eslint": "^9.0.0",
|
|
82
|
-
"eslint-config-prettier": "^9.1.0",
|
|
83
|
-
"prettier": "3.9.5",
|
|
84
|
-
"tsup": "^8.3.0",
|
|
85
|
-
"typescript": "~5.6.0",
|
|
86
|
-
"typescript-eslint": "^8.10.0",
|
|
87
|
-
"vitest": "^3.2.0"
|
|
88
39
|
}
|
|
89
40
|
}
|