shennian 0.3.39 → 0.3.41

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.
Files changed (35) hide show
  1. package/README.md +2 -1
  2. package/dist/publish-build-manifest.json +37 -37
  3. package/dist/src/agents/claude.d.ts +1 -0
  4. package/dist/src/agents/claude.js +4 -4
  5. package/dist/src/agents/codex.d.ts +9 -0
  6. package/dist/src/agents/codex.js +10 -10
  7. package/dist/src/agents/model-registry/service.js +1 -1
  8. package/dist/src/commands/room.d.ts +2 -0
  9. package/dist/src/commands/room.js +3 -3
  10. package/dist/src/index.js +3 -3
  11. package/dist/src/native-fusion/codex-parser.js +4 -4
  12. package/dist/src/native-fusion/service.d.ts +8 -0
  13. package/dist/src/native-fusion/service.js +2 -2
  14. package/dist/src/native-fusion/types.d.ts +10 -0
  15. package/dist/src/room/host-session-observations.d.ts +1 -1
  16. package/dist/src/room/host-session-observations.js +2 -2
  17. package/dist/src/room/invite-qr.d.ts +6 -0
  18. package/dist/src/room/invite-qr.js +1 -0
  19. package/dist/src/room/managed-room-binding.d.ts +1 -1
  20. package/dist/src/room/managed-room-binding.js +1 -1
  21. package/dist/src/room/public-room-client.d.ts +2 -1
  22. package/dist/src/room/public-room-client.js +1 -1
  23. package/dist/src/room/room-action-client.d.ts +5 -5
  24. package/dist/src/room/room-action-client.js +1 -1
  25. package/dist/src/room/session-registry.d.ts +1 -1
  26. package/dist/src/room/session-registry.js +2 -2
  27. package/dist/src/session/handlers/chat.js +2 -2
  28. package/node_modules/@shennian/wire/dist/agent-workspace.d.ts +3 -1
  29. package/node_modules/@shennian/wire/dist/external-message-format.js +1 -1
  30. package/node_modules/@shennian/wire/dist/room.d.ts +18 -1
  31. package/node_modules/@shennian/wire/dist/room.js +18 -1
  32. package/node_modules/@shennian/wire/dist/session.d.ts +10 -0
  33. package/package.json +3 -1
  34. package/dist/src/commands/agent.d.ts +0 -7
  35. package/dist/src/commands/agent.js +0 -3
@@ -1,3 +1,4 @@
1
+ import { type AgentType } from './session.ts';
1
2
  export type RoomVisibility = 'private' | 'public_read';
2
3
  export type RoomJoinPolicy = 'open' | 'approval' | 'closed';
3
4
  export type RoomStatus = 'active' | 'archived' | 'deleted';
@@ -9,11 +10,15 @@ export type RoomActivationMode = 'auto_follow' | 'mention_only' | 'paused';
9
10
  export type RoomActivationCapability = 'managed' | 'idle_resume' | 'notify_only';
10
11
  export type RoomBindingMode = 'managed' | 'hook_native';
11
12
  export type RoomBindingStatus = 'pending_approval' | 'active' | 'paused' | 'detached';
12
- export type RoomRuntimeAdapter = 'codex' | 'claude_code' | 'workbuddy';
13
+ /** `claude_code` is accepted only as a legacy wire value. New writers use the real AgentType. */
14
+ export type RoomRuntimeAdapter = Exclude<AgentType, 'manager' | 'pi' | 'openclaw'> | 'claude_code';
13
15
  export type RoomAttachmentKind = 'image' | 'audio' | 'video' | 'file';
14
16
  export type RoomAttachmentStatus = 'pending' | 'uploaded' | 'scanning' | 'ready' | 'rejected' | 'expired' | 'deleted';
15
17
  /** JSON-safe representation of the database BIGINT sequence. */
16
18
  export type RoomSequence = string;
19
+ export declare function roomRuntimeAgentType(value: string): AgentType | null;
20
+ export declare function isRoomRuntimeAdapter(value: string): value is RoomRuntimeAdapter;
21
+ export declare function roomRuntimeAdapterForAgent(agentType: AgentType): RoomRuntimeAdapter | null;
17
22
  export type RoomSummary = {
18
23
  id: string;
19
24
  name: string;
@@ -28,6 +33,18 @@ export type RoomSummary = {
28
33
  membershipRole?: RoomMembershipRole;
29
34
  pinnedAt?: string | null;
30
35
  updatedAt: string;
36
+ /** Optional list projection used by local-first clients to avoid per-room requests. */
37
+ latestMessage?: RoomMessageView | null;
38
+ /** Compact active-member projection for the list avatar. */
39
+ avatarMembers?: Array<{
40
+ id: string;
41
+ principalType: RoomPrincipalType;
42
+ displayAlias: string;
43
+ /** Stable membership ordering key; older servers may omit it. */
44
+ joinedAt?: string;
45
+ avatar?: Record<string, unknown> | null;
46
+ ownerAvatar?: Record<string, unknown> | null;
47
+ }>;
31
48
  };
32
49
  export type RoomAuthorSnapshot = {
33
50
  membershipId: string;
@@ -1,3 +1,20 @@
1
1
  // @arch docs/features/network-rooms/implementation-plan.md
2
2
  // @test src/__tests__/room.test.ts
3
- export {};
3
+ import { isAvailableAgentType } from "./session.js";
4
+ export function roomRuntimeAgentType(value) {
5
+ if (value === 'claude_code')
6
+ return 'claude';
7
+ if (!isAvailableAgentType(value) ||
8
+ value === 'manager' ||
9
+ value === 'pi' ||
10
+ value === 'openclaw') {
11
+ return null;
12
+ }
13
+ return value;
14
+ }
15
+ export function isRoomRuntimeAdapter(value) {
16
+ return roomRuntimeAgentType(value) !== null;
17
+ }
18
+ export function roomRuntimeAdapterForAgent(agentType) {
19
+ return roomRuntimeAgentType(agentType) ? agentType : null;
20
+ }
@@ -45,6 +45,10 @@ export type AgentRuntimeSummary = {
45
45
  export type AgentInfo = {
46
46
  type: AgentType;
47
47
  models: ModelInfo[];
48
+ /** True when this provider can back a stable Shennian Agent and managed Room session. */
49
+ supportsManagedAgent?: boolean;
50
+ /** True when Manager mode can create this provider as a worker. */
51
+ supportsWorker?: boolean;
48
52
  /** True only after this real provider passed Manager-mode runtime validation. */
49
53
  supportsManagerMode?: boolean;
50
54
  /** Per-machine Agent provider config summary (additive, non-secret). */
@@ -80,6 +84,12 @@ export type SessionActivitySnapshot = {
80
84
  toolCallCount?: number;
81
85
  /** True when the daemon owns a live control channel that can stop the active run. */
82
86
  canStop?: boolean;
87
+ /** Optional owner projection for runs controlled by a native desktop host. */
88
+ owner?: 'shennian' | 'external';
89
+ /** Human-readable native owner. Older clients safely ignore this field. */
90
+ ownerLabel?: string;
91
+ /** External-owner lifecycle. `runPhase` remains the backwards-compatible projection. */
92
+ lifecycle?: 'queued' | 'running';
83
93
  };
84
94
  export type ExternalChannelSessionStatus = {
85
95
  configured?: boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shennian",
3
- "version": "0.3.39",
3
+ "version": "0.3.41",
4
4
  "description": "Shennian — AI Agent Control Plane CLI",
5
5
  "type": "module",
6
6
  "bin": {
@@ -40,12 +40,14 @@
40
40
  "@sinclair/typebox": "^0.34.49",
41
41
  "chalk": "^5.4.1",
42
42
  "commander": "^13.1.0",
43
+ "qrcode": "^1.5.4",
43
44
  "qrcode-terminal": "^0.12.0",
44
45
  "ws": "^8.18.1",
45
46
  "@shennian/wire": "0.1.5"
46
47
  },
47
48
  "devDependencies": {
48
49
  "@types/node": "^20",
50
+ "@types/qrcode": "^1.5.6",
49
51
  "@types/qrcode-terminal": "^0.12.2",
50
52
  "@types/ws": "^8.18.1",
51
53
  "esbuild": "^0.27.4",
@@ -1,7 +0,0 @@
1
- import type { Command } from 'commander';
2
- type FetchLike = typeof fetch;
3
- type AgentCommandOptions = {
4
- fetchImpl?: FetchLike;
5
- };
6
- export declare function registerAgentCommand(program: Command, options?: AgentCommandOptions): void;
7
- export {};
@@ -1,3 +0,0 @@
1
- import{loadConfig as f}from"../config/index.js";import{SERVERS as A}from"../region.js";function k(t,n={}){const e=w(n.fetchImpl??fetch),a=t.command("agent").description("Create and manage stable Shennian Agents");a.command("create").description("Create a stable Agent owned by the paired user").requiredOption("--name <name>","Agent display name").requiredOption("--description <description>","Public Agent responsibility").requiredOption("--runtime <runtime>","Agent runtime, for example codex or claude").requiredOption("--workdir <absolute-path>","Absolute working directory").option("--model <model>","Default model").option("--system-prompt <prompt>","Private system prompt").action(async o=>{await u("agent.create",()=>e("POST","/api/agents",{displayName:o.name,description:o.description,runtimeAdapter:o.runtime,workDir:o.workdir,...o.model!=null?{modelId:o.model}:{},...o.systemPrompt!=null?{systemPrompt:o.systemPrompt}:{}}))}),a.command("get <agent-ref>").description("Get one explicitly referenced stable Agent").action(async o=>{const r=g(o);if(!r)return d("invalid_agent_ref","agent-ref is invalid.",null);await u("agent.get",()=>e("GET",`/api/agents/${encodeURIComponent(r)}`))}),a.command("update <agent-ref>").description("Update fields on one explicitly referenced stable Agent").option("--name <name>","Agent display name").option("--description <description>","Public Agent responsibility").option("--runtime <runtime>","Agent runtime").option("--workdir <absolute-path>","Absolute working directory").option("--model <model>","Default model; use an empty value to clear").option("--system-prompt <prompt>","Private system prompt; use an empty value to clear").action(async(o,r)=>{const s=g(o);if(!s)return d("invalid_agent_ref","agent-ref is invalid.",null);const i={};if(r.name!=null&&(i.displayName=r.name),r.description!=null&&(i.description=r.description),r.runtime!=null&&(i.runtimeAdapter=r.runtime),r.workdir!=null&&(i.workDir=r.workdir),r.model!=null&&(i.modelId=r.model),r.systemPrompt!=null&&(i.systemPrompt=r.systemPrompt),Object.keys(i).length===0)return d("no_changes","Provide at least one field to update.",null);await u("agent.update",()=>e("PATCH",`/api/agents/${encodeURIComponent(s)}`,i))}),l(a,"add"),l(a,"list"),l(a,"remove")}function l(t,n){const e=n==="list"?n:`${n} [name]`;t.command(e,{hidden:!0}).allowUnknownOption(!0).description(`Moved to shennian runtime ${n}`).action(()=>d("command_moved",`Custom runtime management moved to "shennian runtime ${n}".`,{type:"run_command",command:`shennian runtime ${n}`}))}function w(t){return async(n,e,a)=>{const o=f();if(!o.machineToken)throw new m("not_paired","Shennian CLI is not paired.",{type:"run_command",command:"shennian pair --browser"});const r=(o.serverUrl??A.cn.url).replace(/\/+$/,"");let s;try{s=await t(`${r}${e}`,{method:n,headers:{authorization:`Bearer ${o.machineToken}`,...a==null?{}:{"content-type":"application/json"}},...a==null?{}:{body:JSON.stringify(a)},signal:AbortSignal.timeout(15e3)})}catch{throw new m("server_unavailable","Shennian service is unavailable.",null)}const i=await h(s);if(!s.ok){const p=y(i)?i:{};throw new m(typeof p.code=="string"?`agent_${p.code}`:`http_${s.status}`,typeof p.error=="string"?p.error:"Agent request failed.",null)}const c=y(i)&&y(i.agent)?i.agent:null;if(!c||typeof c.id!="string"||typeof c.displayName!="string")throw new m("invalid_server_response","Shennian returned an invalid Agent response.",null);return c}}async function u(t,n){try{const e=await n();process.stdout.write(`${JSON.stringify({ok:!0,command:t,result:{agentRef:e.id,name:e.displayName,description:e.description,runtime:e.runtimeAdapter,workdir:e.workDir,model:e.modelId,systemPromptConfigured:!!e.systemPrompt,avatar:e.avatar??null,status:e.status,createdAt:e.createdAt,updatedAt:e.updatedAt}})}
2
- `)}catch(e){if(e instanceof m){d(e.code,e.message,e.nextAction);return}d("agent_command_failed","Shennian Agent command failed.",null)}}class m extends Error{code;nextAction;constructor(n,e,a){super(e),this.code=n,this.nextAction=a}}function g(t){const n=t.startsWith("agent:")?t.slice(6):t;return/^[A-Za-z0-9_-]{1,191}$/.test(n)?n:null}async function h(t){try{return await t.json()}catch{return null}}function y(t){return!!t&&typeof t=="object"&&!Array.isArray(t)}function d(t,n,e){process.stdout.write(`${JSON.stringify({ok:!1,error:t,message:n,nextAction:e})}
3
- `),process.exitCode=1}export{k as registerAgentCommand};