shennian 0.3.21 → 0.3.22

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.
@@ -506,8 +506,8 @@
506
506
  },
507
507
  {
508
508
  "file": "src/room/room-action-schema.js",
509
- "beforeBytes": 6700,
510
- "afterBytes": 3171
509
+ "beforeBytes": 6434,
510
+ "afterBytes": 3065
511
511
  },
512
512
  {
513
513
  "file": "src/room/room-authorized-action-executor.js",
@@ -536,8 +536,8 @@
536
536
  },
537
537
  {
538
538
  "file": "src/room/tool-schema.js",
539
- "beforeBytes": 5149,
540
- "afterBytes": 3140
539
+ "beforeBytes": 5223,
540
+ "afterBytes": 3212
541
541
  },
542
542
  {
543
543
  "file": "src/room/tool-server.js",
@@ -1 +1 @@
1
- import{randomUUID as g}from"node:crypto";import{DaemonIpcError as u}from"../daemon-ipc/protocol.js";function D(t,n){const e=y(n);switch(t){case"room.status":return d(e,[]),{};case"room.read":{d(e,["afterSequence","limit","attachmentIds","query"]);const o=a(e.query,"query",200),i=e.afterSequence??"0",s=e.limit??50;(typeof i!="string"||!/^(0|[1-9]\d{0,19})$/.test(i))&&r("afterSequence"),(typeof s!="number"||!Number.isInteger(s)||s<1||s>100)&&r("limit");const m=p(e.attachmentIds,"attachmentIds",10);return o&&(e.afterSequence!=null||m)&&r("parameters"),o?{query:o,limit:s}:{afterSequence:i,limit:s,...m?{attachmentIds:m}:{}}}case"room.send":{d(e,["clientMessageId","text","files","mentionMembershipIds","replyToMessageId"]);const o=e.clientMessageId==null?`room-tool-${g()}`:c(e.clientMessageId,"clientMessageId",191),i=a(e.text,"text",2e4),s=h(e.files,"files",10);!i&&!s&&r("parameters");const m=p(e.mentionMembershipIds,"mentionMembershipIds",20),l=a(e.replyToMessageId,"replyToMessageId",191);return{clientMessageId:o,text:i??"",...s?{files:s}:{},...m?{mentionMembershipIds:m}:{},...l?{replyToMessageId:l}:{}}}case"room.mode":return d(e,["activationMode"]),{activationMode:f(e.activationMode)};case"room.create":return d(e,["name","agentAlias","agentDescription","activationMode"]),{name:c(e.name,"name",80),agentAlias:c(e.agentAlias,"agentAlias",80),...a(e.agentDescription,"agentDescription",1e3)?{agentDescription:a(e.agentDescription,"agentDescription",1e3)}:{},activationMode:f(e.activationMode??"auto_follow")};case"room.join":return d(e,["inviteUrl","agentAlias","agentDescription","message","activationMode"]),{inviteUrl:M(e.inviteUrl),agentAlias:c(e.agentAlias,"agentAlias",80),...a(e.agentDescription,"agentDescription",1e3)?{agentDescription:a(e.agentDescription,"agentDescription",1e3)}:{},activationMode:f(e.activationMode??"auto_follow"),...a(e.message,"message",500)?{message:a(e.message,"message",500)}:{}}}}function h(t,n,e){return t==null?void 0:((!Array.isArray(t)||t.length<1||t.length>e)&&r(n),t.map(i=>((typeof i!="string"||!i.trim()||i.length>4096||/[\0\r\n]/.test(i))&&r(n),i.trim())))}function y(t){return t==null?{}:((Array.isArray(t)||typeof t!="object")&&r("parameters"),t)}function d(t,n){const e=new Set(n);Object.keys(t).some(o=>!e.has(o))&&r("parameters")}function c(t,n,e){return(typeof t!="string"||!t.trim()||t.length>e||/[\0\r]/.test(t))&&r(n),t.trim()}function a(t,n,e){if(!(t==null||t===""))return c(t,n,e)}function p(t,n,e){if(t==null)return;(!Array.isArray(t)||t.length>e)&&r(n);const o=t.map(i=>c(i,n,191));return new Set(o).size!==o.length&&r(n),o.length>0?o:void 0}function f(t){if(t==="auto"||t==="auto_follow")return"auto_follow";if(t==="mention"||t==="mention_only")return"mention_only";if(t==="paused")return"paused";r("activationMode")}function M(t){const n=c(t,"inviteUrl",2048);let e;try{e=new URL(n)}catch{r("inviteUrl")}return(e.protocol!=="https:"||e.hostname!=="shennian.net"||!/^\/spaces\/join\/[A-Za-z0-9_-]{43}$/.test(e.pathname)||e.username||e.password||e.search||e.hash)&&r("inviteUrl"),e.toString()}function r(t){throw new u("invalid_params",`${t} is invalid.`)}export{D as normalizeRoomActionParameters};
1
+ import{randomUUID as g}from"node:crypto";import{DaemonIpcError as u}from"../daemon-ipc/protocol.js";function w(t,n){const e=y(n);switch(t){case"room.status":return m(e,[]),{};case"room.read":{m(e,["afterSequence","limit","attachmentIds","query"]);const o=d(e.query,"query",200),i=e.afterSequence??"0",s=e.limit??50;(typeof i!="string"||!/^(0|[1-9]\d{0,19})$/.test(i))&&r("afterSequence"),(typeof s!="number"||!Number.isInteger(s)||s<1||s>100)&&r("limit");const c=p(e.attachmentIds,"attachmentIds",10);return o&&(e.afterSequence!=null||c)&&r("parameters"),o?{query:o,limit:s}:{afterSequence:i,limit:s,...c?{attachmentIds:c}:{}}}case"room.send":{m(e,["clientMessageId","text","files","mentionMembershipIds","replyToMessageId"]);const o=e.clientMessageId==null?`room-tool-${g()}`:a(e.clientMessageId,"clientMessageId",191),i=d(e.text,"text",2e4),s=h(e.files,"files",10);!i&&!s&&r("parameters");const c=p(e.mentionMembershipIds,"mentionMembershipIds",20),l=d(e.replyToMessageId,"replyToMessageId",191);return{clientMessageId:o,text:i??"",...s?{files:s}:{},...c?{mentionMembershipIds:c}:{},...l?{replyToMessageId:l}:{}}}case"room.mode":return m(e,["activationMode"]),{activationMode:f(e.activationMode)};case"room.create":return m(e,["name","agentAlias","agentDescription","activationMode"]),{name:a(e.name,"name",80),agentAlias:a(e.agentAlias,"agentAlias",80),agentDescription:a(e.agentDescription,"agentDescription",1e3),activationMode:f(e.activationMode??"auto_follow")};case"room.join":return m(e,["inviteUrl","agentAlias","agentDescription","message","activationMode"]),{inviteUrl:M(e.inviteUrl),agentAlias:a(e.agentAlias,"agentAlias",80),agentDescription:a(e.agentDescription,"agentDescription",1e3),activationMode:f(e.activationMode??"auto_follow"),...d(e.message,"message",500)?{message:d(e.message,"message",500)}:{}}}}function h(t,n,e){return t==null?void 0:((!Array.isArray(t)||t.length<1||t.length>e)&&r(n),t.map(i=>((typeof i!="string"||!i.trim()||i.length>4096||/[\0\r\n]/.test(i))&&r(n),i.trim())))}function y(t){return t==null?{}:((Array.isArray(t)||typeof t!="object")&&r("parameters"),t)}function m(t,n){const e=new Set(n);Object.keys(t).some(o=>!e.has(o))&&r("parameters")}function a(t,n,e){return(typeof t!="string"||!t.trim()||t.length>e||/[\0\r]/.test(t))&&r(n),t.trim()}function d(t,n,e){if(!(t==null||t===""))return a(t,n,e)}function p(t,n,e){if(t==null)return;(!Array.isArray(t)||t.length>e)&&r(n);const o=t.map(i=>a(i,n,191));return new Set(o).size!==o.length&&r(n),o.length>0?o:void 0}function f(t){if(t==="auto"||t==="auto_follow")return"auto_follow";if(t==="mention"||t==="mention_only")return"mention_only";if(t==="paused")return"paused";r("activationMode")}function M(t){const n=a(t,"inviteUrl",2048);let e;try{e=new URL(n)}catch{r("inviteUrl")}return(e.protocol!=="https:"||e.hostname!=="shennian.net"||!/^\/spaces\/join\/[A-Za-z0-9_-]{43}$/.test(e.pathname)||e.username||e.password||e.search||e.hash)&&r("inviteUrl"),e.toString()}function r(t){throw new u("invalid_params",`${t} is invalid.`)}export{w as normalizeRoomActionParameters};
@@ -4,7 +4,7 @@ export declare const SHENNIAN_ROOM_TOOL_NAME = "shennian_room";
4
4
  export declare const SHENNIAN_ROOM_TOOL: {
5
5
  readonly name: "shennian_room";
6
6
  readonly title: "Shennian Room";
7
- readonly description: "Create, join, read, search, send to, configure, or inspect the single Shennian Room bound to this Agent session. Status includes member and Agent descriptions plus the canonical local JSONL mirror path.";
7
+ readonly description: "Create, join, read, search, send to, configure, or inspect the single Shennian Room bound to this Agent session. Creating or joining requires a non-empty Agent description. Status includes member and Agent descriptions plus the canonical local JSONL mirror path.";
8
8
  readonly inputSchema: {
9
9
  readonly type: "object";
10
10
  readonly additionalProperties: false;
@@ -27,6 +27,7 @@ export declare const SHENNIAN_ROOM_TOOL: {
27
27
  };
28
28
  readonly agentDescription: {
29
29
  readonly type: "string";
30
+ readonly minLength: 1;
30
31
  readonly maxLength: 1000;
31
32
  };
32
33
  readonly inviteUrl: {
@@ -1 +1 @@
1
- import{normalizeRoomActionParameters as c}from"./room-action-schema.js";const d="shennian_room",l={name:d,title:"Shennian Room",description:"Create, join, read, search, send to, configure, or inspect the single Shennian Room bound to this Agent session. Status includes member and Agent descriptions plus the canonical local JSONL mirror path.",inputSchema:{type:"object",additionalProperties:!1,required:["action"],properties:{action:{type:"string",enum:["create","join","read","send","mode","status"],description:"The Room action to perform."},name:{type:"string",minLength:1,maxLength:80},agentAlias:{type:"string",minLength:1,maxLength:80},agentDescription:{type:"string",maxLength:1e3},inviteUrl:{type:"string",format:"uri",maxLength:2048},message:{type:"string",maxLength:500},activationMode:{type:"string",enum:["auto","auto_follow","mention","mention_only","paused"]},afterSequence:{type:"string",pattern:"^(0|[1-9]\\d{0,19})$"},limit:{type:"integer",minimum:1,maximum:100},query:{type:"string",minLength:1,maxLength:200},attachmentIds:{type:"array",maxItems:10,uniqueItems:!0,items:{type:"string",minLength:1,maxLength:191}},clientMessageId:{type:"string",minLength:1,maxLength:191,description:"Optional idempotency key. Shennian generates one when omitted."},text:{type:"string",minLength:1,maxLength:2e4},files:{type:"array",description:"Up to 10 files inside the current Agent workspace to upload privately with this message.",minItems:1,maxItems:10,items:{type:"string",minLength:1,maxLength:4096}},mentionMembershipIds:{type:"array",maxItems:20,uniqueItems:!0,items:{type:"string",minLength:1,maxLength:191}},replyToMessageId:{type:"string",minLength:1,maxLength:191}}}},u=new Map([["create","room.create"],["join","room.join"],["read","room.read"],["send","room.send"],["mode","room.mode"],["status","room.status"]]);function f(i){(!i||typeof i!="object"||Array.isArray(i))&&g();const e=i,n=typeof e.action=="string"?u.get(e.action):void 0;n||g();const o=e._shennianRegistryKey,r=e._shennianInvocationToken,s=e._shennianAuthorizedActionId,a=Object.keys(e).filter(t=>t.startsWith("_shennian"));if(typeof s=="string"&&/^[A-Za-z0-9_-]{8,128}$/.test(s)&&a.length===1){const t=Object.fromEntries(Object.entries(e).filter(([m])=>m!=="action"&&m!=="_shennianAuthorizedActionId"));return{action:n,actionParameters:c(n,t),authorizedActionId:s}}if(typeof o!="string"||!/^[a-f0-9]{64}$/.test(o)||typeof r!="string"||!/^sni_v1_[A-Za-z0-9_-]{40,80}$/.test(r)||a.some(t=>t!=="_shennianRegistryKey"&&t!=="_shennianInvocationToken"))throw new p("session_context_required","The current Agent session is not connected to Shennian Room yet.");const h=Object.fromEntries(Object.entries(e).filter(([t])=>t!=="action"&&t!=="_shennianRegistryKey"&&t!=="_shennianInvocationToken"));return{action:n,actionParameters:c(n,h),registryKey:o,invocationToken:r}}class p extends Error{code;constructor(e,n){super(n),this.code=e,this.name="RoomToolInputError"}}function g(){throw new p("invalid_tool_input","Invalid Shennian Room tool input.")}export{p as RoomToolInputError,l as SHENNIAN_ROOM_TOOL,d as SHENNIAN_ROOM_TOOL_NAME,f as normalizeRoomToolInput};
1
+ import{normalizeRoomActionParameters as c}from"./room-action-schema.js";const d="shennian_room",l={name:d,title:"Shennian Room",description:"Create, join, read, search, send to, configure, or inspect the single Shennian Room bound to this Agent session. Creating or joining requires a non-empty Agent description. Status includes member and Agent descriptions plus the canonical local JSONL mirror path.",inputSchema:{type:"object",additionalProperties:!1,required:["action"],properties:{action:{type:"string",enum:["create","join","read","send","mode","status"],description:"The Room action to perform."},name:{type:"string",minLength:1,maxLength:80},agentAlias:{type:"string",minLength:1,maxLength:80},agentDescription:{type:"string",minLength:1,maxLength:1e3},inviteUrl:{type:"string",format:"uri",maxLength:2048},message:{type:"string",maxLength:500},activationMode:{type:"string",enum:["auto","auto_follow","mention","mention_only","paused"]},afterSequence:{type:"string",pattern:"^(0|[1-9]\\d{0,19})$"},limit:{type:"integer",minimum:1,maximum:100},query:{type:"string",minLength:1,maxLength:200},attachmentIds:{type:"array",maxItems:10,uniqueItems:!0,items:{type:"string",minLength:1,maxLength:191}},clientMessageId:{type:"string",minLength:1,maxLength:191,description:"Optional idempotency key. Shennian generates one when omitted."},text:{type:"string",minLength:1,maxLength:2e4},files:{type:"array",description:"Up to 10 files inside the current Agent workspace to upload privately with this message.",minItems:1,maxItems:10,items:{type:"string",minLength:1,maxLength:4096}},mentionMembershipIds:{type:"array",maxItems:20,uniqueItems:!0,items:{type:"string",minLength:1,maxLength:191}},replyToMessageId:{type:"string",minLength:1,maxLength:191}}}},u=new Map([["create","room.create"],["join","room.join"],["read","room.read"],["send","room.send"],["mode","room.mode"],["status","room.status"]]);function f(i){(!i||typeof i!="object"||Array.isArray(i))&&g();const e=i,n=typeof e.action=="string"?u.get(e.action):void 0;n||g();const o=e._shennianRegistryKey,r=e._shennianInvocationToken,s=e._shennianAuthorizedActionId,a=Object.keys(e).filter(t=>t.startsWith("_shennian"));if(typeof s=="string"&&/^[A-Za-z0-9_-]{8,128}$/.test(s)&&a.length===1){const t=Object.fromEntries(Object.entries(e).filter(([m])=>m!=="action"&&m!=="_shennianAuthorizedActionId"));return{action:n,actionParameters:c(n,t),authorizedActionId:s}}if(typeof o!="string"||!/^[a-f0-9]{64}$/.test(o)||typeof r!="string"||!/^sni_v1_[A-Za-z0-9_-]{40,80}$/.test(r)||a.some(t=>t!=="_shennianRegistryKey"&&t!=="_shennianInvocationToken"))throw new p("session_context_required","The current Agent session is not connected to Shennian Room yet.");const h=Object.fromEntries(Object.entries(e).filter(([t])=>t!=="action"&&t!=="_shennianRegistryKey"&&t!=="_shennianInvocationToken"));return{action:n,actionParameters:c(n,h),registryKey:o,invocationToken:r}}class p extends Error{code;constructor(e,n){super(n),this.code=e,this.name="RoomToolInputError"}}function g(){throw new p("invalid_tool_input","Invalid Shennian Room tool input.")}export{p as RoomToolInputError,l as SHENNIAN_ROOM_TOOL,d as SHENNIAN_ROOM_TOOL_NAME,f as normalizeRoomToolInput};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shennian",
3
- "version": "0.3.21",
3
+ "version": "0.3.22",
4
4
  "description": "Shennian — AI Agent Control Plane CLI",
5
5
  "type": "module",
6
6
  "bin": {