chainlesschain 0.45.20 → 0.45.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chainlesschain",
3
- "version": "0.45.20",
3
+ "version": "0.45.22",
4
4
  "description": "CLI for ChainlessChain - install, configure, and manage your personal AI management system",
5
5
  "type": "module",
6
6
  "bin": {
@@ -20,7 +20,8 @@
20
20
  "format": "prettier --write \"src/**/*.js\" \"bin/**/*.js\" \"__tests__/**/*.js\"",
21
21
  "sync-skill-packs": "node --input-type=module -e \"import { generateCliPacks } from './src/lib/skill-packs/generator.js'; const r = await generateCliPacks({ force: false }); console.log('Skill packs synced:', r.generated.length, 'generated,', r.skipped.length, 'skipped');\"",
22
22
  "postinstall": "node --input-type=module -e \"import { generateCliPacks } from './src/lib/skill-packs/generator.js'; generateCliPacks({ force: false }).catch(() => {});\" 2>/dev/null || true",
23
- "build:web-panel": "cd ../web-panel && npm install --legacy-peer-deps && npm run build && node --input-type=module -e \"import fs from 'fs'; import path from 'path'; const src=path.resolve(process.cwd(),'dist'),dst=path.resolve(process.cwd(),'../cli/src/assets/web-panel'); fs.rmSync(dst,{recursive:true,force:true}); fs.cpSync(src,dst,{recursive:true}); console.log('Web panel bundled to',dst);\"",
23
+ "build:web-panel": "node scripts/build-web-panel.mjs",
24
+ "build:web-panel:force": "node scripts/build-web-panel.mjs --force",
24
25
  "prepublishOnly": "npm run build:web-panel"
25
26
  },
26
27
  "engines": {
@@ -0,0 +1 @@
1
+ ad4e0429f0f727d2e424be07b44b0e8687a6096a0b52fa5e82b1e4475cd9d445
@@ -53,6 +53,7 @@ export class BackgroundTaskManager extends EventEmitter {
53
53
  this.tasks = new Map();
54
54
  this.processes = new Map();
55
55
  this._checkInterval = null;
56
+ this._createSeq = 0;
56
57
  if (options.recoverOnStart) {
57
58
  this._loadPersistedTasks({
58
59
  recoverPending: options.recoverPending !== false,
@@ -87,6 +88,7 @@ export class BackgroundTaskManager extends EventEmitter {
87
88
  recoverySourceStatus: null,
88
89
  ownerNodeId: spec.ownerNodeId || this.nodeId,
89
90
  recoveryDecision: null,
91
+ _seq: ++this._createSeq,
90
92
  };
91
93
 
92
94
  this._recordHistory(task, "created", {
@@ -199,7 +201,11 @@ export class BackgroundTaskManager extends EventEmitter {
199
201
  if (filter.status) {
200
202
  tasks = tasks.filter((task) => task.status === filter.status);
201
203
  }
202
- return tasks.sort((a, b) => b.createdAt - a.createdAt);
204
+ return tasks.sort((a, b) => {
205
+ if (b.createdAt !== a.createdAt) return b.createdAt - a.createdAt;
206
+ // Tiebreak: insertion sequence (newer = higher _seq)
207
+ return (b._seq || 0) - (a._seq || 0);
208
+ });
203
209
  }
204
210
 
205
211
  stop(taskId) {
@@ -143,10 +143,18 @@ export function listJsonlSessions(options = {}) {
143
143
  updated_at: lastEvent
144
144
  ? new Date(lastEvent.timestamp).toISOString()
145
145
  : "",
146
+ _lastTs: lastEvent?.timestamp || 0,
147
+ _eventCount: events.length,
146
148
  };
147
149
  })
148
- .sort((a, b) => (b.updated_at > a.updated_at ? 1 : -1))
149
- .slice(0, limit);
150
+ .sort((a, b) => {
151
+ // Primary: numeric timestamp descending
152
+ if (b._lastTs !== a._lastTs) return b._lastTs - a._lastTs;
153
+ // Tiebreak when ms collides: more events = more recent activity
154
+ return b._eventCount - a._eventCount;
155
+ })
156
+ .slice(0, limit)
157
+ .map(({ _lastTs, _eventCount, ...rest }) => rest);
150
158
 
151
159
  return files;
152
160
  }