Add features across agents, collab, trust, indexes, and hyperbee.

Manual pass: task cancelTask, workflow topologicalOrder/fail/reset, collab kick/replay, trust trustedPeers and multisig TTL sweep, graph shortestPath, inverted topTerms, dedup filterNew, bee notifyBatch/seekVersion — all with tests.

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
Raven Scott
2026-05-21 01:04:42 -04:00
co-authored by Cursor
parent cb9caad46c
commit b8b815fce6
25 changed files with 386 additions and 6 deletions
@@ -16,7 +16,7 @@ class HyperP2PMultisigThreshold extends EventEmitter {
this._peerMsgs = null
}
createProposal (id, signers, threshold) {
createProposal (id, signers, threshold, opts = {}) {
assertNonEmpty(id, 'id')
if (!Array.isArray(signers) || signers.length === 0) {
throw new Error('signers must be a non-empty array')
@@ -24,12 +24,14 @@ class HyperP2PMultisigThreshold extends EventEmitter {
if (threshold < 1 || threshold > signers.length) {
throw new Error('threshold must be between 1 and signers.length')
}
const expiresAt = opts.expiresAt ?? (opts.ttlMs ? Date.now() + opts.ttlMs : null)
const proposal = {
id,
signers: [...signers],
threshold,
signatures: new Set(),
createdAt: Date.now(),
expiresAt,
approved: false
}
this._proposals.set(id, proposal)
@@ -66,9 +68,47 @@ class HyperP2PMultisigThreshold extends EventEmitter {
isApproved (id) {
assertNonEmpty(id, 'id')
const p = this._proposals.get(id)
if (p && p.expiresAt && Date.now() > p.expiresAt) return false
return !!(p && p.approved)
}
signatureCount (id) {
const p = this._proposals.get(id)
return p ? p.signatures.size : 0
}
listProposals () {
return [...this._proposals.values()].map((p) => ({
id: p.id,
signers: p.signers,
threshold: p.threshold,
signatures: p.signatures.size,
approved: p.approved,
expiresAt: p.expiresAt,
createdAt: p.createdAt
}))
}
expireProposal (id) {
assertNonEmpty(id, 'id')
const ok = this._proposals.delete(id)
if (ok) this.emit('expired', { id })
return ok
}
sweepExpired () {
const now = Date.now()
let n = 0
for (const [id, p] of this._proposals) {
if (p.expiresAt && now > p.expiresAt && !p.approved) {
this._proposals.delete(id)
n++
}
}
if (n) this.emit('sweep', { removed: n })
return n
}
_gossip (data) {
if (!this._peerMsgs) return
gossipSend(this, data)
@@ -36,3 +36,12 @@ test('getStats', async (t) => {
t.is(m.getStats().created, 1)
await m.close()
})
test('ttl sweep and listProposals', async (t) => {
const m = new HyperP2PMultisigThreshold()
m.createProposal('exp', ['a', 'b'], 2, { expiresAt: Date.now() - 1 })
t.is(m.listProposals().length, 1)
t.is(m.sweepExpired(), 1)
t.is(m.listProposals().length, 0)
await m.close()
})