instar 0.24.13 → 0.24.14

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 (90) hide show
  1. package/.claude/skills/setup-wizard/skill.md +281 -5
  2. package/dashboard/index.html +341 -0
  3. package/dist/cli.js +18 -0
  4. package/dist/cli.js.map +1 -1
  5. package/dist/commands/server.d.ts.map +1 -1
  6. package/dist/commands/server.js +188 -1
  7. package/dist/commands/server.js.map +1 -1
  8. package/dist/commands/slack-cli.d.ts +16 -0
  9. package/dist/commands/slack-cli.d.ts.map +1 -0
  10. package/dist/commands/slack-cli.js +198 -0
  11. package/dist/commands/slack-cli.js.map +1 -0
  12. package/dist/core/AgentRegistry.d.ts.map +1 -1
  13. package/dist/core/AgentRegistry.js +24 -6
  14. package/dist/core/AgentRegistry.js.map +1 -1
  15. package/dist/core/SleepWakeDetector.d.ts +11 -0
  16. package/dist/core/SleepWakeDetector.d.ts.map +1 -1
  17. package/dist/core/SleepWakeDetector.js +16 -1
  18. package/dist/core/SleepWakeDetector.js.map +1 -1
  19. package/dist/lifeline/ServerSupervisor.d.ts +13 -0
  20. package/dist/lifeline/ServerSupervisor.d.ts.map +1 -1
  21. package/dist/lifeline/ServerSupervisor.js +129 -0
  22. package/dist/lifeline/ServerSupervisor.js.map +1 -1
  23. package/dist/messaging/SessionSummarySentinel.js +1 -1
  24. package/dist/messaging/TelegramAdapter.d.ts +1 -0
  25. package/dist/messaging/TelegramAdapter.d.ts.map +1 -1
  26. package/dist/messaging/TelegramAdapter.js +4 -1
  27. package/dist/messaging/TelegramAdapter.js.map +1 -1
  28. package/dist/messaging/slack/ChannelManager.d.ts +36 -0
  29. package/dist/messaging/slack/ChannelManager.d.ts.map +1 -0
  30. package/dist/messaging/slack/ChannelManager.js +100 -0
  31. package/dist/messaging/slack/ChannelManager.js.map +1 -0
  32. package/dist/messaging/slack/FileHandler.d.ts +30 -0
  33. package/dist/messaging/slack/FileHandler.d.ts.map +1 -0
  34. package/dist/messaging/slack/FileHandler.js +87 -0
  35. package/dist/messaging/slack/FileHandler.js.map +1 -0
  36. package/dist/messaging/slack/RingBuffer.d.ts +22 -0
  37. package/dist/messaging/slack/RingBuffer.d.ts.map +1 -0
  38. package/dist/messaging/slack/RingBuffer.js +48 -0
  39. package/dist/messaging/slack/RingBuffer.js.map +1 -0
  40. package/dist/messaging/slack/SlackAdapter.d.ts +136 -0
  41. package/dist/messaging/slack/SlackAdapter.d.ts.map +1 -0
  42. package/dist/messaging/slack/SlackAdapter.js +572 -0
  43. package/dist/messaging/slack/SlackAdapter.js.map +1 -0
  44. package/dist/messaging/slack/SlackApiClient.d.ts +51 -0
  45. package/dist/messaging/slack/SlackApiClient.d.ts.map +1 -0
  46. package/dist/messaging/slack/SlackApiClient.js +94 -0
  47. package/dist/messaging/slack/SlackApiClient.js.map +1 -0
  48. package/dist/messaging/slack/SocketModeClient.d.ts +44 -0
  49. package/dist/messaging/slack/SocketModeClient.d.ts.map +1 -0
  50. package/dist/messaging/slack/SocketModeClient.js +209 -0
  51. package/dist/messaging/slack/SocketModeClient.js.map +1 -0
  52. package/dist/messaging/slack/index.d.ts +12 -0
  53. package/dist/messaging/slack/index.d.ts.map +1 -0
  54. package/dist/messaging/slack/index.js +15 -0
  55. package/dist/messaging/slack/index.js.map +1 -0
  56. package/dist/messaging/slack/sanitize.d.ts +39 -0
  57. package/dist/messaging/slack/sanitize.d.ts.map +1 -0
  58. package/dist/messaging/slack/sanitize.js +71 -0
  59. package/dist/messaging/slack/sanitize.js.map +1 -0
  60. package/dist/messaging/slack/types.d.ts +155 -0
  61. package/dist/messaging/slack/types.d.ts.map +1 -0
  62. package/dist/messaging/slack/types.js +54 -0
  63. package/dist/messaging/slack/types.js.map +1 -0
  64. package/dist/monitoring/PresenceProxy.d.ts +157 -0
  65. package/dist/monitoring/PresenceProxy.d.ts.map +1 -0
  66. package/dist/monitoring/PresenceProxy.js +891 -0
  67. package/dist/monitoring/PresenceProxy.js.map +1 -0
  68. package/dist/monitoring/SessionWatchdog.d.ts.map +1 -1
  69. package/dist/monitoring/SessionWatchdog.js +2 -0
  70. package/dist/monitoring/SessionWatchdog.js.map +1 -1
  71. package/dist/server/AgentServer.d.ts +1 -0
  72. package/dist/server/AgentServer.d.ts.map +1 -1
  73. package/dist/server/AgentServer.js +49 -47
  74. package/dist/server/AgentServer.js.map +1 -1
  75. package/dist/server/routes.d.ts +1 -0
  76. package/dist/server/routes.d.ts.map +1 -1
  77. package/dist/server/routes.js +213 -4
  78. package/dist/server/routes.js.map +1 -1
  79. package/package.json +1 -1
  80. package/src/data/builtin-manifest.json +94 -78
  81. package/src/templates/hooks/slack-channel-context.sh +98 -0
  82. package/src/templates/scripts/slack-reply.sh +64 -0
  83. package/upgrades/0.24.11.md +23 -0
  84. package/upgrades/0.24.14.md +26 -0
  85. package/upgrades/0.24.6.md +20 -0
  86. package/upgrades/0.24.7.md +24 -0
  87. package/upgrades/0.24.8.md +19 -0
  88. package/upgrades/0.24.9.md +19 -0
  89. package/upgrades/NEXT.md +35 -0
  90. /package/.claude/skills/secret-setup/{skill.md → SKILL.md} +0 -0
@@ -2828,7 +2828,7 @@ export function createRoutes(ctx) {
2828
2828
  res.status(400).json({ error: 'topicId must be a number' });
2829
2829
  return;
2830
2830
  }
2831
- const { text } = req.body;
2831
+ const { text, metadata } = req.body;
2832
2832
  if (!text || typeof text !== 'string') {
2833
2833
  res.status(400).json({ error: '"text" field required' });
2834
2834
  return;
@@ -2838,9 +2838,13 @@ export function createRoutes(ctx) {
2838
2838
  return;
2839
2839
  }
2840
2840
  try {
2841
- await ctx.telegram.sendToTopic(topicId, text);
2842
- // Clear injection tracker the agent has responded to this topic
2843
- ctx.sessionManager.clearInjectionTracker(topicId);
2841
+ const isProxy = metadata?.isProxy === true;
2842
+ await ctx.telegram.sendToTopic(topicId, text, { skipStallClear: isProxy });
2843
+ // Clear injection tracker — but NOT for proxy messages (PresenceProxy)
2844
+ // Proxy messages should not reset stall detection timers
2845
+ if (!isProxy) {
2846
+ ctx.sessionManager.clearInjectionTracker(topicId);
2847
+ }
2844
2848
  res.json({ ok: true, topicId });
2845
2849
  }
2846
2850
  catch (err) {
@@ -2890,6 +2894,91 @@ export function createRoutes(ctx) {
2890
2894
  }
2891
2895
  res.json(ctx.telegram.getLogStats());
2892
2896
  });
2897
+ // ── Slack ──────────────────────────────────────────────────────
2898
+ router.post('/slack/reply/:channelId', async (req, res) => {
2899
+ if (!ctx.slack) {
2900
+ res.status(503).json({ error: 'Slack not configured' });
2901
+ return;
2902
+ }
2903
+ const { channelId } = req.params;
2904
+ const { text, thread_ts } = req.body;
2905
+ if (!text || typeof text !== 'string') {
2906
+ res.status(400).json({ error: '"text" field required' });
2907
+ return;
2908
+ }
2909
+ try {
2910
+ const ts = await ctx.slack.sendToChannel(channelId, text, { thread_ts });
2911
+ res.json({ ok: true, topicId: channelId, ts });
2912
+ }
2913
+ catch (err) {
2914
+ res.status(500).json({ error: err instanceof Error ? err.message : String(err) });
2915
+ }
2916
+ });
2917
+ router.get('/slack/channels', async (req, res) => {
2918
+ if (!ctx.slack) {
2919
+ res.status(503).json({ error: 'Slack not configured' });
2920
+ return;
2921
+ }
2922
+ try {
2923
+ const channels = await ctx.slack.api.call('conversations.list', {
2924
+ types: 'public_channel,private_channel',
2925
+ exclude_archived: req.query.include_archived !== 'true',
2926
+ limit: 200,
2927
+ });
2928
+ res.json({ ok: true, channels: channels.channels ?? [] });
2929
+ }
2930
+ catch (err) {
2931
+ res.status(500).json({ error: err instanceof Error ? err.message : String(err) });
2932
+ }
2933
+ });
2934
+ router.post('/slack/channels', async (req, res) => {
2935
+ if (!ctx.slack) {
2936
+ res.status(503).json({ error: 'Slack not configured' });
2937
+ return;
2938
+ }
2939
+ const { name, is_private } = req.body;
2940
+ if (!name || typeof name !== 'string') {
2941
+ res.status(400).json({ error: '"name" field required' });
2942
+ return;
2943
+ }
2944
+ try {
2945
+ const channelId = await ctx.slack.createChannel(name, is_private);
2946
+ res.json({ ok: true, channelId });
2947
+ }
2948
+ catch (err) {
2949
+ res.status(400).json({ error: err instanceof Error ? err.message : String(err) });
2950
+ }
2951
+ });
2952
+ router.get('/slack/channels/:channelId/messages', (req, res) => {
2953
+ if (!ctx.slack) {
2954
+ res.status(503).json({ error: 'Slack not configured' });
2955
+ return;
2956
+ }
2957
+ const { channelId } = req.params;
2958
+ const limit = Math.min(parseInt(req.query.limit, 10) || 30, 100);
2959
+ const messages = ctx.slack.getChannelMessages(channelId, limit);
2960
+ res.json({ ok: true, messages, count: messages.length });
2961
+ });
2962
+ router.get('/slack/search', (req, res) => {
2963
+ if (!ctx.slack) {
2964
+ res.status(503).json({ error: 'Slack not configured' });
2965
+ return;
2966
+ }
2967
+ const query = req.query.q;
2968
+ const channelId = req.query.channelId;
2969
+ const since = req.query.since ? new Date(req.query.since) : undefined;
2970
+ const rawLimit = parseInt(req.query.limit, 10) || 50;
2971
+ const limit = Math.min(Math.max(rawLimit, 1), 500);
2972
+ const results = ctx.slack.searchLog({ query, channelId, since, limit });
2973
+ res.json({ results, count: results.length });
2974
+ });
2975
+ router.get('/slack/log-stats', (req, res) => {
2976
+ if (!ctx.slack) {
2977
+ res.status(503).json({ error: 'Slack not configured' });
2978
+ return;
2979
+ }
2980
+ res.json(ctx.slack.getLogStats());
2981
+ });
2893
2982
  // ── Attention Queue ─────────────────────────────────────────────
2894
2983
  router.post('/attention', async (req, res) => {
2895
2984
  if (!ctx.telegram) {
@@ -4163,6 +4252,12 @@ export function createRoutes(ctx) {
4163
4252
  return;
4164
4253
  }
4165
4254
  const tunnelType = (ctx.config.tunnel?.type === 'named' ? 'named' : 'quick');
4255
+ // Named tunnels have permanent URLs — skip periodic refresh calls since
4256
+ // the URL never changes. The initial broadcast on server startup is sufficient.
4257
+ if (tunnelType === 'named') {
4258
+ res.json({ action: 'skipped', reason: 'named tunnel — URL is permanent', url: tunnelUrl, tunnelType });
4259
+ return;
4260
+ }
4166
4261
  try {
4167
4262
  await ctx.telegram.broadcastDashboardUrl(tunnelUrl, tunnelType);
4168
4263
  res.json({ action: 'refreshed', url: tunnelUrl, tunnelType });
@@ -5181,6 +5276,120 @@ export function createRoutes(ctx) {
5181
5276
  res.status(500).json({ error: err instanceof Error ? err.message : 'Triage failed' });
5182
5277
  }
5183
5278
  });
5279
+ // ── Systems Status (aggregated subsystem overview) ────────────────
5280
+ router.get('/systems/status', (_req, res) => {
5281
+ const uptimeMs = Date.now() - ctx.startTime.getTime();
5282
+ function proc(name, subsystem, statusFn) {
5283
+ if (!subsystem)
5284
+ return { name, enabled: false, status: 'not tracked' };
5285
+ try {
5286
+ const details = statusFn ? statusFn() : undefined;
5287
+ return { name, enabled: true, status: 'running', details };
5288
+ }
5289
+ catch {
5290
+ return { name, enabled: true, status: 'error' };
5291
+ }
5292
+ }
5293
+ const categories = [
5294
+ {
5295
+ id: 'session-management',
5296
+ name: 'Session Management & Recovery',
5297
+ processes: [
5298
+ proc('SessionWatchdog', ctx.watchdog, () => ctx.watchdog?.getStatus()),
5299
+ proc('StallTriageNurse', ctx.triageNurse, () => ctx.triageNurse?.getStatus()),
5300
+ proc('SessionActivitySentinel', ctx.activitySentinel),
5301
+ proc('SessionSummarySentinel', ctx.summarySentinel),
5302
+ proc('SpawnRequestManager', ctx.spawnManager),
5303
+ ],
5304
+ },
5305
+ {
5306
+ id: 'coherence-integrity',
5307
+ name: 'Coherence & Integrity',
5308
+ processes: [
5309
+ proc('CoherenceMonitor', ctx.coherenceMonitor, () => ctx.coherenceMonitor?.getLastReport()),
5310
+ proc('CoherenceGate (Scope)', ctx.coherenceGate),
5311
+ proc('ResponseReviewGate', ctx.responseReviewGate),
5312
+ proc('CanonicalState', ctx.canonicalState),
5313
+ proc('InstructionsVerifier', ctx.instructionsVerifier),
5314
+ ],
5315
+ },
5316
+ {
5317
+ id: 'resource-monitoring',
5318
+ name: 'Resource Monitoring',
5319
+ processes: [
5320
+ proc('MemoryPressureMonitor', ctx.memoryMonitor, () => ctx.memoryMonitor?.getState()),
5321
+ proc('OrphanProcessReaper', ctx.orphanReaper, () => ctx.orphanReaper?.getLastReport()),
5322
+ proc('QuotaTracker', ctx.quotaTracker, () => ctx.quotaTracker?.getState()),
5323
+ proc('QuotaManager', ctx.quotaManager),
5324
+ ],
5325
+ },
5326
+ {
5327
+ id: 'scheduling-jobs',
5328
+ name: 'Scheduling & Jobs',
5329
+ processes: [
5330
+ proc('JobScheduler', ctx.scheduler),
5331
+ proc('CommitmentTracker', ctx.commitmentTracker, () => ({ active: ctx.commitmentTracker?.getActive().length ?? 0 })),
5332
+ ],
5333
+ },
5334
+ {
5335
+ id: 'messaging-communication',
5336
+ name: 'Messaging & Communication',
5337
+ processes: [
5338
+ proc('Telegram', ctx.telegram),
5339
+ proc('WhatsApp', ctx.whatsapp),
5340
+ proc('MessageBridge', ctx.messageBridge),
5341
+ proc('MessageRouter', ctx.messageRouter),
5342
+ ],
5343
+ },
5344
+ {
5345
+ id: 'knowledge-memory',
5346
+ name: 'Knowledge & Memory',
5347
+ processes: [
5348
+ proc('TopicMemory', ctx.topicMemory),
5349
+ proc('SemanticMemory', ctx.semanticMemory),
5350
+ proc('WorkingMemoryAssembler', ctx.workingMemory),
5351
+ proc('SelfKnowledgeTree', ctx.selfKnowledgeTree),
5352
+ ],
5353
+ },
5354
+ {
5355
+ id: 'safety-trust',
5356
+ name: 'Safety & Trust',
5357
+ processes: [
5358
+ proc('ExternalOperationGate', ctx.operationGate),
5359
+ proc('MessageSentinel', ctx.sentinel),
5360
+ proc('AdaptiveTrust', ctx.adaptiveTrust),
5361
+ proc('AutonomyManager', ctx.autonomyManager),
5362
+ ],
5363
+ },
5364
+ {
5365
+ id: 'evolution-discovery',
5366
+ name: 'Evolution & Discovery',
5367
+ processes: [
5368
+ proc('EvolutionManager', ctx.evolution),
5369
+ proc('AutonomousEvolution', ctx.autonomousEvolution),
5370
+ proc('CapabilityMapper', ctx.capabilityMapper),
5371
+ proc('CoverageAuditor', ctx.coverageAuditor),
5372
+ ],
5373
+ },
5374
+ {
5375
+ id: 'infrastructure',
5376
+ name: 'Infrastructure & Networking',
5377
+ processes: [
5378
+ proc('TunnelManager', ctx.tunnel),
5379
+ proc('WorktreeMonitor', ctx.worktreeMonitor),
5380
+ proc('ThreadlineRouter', ctx.threadlineRouter),
5381
+ proc('SystemReviewer', ctx.systemReviewer, () => ctx.systemReviewer?.getHealthStatus()),
5382
+ ],
5383
+ },
5384
+ ];
5385
+ // Recent degradation events
5386
+ const allEvents = DegradationReporter.getInstance().getEvents();
5387
+ const recentEvents = allEvents.slice(-20).reverse().map(e => ({
5388
+ ...e,
5389
+ narrative: DegradationReporter.narrativeFor(e),
5390
+ }));
5391
+ res.json({ uptime: uptimeMs, categories, recentEvents });
5392
+ });
5184
5393
  // ── External Operation Safety ────────────────────────────────────
5185
5394
  // POST /operations/classify — classify an external operation
5186
5395
  router.post('/operations/classify', (req, res) => {