instar 0.28.89 → 0.28.90

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 (41) hide show
  1. package/dist/commands/server.d.ts.map +1 -1
  2. package/dist/commands/server.js +45 -1
  3. package/dist/commands/server.js.map +1 -1
  4. package/dist/monitoring/CommitmentTracker.d.ts +65 -2
  5. package/dist/monitoring/CommitmentTracker.d.ts.map +1 -1
  6. package/dist/monitoring/CommitmentTracker.js +113 -0
  7. package/dist/monitoring/CommitmentTracker.js.map +1 -1
  8. package/dist/server/AgentServer.d.ts +5 -0
  9. package/dist/server/AgentServer.d.ts.map +1 -1
  10. package/dist/server/AgentServer.js +2 -0
  11. package/dist/server/AgentServer.js.map +1 -1
  12. package/dist/server/routes.d.ts +6 -0
  13. package/dist/server/routes.d.ts.map +1 -1
  14. package/dist/server/routes.js +44 -1
  15. package/dist/server/routes.js.map +1 -1
  16. package/dist/threadline/SalienceGate.d.ts +87 -0
  17. package/dist/threadline/SalienceGate.d.ts.map +1 -0
  18. package/dist/threadline/SalienceGate.js +100 -0
  19. package/dist/threadline/SalienceGate.js.map +1 -0
  20. package/dist/threadline/ThreadResumeMap.d.ts +14 -0
  21. package/dist/threadline/ThreadResumeMap.d.ts.map +1 -1
  22. package/dist/threadline/ThreadResumeMap.js.map +1 -1
  23. package/dist/threadline/ThreadlineMCPServer.d.ts +4 -0
  24. package/dist/threadline/ThreadlineMCPServer.d.ts.map +1 -1
  25. package/dist/threadline/ThreadlineMCPServer.js +10 -0
  26. package/dist/threadline/ThreadlineMCPServer.js.map +1 -1
  27. package/dist/threadline/ThreadlineRouter.d.ts +13 -0
  28. package/dist/threadline/ThreadlineRouter.d.ts.map +1 -1
  29. package/dist/threadline/ThreadlineRouter.js +47 -0
  30. package/dist/threadline/ThreadlineRouter.js.map +1 -1
  31. package/dist/threadline/TopicLinkageHandler.d.ts +161 -0
  32. package/dist/threadline/TopicLinkageHandler.d.ts.map +1 -0
  33. package/dist/threadline/TopicLinkageHandler.js +518 -0
  34. package/dist/threadline/TopicLinkageHandler.js.map +1 -0
  35. package/dist/threadline/mcp-stdio-entry.js +5 -0
  36. package/dist/threadline/mcp-stdio-entry.js.map +1 -1
  37. package/package.json +1 -1
  38. package/src/data/builtin-manifest.json +47 -47
  39. package/upgrades/0.28.89.md +37 -0
  40. package/upgrades/0.28.90.md +52 -0
  41. package/upgrades/side-effects/thread-topic-linkage.md +243 -0
@@ -10306,11 +10306,48 @@ export function createRoutes(ctx) {
10306
10306
  // HTTP endpoint.
10307
10307
  router.post('/threadline/relay-send', async (req, res) => {
10308
10308
  const relayClient = ctx.threadlineRelayClient;
10309
- const { targetAgent, message, threadId, waitForReply, timeoutSeconds } = req.body;
10309
+ const { targetAgent, message, threadId, waitForReply, timeoutSeconds, originTopicId, purpose, } = req.body;
10310
10310
  if (!targetAgent || !message) {
10311
10311
  res.status(400).json({ success: false, error: 'Missing required fields: targetAgent, message' });
10312
10312
  return;
10313
10313
  }
10314
+ // THREAD-TOPIC-LINKAGE-SPEC.md: validate the optional originTopicId early.
10315
+ // We accept either number or numeric string; ignore on type mismatch (the
10316
+ // send still goes through, just without topic linkage).
10317
+ let resolvedOriginTopicId;
10318
+ if (originTopicId !== undefined && originTopicId !== null) {
10319
+ const asNum = typeof originTopicId === 'number' ? originTopicId : Number(originTopicId);
10320
+ if (Number.isFinite(asNum) && Number.isInteger(asNum) && asNum > 0) {
10321
+ resolvedOriginTopicId = asNum;
10322
+ }
10323
+ }
10324
+ const resolvedPurpose = typeof purpose === 'string' && purpose.trim().length > 0
10325
+ ? purpose.trim().slice(0, 1024)
10326
+ : undefined;
10327
+ /**
10328
+ * Outbound origin capture (spec §5.2). Idempotent: handler returns the
10329
+ * existing commitment when one already exists for this threadId, so 4
10330
+ * call-sites below are safe.
10331
+ */
10332
+ const captureOrigin = async (effThreadId, remoteAgentDisplay) => {
10333
+ if (!ctx.topicLinkageHandler)
10334
+ return;
10335
+ if (!resolvedOriginTopicId)
10336
+ return;
10337
+ try {
10338
+ ctx.topicLinkageHandler.captureOriginOnSend({
10339
+ threadId: effThreadId,
10340
+ remoteAgent: remoteAgentDisplay,
10341
+ remoteAgentDisplayName: remoteAgentDisplay,
10342
+ originTopicId: resolvedOriginTopicId,
10343
+ purpose: resolvedPurpose,
10344
+ subject: 'Threadline conversation',
10345
+ });
10346
+ }
10347
+ catch (err) {
10348
+ console.warn(`[relay-send] captureOrigin failed for thread ${effThreadId}: ${err instanceof Error ? err.message : String(err)}`);
10349
+ }
10350
+ };
10314
10351
  // Validate message size (64KB limit matching inbound)
10315
10352
  if (Buffer.byteLength(message, 'utf-8') > 64 * 1024) {
10316
10353
  res.status(413).json({ success: false, error: 'Message too large (64KB limit)' });
@@ -10589,6 +10626,7 @@ export function createRoutes(ctx) {
10589
10626
  outcome,
10590
10627
  }).catch(() => { });
10591
10628
  }
10629
+ await captureOrigin(effectiveThreadId, localTarget.name);
10592
10630
  if (waitForReply) {
10593
10631
  const reply = await waitForThreadlineReply(ctx, localTarget.name, effectiveThreadId, timeoutSeconds);
10594
10632
  res.json({
@@ -10600,6 +10638,7 @@ export function createRoutes(ctx) {
10600
10638
  deliveryOutcome: outcome,
10601
10639
  threadline: tl,
10602
10640
  reply,
10641
+ topicLinkageStamped: resolvedOriginTopicId !== undefined,
10603
10642
  });
10604
10643
  }
10605
10644
  else {
@@ -10611,6 +10650,7 @@ export function createRoutes(ctx) {
10611
10650
  deliveryPath: 'local',
10612
10651
  deliveryOutcome: outcome,
10613
10652
  threadline: tl,
10653
+ topicLinkageStamped: resolvedOriginTopicId !== undefined,
10614
10654
  });
10615
10655
  }
10616
10656
  return;
@@ -10699,6 +10739,7 @@ export function createRoutes(ctx) {
10699
10739
  outcome: 'relay-sent',
10700
10740
  }).catch(() => { });
10701
10741
  }
10742
+ await captureOrigin(effectiveRelayThreadId, targetAgent);
10702
10743
  if (waitForReply) {
10703
10744
  const reply = await waitForThreadlineReply(ctx, resolvedId, effectiveRelayThreadId, timeoutSeconds);
10704
10745
  res.json({
@@ -10708,6 +10749,7 @@ export function createRoutes(ctx) {
10708
10749
  resolvedAgent: resolvedId,
10709
10750
  deliveryPath: 'relay',
10710
10751
  reply,
10752
+ topicLinkageStamped: resolvedOriginTopicId !== undefined,
10711
10753
  });
10712
10754
  }
10713
10755
  else {
@@ -10717,6 +10759,7 @@ export function createRoutes(ctx) {
10717
10759
  threadId: effectiveRelayThreadId,
10718
10760
  resolvedAgent: resolvedId,
10719
10761
  deliveryPath: 'relay',
10762
+ topicLinkageStamped: resolvedOriginTopicId !== undefined,
10720
10763
  });
10721
10764
  }
10722
10765
  }