instar 0.28.2 → 0.28.3
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/dashboard/index.html +1 -1
- package/dist/commands/server.d.ts.map +1 -1
- package/dist/commands/server.js +89 -49
- package/dist/commands/server.js.map +1 -1
- package/dist/core/Config.js +2 -2
- package/dist/core/Config.js.map +1 -1
- package/dist/core/SessionManager.d.ts +1 -0
- package/dist/core/SessionManager.d.ts.map +1 -1
- package/dist/core/SessionManager.js +3 -0
- package/dist/core/SessionManager.js.map +1 -1
- package/dist/lifeline/ServerSupervisor.d.ts +1 -0
- package/dist/lifeline/ServerSupervisor.d.ts.map +1 -1
- package/dist/lifeline/ServerSupervisor.js +43 -10
- package/dist/lifeline/ServerSupervisor.js.map +1 -1
- package/dist/messaging/TelegramAdapter.d.ts +13 -1
- package/dist/messaging/TelegramAdapter.d.ts.map +1 -1
- package/dist/messaging/TelegramAdapter.js +90 -7
- package/dist/messaging/TelegramAdapter.js.map +1 -1
- package/dist/messaging/imessage/IMessageAdapter.d.ts +4 -2
- package/dist/messaging/imessage/IMessageAdapter.d.ts.map +1 -1
- package/dist/messaging/imessage/IMessageAdapter.js +19 -5
- package/dist/messaging/imessage/IMessageAdapter.js.map +1 -1
- package/dist/messaging/slack/SlackAdapter.d.ts +6 -0
- package/dist/messaging/slack/SlackAdapter.d.ts.map +1 -1
- package/dist/messaging/slack/SlackAdapter.js +27 -0
- package/dist/messaging/slack/SlackAdapter.js.map +1 -1
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +77 -19
- package/dist/server/routes.js.map +1 -1
- package/dist/threadline/AgentTrustManager.d.ts +15 -3
- package/dist/threadline/AgentTrustManager.d.ts.map +1 -1
- package/dist/threadline/AgentTrustManager.js +40 -11
- package/dist/threadline/AgentTrustManager.js.map +1 -1
- package/dist/threadline/ThreadlineMCPServer.d.ts.map +1 -1
- package/dist/threadline/ThreadlineMCPServer.js +32 -10
- package/dist/threadline/ThreadlineMCPServer.js.map +1 -1
- package/dist/threadline/client/ThreadlineClient.d.ts +9 -1
- package/dist/threadline/client/ThreadlineClient.d.ts.map +1 -1
- package/dist/threadline/client/ThreadlineClient.js +64 -10
- package/dist/threadline/client/ThreadlineClient.js.map +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +48 -48
- package/src/templates/hooks/compaction-recovery.sh +82 -3
- package/upgrades/0.28.3.md +35 -0
package/dist/server/routes.js
CHANGED
|
@@ -2148,7 +2148,7 @@ export function createRoutes(ctx) {
|
|
|
2148
2148
|
result.platform = 'telegram';
|
|
2149
2149
|
result.platformId = topicId;
|
|
2150
2150
|
const topicName = ctx.telegram.getTopicName?.(topicId);
|
|
2151
|
-
if (topicName)
|
|
2151
|
+
if (topicName && !/^topic-\d+$/.test(topicName))
|
|
2152
2152
|
result.platformName = topicName;
|
|
2153
2153
|
}
|
|
2154
2154
|
}
|
|
@@ -4330,7 +4330,7 @@ export function createRoutes(ctx) {
|
|
|
4330
4330
|
res.send(html);
|
|
4331
4331
|
});
|
|
4332
4332
|
// Receive a secret submission (user-facing, NO auth — token + CSRF is the auth)
|
|
4333
|
-
router.post('/secrets/drop/:token', (req, res) => {
|
|
4333
|
+
router.post('/secrets/drop/:token', async (req, res) => {
|
|
4334
4334
|
const { _csrf, ...values } = req.body;
|
|
4335
4335
|
if (!_csrf || typeof _csrf !== 'string') {
|
|
4336
4336
|
res.status(400).json({ error: 'Missing CSRF token' });
|
|
@@ -4384,15 +4384,32 @@ export function createRoutes(ctx) {
|
|
|
4384
4384
|
else {
|
|
4385
4385
|
// No live session — spawn one to handle the secret receipt
|
|
4386
4386
|
let topicName = `topic-${topicId}`;
|
|
4387
|
-
|
|
4388
|
-
|
|
4389
|
-
|
|
4390
|
-
|
|
4391
|
-
|
|
4392
|
-
topicName = stored;
|
|
4387
|
+
// Try live adapter first, then disk registry, then active probe
|
|
4388
|
+
if (ctx.telegram) {
|
|
4389
|
+
const liveName = ctx.telegram.getTopicName(topicId);
|
|
4390
|
+
if (liveName && !/^topic-\d+$/.test(liveName)) {
|
|
4391
|
+
topicName = liveName;
|
|
4393
4392
|
}
|
|
4394
4393
|
}
|
|
4395
|
-
|
|
4394
|
+
if (/^topic-\d+$/.test(topicName)) {
|
|
4395
|
+
try {
|
|
4396
|
+
if (fs.existsSync(sdRegistryPath)) {
|
|
4397
|
+
const reg = JSON.parse(fs.readFileSync(sdRegistryPath, 'utf-8'));
|
|
4398
|
+
const stored = reg.topicToName?.[String(topicId)];
|
|
4399
|
+
if (stored && !/^topic-\d+$/.test(stored))
|
|
4400
|
+
topicName = stored;
|
|
4401
|
+
}
|
|
4402
|
+
}
|
|
4403
|
+
catch { /* fall through */ }
|
|
4404
|
+
}
|
|
4405
|
+
if (/^topic-\d+$/.test(topicName) && ctx.telegram) {
|
|
4406
|
+
try {
|
|
4407
|
+
const resolved = await ctx.telegram.resolveTopicName(topicId);
|
|
4408
|
+
if (resolved)
|
|
4409
|
+
topicName = resolved;
|
|
4410
|
+
}
|
|
4411
|
+
catch { /* fall through to default */ }
|
|
4412
|
+
}
|
|
4396
4413
|
// Build context with thread history
|
|
4397
4414
|
const historyLines = [];
|
|
4398
4415
|
if (ctx.telegram) {
|
|
@@ -4564,7 +4581,7 @@ export function createRoutes(ctx) {
|
|
|
4564
4581
|
// ── Internal: Lifeline Telegram Forward ─────────────────────────
|
|
4565
4582
|
// Receives messages from the Telegram Lifeline process and injects
|
|
4566
4583
|
// them into the appropriate session, just like TelegramAdapter would.
|
|
4567
|
-
router.post('/internal/telegram-forward', (req, res) => {
|
|
4584
|
+
router.post('/internal/telegram-forward', async (req, res) => {
|
|
4568
4585
|
const { topicId, text, fromUserId, fromUsername, fromFirstName, messageId } = req.body;
|
|
4569
4586
|
if (!topicId || !text) {
|
|
4570
4587
|
res.status(400).json({ error: 'topicId and text required' });
|
|
@@ -4680,15 +4697,32 @@ export function createRoutes(ctx) {
|
|
|
4680
4697
|
// tmux names include the project prefix (e.g., "ai-guy-lifeline"), and
|
|
4681
4698
|
// spawnInteractiveSession prepends it again → cascading names.
|
|
4682
4699
|
let topicName = `topic-${topicId}`;
|
|
4683
|
-
|
|
4684
|
-
|
|
4685
|
-
|
|
4686
|
-
|
|
4687
|
-
|
|
4688
|
-
topicName = stored;
|
|
4700
|
+
// Try live adapter first, then disk registry, then active probe
|
|
4701
|
+
if (ctx.telegram) {
|
|
4702
|
+
const liveName = ctx.telegram.getTopicName(topicId);
|
|
4703
|
+
if (liveName && !/^topic-\d+$/.test(liveName)) {
|
|
4704
|
+
topicName = liveName;
|
|
4689
4705
|
}
|
|
4690
4706
|
}
|
|
4691
|
-
|
|
4707
|
+
if (/^topic-\d+$/.test(topicName)) {
|
|
4708
|
+
try {
|
|
4709
|
+
if (fs.existsSync(registryPath)) {
|
|
4710
|
+
const reg = JSON.parse(fs.readFileSync(registryPath, 'utf-8'));
|
|
4711
|
+
const stored = reg.topicToName?.[String(topicId)];
|
|
4712
|
+
if (stored && !/^topic-\d+$/.test(stored))
|
|
4713
|
+
topicName = stored;
|
|
4714
|
+
}
|
|
4715
|
+
}
|
|
4716
|
+
catch { /* fall through */ }
|
|
4717
|
+
}
|
|
4718
|
+
if (/^topic-\d+$/.test(topicName) && ctx.telegram) {
|
|
4719
|
+
try {
|
|
4720
|
+
const resolved = await ctx.telegram.resolveTopicName(topicId);
|
|
4721
|
+
if (resolved)
|
|
4722
|
+
topicName = resolved;
|
|
4723
|
+
}
|
|
4724
|
+
catch { /* fall through to default */ }
|
|
4725
|
+
}
|
|
4692
4726
|
console.log(`[telegram-forward] No live session for topic ${topicId}, spawning "${topicName}"...`);
|
|
4693
4727
|
// Fetch thread history so auto-spawned sessions have full conversational context
|
|
4694
4728
|
const historyLines = [];
|
|
@@ -7656,7 +7690,30 @@ export function createRoutes(ctx) {
|
|
|
7656
7690
|
if (fs.existsSync(knownAgentsPath)) {
|
|
7657
7691
|
const knownData = JSON.parse(fs.readFileSync(knownAgentsPath, 'utf-8'));
|
|
7658
7692
|
const agents = knownData.agents ?? [];
|
|
7659
|
-
|
|
7693
|
+
// Support "name:fingerprintPrefix" disambiguation syntax
|
|
7694
|
+
let targetName = targetAgent;
|
|
7695
|
+
let targetFpPrefix;
|
|
7696
|
+
const colonIdx = targetAgent.lastIndexOf(':');
|
|
7697
|
+
if (colonIdx > 0 && colonIdx < targetAgent.length - 1) {
|
|
7698
|
+
const suffix = targetAgent.substring(colonIdx + 1);
|
|
7699
|
+
if (/^[0-9a-f]{4,32}$/i.test(suffix)) {
|
|
7700
|
+
targetName = targetAgent.substring(0, colonIdx);
|
|
7701
|
+
targetFpPrefix = suffix.toLowerCase();
|
|
7702
|
+
}
|
|
7703
|
+
}
|
|
7704
|
+
const nameMatches = agents.filter(a => a.name === targetName || a.name?.toLowerCase() === targetName?.toLowerCase());
|
|
7705
|
+
// If multiple same-named agents, disambiguate by fingerprint prefix
|
|
7706
|
+
let localTarget = nameMatches.length === 1 ? nameMatches[0] : undefined;
|
|
7707
|
+
if (nameMatches.length > 1 && targetFpPrefix) {
|
|
7708
|
+
localTarget = nameMatches.find(a => {
|
|
7709
|
+
const fp = a.fingerprint || a.publicKey?.substring(0, 32);
|
|
7710
|
+
return fp?.toLowerCase().startsWith(targetFpPrefix);
|
|
7711
|
+
});
|
|
7712
|
+
}
|
|
7713
|
+
else if (nameMatches.length > 1 && !targetFpPrefix) {
|
|
7714
|
+
// Ambiguous — skip local delivery, let relay handle it
|
|
7715
|
+
localTarget = undefined;
|
|
7716
|
+
}
|
|
7660
7717
|
if (localTarget?.port && localTarget.name !== ctx.config.projectName) {
|
|
7661
7718
|
// Check if the local agent is actually running
|
|
7662
7719
|
try {
|
|
@@ -8409,7 +8466,7 @@ export function createRoutes(ctx) {
|
|
|
8409
8466
|
res.status(501).json({ error: 'FeatureRegistry not initialized' });
|
|
8410
8467
|
return;
|
|
8411
8468
|
}
|
|
8412
|
-
const { to, userId: bodyUserId, trigger, consentRecord, context } = req.body || {};
|
|
8469
|
+
const { to, userId: bodyUserId, trigger, consentRecord, context, activationChallenge } = req.body || {};
|
|
8413
8470
|
if (!to) {
|
|
8414
8471
|
res.status(400).json({ error: { code: 'MISSING_TARGET', message: 'Request body must include "to" (target state)' } });
|
|
8415
8472
|
return;
|
|
@@ -8419,6 +8476,7 @@ export function createRoutes(ctx) {
|
|
|
8419
8476
|
trigger,
|
|
8420
8477
|
consentRecord,
|
|
8421
8478
|
context,
|
|
8479
|
+
activationChallenge,
|
|
8422
8480
|
});
|
|
8423
8481
|
if (!result.success) {
|
|
8424
8482
|
const status = result.error?.code === 'FEATURE_NOT_FOUND' ? 404
|