shennian 0.4.69 → 0.4.72
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/publish-build-manifest.json +150 -90
- package/dist/src/agent-env.js +4 -4
- package/dist/src/agents/adapter.d.ts +7 -3
- package/dist/src/agents/auth-status.d.ts +4 -0
- package/dist/src/agents/auth-status.js +2 -0
- package/dist/src/agents/claude.js +4 -4
- package/dist/src/agents/codex-protocol.d.ts +103 -0
- package/dist/src/agents/codex-protocol.js +3 -0
- package/dist/src/agents/codex-runtime.d.ts +91 -0
- package/dist/src/agents/codex-runtime.js +14 -0
- package/dist/src/agents/codex.d.ts +15 -91
- package/dist/src/agents/codex.js +2 -17
- package/dist/src/agents/command-spec.js +4 -3
- package/dist/src/agents/detect.js +1 -1
- package/dist/src/agents/manager.d.ts +4 -3
- package/dist/src/agents/manager.js +4 -4
- package/dist/src/agents/model-registry/discovery.js +3 -3
- package/dist/src/agents/model-registry/parsers.js +4 -4
- package/dist/src/agents/model-registry/service.d.ts +6 -2
- package/dist/src/agents/model-registry/service.js +1 -1
- package/dist/src/agents/model-registry/types.d.ts +9 -1
- package/dist/src/agents/model-registry/types.js +1 -1
- package/dist/src/agents/opencode.d.ts +4 -0
- package/dist/src/agents/opencode.js +1 -1
- package/dist/src/commands/agent-readiness.d.ts +17 -0
- package/dist/src/commands/agent-readiness.js +2 -0
- package/dist/src/commands/agent.js +2 -2
- package/dist/src/commands/daemon-instance-lock.js +1 -1
- package/dist/src/commands/daemon-process.d.ts +1 -0
- package/dist/src/commands/daemon-process.js +1 -1
- package/dist/src/commands/daemon-service-spec.d.ts +28 -0
- package/dist/src/commands/daemon-service-spec.js +1 -0
- package/dist/src/commands/daemon-start-wait.d.ts +1 -1
- package/dist/src/commands/daemon-start-wait.js +1 -1
- package/dist/src/commands/daemon-state.d.ts +57 -0
- package/dist/src/commands/daemon-state.js +1 -0
- package/dist/src/commands/daemon-windows.d.ts +8 -0
- package/dist/src/commands/daemon-windows.js +10 -10
- package/dist/src/commands/daemon.d.ts +4 -64
- package/dist/src/commands/daemon.js +13 -13
- package/dist/src/commands/manager.js +1 -1
- package/dist/src/commands/upgrade.js +1 -1
- package/dist/src/commands/worker.d.ts +11 -0
- package/dist/src/commands/worker.js +2 -0
- package/dist/src/daemon-ipc/agent-readiness.d.ts +14 -0
- package/dist/src/daemon-ipc/agent-readiness.js +1 -0
- package/dist/src/daemon-ipc/control.d.ts +1 -1
- package/dist/src/daemon-ipc/control.js +1 -1
- package/dist/src/index.js +3 -3
- package/dist/src/manager/prompt.d.ts +1 -1
- package/dist/src/manager/prompt.js +6 -6
- package/dist/src/manager/registry.d.ts +48 -2
- package/dist/src/manager/registry.js +1 -1
- package/dist/src/manager/runtime.d.ts +2 -2
- package/dist/src/manager/runtime.js +6 -6
- package/dist/src/manager/worker-ipc.d.ts +7 -0
- package/dist/src/manager/worker-ipc.js +1 -1
- package/dist/src/native-fusion/local-repository.d.ts +6 -1
- package/dist/src/native-fusion/local-repository.js +2 -2
- package/dist/src/native-fusion/service.d.ts +2 -0
- package/dist/src/native-fusion/service.js +2 -2
- package/dist/src/native-fusion/source-visibility-audit.d.ts +16 -0
- package/dist/src/native-fusion/source-visibility-audit.js +1 -0
- package/dist/src/native-fusion/source-visibility.d.ts +25 -0
- package/dist/src/native-fusion/source-visibility.js +1 -0
- package/dist/src/native-fusion/state.d.ts +1 -0
- package/dist/src/native-fusion/state.js +2 -2
- package/dist/src/native-fusion/types.d.ts +5 -0
- package/dist/src/room/managed-room-binding.d.ts +2 -0
- package/dist/src/room/managed-room-binding.js +1 -1
- package/dist/src/room/room-binding-client.d.ts +1 -0
- package/dist/src/room/room-binding-client.js +1 -1
- package/dist/src/runtime-distribution.d.ts +13 -0
- package/dist/src/runtime-distribution.js +1 -0
- package/dist/src/security/managed-agent-policy.d.ts +7 -0
- package/dist/src/security/managed-agent-policy.js +1 -1
- package/dist/src/session/handlers/agent-workspace-validation.d.ts +1 -0
- package/dist/src/session/handlers/agent-workspace-validation.js +1 -1
- package/dist/src/session/handlers/agents.d.ts +7 -1
- package/dist/src/session/handlers/agents.js +1 -1
- package/dist/src/session/handlers/chat-context.d.ts +31 -0
- package/dist/src/session/handlers/chat-context.js +1 -0
- package/dist/src/session/handlers/chat-events.d.ts +1 -1
- package/dist/src/session/handlers/chat-events.js +2 -2
- package/dist/src/session/handlers/chat-session-lifecycle.d.ts +2 -2
- package/dist/src/session/handlers/chat-session-lifecycle.js +1 -1
- package/dist/src/session/handlers/chat.d.ts +3 -29
- package/dist/src/session/handlers/chat.js +1 -1
- package/dist/src/session/manager.js +2 -2
- package/dist/src/session/queue-helpers.js +2 -2
- package/dist/src/session/queue-message.d.ts +2 -0
- package/dist/src/session/queue.d.ts +7 -1
- package/dist/src/session/queue.js +1 -1
- package/dist/src/session/queued-chat-dispatch.d.ts +4 -1
- package/dist/src/session/queued-chat-dispatch.js +1 -1
- package/dist/src/session/store.d.ts +4 -2
- package/dist/src/session/store.js +2 -2
- package/dist/src/session/types.d.ts +1 -0
- package/dist/src/upgrade/engine.js +2 -2
- package/dist/src/upgrade/scheduler.js +1 -1
- package/dist/src/upgrade/updater-launcher.js +3 -3
- package/node_modules/@shennian/wire/dist/room.d.ts +2 -0
- package/node_modules/@shennian/wire/dist/session-sync.d.ts +2 -1
- package/node_modules/@shennian/wire/dist/session.d.ts +25 -1
- package/node_modules/@shennian/wire/dist/session.js +8 -0
- package/package.json +1 -1
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import s from"node:fs";import c from"node:path";import{execSync as
|
|
1
|
+
import s from"node:fs";import{assertStandaloneUpgrade as F,isDesktopDistribution as T}from"../runtime-distribution.js";import c from"node:path";import{execSync as U,execFile as J}from"node:child_process";import{promisify as O}from"node:util";import{fileURLToPath as L}from"node:url";import{getShennianDir as _,resolveShennianPath as m}from"../config/index.js";import{getUpgradeDistTag as P}from"./channel.js";import{fetchCliDistribution as I}from"./distribution.js";const f=O(J),y=m("upgrade-attempt.json"),G=3,H="https://registry.npmjs.org",B=10*6e4,$=[5*6e4,30*6e4,120*6e4,360*6e4];function g(){try{const r=h();if(r)return JSON.parse(s.readFileSync(r,"utf-8")).version}catch{}return"0.0.0"}function h(r=L(import.meta.url)){let e=c.dirname(r);for(let n=0;n<6;n++){const t=c.join(e,"package.json");if(s.existsSync(t)&&JSON.parse(s.readFileSync(t,"utf-8")).name==="shennian")return t;e=c.dirname(e)}return null}async function Y(){let r;try{const e=await fetch(`https://registry.npmjs.org/shennian/${P()}`,{headers:{Accept:"application/json"},signal:AbortSignal.timeout(1e4)});if(!e.ok)throw new Error(`npm registry returned ${e.status}`);const n=await e.json();if(typeof n?.version!="string"||!/^\d+\.\d+\.\d+$/.test(n.version))throw new Error("npm registry returned an unsupported CLI version (expected numeric major.minor.patch)");return n.version}catch(e){r=e}try{return(await I()).version}catch(e){const n=r instanceof Error?r.message:String(r),t=e instanceof Error?e.message:String(e);throw new Error(`npm registry unavailable: ${n}; Shennian fallback failed: ${t}`)}}function z(r,e){const n=p=>p.replace(/^v/,"").split(".").map(Number),[t,a,o]=n(r),[i,u,l]=n(e);return i>t?"major":i===t&&u>a?"minor":i===t&&u===a&&l>o?"patch":"none"}function K(){return U("npm root -g",{encoding:"utf-8",stdio:"pipe",windowsHide:!0}).trim()}function X(r,e=process.platform){const n=e==="win32"?c.win32:c.posix,t=n.dirname(r),a=n.dirname(t);if(n.basename(a)!=="node_modules")return null;const o=n.dirname(a);return n.basename(o)==="lib"?n.dirname(o):o}function N(){const r=h();return r?X(r):null}function Z(){const r=h();return r?c.join(c.dirname(r),"dist","bin","shennian.js"):c.join(K(),"shennian","dist","bin","shennian.js")}function q(){try{return JSON.parse(s.readFileSync(y,"utf-8"))}catch{return null}}function d(r){s.mkdirSync(_(),{recursive:!0}),s.writeFileSync(y,JSON.stringify(r,null,2))}function Q(){try{s.unlinkSync(y)}catch{}}function j(){return m("upgrade-failures.json")}function W(){return m("upgrade.lock")}function V(r=W(),e={}){const n=e.now??Date.now(),t=e.pid??process.pid,a=e.isProcessAlive??(l=>{try{return process.kill(l,0),!0}catch{return!1}});s.mkdirSync(c.dirname(r),{recursive:!0});const o=()=>s.openSync(r,"wx",384);let i;try{i=o()}catch(l){if(l.code!=="EEXIST")throw l;let p=!1;try{const A=JSON.parse(s.readFileSync(r,"utf-8")),E=Number(A.pid),b=Number(A.createdAt);p=!Number.isInteger(E)||!Number.isFinite(b)||n-b>B||!a(E)}catch{p=!0}if(!p)throw new Error("Another Shennian upgrade is already running");s.rmSync(r,{force:!0}),i=o()}s.writeFileSync(i,JSON.stringify({pid:t,createdAt:n})),s.closeSync(i);let u=!1;return{release(){if(!u){u=!0;try{s.unlinkSync(r)}catch{}}}}}function w(r=j()){try{const e=JSON.parse(s.readFileSync(r,"utf-8"));return!e||typeof e!="object"||!e.versions?{versions:{}}:{versions:e.versions}}catch{return{versions:{}}}}function C(r){s.mkdirSync(_(),{recursive:!0}),s.writeFileSync(j(),JSON.stringify(r,null,2))}function rr(r){return $[Math.min(Math.max(r-1,0),$.length-1)]}function dr(r,e=Date.now(),n=w()){const t=n.versions[r];return!!(t&&t.nextRetryAt>e)}function mr(r,e,n=Date.now()){const t=w(),a=t.versions[r],o=(a?.failureCount??0)+1,i={version:r,failureCount:o,firstFailedAt:a?.firstFailedAt??n,lastFailedAt:n,nextRetryAt:n+rr(o),error:e};return t.versions[r]=i,C(t),i}function k(r){const e=w();e.versions[r]&&(delete e.versions[r],C(e))}async function yr(){if(T())return null;const r=q();return r?Date.now()-r.attemptAt>600*1e3?(Q(),null):(r.attemptCount++,r.attemptCount>=G?(d(r),r):(d(r),null)):null}async function gr(r,e,n={}){let t;try{F(),t=V()}catch(a){return{ok:!1,error:a instanceof Error?a.message:String(a)}}try{return await er(r,e,n)}finally{t.release()}}async function er(r,e,n={}){const t=n.currentVersion??g(),a=g();if(t===r)return k(r),{ok:!1,error:`Already on version ${r}`};e({step:"checking"});try{U("npm --version",{stdio:"pipe",windowsHide:!0})}catch{return{ok:!1,error:"npm is not available in PATH"}}if(a===r){e({step:"verifying",version:r});try{await v(r)}catch(o){return{ok:!1,error:`Smoke test failed: ${o instanceof Error?o.message:String(o)}`}}return d({from:t,to:r,attemptCount:0,attemptAt:Date.now()}),k(r),e({step:"restarting",from:t,to:r}),{ok:!0,from:t,to:r}}e({step:"backing-up"}),e({step:"installing",version:r});try{await M(r)}catch(o){const i=await R(t);return{ok:!1,error:`npm install failed: ${o instanceof Error?o.message:String(o)}${i.ok?"":`; rollback failed: ${i.error}`}`,rolledBack:i.ok}}e({step:"verifying",version:r});try{await v(r)}catch(o){const i=await R(t);return{ok:!1,error:`Smoke test failed: ${o instanceof Error?o.message:String(o)}${i.ok?"":`; rollback failed: ${i.error}`}`,rolledBack:i.ok}}return d({from:t,to:r,attemptCount:0,attemptAt:Date.now()}),k(r),e({step:"restarting",from:t,to:r}),{ok:!0,from:t,to:r}}function D(r){if(!/^[0-9]+\.[0-9]+\.[0-9]+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/.test(r))throw new Error(`Invalid npm version: ${r}`)}function S(){return process.platform==="win32"?"npm.cmd":"npm"}function tr(r,e){return{timeout:e,windowsHide:!0,shell:r==="win32"}}function x(r){return tr(process.platform,r)}async function M(r){F(),D(r);const e=N(),n=["install","-g",`shennian@${r}`,...e?["--prefix",e]:[]];try{await f(S(),n,x(12e4))}catch(t){const a=t instanceof Error?t.message:String(t);try{await f(S(),[...n,"--registry",H],{...x(12e4)})}catch(o){const i=o instanceof Error?o.message:String(o);throw new Error(`${a}
|
|
2
2
|
--- npmjs fallback ---
|
|
3
|
-
${i}`)}}}async function v(r){
|
|
3
|
+
${i}`)}}}async function v(r){D(r);const e=Z(),{stdout:n}=await f(process.execPath,[e,"--version"],{timeout:1e4,windowsHide:!0});if(n.trim()!==r)throw new Error(`Version verification failed: expected ${r}, got ${n.trim()||"empty output"}`);const t=N();await f(S(),["ls","-g",`shennian@${r}`,"--omit=dev","--depth=0",...t?["--prefix",t]:[]],{...x(3e4)})}async function nr(r,e={}){await(e.install??M)(r),await(e.verify??v)(r)}async function R(r){try{return await nr(r),{ok:!0}}catch(e){return{ok:!1,error:e instanceof Error?e.message:String(e)}}}async function hr(r){const e=r??g(),n=await Y(),t=z(e,n);return t==="none"?{hasUpdate:!1}:{hasUpdate:!0,current:e,latest:n,changeType:t}}export{V as acquireUpgradeLock,hr as checkForUpdate,Q as clearUpgradeAttempt,k as clearUpgradeFailure,z as compareVersions,Y as fetchLatestVersion,h as findPackageJson,g as getCurrentVersion,rr as getUpgradeRetryDelayMs,yr as handleStartupCrashCheck,M as installShennianVersion,dr as isUpgradeVersionInCooldown,tr as npmExecOptionsForPlatform,gr as performUpgrade,q as readUpgradeAttempt,w as readUpgradeFailures,mr as recordUpgradeFailure,X as resolveNpmGlobalPrefixFromPackageJson,nr as rollbackToExactVersion,v as verifyInstalledVersion,d as writeUpgradeAttempt};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{checkForUpdate as
|
|
1
|
+
import{isDesktopDistribution as a}from"../runtime-distribution.js";import{checkForUpdate as u,isUpgradeVersionInCooldown as c}from"./engine.js";const d={automaticPatchEnabled:!1,rolloutPercentage:0,pausedVersions:[],blockedVersions:[],blockedCurrentVersions:[],killSwitch:!0,releaseLevel:"normal",maxIdleWaitMs:30*6e4,requiredCapabilities:[],externalUpdaterEnabled:!1};function m(r){let i=2166136261;for(let t=0;t<r.length;t++)i^=r.charCodeAt(t),i=Math.imul(i,16777619);return(i>>>0)%100}function h(r,i,t,e){if(r.killSwitch||!r.automaticPatchEnabled||r.blockedVersions.includes(e)||r.pausedVersions.includes(e)||r.pausedVersions.includes(t))return!1;const s=Math.max(0,Math.min(100,Math.floor(r.rolloutPercentage)));return m(i)<s}async function p(r){const i=new URL("/api/releases/cli-policy",r),t=await fetch(i,{headers:{Accept:"application/json"},signal:AbortSignal.timeout(1e4)});if(!t.ok)throw new Error(`release policy returned ${t.status}`);const e=await t.json();return{automaticPatchEnabled:e.automaticPatchEnabled===!0,rolloutPercentage:typeof e.rolloutPercentage=="number"?e.rolloutPercentage:0,pausedVersions:Array.isArray(e.pausedVersions)?e.pausedVersions.filter(s=>typeof s=="string"):[],blockedVersions:Array.isArray(e.blockedVersions)?e.blockedVersions.filter(s=>typeof s=="string"):[],blockedCurrentVersions:Array.isArray(e.blockedCurrentVersions)?e.blockedCurrentVersions.filter(s=>typeof s=="string"):[],killSwitch:e.killSwitch!==!1,releaseLevel:e.releaseLevel==="required"||e.releaseLevel==="blocked"?e.releaseLevel:"normal",maxIdleWaitMs:typeof e.maxIdleWaitMs=="number"&&Number.isFinite(e.maxIdleWaitMs)?Math.max(0,Math.min(1440*6e4,Math.floor(e.maxIdleWaitMs))):30*6e4,...typeof e.minimumSessionSyncProtocolVersion=="number"?{minimumSessionSyncProtocolVersion:e.minimumSessionSyncProtocolVersion}:{},...typeof e.minimumDataEpoch=="number"?{minimumDataEpoch:e.minimumDataEpoch}:{},requiredCapabilities:Array.isArray(e.requiredCapabilities)?e.requiredCapabilities.filter(s=>typeof s=="string"):[],externalUpdaterEnabled:e.externalUpdaterEnabled===!0,...typeof e.minimumUpdaterProtocolVersion=="number"?{minimumUpdaterProtocolVersion:e.minimumUpdaterProtocolVersion}:{}}}class b{deps;policy="none";timer=null;started=!1;upgradeInFlight=!1;constructor(i){this.deps=i}start(){a()||this.started||(this.started=!0,this.arm(this.deps.initialDelayMs??3e4))}stop(){this.started=!1,this.timer&&(this.deps.clearTimeout??clearTimeout)(this.timer),this.timer=null}setPolicy(i){this.policy=i,this.started&&(this.timer||this.arm(0))}getPolicy(){return this.policy}async runOnce(){if(a()||this.upgradeInFlight)return;const i=await(this.deps.checkForUpdate??u)(this.deps.currentVersion);if(!i.hasUpdate||(this.deps.inCooldown??c)(i.latest))return;let t=d;try{t=await(this.deps.fetchReleasePolicy??(()=>p(this.deps.serverUrl)))()}catch{return}if(t.killSwitch||!t.externalUpdaterEnabled||t.blockedVersions.includes(i.latest)||t.pausedVersions.includes(i.latest)||t.pausedVersions.includes(i.current))return;const e=t.blockedCurrentVersions.includes(i.current)?"blocked":t.releaseLevel,s=t.minimumSessionSyncProtocolVersion!==void 0&&(this.deps.sessionSyncProtocolVersion??0)<t.minimumSessionSyncProtocolVersion||t.minimumDataEpoch!==void 0&&(this.deps.dataEpoch??0)<t.minimumDataEpoch||t.requiredCapabilities.some(l=>!(this.deps.advertisedCapabilities??[]).includes(l))||t.minimumUpdaterProtocolVersion!==void 0&&(this.deps.updaterProtocolVersion??0)<t.minimumUpdaterProtocolVersion,n=e==="required"||e==="blocked"||s;if(!n&&(this.policy!=="patch"||i.changeType!=="patch"||!h(t,this.deps.machineId,i.current,i.latest)))return;const o=this.deps.getIdleState();if(!(!n&&!o.idle)){this.upgradeInFlight=!0;try{await this.deps.startUpgrade(i.latest,n)}finally{this.upgradeInFlight=!1}}}nextIntervalMs(){return this.deps.intervalMs??5*6e4+Math.floor((this.deps.random??Math.random)()*10*6e4)}arm(i){if(!this.started||this.timer)return;const t=this.deps.setTimeout??setTimeout;this.timer=t(()=>{this.timer=null,this.runOnce().catch(()=>{}).finally(()=>{this.started&&this.arm(this.nextIntervalMs())})},i),this.timer.unref?.()}}export{b as AutoUpgradeScheduler,m as deterministicRolloutBucket,p as fetchCliReleasePolicy,h as isAutomaticPatchAllowed};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import r from"node:fs";import d from"node:path";import{randomUUID as y}from"node:crypto";import{spawn as
|
|
2
|
-
`,{mode:384,flag:"wx"});const n=r.openSync(a,process.platform==="win32"?"r+":"r");try{r.fsyncSync(n)}finally{r.closeSync(n)}if(r.renameSync(a,e),process.platform!=="win32"){const t=r.openSync(d.dirname(e),"r");try{r.fsyncSync(t)}finally{r.closeSync(t)}}}finally{try{r.unlinkSync(a)}catch{}}}function
|
|
3
|
-
`,{mode:384,flag:"wx"});const c=r.openSync(t,process.platform==="win32"?"r+":"r");try{r.fsyncSync(c)}finally{r.closeSync(c)}if(r.renameSync(t,n),process.platform!=="win32"){const s=r.openSync(a,"r");try{r.fsyncSync(s)}finally{r.closeSync(s)}}return n}finally{try{r.unlinkSync(t)}catch{}}}function
|
|
1
|
+
import r from"node:fs";import{assertStandaloneUpgrade as I}from"../runtime-distribution.js";import d from"node:path";import{randomUUID as y}from"node:crypto";import{spawn as j,spawnSync as P}from"node:child_process";import{resolveShennianPath as p}from"../config/index.js";import{findPackageJson as _,resolveNpmGlobalPrefixFromPackageJson as E}from"./engine.js";import{ensureUpdaterInstalled as J}from"./updater-bootstrap.js";import{UPDATER_PROTOCOL_VERSION as S}from"./updater-protocol.js";function w(e,o){r.mkdirSync(d.dirname(e),{recursive:!0,mode:448});const a=`${e}.tmp-${process.pid}-${y()}`;try{r.writeFileSync(a,`${JSON.stringify(o,null,2)}
|
|
2
|
+
`,{mode:384,flag:"wx"});const n=r.openSync(a,process.platform==="win32"?"r+":"r");try{r.fsyncSync(n)}finally{r.closeSync(n)}if(r.renameSync(a,e),process.platform!=="win32"){const t=r.openSync(d.dirname(e),"r");try{r.fsyncSync(t)}finally{r.closeSync(t)}}}finally{try{r.unlinkSync(a)}catch{}}}function $(e){I();const o=e.root??p("runtime","updater"),a=_(),n=e.npmPrefix??(a?E(a):null);if(!n)throw new Error("Cannot determine the active npm prefix");const t=e.jobId??y();return{protocolVersion:S,jobId:t,fromVersion:e.fromVersion,targetVersion:e.targetVersion,npmPrefix:n,npmExecutable:e.npmExecutable??(process.platform==="win32"?"npm.cmd":"npm"),nodeExecutable:e.nodeExecutable??process.execPath,packageName:"shennian",operation:e.operation??"upgrade",oldDaemonPid:e.oldDaemonPid,platform:process.platform,createdAt:(e.now??new Date).toISOString(),daemonExitTimeoutMs:15e3,commandTimeoutMs:12e4,resultPath:d.join(o,"results",`${t}.json`),attemptPath:p("upgrade-attempt.json"),...e.requireHandoffAck?{requireHandoffAck:!0}:{},...e.rollbackJobId?{rollbackJobId:e.rollbackJobId}:{},...e.isolatedDaemonStart?{isolatedDaemonStart:!0}:{}}}function O(e,o=p("runtime","updater")){const a=d.join(o,"jobs");r.mkdirSync(a,{recursive:!0,mode:448});const n=d.join(a,`${e.jobId}.json`),t=`${n}.tmp-${process.pid}-${y()}`;try{r.writeFileSync(t,`${JSON.stringify(e,null,2)}
|
|
3
|
+
`,{mode:384,flag:"wx"});const c=r.openSync(t,process.platform==="win32"?"r+":"r");try{r.fsyncSync(c)}finally{r.closeSync(c)}if(r.renameSync(t,n),process.platform!=="win32"){const s=r.openSync(a,"r");try{r.fsyncSync(s)}finally{r.closeSync(s)}}return n}finally{try{r.unlinkSync(t)}catch{}}}function F(e,o){return e==="linux"&&/(?:^|\/)shennian\.service(?:\n|$)/m.test(o.trim())}function R(e,o={}){const a=o.root??e.root??p("runtime","updater"),n=o.readiness??J({root:a}),t=$({...e,root:a}),c=O(t,a),s=d.join(a,"updater.lock");r.mkdirSync(a,{recursive:!0,mode:448});let l=null,f=!1;const h=()=>{if(f){try{JSON.parse(r.readFileSync(s,"utf8")).jobId===t.jobId&&r.unlinkSync(s)}catch{}f=!1}};try{try{l=r.openSync(s,"wx",384),f=!0}catch(i){if(i.code!=="EEXIST")throw i;let b=!1;try{const g=JSON.parse(r.readFileSync(s,"utf8")),k=o.isAlive??(x=>{try{return process.kill(x,0),!0}catch{return!1}});b=!!(g.pid&&k(g.pid))}catch{}if(b)throw new Error("upgrade_locked");r.rmSync(s,{force:!0}),l=r.openSync(s,"wx",384),f=!0}r.writeFileSync(l,JSON.stringify({jobId:t.jobId,phase:"handoff",pid:process.pid,createdAt:(o.now??Date.now)()})),r.closeSync(l),l=null;let u=o.serviceCgroup??"";if(process.platform==="linux"&&!o.spawn&&o.serviceCgroup===void 0)try{u=r.readFileSync("/proc/self/cgroup","utf8")}catch{}if(F(o.platform??process.platform,u)){const i=(o.systemdRun??P)("systemd-run",["--user","--quiet","--collect",`--unit=shennian-updater-${t.jobId}`,"--property=Type=exec","--property=KillMode=process",`--setenv=PATH=${process.env.PATH??"/usr/local/bin:/usr/bin:/bin"}`,"--",t.nodeExecutable,n.workerPath,c],{encoding:"utf8",stdio:"pipe",timeout:1e4});if(i.error||i.status!==0)throw new Error("updater_service_launch_failed");return{job:t,process:null}}const m=(o.spawn??j)(t.nodeExecutable,[n.workerPath,c],{detached:!0,stdio:"ignore",windowsHide:!0});return m.once?.("error",i=>{w(t.resultPath,{protocolVersion:S,jobId:t.jobId,state:"failed",fromVersion:t.fromVersion,targetVersion:t.targetVersion,errorCode:"internal_error",errorSummary:i instanceof Error?i.message.slice(0,500):"updater_spawn_failed",updatedAt:new Date().toISOString()}),h()}),m.unref(),{job:t,process:m}}catch(u){l!==null&&r.closeSync(l),h();try{r.unlinkSync(c)}catch{}throw u}}async function L(e,o=8e3){const a=Date.now()+o;for(;Date.now()<a;){let n=null;try{n=JSON.parse(r.readFileSync(e.resultPath,"utf8"))}catch{}if(n?.jobId===e.jobId&&n.state==="waiting_for_daemon")return;if(n?.jobId===e.jobId&&n.state==="failed")throw new Error(n.errorCode??"updater_not_ready");await new Promise(t=>setTimeout(t,50))}throw new Error("updater_readiness_timeout")}function q(e){w(`${e.resultPath}.handoff`,{jobId:e.jobId})}function M(e,o,a=p("runtime","updater")){if(!/^[A-Za-z0-9_-]{1,128}$/.test(e))return!1;const n=d.join(a,"results",`${e}.json`);try{const t=r.lstatSync(n);if(t.isSymbolicLink()||!t.isFile())return!1;const c=JSON.parse(r.readFileSync(n,"utf8"));return c.protocolVersion!==S||c.jobId!==e||c.state!=="starting"||c.targetVersion!==o?!1:(w(n,{...c,state:c.operation==="rollback"?"rolled_back":"healthy",effectiveVersion:o,updatedAt:new Date().toISOString()}),!0)}catch{return!1}}export{q as confirmUpdaterHandoff,$ as createUpdaterJob,R as launchUpdater,M as markUpdaterHealthy,F as needsSystemdUpdater,L as waitForUpdaterReady,O as writeUpdaterJob};
|
|
@@ -38,6 +38,8 @@ export type RoomSummary = {
|
|
|
38
38
|
lastReadSequence?: RoomSequence;
|
|
39
39
|
unreadCount?: number;
|
|
40
40
|
membershipRole?: RoomMembershipRole;
|
|
41
|
+
/** The signed-in human's relationship to this Room. Older servers may omit it. */
|
|
42
|
+
membershipStatus?: 'active' | 'left' | 'removed';
|
|
41
43
|
pinnedAt?: string | null;
|
|
42
44
|
updatedAt: string;
|
|
43
45
|
/** Optional list projection used by local-first clients to avoid per-room requests. */
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Envelope } from './envelope.ts';
|
|
2
|
-
import type { AgentType, ManagerConfig, SessionMode } from './session.ts';
|
|
3
2
|
import type { ProjectFsOpaqueCapability } from './project-fs.ts';
|
|
3
|
+
import type { AgentType, ManagerConfig, SessionMode } from './session.ts';
|
|
4
4
|
export declare const SESSION_SYNC_PROTOCOL_VERSION: 2;
|
|
5
5
|
export type SessionSyncProtocolVersion = typeof SESSION_SYNC_PROTOCOL_VERSION;
|
|
6
6
|
/**
|
|
@@ -320,6 +320,7 @@ export type SessionBodyReplicaErrorEvent = {
|
|
|
320
320
|
* accepted from a daemon payload.
|
|
321
321
|
*/
|
|
322
322
|
export type DaemonSessionIndexProjection = {
|
|
323
|
+
nativeSessionVisibility?: 'user' | 'internal';
|
|
323
324
|
id: string;
|
|
324
325
|
agentType: AgentType;
|
|
325
326
|
sessionMode?: SessionMode;
|
|
@@ -117,6 +117,8 @@ export type AcpExternalSessionIdentity = {
|
|
|
117
117
|
export type AgentInfo = {
|
|
118
118
|
type: AgentType;
|
|
119
119
|
models: ModelInfo[];
|
|
120
|
+
/** True when this runtime can back an ordinary Shennian session. */
|
|
121
|
+
supportsStandardSession?: boolean;
|
|
120
122
|
/** User-facing grouping. Omitted by older daemons and interpreted as deep. */
|
|
121
123
|
integration?: AgentIntegration;
|
|
122
124
|
/** Non-secret metadata used for dynamic ACP display fallbacks. */
|
|
@@ -137,6 +139,10 @@ export type AgentInfo = {
|
|
|
137
139
|
supportsWorker?: boolean;
|
|
138
140
|
/** True only after this real provider passed Manager-mode runtime validation. */
|
|
139
141
|
supportsManagerMode?: boolean;
|
|
142
|
+
/** True when a managed Room turn can receive explicit Room tools. */
|
|
143
|
+
supportsRoomTools?: boolean;
|
|
144
|
+
/** True when the public temporary Worker controller may target this runtime. */
|
|
145
|
+
supportsExternalWorkerTarget?: boolean;
|
|
140
146
|
/** Per-machine Agent provider config summary (additive, non-secret). */
|
|
141
147
|
config?: AgentConfigSummary;
|
|
142
148
|
/** Non-secret runtime version and compatibility summary. */
|
|
@@ -279,6 +285,8 @@ export type NianSession = {
|
|
|
279
285
|
agentType: AgentType;
|
|
280
286
|
/** Missing on legacy records/clients and normalized to standard, except legacy agentType=manager. */
|
|
281
287
|
sessionMode?: SessionMode;
|
|
288
|
+
/** Internal orchestration stays out of personal discovery; linked details remain readable. */
|
|
289
|
+
nativeSessionVisibility?: 'user' | 'internal';
|
|
282
290
|
managerConfig?: ManagerConfig | null;
|
|
283
291
|
agentSessionId: string | null;
|
|
284
292
|
sourceMode?: NativeSessionSourceMode | null;
|
|
@@ -336,7 +344,7 @@ export type NianSession = {
|
|
|
336
344
|
activity?: SessionActivitySnapshot | null;
|
|
337
345
|
externalChannel?: ExternalChannelSessionStatus | null;
|
|
338
346
|
};
|
|
339
|
-
export type SessionListProjection = Pick<NianSession, 'id' | 'machineId' | 'userId' | 'agentType' | 'sessionMode' | 'managerConfig' | 'agentSessionId' | 'modelId' | 'managerDefaultWorkerAgentType' | 'managerDefaultWorkerModelId' | 'title' | 'titleSource' | 'titleRevision' | 'titleLockedByUser' | 'titleOriginEventId' | 'status' | 'workDir' | 'lastMessagePreview' | 'lastMessagePreviewMessageId' | 'lastMessagePreviewAt' | 'lastVisibleEventAt' | 'bodyStorageMode' | 'bodyRevision' | 'indexRevision' | 'dataEpoch' | 'firstAvailableSeq' | 'visibleMessageCount' | 'lastVisibleMessageId' | 'attentionCount' | 'lastAttentionId' | 'lastBodyCommittedAt' | 'deletionRevision' | 'lastActivityAt' | 'createdAt' | 'updatedAt' | 'deletedAt' | 'machineName' | 'ownerName' | 'ownerPhone' | 'ownerEmail' | 'canManage' | 'sharedMachineSession' | 'activity' | 'externalChannel'>;
|
|
347
|
+
export type SessionListProjection = Pick<NianSession, 'id' | 'machineId' | 'userId' | 'agentType' | 'sessionMode' | 'nativeSessionVisibility' | 'managerConfig' | 'agentSessionId' | 'modelId' | 'managerDefaultWorkerAgentType' | 'managerDefaultWorkerModelId' | 'title' | 'titleSource' | 'titleRevision' | 'titleLockedByUser' | 'titleOriginEventId' | 'status' | 'workDir' | 'lastMessagePreview' | 'lastMessagePreviewMessageId' | 'lastMessagePreviewAt' | 'lastVisibleEventAt' | 'bodyStorageMode' | 'bodyRevision' | 'indexRevision' | 'dataEpoch' | 'firstAvailableSeq' | 'visibleMessageCount' | 'lastVisibleMessageId' | 'attentionCount' | 'lastAttentionId' | 'lastBodyCommittedAt' | 'deletionRevision' | 'lastActivityAt' | 'createdAt' | 'updatedAt' | 'deletedAt' | 'machineName' | 'ownerName' | 'ownerPhone' | 'ownerEmail' | 'canManage' | 'sharedMachineSession' | 'activity' | 'externalChannel'>;
|
|
340
348
|
export type ChatSendParams = PersonalSyncIdentity & {
|
|
341
349
|
sessionId: string;
|
|
342
350
|
text: string;
|
|
@@ -382,6 +390,12 @@ export type QueuedChatMessage = PersonalSyncIdentity & {
|
|
|
382
390
|
replyTarget?: string | null;
|
|
383
391
|
createdAt: string;
|
|
384
392
|
updatedAt: string;
|
|
393
|
+
/** Presentation state for the shared pending-message panel. */
|
|
394
|
+
pendingState?: 'waiting' | 'submitting' | 'provider_queued';
|
|
395
|
+
/** Whether the current client may delete this item before Provider claim. */
|
|
396
|
+
canDelete?: boolean;
|
|
397
|
+
/** Whether the daemon currently has a truthful immediate-send path. */
|
|
398
|
+
canPromote?: boolean;
|
|
385
399
|
};
|
|
386
400
|
export type ChatQueueSnapshot = PersonalSyncIdentity & {
|
|
387
401
|
sessionId: string;
|
|
@@ -389,6 +403,8 @@ export type ChatQueueSnapshot = PersonalSyncIdentity & {
|
|
|
389
403
|
pending: QueuedChatMessage[];
|
|
390
404
|
/** Owner-authored messages that may be deleted or promoted by the current UI. */
|
|
391
405
|
controllablePending?: QueuedChatMessage[];
|
|
406
|
+
/** All owner-authored pending items that belong in the shared composer panel. */
|
|
407
|
+
visiblePending?: QueuedChatMessage[];
|
|
392
408
|
};
|
|
393
409
|
export type ChatEnqueueParams = ChatSendParams & {
|
|
394
410
|
queueMessageId?: string;
|
|
@@ -439,3 +455,11 @@ export type FsReadParams = {
|
|
|
439
455
|
path: string;
|
|
440
456
|
rootPath?: string;
|
|
441
457
|
};
|
|
458
|
+
/** Visibility is separate from access: an Owner can still open linked internal details. */
|
|
459
|
+
export declare function isInternalSession(session: {
|
|
460
|
+
id: string;
|
|
461
|
+
nativeSessionVisibility?: string | null;
|
|
462
|
+
agentType?: string;
|
|
463
|
+
sessionMode?: string | null;
|
|
464
|
+
agentIdentityId?: string | null;
|
|
465
|
+
}): boolean;
|
|
@@ -50,3 +50,11 @@ export function filterAvailableAgentInfos(agents) {
|
|
|
50
50
|
}
|
|
51
51
|
return filtered;
|
|
52
52
|
}
|
|
53
|
+
/** Visibility is separate from access: an Owner can still open linked internal details. */
|
|
54
|
+
export function isInternalSession(session) {
|
|
55
|
+
return session.nativeSessionVisibility === 'internal'
|
|
56
|
+
|| session.id.startsWith('sess_worker_')
|
|
57
|
+
|| session.agentType === 'manager'
|
|
58
|
+
|| session.sessionMode === 'manager'
|
|
59
|
+
|| Boolean(session.agentIdentityId);
|
|
60
|
+
}
|