Repository navigation
docs(changelog): release v0.1.4 - #2780
Closed
MatiasxVarela wants to merge 142 commits into
Closed
MatiasxVarela wants to merge 142 commits into
MatiasxVarela wants to merge 142 commits into
Conversation
…ocol CLAUDE.md now points to AGENTS.md. Adds odd/agent-protocol.md adapted from orbit and odd/archive/.
Adds Claude settings with git-gate and prettier hooks, scripts/check-docs.sh wired into Husky pre-commit, a Makefile with a not-prod guard, purple-checks CI, GHCR image publishing on v* tags, VERSION 0.1.0 and a fork CHANGELOG section. Upstream Docker Hub publish workflows are disabled.
Adds purple-typescript, purple-baileys, purple-contract (with consumer matrix for orbit, canal-whatsapp and stenfar), purple-upstream-sync and purple-release. .pi/settings.json reuses .claude/skills.
…-tooling' into chore/agentic-setup
git-gate: ignore flags inside quoted messages, check merge/rebase against HEAD, full check on push without base ref, explicit npm ci message when toolchain is missing. Align purple-release with GHCR workflow and CHANGELOG layout, fix upstream remote wording, list the three Prisma schemas.
…rors Falls back to node when jq is missing and blocks unparseable git writes. A failing git diff escalates to a full tsc + eslint check. Verified against the real toolchain after npm ci and prisma generate.
chore: organize repo for agentic development
odd/tasks/ and odd/archive/ are gitignored because the repo is public. odd/agent-protocol.md stays tracked. AGENTS.md documents that unfixed security findings never go into commits, PRs or issues.
chore(odd): keep feature task docs local
…es (#2) The auth guard authorizes req.params.instanceName, but dataValidate merged the query into the same instance object, so ?instanceName=OTHER ran against another tenant's instance (CWE-639). Instance routes now restore the authorized name from the path param and drop instanceId; the create body is merged only on the exact /instance/create route. fetchInstances and instance creation keep their behavior. Adds AGENTS.md hard rule (e): no code comments. Upstream: evolution-foundation#2549 (7a55a2b), adapted.
Since 2026-07-28 WhatsApp sends a companion_reg_refresh notification during device registration. Baileys drops it, so the QR keeps advertising a retired adv secret and pairing fails intermittently. Bumps baileys 7.0.0-rc.9 to 7.0.0-rc14 (also fixes CVE-2026-48063, patched in rc12) and vendors WhiskeySockets/Baileys#2765 (companion_reg_refresh handling, skipped on registered sessions) and evolution-foundation#2602 (link_code_companion_reg guard) through patch-package. The Dockerfile copies patches/ before npm ci. (cherry picked from commit 5cdf32409a7c10066dd6c5b15af7a3ef7c5aac94) Upstream: evolution-foundation#2759 (5cdf324), unmerged
The vendored WhiskeySockets/Baileys#2765 and evolution-foundation#2602 code now carries no comments, per the no-code-comments rule. Behavior is unchanged: the patch applies on npm ci and the patched modules import cleanly.
postinstall runs patch-package, so it must be available when only production dependencies are installed; otherwise the baileys patch is silently skipped.
fix(deps): patch baileys rc14 to restore WhatsApp device pairing
… sync keys The Prisma, Redis and provider-files auth states read app-state-sync-key values with AppStateSyncKeyData.create(), which copies fields without coercion, so the stored base64 keyData never becomes bytes again. Baileys then fails to decrypt app-state mutations (labels, archive, mute, pin, contact names) and those events never fire. fromObject() performs the conversion, matching Baileys' reference auth state. (cherry picked from commit 65b5acf) Upstream: evolution-foundation#2685 (65b5acf), unmerged
fix(auth-state): restore AppStateSyncKeyData.fromObject for app-state sync keys
Evolution has no tests. Vitest runs TypeScript directly and loads ESM-only Baileys from this CommonJS project without transforming node_modules. Tests live in test/, mirroring src/, outside the tsc and tsup build; /test/ is no longer gitignored. CI runs npm test in purple-checks; make test and AGENTS.md document it.
Pins current behavior: JID passthrough and normalization, group ids, the AR/MX 13-digit and BR 9th-digit rules, and message content extraction per type with S3 on and off. Suspected bugs are asserted as-is, not fixed: AR/MX numbers lose their third digit, ad-only messages duplicate the externalAdReplyBody prefix, and a location without latitude throws.
…nd onWhatsappCache Covers each trigger type and operator and the cache hit, miss, update-skip and expiry paths with mocked Prisma and config. Suspected bugs are asserted as-is, not fixed: non BR/MX/AR numbers get the domain appended twice in onWhatsappCache, a jid without a domain becomes @undefined, an invalid stored regex rejects the whole bot lookup, and search values with spaces never match.
…tates Round-trips creds, Signal keys and app-state-sync-key values through fakes that reproduce the real BufferJSON serialization, so binary fields must survive storage. Covers the base64 keyData path that fromObject converts back to bytes. Suspected bugs are asserted as-is, not fixed: Prisma removeCreds keeps the Session row when Redis is enabled and leaves local key files on disk, fs.writeFile errors reject keys.set, and provider-files errors are swallowed without logs.
…GES_UPSERT Moves the remoteJid -> remoteJidAlt replacement applied before the MESSAGES_UPSERT webhook into resolvePhoneRemoteJid, so the rule the consumer products depend on is unit-tested. Behavior is unchanged: remoteJid is replaced only when it is a @lid and remoteJidAlt is present.
lint-staged 17 replaces micromatch with picomatch, removing one dependency path to braces@3.0.3 (GHSA-vfj7-8cjw-p6xm, no patched release). It requires Node >= 22.22.1, so CI moves from the end-of-life Node 20 to 24, matching the Dockerfile. braces is still pulled in by patch-package via find-yarn-workspace-root.
A persistent mockRejectedValue on the Prisma session fake leaked into later tests, so the suite only passed in default order. restoreMocks resets every vi.fn to its original implementation before each test, unstubEnvs and unstubGlobals undo stubs, and sequence.shuffle randomizes order locally and in CI so hidden coupling fails fast. Manual vi.clearAllMocks calls are now redundant.
Characterization tests asserted buggy behavior as if it were the contract. Each pinned bug is now named KNOWN BUG (current behavior) and paired with an it.fails asserting the correct behavior, so fixing the bug flips the it.fails and forces both into one normal test. createJid AR/MX keeps only the KNOWN BUG name because the correct rule is unclear. AGENTS.md documents the convention.
The cache fake encoded once and rejected on errors, while production double-encodes (CacheService + RedisCache) and CacheService swallows inner errors. test/helpers now provides an in-memory ICache with RedisCache's serialization and a down mode behind the real CacheService, plus shared Logger and fs/promises fakes. With Redis down, saveCreds resolves, nothing persists and reopening yields fresh creds. The removeData log-key KNOWN BUG is dropped: CacheService.hDelete catches its own errors, so that path is unreachable.
Adds cases that fail when their target line is mutated: onWhatsappCache isDataSame and null jidOptions updates, getConversationMessage view-once and list fallbacks, query-side accent stripping and empty queries, createJid unknown domains, short dashed ids and device-suffixed broadcasts, fixFileName slashes, no creds persisted on Redis open, exact provider-files log payloads, and findBotByTrigger enabled/instanceId filtering. A @lid substring that is not a suffix is pinned as a KNOWN BUG in resolvePhoneRemoteJid.
fix(baileys): fill remoteJidAlt for @lid history sync messages
* feat(baileys): backfill remoteJidAlt on stored lid messages When an instance learns a LID->phone pair, via the Baileys lid-mapping.update event or a live messages.upsert carrying a @lid remoteJid with a phone remoteJidAlt, older Message rows of that instance keyed by the lid get key.remoteJidAlt filled with the phone JID. key.remoteJid is never rewritten and existing phone remoteJidAlt values are kept. The update is a parameterized jsonb_set, runs at most once per (instance, lid) per process via a bounded set, is fire-and-forget, logs failures at warn and is skipped when message saving is disabled. 1:1 chats only. Inspired by upstream evolution-foundation#2663 by @fidelis05. * fix(baileys): retry failed lid backfills, run them one at a time, postgres only * test(baileys): cover lid backfill scheduling guards and lid-mapping dispatch * test(baileys): cover the messages.upsert lid backfill trigger * test(utils): use fictional phone and lid fixtures * test(utils): replace real phone numbers with fictional fixtures
…-alt-script chore(scripts): add one-off backfill for @lid remoteJidAlt
Sent messages stayed PENDING because messages.update only wrote Message.status for received messages. The status now only moves forward, ERROR is always kept unless the message is DELETED or EDITED, and those stay final. Webhooks and MessageUpdate rows are unchanged.
…he status write fails
fix(baileys): advance the status of sent messages from acks
logout() throws for sockets that were never paired, which skipped closing the socket, resetting the QR count and setting the state to close, so instances stayed connecting and /instance/connect returned an expired QR. The state is now always closed and persisted.
…ceipts getMessage now returns nothing for deleted messages, incoming revokes mark the stored message DELETED, and deleteMessage only looks up rows of its own instance. Inspired by upstream evolution-foundation#2751 by @sossei.
fix(monitor): close unpaired instances when the QR code limit is reached
…-messages # Conflicts: # CHANGELOG.md
fix(baileys): do not resend messages deleted for everyone on retry receipts
Adds the two indexes stenfar had created by hand as migrations with the same names, using CREATE INDEX CONCURRENTLY IF NOT EXISTS so they are a no-op where they exist and do not block writes where they are built.
Replaces the unconditional console.log calls in the Baileys service with logger calls that carry only ids, counts and types, including logger calls that passed whole messages with base64 media.
updateChatUnreadMessages and the edit lookup matched rows of any instance with the same remote jid or key id, so another instance's chat or message could be updated. The edit guards now throw explicitly.
One failing message in messages.upsert or messages.update dropped the rest of the batch and their webhooks, and early returns in presence and label handling skipped later event types of the same Baileys batch.
perf(prisma): index message lookups by key id and remote jid
…edit fix(baileys): scope unread counts and message edits to the instance
…e-logs # Conflicts: # CHANGELOG.md
fix(baileys): stop printing message payloads and base64 media to stdout
# Conflicts: # CHANGELOG.md
fix(baileys): isolate errors per message, update and event type
…ChatUnread (#43) getLastMessage filtered the Message.key JSON column with { remoteJid }, which Prisma rejects as an unknown argument, so archiveChat and markChatUnread failed with 500 whenever the caller sent only `chat`. It also compared the raw number against stored JIDs. - Filter with { path: ['remoteJid'], equals } on the JID built by createJid, keeping @lid addressing intact. - archiveChat accepts chats without stored messages by sending an empty lastMessages list instead of failing. - The fallback messageTimestamp is unix seconds instead of milliseconds. Response shapes are unchanged. Credit: based on the fix by Razario in we-digital/wdgtl-evo-api (commit 2e045cb, "Fix WA mute units, archive JID lookup, and chat-update spam"). Co-authored-by: matiasxvarela <mvarela@decampoacampo>
Author
|
Opened against the wrong repository by mistake, sorry for the noise. |
Contributor
|
Sorry @MatiasxVarela, your pull request is larger than the review limit of 150,000 diff characters |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Release notes for v0.1.4 (#32–#43). After merge, tag
v0.1.4on main to publish the image to GHCR.