instar 1.1.3 → 1.2.1
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/README.md +270 -1
- package/dist/server/SecretDrop.d.ts +56 -3
- package/dist/server/SecretDrop.d.ts.map +1 -1
- package/dist/server/SecretDrop.js +116 -6
- package/dist/server/SecretDrop.js.map +1 -1
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +46 -5
- package/dist/server/routes.js.map +1 -1
- package/package.json +2 -1
- package/scripts/check-repo-invariants.mjs +68 -0
- package/scripts/lib/telegram-historian.mjs +224 -0
- package/scripts/lib/topic-memory-importer.mjs +132 -0
- package/scripts/pre-push-fixture-guard.mjs +155 -0
- package/scripts/telegram-history-backfill.mjs +353 -0
- package/src/data/builtin-manifest.json +46 -46
- package/upgrades/1.1.4.md +143 -0
- package/upgrades/1.2.1.md +71 -0
- package/upgrades/side-effects/secret-drop-hardening.md +64 -0
- package/upgrades/side-effects/telegram-history-backfill.md +131 -0
- package/upgrades/side-effects/test-env-isolation.md +84 -0
package/dist/server/routes.js
CHANGED
|
@@ -7285,6 +7285,35 @@ export function createRoutes(ctx) {
|
|
|
7285
7285
|
});
|
|
7286
7286
|
// ── Secret Drop (secure secret submission) ─────────────────────
|
|
7287
7287
|
const secretDrop = new SecretDrop(ctx.config.projectName || 'Agent');
|
|
7288
|
+
// Stuck-consumer hardening: when an agent's consumer chain fails to
|
|
7289
|
+
// claim a submitted secret within the grace window, route a visible
|
|
7290
|
+
// cue to the bound topic so the operator hears about the failure
|
|
7291
|
+
// instead of silently waiting on a value that never arrives. Added
|
|
7292
|
+
// 2026-05-20 in response to the topic-10873 lost-SMS-code incident.
|
|
7293
|
+
secretDrop.onStuckConsumer((event) => {
|
|
7294
|
+
if (!event.topicId || !ctx.sessionManager)
|
|
7295
|
+
return;
|
|
7296
|
+
const topicId = event.topicId;
|
|
7297
|
+
const systemMsg = `[secret-drop-stuck] Secret "${event.label}" was submitted but has not been consumed by an agent process. ` +
|
|
7298
|
+
`If you weren't expecting this, the consumer may have hit a bug. ` +
|
|
7299
|
+
`The submission will auto-clean in ~${event.minutesUntilCleanup} minute(s). ` +
|
|
7300
|
+
`To retry, re-read it (non-destructive): curl -s -X POST -H "Authorization: Bearer $AUTH" http://localhost:${ctx.config.port}/secrets/retrieve/${event.token}.`;
|
|
7301
|
+
try {
|
|
7302
|
+
const sdRegistryPath = path.join(ctx.config.stateDir, 'topic-session-registry.json');
|
|
7303
|
+
let targetSession = null;
|
|
7304
|
+
if (fs.existsSync(sdRegistryPath)) {
|
|
7305
|
+
const registry = JSON.parse(fs.readFileSync(sdRegistryPath, 'utf-8'));
|
|
7306
|
+
targetSession = registry.topicToSession?.[String(topicId)] ?? null;
|
|
7307
|
+
}
|
|
7308
|
+
if (targetSession && ctx.sessionManager.isSessionAlive(targetSession)) {
|
|
7309
|
+
ctx.sessionManager.injectPasteNotification(targetSession, `<system-reminder>${systemMsg}</system-reminder>`);
|
|
7310
|
+
}
|
|
7311
|
+
}
|
|
7312
|
+
catch (err) {
|
|
7313
|
+
// @silent-fallback-ok — the stuck-consumer signal is best-effort
|
|
7314
|
+
console.error('[secret-drop] stuck-consumer notify failed:', err instanceof Error ? err.message : String(err));
|
|
7315
|
+
}
|
|
7316
|
+
});
|
|
7288
7317
|
/** Build a browser-clickable tunnel URL for a secret drop */
|
|
7289
7318
|
function secretDropUrl(token) {
|
|
7290
7319
|
const localUrl = `/secrets/drop/${token}`;
|
|
@@ -7391,7 +7420,9 @@ export function createRoutes(ctx) {
|
|
|
7391
7420
|
const fieldCount = Object.keys(submission.values).length;
|
|
7392
7421
|
const fieldNames = Object.keys(submission.values).join(', ');
|
|
7393
7422
|
const systemMsg = `[secret-drop-received] Secret "${submission.label}" was just submitted (${fieldCount} field${fieldCount !== 1 ? 's' : ''}: ${fieldNames}). ` +
|
|
7394
|
-
`Retrieve
|
|
7423
|
+
`Retrieve (non-destructive — safe to retry on parse error): curl -s -X POST -H "Authorization: Bearer $AUTH" http://localhost:${ctx.config.port}/secrets/retrieve/${req.params.token}. ` +
|
|
7424
|
+
`When you have successfully handed off the value, consume it: append ?consume=true to the same URL. ` +
|
|
7425
|
+
`Then acknowledge receipt to the user conversationally via Telegram topic ${topicId}.`;
|
|
7395
7426
|
const sdRegistryPath = path.join(ctx.config.stateDir, 'topic-session-registry.json');
|
|
7396
7427
|
let targetSession = null;
|
|
7397
7428
|
try {
|
|
@@ -7530,15 +7561,25 @@ export function createRoutes(ctx) {
|
|
|
7530
7561
|
}
|
|
7531
7562
|
res.json({ ok: true });
|
|
7532
7563
|
});
|
|
7533
|
-
// Retrieve a received secret (agent-facing, requires auth)
|
|
7534
|
-
//
|
|
7564
|
+
// Retrieve a received secret (agent-facing, requires auth).
|
|
7565
|
+
//
|
|
7566
|
+
// Non-destructive by default — repeated calls return the same value
|
|
7567
|
+
// until the in-memory cleanup timer fires (~5 min). Pass `?consume=true`
|
|
7568
|
+
// for the legacy one-shot semantics. Rationale: a buggy consumer that
|
|
7569
|
+
// dropped the response value used to lose the secret with no recovery;
|
|
7570
|
+
// non-destructive default lets the caller retry. See
|
|
7571
|
+
// docs/specs/secret-drop-hardening.md for the full rationale.
|
|
7535
7572
|
router.post('/secrets/retrieve/:token', (req, res) => {
|
|
7536
|
-
const
|
|
7573
|
+
const consumeFlag = req.query.consume;
|
|
7574
|
+
const consume = consumeFlag === 'true' || consumeFlag === '1';
|
|
7575
|
+
const submission = consume
|
|
7576
|
+
? secretDrop.consumeReceived(req.params.token)
|
|
7577
|
+
: secretDrop.peekReceived(req.params.token);
|
|
7537
7578
|
if (!submission) {
|
|
7538
7579
|
res.status(404).json({ error: 'No submission found for this token' });
|
|
7539
7580
|
return;
|
|
7540
7581
|
}
|
|
7541
|
-
res.json(submission);
|
|
7582
|
+
res.json({ ...submission, consumed: consume });
|
|
7542
7583
|
});
|
|
7543
7584
|
// ── Tunnel Status ──────────────────────────────────────────────
|
|
7544
7585
|
router.get('/tunnel', (_req, res) => {
|