@prismer/runtime 2.0.5 → 2.0.6

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/cli.cjs CHANGED
@@ -2268,7 +2268,7 @@ var require_package = __commonJS({
2268
2268
  "package.json"(exports2, module2) {
2269
2269
  module2.exports = {
2270
2270
  name: "@prismer/runtime",
2271
- version: "2.0.5",
2271
+ version: "2.0.6",
2272
2272
  description: "Prismer Cloud daemon runtime \u2014 TS-only adapter host for hosted IM agents",
2273
2273
  type: "module",
2274
2274
  main: "dist/index.js",
@@ -12795,6 +12795,7 @@ var Runner = class extends import_node_events3.EventEmitter {
12795
12795
  workspaceId = "";
12796
12796
  wsConnected = false;
12797
12797
  hostedAgents = /* @__PURE__ */ new Map();
12798
+ rejectedHostedAgentIds = /* @__PURE__ */ new Map();
12798
12799
  runningTasks = /* @__PURE__ */ new Map();
12799
12800
  lastTaskError;
12800
12801
  heartbeatTimer;
@@ -13240,6 +13241,9 @@ var Runner = class extends import_node_events3.EventEmitter {
13240
13241
  profilesByAgent.set(p.agent_im_user_id, list);
13241
13242
  }
13242
13243
  for (const a of agents) {
13244
+ if (this.rejectedHostedAgentIds.has(a.im_user_id)) {
13245
+ continue;
13246
+ }
13243
13247
  let caps = [];
13244
13248
  try {
13245
13249
  caps = JSON.parse(a.capabilities);
@@ -13289,6 +13293,7 @@ var Runner = class extends import_node_events3.EventEmitter {
13289
13293
  * Used to populate the `agents` list in agent.host.declare.
13290
13294
  */
13291
13295
  setHostedAgent(agent) {
13296
+ this.rejectedHostedAgentIds.delete(agent.imUserId);
13292
13297
  this.hostedAgents.set(agent.imUserId, {
13293
13298
  imUserId: agent.imUserId,
13294
13299
  name: agent.name,
@@ -13321,6 +13326,7 @@ var Runner = class extends import_node_events3.EventEmitter {
13321
13326
  );
13322
13327
  });
13323
13328
  tx(payload);
13329
+ this.rejectedHostedAgentIds.delete(payload.imUserId);
13324
13330
  this.loadAgentsFromDb();
13325
13331
  if (this.wsConnected) this.sendDeclare();
13326
13332
  return {
@@ -13568,6 +13574,7 @@ var Runner = class extends import_node_events3.EventEmitter {
13568
13574
  }
13569
13575
  async onHostAcked(payload) {
13570
13576
  this.workspaceId = payload.workspaceId;
13577
+ const ownershipLockChanged = await this.applyHostAckOwnershipLock(payload);
13571
13578
  void this.reportTransport().catch((err) => {
13572
13579
  process.stderr.write(
13573
13580
  `[daemon] transport-probe report failed: ${err.message}
@@ -13583,7 +13590,9 @@ var Runner = class extends import_node_events3.EventEmitter {
13583
13590
  (err) => log7.error("Asset sync failed", err.message)
13584
13591
  );
13585
13592
  await this.ensureDropFolderRuntime(this.workspaceId);
13586
- for (const id of payload.profilesToSync) {
13593
+ const profilesToSync = payload.profilesToSync ?? [];
13594
+ const profilesToDelete = payload.profilesToDelete ?? [];
13595
+ for (const id of profilesToSync) {
13587
13596
  try {
13588
13597
  await this.servicePool.drop(id);
13589
13598
  await this.syncProfileFromCloud(id);
@@ -13591,7 +13600,7 @@ var Runner = class extends import_node_events3.EventEmitter {
13591
13600
  this.emit("sync-error", err);
13592
13601
  }
13593
13602
  }
13594
- for (const id of payload.profilesToDelete ?? []) {
13603
+ for (const id of profilesToDelete) {
13595
13604
  const row = this.db.prepare("SELECT agent_im_user_id FROM agent_profiles WHERE id = ?").get(id);
13596
13605
  this.db.prepare("DELETE FROM agent_profiles WHERE id = ?").run(id);
13597
13606
  if (row) {
@@ -13600,10 +13609,37 @@ var Runner = class extends import_node_events3.EventEmitter {
13600
13609
  process.stderr.write(`[daemon] tombstone profile=${id}
13601
13610
  `);
13602
13611
  }
13603
- if (payload.profilesToDelete?.length) this.loadAgentsFromDb();
13604
- if ((payload.profilesToSync.length > 0 || (payload.profilesToDelete?.length ?? 0) > 0) && this.wsConnected) this.sendDeclare();
13612
+ if (profilesToDelete.length) this.loadAgentsFromDb();
13613
+ if ((ownershipLockChanged || profilesToSync.length > 0 || profilesToDelete.length > 0) && this.wsConnected) {
13614
+ this.sendDeclare();
13615
+ }
13605
13616
  this.emit("host-acked", payload);
13606
13617
  }
13618
+ async applyHostAckOwnershipLock(payload) {
13619
+ const rejected = payload.rejectedAgents ?? [];
13620
+ if (rejected.length === 0) return false;
13621
+ let changed = false;
13622
+ for (const rejection of rejected) {
13623
+ if (!rejection?.imUserId) continue;
13624
+ const agentImUserId = rejection.imUserId;
13625
+ this.rejectedHostedAgentIds.set(agentImUserId, {
13626
+ ...rejection,
13627
+ rejectedAt: Date.now()
13628
+ });
13629
+ const wasHosted = this.hostedAgents.delete(agentImUserId);
13630
+ const profiles = this.db.prepare("SELECT id FROM agent_profiles WHERE agent_im_user_id = ?").all(agentImUserId);
13631
+ const deleted = this.db.prepare("DELETE FROM agents WHERE im_user_id = ?").run(agentImUserId);
13632
+ await Promise.all(profiles.map((profile) => this.servicePool.drop(profile.id)));
13633
+ if (wasHosted || deleted.changes > 0) {
13634
+ changed = true;
13635
+ process.stderr.write(
13636
+ `[daemon] ownership rejected agent=${agentImUserId} reason=${rejection.reason} owner=${rejection.ownerDaemonId ?? "(unknown)"} \u2014 stop declaring locally
13637
+ `
13638
+ );
13639
+ }
13640
+ }
13641
+ return changed;
13642
+ }
13607
13643
  async onTaskDispatch(payload, requestId) {
13608
13644
  const targetDaemonId = readTargetDaemonId(payload);
13609
13645
  if (targetDaemonId && targetDaemonId !== this.config.daemon_id) {
@@ -13886,18 +13922,22 @@ var Runner = class extends import_node_events3.EventEmitter {
13886
13922
  const name = agent?.card?.name || agent?.displayName || agent?.username || profile.agentImUserId;
13887
13923
  const now = Date.now();
13888
13924
  const tx = this.db.transaction(() => {
13889
- this.db.prepare(
13890
- `INSERT OR REPLACE INTO agents
13891
- (im_user_id, workspace_id, name, adapter_name, capabilities, status, version, synced_at, dirty)
13892
- VALUES (?, ?, ?, ?, ?, 'offline', 1, ?, 0)`
13893
- ).run(
13894
- profile.agentImUserId,
13895
- profile.workspaceId,
13896
- name,
13897
- profile.adapterName,
13898
- JSON.stringify(capabilities),
13899
- now
13900
- );
13925
+ if (this.rejectedHostedAgentIds.has(profile.agentImUserId)) {
13926
+ this.db.prepare("DELETE FROM agents WHERE im_user_id = ?").run(profile.agentImUserId);
13927
+ } else {
13928
+ this.db.prepare(
13929
+ `INSERT OR REPLACE INTO agents
13930
+ (im_user_id, workspace_id, name, adapter_name, capabilities, status, version, synced_at, dirty)
13931
+ VALUES (?, ?, ?, ?, ?, 'offline', 1, ?, 0)`
13932
+ ).run(
13933
+ profile.agentImUserId,
13934
+ profile.workspaceId,
13935
+ name,
13936
+ profile.adapterName,
13937
+ JSON.stringify(capabilities),
13938
+ now
13939
+ );
13940
+ }
13901
13941
  this.db.prepare(
13902
13942
  `INSERT OR REPLACE INTO agent_profiles
13903
13943
  (id, workspace_id, agent_im_user_id, adapter_name, name, config, version, synced_at, dirty, deleted_at)
@@ -16837,7 +16877,7 @@ async function readResponseError(res) {
16837
16877
 
16838
16878
  // src/cli/index.ts
16839
16879
  init_ui();
16840
- var VERSION = "2.0.5";
16880
+ var VERSION = "2.0.6";
16841
16881
  function buildProgram() {
16842
16882
  const program = new import_commander20.Command("prismer").description("Prismer Cloud daemon CLI (TS-only).").version(VERSION);
16843
16883
  program.addCommand(buildBannerCommand());
package/dist/cli.js CHANGED
@@ -2245,7 +2245,7 @@ var require_package = __commonJS({
2245
2245
  "package.json"(exports, module) {
2246
2246
  module.exports = {
2247
2247
  name: "@prismer/runtime",
2248
- version: "2.0.5",
2248
+ version: "2.0.6",
2249
2249
  description: "Prismer Cloud daemon runtime \u2014 TS-only adapter host for hosted IM agents",
2250
2250
  type: "module",
2251
2251
  main: "dist/index.js",
@@ -12778,6 +12778,7 @@ var Runner = class extends EventEmitter3 {
12778
12778
  workspaceId = "";
12779
12779
  wsConnected = false;
12780
12780
  hostedAgents = /* @__PURE__ */ new Map();
12781
+ rejectedHostedAgentIds = /* @__PURE__ */ new Map();
12781
12782
  runningTasks = /* @__PURE__ */ new Map();
12782
12783
  lastTaskError;
12783
12784
  heartbeatTimer;
@@ -13223,6 +13224,9 @@ var Runner = class extends EventEmitter3 {
13223
13224
  profilesByAgent.set(p.agent_im_user_id, list);
13224
13225
  }
13225
13226
  for (const a of agents) {
13227
+ if (this.rejectedHostedAgentIds.has(a.im_user_id)) {
13228
+ continue;
13229
+ }
13226
13230
  let caps = [];
13227
13231
  try {
13228
13232
  caps = JSON.parse(a.capabilities);
@@ -13272,6 +13276,7 @@ var Runner = class extends EventEmitter3 {
13272
13276
  * Used to populate the `agents` list in agent.host.declare.
13273
13277
  */
13274
13278
  setHostedAgent(agent) {
13279
+ this.rejectedHostedAgentIds.delete(agent.imUserId);
13275
13280
  this.hostedAgents.set(agent.imUserId, {
13276
13281
  imUserId: agent.imUserId,
13277
13282
  name: agent.name,
@@ -13304,6 +13309,7 @@ var Runner = class extends EventEmitter3 {
13304
13309
  );
13305
13310
  });
13306
13311
  tx(payload);
13312
+ this.rejectedHostedAgentIds.delete(payload.imUserId);
13307
13313
  this.loadAgentsFromDb();
13308
13314
  if (this.wsConnected) this.sendDeclare();
13309
13315
  return {
@@ -13551,6 +13557,7 @@ var Runner = class extends EventEmitter3 {
13551
13557
  }
13552
13558
  async onHostAcked(payload) {
13553
13559
  this.workspaceId = payload.workspaceId;
13560
+ const ownershipLockChanged = await this.applyHostAckOwnershipLock(payload);
13554
13561
  void this.reportTransport().catch((err) => {
13555
13562
  process.stderr.write(
13556
13563
  `[daemon] transport-probe report failed: ${err.message}
@@ -13566,7 +13573,9 @@ var Runner = class extends EventEmitter3 {
13566
13573
  (err) => log7.error("Asset sync failed", err.message)
13567
13574
  );
13568
13575
  await this.ensureDropFolderRuntime(this.workspaceId);
13569
- for (const id of payload.profilesToSync) {
13576
+ const profilesToSync = payload.profilesToSync ?? [];
13577
+ const profilesToDelete = payload.profilesToDelete ?? [];
13578
+ for (const id of profilesToSync) {
13570
13579
  try {
13571
13580
  await this.servicePool.drop(id);
13572
13581
  await this.syncProfileFromCloud(id);
@@ -13574,7 +13583,7 @@ var Runner = class extends EventEmitter3 {
13574
13583
  this.emit("sync-error", err);
13575
13584
  }
13576
13585
  }
13577
- for (const id of payload.profilesToDelete ?? []) {
13586
+ for (const id of profilesToDelete) {
13578
13587
  const row = this.db.prepare("SELECT agent_im_user_id FROM agent_profiles WHERE id = ?").get(id);
13579
13588
  this.db.prepare("DELETE FROM agent_profiles WHERE id = ?").run(id);
13580
13589
  if (row) {
@@ -13583,10 +13592,37 @@ var Runner = class extends EventEmitter3 {
13583
13592
  process.stderr.write(`[daemon] tombstone profile=${id}
13584
13593
  `);
13585
13594
  }
13586
- if (payload.profilesToDelete?.length) this.loadAgentsFromDb();
13587
- if ((payload.profilesToSync.length > 0 || (payload.profilesToDelete?.length ?? 0) > 0) && this.wsConnected) this.sendDeclare();
13595
+ if (profilesToDelete.length) this.loadAgentsFromDb();
13596
+ if ((ownershipLockChanged || profilesToSync.length > 0 || profilesToDelete.length > 0) && this.wsConnected) {
13597
+ this.sendDeclare();
13598
+ }
13588
13599
  this.emit("host-acked", payload);
13589
13600
  }
13601
+ async applyHostAckOwnershipLock(payload) {
13602
+ const rejected = payload.rejectedAgents ?? [];
13603
+ if (rejected.length === 0) return false;
13604
+ let changed = false;
13605
+ for (const rejection of rejected) {
13606
+ if (!rejection?.imUserId) continue;
13607
+ const agentImUserId = rejection.imUserId;
13608
+ this.rejectedHostedAgentIds.set(agentImUserId, {
13609
+ ...rejection,
13610
+ rejectedAt: Date.now()
13611
+ });
13612
+ const wasHosted = this.hostedAgents.delete(agentImUserId);
13613
+ const profiles = this.db.prepare("SELECT id FROM agent_profiles WHERE agent_im_user_id = ?").all(agentImUserId);
13614
+ const deleted = this.db.prepare("DELETE FROM agents WHERE im_user_id = ?").run(agentImUserId);
13615
+ await Promise.all(profiles.map((profile) => this.servicePool.drop(profile.id)));
13616
+ if (wasHosted || deleted.changes > 0) {
13617
+ changed = true;
13618
+ process.stderr.write(
13619
+ `[daemon] ownership rejected agent=${agentImUserId} reason=${rejection.reason} owner=${rejection.ownerDaemonId ?? "(unknown)"} \u2014 stop declaring locally
13620
+ `
13621
+ );
13622
+ }
13623
+ }
13624
+ return changed;
13625
+ }
13590
13626
  async onTaskDispatch(payload, requestId) {
13591
13627
  const targetDaemonId = readTargetDaemonId(payload);
13592
13628
  if (targetDaemonId && targetDaemonId !== this.config.daemon_id) {
@@ -13869,18 +13905,22 @@ var Runner = class extends EventEmitter3 {
13869
13905
  const name = agent?.card?.name || agent?.displayName || agent?.username || profile.agentImUserId;
13870
13906
  const now = Date.now();
13871
13907
  const tx = this.db.transaction(() => {
13872
- this.db.prepare(
13873
- `INSERT OR REPLACE INTO agents
13874
- (im_user_id, workspace_id, name, adapter_name, capabilities, status, version, synced_at, dirty)
13875
- VALUES (?, ?, ?, ?, ?, 'offline', 1, ?, 0)`
13876
- ).run(
13877
- profile.agentImUserId,
13878
- profile.workspaceId,
13879
- name,
13880
- profile.adapterName,
13881
- JSON.stringify(capabilities),
13882
- now
13883
- );
13908
+ if (this.rejectedHostedAgentIds.has(profile.agentImUserId)) {
13909
+ this.db.prepare("DELETE FROM agents WHERE im_user_id = ?").run(profile.agentImUserId);
13910
+ } else {
13911
+ this.db.prepare(
13912
+ `INSERT OR REPLACE INTO agents
13913
+ (im_user_id, workspace_id, name, adapter_name, capabilities, status, version, synced_at, dirty)
13914
+ VALUES (?, ?, ?, ?, ?, 'offline', 1, ?, 0)`
13915
+ ).run(
13916
+ profile.agentImUserId,
13917
+ profile.workspaceId,
13918
+ name,
13919
+ profile.adapterName,
13920
+ JSON.stringify(capabilities),
13921
+ now
13922
+ );
13923
+ }
13884
13924
  this.db.prepare(
13885
13925
  `INSERT OR REPLACE INTO agent_profiles
13886
13926
  (id, workspace_id, agent_im_user_id, adapter_name, name, config, version, synced_at, dirty, deleted_at)
@@ -16820,7 +16860,7 @@ async function readResponseError(res) {
16820
16860
 
16821
16861
  // src/cli/index.ts
16822
16862
  init_ui();
16823
- var VERSION = "2.0.5";
16863
+ var VERSION = "2.0.6";
16824
16864
  function buildProgram() {
16825
16865
  const program = new Command20("prismer").description("Prismer Cloud daemon CLI (TS-only).").version(VERSION);
16826
16866
  program.addCommand(buildBannerCommand());
package/dist/index.cjs CHANGED
@@ -2657,7 +2657,7 @@ var require_package = __commonJS({
2657
2657
  "package.json"(exports2, module2) {
2658
2658
  module2.exports = {
2659
2659
  name: "@prismer/runtime",
2660
- version: "2.0.5",
2660
+ version: "2.0.6",
2661
2661
  description: "Prismer Cloud daemon runtime \u2014 TS-only adapter host for hosted IM agents",
2662
2662
  type: "module",
2663
2663
  main: "dist/index.js",
@@ -11046,6 +11046,7 @@ var Runner = class extends import_node_events3.EventEmitter {
11046
11046
  workspaceId = "";
11047
11047
  wsConnected = false;
11048
11048
  hostedAgents = /* @__PURE__ */ new Map();
11049
+ rejectedHostedAgentIds = /* @__PURE__ */ new Map();
11049
11050
  runningTasks = /* @__PURE__ */ new Map();
11050
11051
  lastTaskError;
11051
11052
  heartbeatTimer;
@@ -11491,6 +11492,9 @@ var Runner = class extends import_node_events3.EventEmitter {
11491
11492
  profilesByAgent.set(p.agent_im_user_id, list);
11492
11493
  }
11493
11494
  for (const a of agents) {
11495
+ if (this.rejectedHostedAgentIds.has(a.im_user_id)) {
11496
+ continue;
11497
+ }
11494
11498
  let caps = [];
11495
11499
  try {
11496
11500
  caps = JSON.parse(a.capabilities);
@@ -11540,6 +11544,7 @@ var Runner = class extends import_node_events3.EventEmitter {
11540
11544
  * Used to populate the `agents` list in agent.host.declare.
11541
11545
  */
11542
11546
  setHostedAgent(agent) {
11547
+ this.rejectedHostedAgentIds.delete(agent.imUserId);
11543
11548
  this.hostedAgents.set(agent.imUserId, {
11544
11549
  imUserId: agent.imUserId,
11545
11550
  name: agent.name,
@@ -11572,6 +11577,7 @@ var Runner = class extends import_node_events3.EventEmitter {
11572
11577
  );
11573
11578
  });
11574
11579
  tx(payload);
11580
+ this.rejectedHostedAgentIds.delete(payload.imUserId);
11575
11581
  this.loadAgentsFromDb();
11576
11582
  if (this.wsConnected) this.sendDeclare();
11577
11583
  return {
@@ -11819,6 +11825,7 @@ var Runner = class extends import_node_events3.EventEmitter {
11819
11825
  }
11820
11826
  async onHostAcked(payload) {
11821
11827
  this.workspaceId = payload.workspaceId;
11828
+ const ownershipLockChanged = await this.applyHostAckOwnershipLock(payload);
11822
11829
  void this.reportTransport().catch((err) => {
11823
11830
  process.stderr.write(
11824
11831
  `[daemon] transport-probe report failed: ${err.message}
@@ -11834,7 +11841,9 @@ var Runner = class extends import_node_events3.EventEmitter {
11834
11841
  (err) => log7.error("Asset sync failed", err.message)
11835
11842
  );
11836
11843
  await this.ensureDropFolderRuntime(this.workspaceId);
11837
- for (const id of payload.profilesToSync) {
11844
+ const profilesToSync = payload.profilesToSync ?? [];
11845
+ const profilesToDelete = payload.profilesToDelete ?? [];
11846
+ for (const id of profilesToSync) {
11838
11847
  try {
11839
11848
  await this.servicePool.drop(id);
11840
11849
  await this.syncProfileFromCloud(id);
@@ -11842,7 +11851,7 @@ var Runner = class extends import_node_events3.EventEmitter {
11842
11851
  this.emit("sync-error", err);
11843
11852
  }
11844
11853
  }
11845
- for (const id of payload.profilesToDelete ?? []) {
11854
+ for (const id of profilesToDelete) {
11846
11855
  const row = this.db.prepare("SELECT agent_im_user_id FROM agent_profiles WHERE id = ?").get(id);
11847
11856
  this.db.prepare("DELETE FROM agent_profiles WHERE id = ?").run(id);
11848
11857
  if (row) {
@@ -11851,10 +11860,37 @@ var Runner = class extends import_node_events3.EventEmitter {
11851
11860
  process.stderr.write(`[daemon] tombstone profile=${id}
11852
11861
  `);
11853
11862
  }
11854
- if (payload.profilesToDelete?.length) this.loadAgentsFromDb();
11855
- if ((payload.profilesToSync.length > 0 || (payload.profilesToDelete?.length ?? 0) > 0) && this.wsConnected) this.sendDeclare();
11863
+ if (profilesToDelete.length) this.loadAgentsFromDb();
11864
+ if ((ownershipLockChanged || profilesToSync.length > 0 || profilesToDelete.length > 0) && this.wsConnected) {
11865
+ this.sendDeclare();
11866
+ }
11856
11867
  this.emit("host-acked", payload);
11857
11868
  }
11869
+ async applyHostAckOwnershipLock(payload) {
11870
+ const rejected = payload.rejectedAgents ?? [];
11871
+ if (rejected.length === 0) return false;
11872
+ let changed = false;
11873
+ for (const rejection of rejected) {
11874
+ if (!rejection?.imUserId) continue;
11875
+ const agentImUserId = rejection.imUserId;
11876
+ this.rejectedHostedAgentIds.set(agentImUserId, {
11877
+ ...rejection,
11878
+ rejectedAt: Date.now()
11879
+ });
11880
+ const wasHosted = this.hostedAgents.delete(agentImUserId);
11881
+ const profiles = this.db.prepare("SELECT id FROM agent_profiles WHERE agent_im_user_id = ?").all(agentImUserId);
11882
+ const deleted = this.db.prepare("DELETE FROM agents WHERE im_user_id = ?").run(agentImUserId);
11883
+ await Promise.all(profiles.map((profile) => this.servicePool.drop(profile.id)));
11884
+ if (wasHosted || deleted.changes > 0) {
11885
+ changed = true;
11886
+ process.stderr.write(
11887
+ `[daemon] ownership rejected agent=${agentImUserId} reason=${rejection.reason} owner=${rejection.ownerDaemonId ?? "(unknown)"} \u2014 stop declaring locally
11888
+ `
11889
+ );
11890
+ }
11891
+ }
11892
+ return changed;
11893
+ }
11858
11894
  async onTaskDispatch(payload, requestId) {
11859
11895
  const targetDaemonId = readTargetDaemonId(payload);
11860
11896
  if (targetDaemonId && targetDaemonId !== this.config.daemon_id) {
@@ -12137,18 +12173,22 @@ var Runner = class extends import_node_events3.EventEmitter {
12137
12173
  const name = agent?.card?.name || agent?.displayName || agent?.username || profile.agentImUserId;
12138
12174
  const now = Date.now();
12139
12175
  const tx = this.db.transaction(() => {
12140
- this.db.prepare(
12141
- `INSERT OR REPLACE INTO agents
12142
- (im_user_id, workspace_id, name, adapter_name, capabilities, status, version, synced_at, dirty)
12143
- VALUES (?, ?, ?, ?, ?, 'offline', 1, ?, 0)`
12144
- ).run(
12145
- profile.agentImUserId,
12146
- profile.workspaceId,
12147
- name,
12148
- profile.adapterName,
12149
- JSON.stringify(capabilities),
12150
- now
12151
- );
12176
+ if (this.rejectedHostedAgentIds.has(profile.agentImUserId)) {
12177
+ this.db.prepare("DELETE FROM agents WHERE im_user_id = ?").run(profile.agentImUserId);
12178
+ } else {
12179
+ this.db.prepare(
12180
+ `INSERT OR REPLACE INTO agents
12181
+ (im_user_id, workspace_id, name, adapter_name, capabilities, status, version, synced_at, dirty)
12182
+ VALUES (?, ?, ?, ?, ?, 'offline', 1, ?, 0)`
12183
+ ).run(
12184
+ profile.agentImUserId,
12185
+ profile.workspaceId,
12186
+ name,
12187
+ profile.adapterName,
12188
+ JSON.stringify(capabilities),
12189
+ now
12190
+ );
12191
+ }
12152
12192
  this.db.prepare(
12153
12193
  `INSERT OR REPLACE INTO agent_profiles
12154
12194
  (id, workspace_id, agent_im_user_id, adapter_name, name, config, version, synced_at, dirty, deleted_at)
@@ -17012,7 +17052,7 @@ async function readResponseError(res) {
17012
17052
 
17013
17053
  // src/cli/index.ts
17014
17054
  init_ui();
17015
- var VERSION = "2.0.5";
17055
+ var VERSION = "2.0.6";
17016
17056
  function buildProgram() {
17017
17057
  const program = new import_commander20.Command("prismer").description("Prismer Cloud daemon CLI (TS-only).").version(VERSION);
17018
17058
  program.addCommand(buildBannerCommand());
package/dist/index.d.cts CHANGED
@@ -21,6 +21,11 @@ interface AgentHostDeclarePayload {
21
21
  platform: 'darwin' | 'linux' | 'win32';
22
22
  agents: HostedAgentDeclaration[];
23
23
  }
24
+ interface RejectedHostedAgent {
25
+ imUserId: string;
26
+ reason: 'bound-to-other-daemon' | 'not-owned' | 'unknown';
27
+ ownerDaemonId?: string;
28
+ }
24
29
  interface HostAckedPayload {
25
30
  workspaceId: string;
26
31
  syncCursor: {
@@ -32,6 +37,8 @@ interface HostAckedPayload {
32
37
  /** Profile IDs the daemon declared but that no longer exist on the cloud
33
38
  * (soft-deleted). The daemon should remove these from its local store. */
34
39
  profilesToDelete: string[];
40
+ acceptedAgents?: string[];
41
+ rejectedAgents?: RejectedHostedAgent[];
35
42
  }
36
43
  interface AgentStatusChangedPayload {
37
44
  agentImUserId: string;
@@ -2307,6 +2314,7 @@ declare class Runner extends EventEmitter {
2307
2314
  private workspaceId;
2308
2315
  private wsConnected;
2309
2316
  private readonly hostedAgents;
2317
+ private readonly rejectedHostedAgentIds;
2310
2318
  private readonly runningTasks;
2311
2319
  private lastTaskError?;
2312
2320
  private heartbeatTimer?;
@@ -2417,6 +2425,7 @@ declare class Runner extends EventEmitter {
2417
2425
  */
2418
2426
  private onWebhookDispatch;
2419
2427
  private onHostAcked;
2428
+ private applyHostAckOwnershipLock;
2420
2429
  private onTaskDispatch;
2421
2430
  private onTaskCancel;
2422
2431
  private findMessageDispatchAgent;
@@ -2646,4 +2655,4 @@ declare const codexAdapter: AdapterDef;
2646
2655
  declare function buildProgram(): Command;
2647
2656
  declare function runCli(argv?: string[]): Promise<void>;
2648
2657
 
2649
- export { type AcquireResult, type AdapterDef, type AdapterKind, AdapterRegistry, type AdapterService, type AgentChangedPayload, type AgentDispatchReplyAttachment, type AgentDispatchReplyPayload, type AgentDispatchReplyStatus, type AgentDispatchRequest, type AgentDispatchResponse, type AgentHostDeclarePayload, type AgentProfile, type AgentProfileChangedPayload, type AgentStatusChangedPayload, AssetCache, type AssetCacheOptions, type AssetChangedPayload, type AssetDispatchObservation, type AssetDispatchStrategy, type AssetRef, BUILTIN_ROLE_TEMPLATES, type CachedAsset, type ClaudeCodeConfig, CloudClient, type CloudClientOptions, CloudError, type CloudResponse, type CodexConfig, type Config, type ConfigPaths, ConfigSchema, type DispatchDeps, type Envelope, type FlushFn, type FlushResult, type HealthStatus, type HermesProfileConfig, type HostAckedPayload, type HostedAgentDeclaration, type IMAgentStatus, type IMWSMessage, type LocalDb, LocalServer, type LocalServerOptions, type LocalServerState, type MessageDispatchAgent, type MessageDispatchDeps, type MessageDispatchHandle, type MessageDispatchTaskInput, type NormalizedContent, type OpenClawProfileConfig, type PairOptions, type PairResult, type ParseClaim, ParseClaimController, type ParseClaimControllerOptions, type ParsedPrismerUri, type PrismerUriType, type RoleTemplate, Runner, type RunnerOptions, ServicePool, type SyncOperation, SyncQueue, type SyncQueueRow, type SyncResourceType, type SyncStatus, SyncWorker, type SyncWorkerOptions, TARGET_SCHEMA_VERSION, type TaskCancelPayload, type TaskDispatchContextEntry, type TaskDispatchProgressPayload, type TaskDispatchReplyPayload, type TaskDispatchRequestPayload, type TaskInput, type TaskResult, UriResolver, type UriResolverOptions, type UrlResolution, type ValidationResult, WS_CLOSE, type WorkspaceChangedPayload, type WorkspaceFileBinding, type WorkspaceFileChangedPayload, WorkspaceMirror, type WorkspaceMirrorOptions, WsClient, type WsClientOptions, buildProgram, claudeCodeAdapter, codexAdapter, composePrompt, configExists, currentSchemaVersion, deriveWsUrl, envelope, extractHttpUrls, getRoleTemplate, handleAgentMessageDispatch, handleDispatch, hermesAdapter, isDaemonId, listRoleTemplates, loadConfig, newDaemonId, nextBackoffMs, openLocalDb, openclawAdapter, pair, parseCodexOutput, parseUris, resolvePaths, runCli, runMigrations, saveConfig };
2658
+ export { type AcquireResult, type AdapterDef, type AdapterKind, AdapterRegistry, type AdapterService, type AgentChangedPayload, type AgentDispatchReplyAttachment, type AgentDispatchReplyPayload, type AgentDispatchReplyStatus, type AgentDispatchRequest, type AgentDispatchResponse, type AgentHostDeclarePayload, type AgentProfile, type AgentProfileChangedPayload, type AgentStatusChangedPayload, AssetCache, type AssetCacheOptions, type AssetChangedPayload, type AssetDispatchObservation, type AssetDispatchStrategy, type AssetRef, BUILTIN_ROLE_TEMPLATES, type CachedAsset, type ClaudeCodeConfig, CloudClient, type CloudClientOptions, CloudError, type CloudResponse, type CodexConfig, type Config, type ConfigPaths, ConfigSchema, type DispatchDeps, type Envelope, type FlushFn, type FlushResult, type HealthStatus, type HermesProfileConfig, type HostAckedPayload, type HostedAgentDeclaration, type IMAgentStatus, type IMWSMessage, type LocalDb, LocalServer, type LocalServerOptions, type LocalServerState, type MessageDispatchAgent, type MessageDispatchDeps, type MessageDispatchHandle, type MessageDispatchTaskInput, type NormalizedContent, type OpenClawProfileConfig, type PairOptions, type PairResult, type ParseClaim, ParseClaimController, type ParseClaimControllerOptions, type ParsedPrismerUri, type PrismerUriType, type RejectedHostedAgent, type RoleTemplate, Runner, type RunnerOptions, ServicePool, type SyncOperation, SyncQueue, type SyncQueueRow, type SyncResourceType, type SyncStatus, SyncWorker, type SyncWorkerOptions, TARGET_SCHEMA_VERSION, type TaskCancelPayload, type TaskDispatchContextEntry, type TaskDispatchProgressPayload, type TaskDispatchReplyPayload, type TaskDispatchRequestPayload, type TaskInput, type TaskResult, UriResolver, type UriResolverOptions, type UrlResolution, type ValidationResult, WS_CLOSE, type WorkspaceChangedPayload, type WorkspaceFileBinding, type WorkspaceFileChangedPayload, WorkspaceMirror, type WorkspaceMirrorOptions, WsClient, type WsClientOptions, buildProgram, claudeCodeAdapter, codexAdapter, composePrompt, configExists, currentSchemaVersion, deriveWsUrl, envelope, extractHttpUrls, getRoleTemplate, handleAgentMessageDispatch, handleDispatch, hermesAdapter, isDaemonId, listRoleTemplates, loadConfig, newDaemonId, nextBackoffMs, openLocalDb, openclawAdapter, pair, parseCodexOutput, parseUris, resolvePaths, runCli, runMigrations, saveConfig };
package/dist/index.d.ts CHANGED
@@ -21,6 +21,11 @@ interface AgentHostDeclarePayload {
21
21
  platform: 'darwin' | 'linux' | 'win32';
22
22
  agents: HostedAgentDeclaration[];
23
23
  }
24
+ interface RejectedHostedAgent {
25
+ imUserId: string;
26
+ reason: 'bound-to-other-daemon' | 'not-owned' | 'unknown';
27
+ ownerDaemonId?: string;
28
+ }
24
29
  interface HostAckedPayload {
25
30
  workspaceId: string;
26
31
  syncCursor: {
@@ -32,6 +37,8 @@ interface HostAckedPayload {
32
37
  /** Profile IDs the daemon declared but that no longer exist on the cloud
33
38
  * (soft-deleted). The daemon should remove these from its local store. */
34
39
  profilesToDelete: string[];
40
+ acceptedAgents?: string[];
41
+ rejectedAgents?: RejectedHostedAgent[];
35
42
  }
36
43
  interface AgentStatusChangedPayload {
37
44
  agentImUserId: string;
@@ -2307,6 +2314,7 @@ declare class Runner extends EventEmitter {
2307
2314
  private workspaceId;
2308
2315
  private wsConnected;
2309
2316
  private readonly hostedAgents;
2317
+ private readonly rejectedHostedAgentIds;
2310
2318
  private readonly runningTasks;
2311
2319
  private lastTaskError?;
2312
2320
  private heartbeatTimer?;
@@ -2417,6 +2425,7 @@ declare class Runner extends EventEmitter {
2417
2425
  */
2418
2426
  private onWebhookDispatch;
2419
2427
  private onHostAcked;
2428
+ private applyHostAckOwnershipLock;
2420
2429
  private onTaskDispatch;
2421
2430
  private onTaskCancel;
2422
2431
  private findMessageDispatchAgent;
@@ -2646,4 +2655,4 @@ declare const codexAdapter: AdapterDef;
2646
2655
  declare function buildProgram(): Command;
2647
2656
  declare function runCli(argv?: string[]): Promise<void>;
2648
2657
 
2649
- export { type AcquireResult, type AdapterDef, type AdapterKind, AdapterRegistry, type AdapterService, type AgentChangedPayload, type AgentDispatchReplyAttachment, type AgentDispatchReplyPayload, type AgentDispatchReplyStatus, type AgentDispatchRequest, type AgentDispatchResponse, type AgentHostDeclarePayload, type AgentProfile, type AgentProfileChangedPayload, type AgentStatusChangedPayload, AssetCache, type AssetCacheOptions, type AssetChangedPayload, type AssetDispatchObservation, type AssetDispatchStrategy, type AssetRef, BUILTIN_ROLE_TEMPLATES, type CachedAsset, type ClaudeCodeConfig, CloudClient, type CloudClientOptions, CloudError, type CloudResponse, type CodexConfig, type Config, type ConfigPaths, ConfigSchema, type DispatchDeps, type Envelope, type FlushFn, type FlushResult, type HealthStatus, type HermesProfileConfig, type HostAckedPayload, type HostedAgentDeclaration, type IMAgentStatus, type IMWSMessage, type LocalDb, LocalServer, type LocalServerOptions, type LocalServerState, type MessageDispatchAgent, type MessageDispatchDeps, type MessageDispatchHandle, type MessageDispatchTaskInput, type NormalizedContent, type OpenClawProfileConfig, type PairOptions, type PairResult, type ParseClaim, ParseClaimController, type ParseClaimControllerOptions, type ParsedPrismerUri, type PrismerUriType, type RoleTemplate, Runner, type RunnerOptions, ServicePool, type SyncOperation, SyncQueue, type SyncQueueRow, type SyncResourceType, type SyncStatus, SyncWorker, type SyncWorkerOptions, TARGET_SCHEMA_VERSION, type TaskCancelPayload, type TaskDispatchContextEntry, type TaskDispatchProgressPayload, type TaskDispatchReplyPayload, type TaskDispatchRequestPayload, type TaskInput, type TaskResult, UriResolver, type UriResolverOptions, type UrlResolution, type ValidationResult, WS_CLOSE, type WorkspaceChangedPayload, type WorkspaceFileBinding, type WorkspaceFileChangedPayload, WorkspaceMirror, type WorkspaceMirrorOptions, WsClient, type WsClientOptions, buildProgram, claudeCodeAdapter, codexAdapter, composePrompt, configExists, currentSchemaVersion, deriveWsUrl, envelope, extractHttpUrls, getRoleTemplate, handleAgentMessageDispatch, handleDispatch, hermesAdapter, isDaemonId, listRoleTemplates, loadConfig, newDaemonId, nextBackoffMs, openLocalDb, openclawAdapter, pair, parseCodexOutput, parseUris, resolvePaths, runCli, runMigrations, saveConfig };
2658
+ export { type AcquireResult, type AdapterDef, type AdapterKind, AdapterRegistry, type AdapterService, type AgentChangedPayload, type AgentDispatchReplyAttachment, type AgentDispatchReplyPayload, type AgentDispatchReplyStatus, type AgentDispatchRequest, type AgentDispatchResponse, type AgentHostDeclarePayload, type AgentProfile, type AgentProfileChangedPayload, type AgentStatusChangedPayload, AssetCache, type AssetCacheOptions, type AssetChangedPayload, type AssetDispatchObservation, type AssetDispatchStrategy, type AssetRef, BUILTIN_ROLE_TEMPLATES, type CachedAsset, type ClaudeCodeConfig, CloudClient, type CloudClientOptions, CloudError, type CloudResponse, type CodexConfig, type Config, type ConfigPaths, ConfigSchema, type DispatchDeps, type Envelope, type FlushFn, type FlushResult, type HealthStatus, type HermesProfileConfig, type HostAckedPayload, type HostedAgentDeclaration, type IMAgentStatus, type IMWSMessage, type LocalDb, LocalServer, type LocalServerOptions, type LocalServerState, type MessageDispatchAgent, type MessageDispatchDeps, type MessageDispatchHandle, type MessageDispatchTaskInput, type NormalizedContent, type OpenClawProfileConfig, type PairOptions, type PairResult, type ParseClaim, ParseClaimController, type ParseClaimControllerOptions, type ParsedPrismerUri, type PrismerUriType, type RejectedHostedAgent, type RoleTemplate, Runner, type RunnerOptions, ServicePool, type SyncOperation, SyncQueue, type SyncQueueRow, type SyncResourceType, type SyncStatus, SyncWorker, type SyncWorkerOptions, TARGET_SCHEMA_VERSION, type TaskCancelPayload, type TaskDispatchContextEntry, type TaskDispatchProgressPayload, type TaskDispatchReplyPayload, type TaskDispatchRequestPayload, type TaskInput, type TaskResult, UriResolver, type UriResolverOptions, type UrlResolution, type ValidationResult, WS_CLOSE, type WorkspaceChangedPayload, type WorkspaceFileBinding, type WorkspaceFileChangedPayload, WorkspaceMirror, type WorkspaceMirrorOptions, WsClient, type WsClientOptions, buildProgram, claudeCodeAdapter, codexAdapter, composePrompt, configExists, currentSchemaVersion, deriveWsUrl, envelope, extractHttpUrls, getRoleTemplate, handleAgentMessageDispatch, handleDispatch, hermesAdapter, isDaemonId, listRoleTemplates, loadConfig, newDaemonId, nextBackoffMs, openLocalDb, openclawAdapter, pair, parseCodexOutput, parseUris, resolvePaths, runCli, runMigrations, saveConfig };
package/dist/index.js CHANGED
@@ -2633,7 +2633,7 @@ var require_package = __commonJS({
2633
2633
  "package.json"(exports, module) {
2634
2634
  module.exports = {
2635
2635
  name: "@prismer/runtime",
2636
- version: "2.0.5",
2636
+ version: "2.0.6",
2637
2637
  description: "Prismer Cloud daemon runtime \u2014 TS-only adapter host for hosted IM agents",
2638
2638
  type: "module",
2639
2639
  main: "dist/index.js",
@@ -10971,6 +10971,7 @@ var Runner = class extends EventEmitter3 {
10971
10971
  workspaceId = "";
10972
10972
  wsConnected = false;
10973
10973
  hostedAgents = /* @__PURE__ */ new Map();
10974
+ rejectedHostedAgentIds = /* @__PURE__ */ new Map();
10974
10975
  runningTasks = /* @__PURE__ */ new Map();
10975
10976
  lastTaskError;
10976
10977
  heartbeatTimer;
@@ -11416,6 +11417,9 @@ var Runner = class extends EventEmitter3 {
11416
11417
  profilesByAgent.set(p.agent_im_user_id, list);
11417
11418
  }
11418
11419
  for (const a of agents) {
11420
+ if (this.rejectedHostedAgentIds.has(a.im_user_id)) {
11421
+ continue;
11422
+ }
11419
11423
  let caps = [];
11420
11424
  try {
11421
11425
  caps = JSON.parse(a.capabilities);
@@ -11465,6 +11469,7 @@ var Runner = class extends EventEmitter3 {
11465
11469
  * Used to populate the `agents` list in agent.host.declare.
11466
11470
  */
11467
11471
  setHostedAgent(agent) {
11472
+ this.rejectedHostedAgentIds.delete(agent.imUserId);
11468
11473
  this.hostedAgents.set(agent.imUserId, {
11469
11474
  imUserId: agent.imUserId,
11470
11475
  name: agent.name,
@@ -11497,6 +11502,7 @@ var Runner = class extends EventEmitter3 {
11497
11502
  );
11498
11503
  });
11499
11504
  tx(payload);
11505
+ this.rejectedHostedAgentIds.delete(payload.imUserId);
11500
11506
  this.loadAgentsFromDb();
11501
11507
  if (this.wsConnected) this.sendDeclare();
11502
11508
  return {
@@ -11744,6 +11750,7 @@ var Runner = class extends EventEmitter3 {
11744
11750
  }
11745
11751
  async onHostAcked(payload) {
11746
11752
  this.workspaceId = payload.workspaceId;
11753
+ const ownershipLockChanged = await this.applyHostAckOwnershipLock(payload);
11747
11754
  void this.reportTransport().catch((err) => {
11748
11755
  process.stderr.write(
11749
11756
  `[daemon] transport-probe report failed: ${err.message}
@@ -11759,7 +11766,9 @@ var Runner = class extends EventEmitter3 {
11759
11766
  (err) => log7.error("Asset sync failed", err.message)
11760
11767
  );
11761
11768
  await this.ensureDropFolderRuntime(this.workspaceId);
11762
- for (const id of payload.profilesToSync) {
11769
+ const profilesToSync = payload.profilesToSync ?? [];
11770
+ const profilesToDelete = payload.profilesToDelete ?? [];
11771
+ for (const id of profilesToSync) {
11763
11772
  try {
11764
11773
  await this.servicePool.drop(id);
11765
11774
  await this.syncProfileFromCloud(id);
@@ -11767,7 +11776,7 @@ var Runner = class extends EventEmitter3 {
11767
11776
  this.emit("sync-error", err);
11768
11777
  }
11769
11778
  }
11770
- for (const id of payload.profilesToDelete ?? []) {
11779
+ for (const id of profilesToDelete) {
11771
11780
  const row = this.db.prepare("SELECT agent_im_user_id FROM agent_profiles WHERE id = ?").get(id);
11772
11781
  this.db.prepare("DELETE FROM agent_profiles WHERE id = ?").run(id);
11773
11782
  if (row) {
@@ -11776,10 +11785,37 @@ var Runner = class extends EventEmitter3 {
11776
11785
  process.stderr.write(`[daemon] tombstone profile=${id}
11777
11786
  `);
11778
11787
  }
11779
- if (payload.profilesToDelete?.length) this.loadAgentsFromDb();
11780
- if ((payload.profilesToSync.length > 0 || (payload.profilesToDelete?.length ?? 0) > 0) && this.wsConnected) this.sendDeclare();
11788
+ if (profilesToDelete.length) this.loadAgentsFromDb();
11789
+ if ((ownershipLockChanged || profilesToSync.length > 0 || profilesToDelete.length > 0) && this.wsConnected) {
11790
+ this.sendDeclare();
11791
+ }
11781
11792
  this.emit("host-acked", payload);
11782
11793
  }
11794
+ async applyHostAckOwnershipLock(payload) {
11795
+ const rejected = payload.rejectedAgents ?? [];
11796
+ if (rejected.length === 0) return false;
11797
+ let changed = false;
11798
+ for (const rejection of rejected) {
11799
+ if (!rejection?.imUserId) continue;
11800
+ const agentImUserId = rejection.imUserId;
11801
+ this.rejectedHostedAgentIds.set(agentImUserId, {
11802
+ ...rejection,
11803
+ rejectedAt: Date.now()
11804
+ });
11805
+ const wasHosted = this.hostedAgents.delete(agentImUserId);
11806
+ const profiles = this.db.prepare("SELECT id FROM agent_profiles WHERE agent_im_user_id = ?").all(agentImUserId);
11807
+ const deleted = this.db.prepare("DELETE FROM agents WHERE im_user_id = ?").run(agentImUserId);
11808
+ await Promise.all(profiles.map((profile) => this.servicePool.drop(profile.id)));
11809
+ if (wasHosted || deleted.changes > 0) {
11810
+ changed = true;
11811
+ process.stderr.write(
11812
+ `[daemon] ownership rejected agent=${agentImUserId} reason=${rejection.reason} owner=${rejection.ownerDaemonId ?? "(unknown)"} \u2014 stop declaring locally
11813
+ `
11814
+ );
11815
+ }
11816
+ }
11817
+ return changed;
11818
+ }
11783
11819
  async onTaskDispatch(payload, requestId) {
11784
11820
  const targetDaemonId = readTargetDaemonId(payload);
11785
11821
  if (targetDaemonId && targetDaemonId !== this.config.daemon_id) {
@@ -12062,18 +12098,22 @@ var Runner = class extends EventEmitter3 {
12062
12098
  const name = agent?.card?.name || agent?.displayName || agent?.username || profile.agentImUserId;
12063
12099
  const now = Date.now();
12064
12100
  const tx = this.db.transaction(() => {
12065
- this.db.prepare(
12066
- `INSERT OR REPLACE INTO agents
12067
- (im_user_id, workspace_id, name, adapter_name, capabilities, status, version, synced_at, dirty)
12068
- VALUES (?, ?, ?, ?, ?, 'offline', 1, ?, 0)`
12069
- ).run(
12070
- profile.agentImUserId,
12071
- profile.workspaceId,
12072
- name,
12073
- profile.adapterName,
12074
- JSON.stringify(capabilities),
12075
- now
12076
- );
12101
+ if (this.rejectedHostedAgentIds.has(profile.agentImUserId)) {
12102
+ this.db.prepare("DELETE FROM agents WHERE im_user_id = ?").run(profile.agentImUserId);
12103
+ } else {
12104
+ this.db.prepare(
12105
+ `INSERT OR REPLACE INTO agents
12106
+ (im_user_id, workspace_id, name, adapter_name, capabilities, status, version, synced_at, dirty)
12107
+ VALUES (?, ?, ?, ?, ?, 'offline', 1, ?, 0)`
12108
+ ).run(
12109
+ profile.agentImUserId,
12110
+ profile.workspaceId,
12111
+ name,
12112
+ profile.adapterName,
12113
+ JSON.stringify(capabilities),
12114
+ now
12115
+ );
12116
+ }
12077
12117
  this.db.prepare(
12078
12118
  `INSERT OR REPLACE INTO agent_profiles
12079
12119
  (id, workspace_id, agent_im_user_id, adapter_name, name, config, version, synced_at, dirty, deleted_at)
@@ -16944,7 +16984,7 @@ async function readResponseError(res) {
16944
16984
 
16945
16985
  // src/cli/index.ts
16946
16986
  init_ui();
16947
- var VERSION = "2.0.5";
16987
+ var VERSION = "2.0.6";
16948
16988
  function buildProgram() {
16949
16989
  const program = new Command20("prismer").description("Prismer Cloud daemon CLI (TS-only).").version(VERSION);
16950
16990
  program.addCommand(buildBannerCommand());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prismer/runtime",
3
- "version": "2.0.5",
3
+ "version": "2.0.6",
4
4
  "description": "Prismer Cloud daemon runtime — TS-only adapter host for hosted IM agents",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",