shennian 0.4.38 → 0.4.39

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.
@@ -891,8 +891,8 @@
891
891
  },
892
892
  {
893
893
  "file": "src/upgrade/scheduler.js",
894
- "beforeBytes": 7340,
895
- "afterBytes": 4250
894
+ "beforeBytes": 7315,
895
+ "afterBytes": 4167
896
896
  },
897
897
  {
898
898
  "file": "src/upgrade/updater-bootstrap.js",
@@ -12,6 +12,7 @@ export type CliReleasePolicy = {
12
12
  blockedCurrentVersions: string[];
13
13
  killSwitch: boolean;
14
14
  releaseLevel: 'normal' | 'required' | 'blocked';
15
+ /** Legacy wire field; normal updates now wait for idle without a deadline. */
15
16
  maxIdleWaitMs: number;
16
17
  minimumSessionSyncProtocolVersion?: number;
17
18
  minimumDataEpoch?: number;
@@ -32,7 +33,7 @@ type AutoUpgradeSchedulerDeps = {
32
33
  intervalMs?: number;
33
34
  setTimeout?: (handler: () => void, delayMs: number) => ReturnType<typeof setTimeout>;
34
35
  clearTimeout?: (timer: ReturnType<typeof setTimeout>) => void;
35
- now?: () => number;
36
+ random?: () => number;
36
37
  sessionSyncProtocolVersion?: number;
37
38
  dataEpoch?: number;
38
39
  advertisedCapabilities?: readonly string[];
@@ -47,13 +48,13 @@ export declare class AutoUpgradeScheduler {
47
48
  private timer;
48
49
  private started;
49
50
  private upgradeInFlight;
50
- private eligibleSince;
51
51
  constructor(deps: AutoUpgradeSchedulerDeps);
52
52
  start(): void;
53
53
  stop(): void;
54
54
  setPolicy(policy: RuntimeAutoUpgradePolicy): void;
55
55
  getPolicy(): RuntimeAutoUpgradePolicy;
56
56
  runOnce(): Promise<void>;
57
+ private nextIntervalMs;
57
58
  private arm;
58
59
  }
59
60
  export {};
@@ -1 +1 @@
1
- import{checkForUpdate as d,isUpgradeVersionInCooldown as u}from"./engine.js";const m={automaticPatchEnabled:!1,rolloutPercentage:0,pausedVersions:[],blockedVersions:[],blockedCurrentVersions:[],killSwitch:!0,releaseLevel:"normal",maxIdleWaitMs:30*6e4,requiredCapabilities:[],externalUpdaterEnabled:!1};function h(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 p(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 h(i)<s}async function f(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 y{deps;policy="none";timer=null;started=!1;upgradeInFlight=!1;eligibleSince=new Map;constructor(i){this.deps=i}start(){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(this.upgradeInFlight)return;const i=await(this.deps.checkForUpdate??d)(this.deps.currentVersion);if(!i.hasUpdate||(this.deps.inCooldown??u)(i.latest))return;let t=m;try{t=await(this.deps.fetchReleasePolicy??(()=>f(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(c=>!(this.deps.advertisedCapabilities??[]).includes(c))||t.minimumUpdaterProtocolVersion!==void 0&&(this.deps.updaterProtocolVersion??0)<t.minimumUpdaterProtocolVersion,a=e==="required"||e==="blocked"||s;if(!a&&(this.policy!=="patch"||i.changeType!=="patch"||!p(t,this.deps.machineId,i.current,i.latest)))return;const l=this.deps.getIdleState(),n=(this.deps.now??Date.now)(),o=this.eligibleSince.get(i.latest)??n;if(this.eligibleSince.set(i.latest,o),!(!a&&!l.idle&&n-o<t.maxIdleWaitMs)){this.upgradeInFlight=!0;try{await this.deps.startUpgrade(i.latest),this.eligibleSince.delete(i.latest)}finally{this.upgradeInFlight=!1}}}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.deps.intervalMs??5*6e4)})},i),this.timer.unref?.()}}export{y as AutoUpgradeScheduler,h as deterministicRolloutBucket,f as fetchCliReleasePolicy,p as isAutomaticPatchAllowed};
1
+ import{checkForUpdate as l,isUpgradeVersionInCooldown as c}from"./engine.js";const u={automaticPatchEnabled:!1,rolloutPercentage:0,pausedVersions:[],blockedVersions:[],blockedCurrentVersions:[],killSwitch:!0,releaseLevel:"normal",maxIdleWaitMs:30*6e4,requiredCapabilities:[],externalUpdaterEnabled:!1};function d(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 m(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 d(i)<s}async function h(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 f{deps;policy="none";timer=null;started=!1;upgradeInFlight=!1;constructor(i){this.deps=i}start(){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(this.upgradeInFlight)return;const i=await(this.deps.checkForUpdate??l)(this.deps.currentVersion);if(!i.hasUpdate||(this.deps.inCooldown??c)(i.latest))return;let t=u;try{t=await(this.deps.fetchReleasePolicy??(()=>h(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(o=>!(this.deps.advertisedCapabilities??[]).includes(o))||t.minimumUpdaterProtocolVersion!==void 0&&(this.deps.updaterProtocolVersion??0)<t.minimumUpdaterProtocolVersion,a=e==="required"||e==="blocked"||s;if(!a&&(this.policy!=="patch"||i.changeType!=="patch"||!m(t,this.deps.machineId,i.current,i.latest)))return;const n=this.deps.getIdleState();if(!(!a&&!n.idle)){this.upgradeInFlight=!0;try{await this.deps.startUpgrade(i.latest)}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{f as AutoUpgradeScheduler,d as deterministicRolloutBucket,h as fetchCliReleasePolicy,m as isAutomaticPatchAllowed};
@@ -271,6 +271,8 @@ export type NianSession = {
271
271
  id: string;
272
272
  /** Device-local lifecycle only; never sent as canonical session metadata. */
273
273
  localCreationState?: 'draft' | 'created';
274
+ /** Client-local user-message sort watermark; not canonical server metadata. */
275
+ lastUserMessageAt?: string | null;
274
276
  agentIdentityId?: string | null;
275
277
  machineId: string;
276
278
  userId: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shennian",
3
- "version": "0.4.38",
3
+ "version": "0.4.39",
4
4
  "description": "Shennian — AI Agent Control Plane CLI",
5
5
  "type": "module",
6
6
  "bin": {