658 Commits

Author SHA1 Message Date
jiarung
6f85d77f63
Merge branch 'main' into fix/token-usage-input-output-breakdown 2026-03-16 11:58:02 +08:00
Peter Steinberger
46482a283a
feat: add nostr setup and unify channel setup discovery 2026-03-15 19:58:22 -07:00
jiarung
ef90401a49
Merge branch 'main' into fix/token-usage-input-output-breakdown 2026-03-16 10:29:47 +08:00
Peter Steinberger
47a9c1a893 refactor: merge minimax bundled plugins 2026-03-16 02:26:45 +00:00
Peter Steinberger
38abdea8ce fix: restore ci type checks 2026-03-16 02:23:44 +00:00
Peter Steinberger
2b57d3bb34 build(plugin-sdk): enforce export sync in check 2026-03-16 02:11:19 +00:00
Peter Steinberger
39aba198f1 fix(docs): run i18n through a local rpc client 2026-03-16 02:11:18 +00:00
Peter Steinberger
0a136f1b90 fix(docs): harden i18n prompt failures 2026-03-16 02:11:18 +00:00
Peter Steinberger
59940cb3ee refactor(plugin-sdk): centralize entrypoint manifest 2026-03-16 02:11:18 +00:00
Peter Steinberger
70a6d40d37 fix: remove stale dist plugin dirs 2026-03-16 02:10:36 +00:00
Peter Steinberger
fb991e6f31
perf(plugins): lazy-load setup surfaces 2026-03-15 18:46:54 -07:00
Peter Steinberger
9c89a74f84
perf(cli): trim help startup imports 2026-03-15 18:20:52 -07:00
Peter Steinberger
bc5054ce68 refactor(google): merge gemini auth into google plugin 2026-03-16 01:19:32 +00:00
Vincent Koc
c0e0115b31 CI: add CLI startup memory regression check 2026-03-15 17:42:48 -07:00
Peter Steinberger
c156f7c7e3 fix: reduce plugin and discord warning noise 2026-03-16 00:24:44 +00:00
Peter Steinberger
a058bf918d
feat(plugins): test bundle MCP end to end 2026-03-15 16:51:13 -07:00
Gustavo Madeira Santana
14137bef22
Plugins: clean stale bundled skill outputs 2026-03-15 21:48:09 +00:00
Gustavo Madeira Santana
50a6902a9a
Plugins: skip nested node_modules in bundled skills 2026-03-15 21:43:13 +00:00
Gustavo Madeira Santana
1839bc0b1a
Plugins: relocate bundled skill assets 2026-03-15 21:42:02 +00:00
Nimrod Gutman
50c8934231
fix(dev): align gateway watch with tsdown wrapper (#47636) 2026-03-15 23:28:57 +02:00
Vincent Koc
5a7aba94a2
CLI: support package-manager installs from GitHub main (#47630)
* CLI: resolve package-manager main install specs

* CLI: skip registry resolution for raw package specs

* CLI: support main package target updates

* CLI: document package update specs in help

* Tests: cover package install spec resolution

* Tests: cover npm main-package updates

* Tests: cover update --tag main

* Installer: support main package targets

* Installer: support main package targets on Windows

* Docs: document package-manager main updates

* Docs: document installer main targets

* Docs: document npm and pnpm main installs

* Docs: document update --tag main

* Changelog: note package-manager main installs

* Update src/infra/update-global.test.ts

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2026-03-15 14:18:12 -07:00
Nimrod Gutman
47fd8558cd
fix(plugins): fix bundled plugin roots and skill assets (#47601)
* fix(acpx): resolve bundled plugin root correctly

* fix(plugins): copy bundled plugin skill assets

* fix(plugins): tolerate missing bundled skill paths
2026-03-15 23:00:30 +02:00
Gustavo Madeira Santana
4fb0160309
Gateway: sync runtime post-build artifacts 2026-03-15 20:44:15 +00:00
Ted Li
07f890fa45
fix(release): block oversized npm packs that regress low-memory startup (#46850)
* fix(release): guard npm pack size regressions

* fix(release): fail closed when npm omits pack size
2026-03-15 21:31:30 +01:00
Gustavo Madeira Santana
594920f8cc
Scripts: rebuild on extension and tsdown config changes (#47571)
Merged via squash.

Prepared head SHA: edd8ed825469128bbe85f86e2e1341f6c57687d7
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Reviewed-by: @gumadeiras
2026-03-15 16:19:27 -04:00
Onur Solmaz
a2080421a1
Docs: move release runbook to maintainer repo (#47532)
* Docs: redact private release setup

* Docs: tighten release order

* Docs: move release runbook to maintainer repo

* Docs: delete public mac release page

* Docs: remove zh-CN mac release page

* Docs: turn release checklist into release policy

* Docs: point release policy to private docs

* Docs: regenerate zh-CN release policy pages

* Docs: preserve Doctor in zh-CN hubs

* Docs: fix zh-CN polls label

* Docs: tighten docs i18n term guardrails

* Docs: enforce zh-CN glossary coverage
2026-03-15 20:42:39 +01:00
Nimrod Gutman
e2dac5d5cb
fix(plugins): load bundled extensions from dist (#47560) 2026-03-15 21:16:27 +02:00
jiarung
3af18e3591
Merge branch 'main' into fix/token-usage-input-output-breakdown 2026-03-16 00:33:08 +08:00
Harold Hunt
53462b990d
chore(gateway): ignore .test.ts changes in gateway:watch (#36211) 2026-03-15 11:14:28 -04:00
jiarung
a47f7e465c
Merge branch 'main' into fix/token-usage-input-output-breakdown 2026-03-15 21:22:22 +08:00
jiarung
9944231ff4 fix(file-lock,git-hooks): PID reuse detection, null-payload race, prerelease sort
Three independent fixes bundled here because they came from the same
review pass.

── 1. Record lock owner identity beyond PID (file-lock) ──────────────

Stale-lock detection used only isPidAlive(), but PIDs are reusable.
On systems with small PID namespaces (containers, rapid restarts) a
crashed writer's PID can be reassigned to an unrelated live process,
causing isStaleLock to return false and the lock to appear held
indefinitely.

Fix: record the process start time (field 22 from /proc/{pid}/stat)
alongside pid and createdAt.  On Linux, if the current holder's
startTime differs from the stored value the PID was recycled and the
lock is reclaimed immediately.  On other platforms startTime is omitted
and the existing createdAt age-check (a reused PID inherits the old
timestamp, exceeding staleMs) remains as the fallback.

── 2. Restore mtime fallback for null/unparseable payloads (file-lock) ─

The previous fix treated null payload as immediately stale.  But the
lock file is created (empty) by open('wx') before writeFile fills in
the JSON.  A live writer still in that window has an empty file; marking
it stale immediately allows a second process to steal the lock and both
to enter fn() concurrently.

Fix: when payload is null, fall back to the file's mtime.  A file
younger than staleMs may belong to a live writer and is left alone; a
file older than staleMs was definitely orphaned and is reclaimed.  A
new test asserts that a freshly-created empty lock (recent mtime) is NOT
treated as stale.

── 3. Strip prerelease suffix before printf '%05d' (resolve-node.sh) ──

When an nvm install has a prerelease directory name (e.g.
v22.0.0-rc.1/bin/node), splitting on '.' leaves _pa as '0-rc.1'.
printf '%05d' then fails because '0-rc.1' is not an integer, and
set -euo pipefail aborts the hook before lint/format can run — the
opposite of what the nvm fallback is meant to achieve.

Fix: strip the longest non-digit suffix from each component before
printf: '0-rc.1' → '0', '14' → '14' (no-op for normal releases).
Uses POSIX parameter expansion  so it works on both
GNU bash and macOS bash 3.x.
2026-03-15 07:46:31 +00:00
jiarung
d3971e77fd fix(git-hooks): replace GNU-only sort -V with portable zero-pad sort
sort -V is a GNU extension; BSD sort on macOS does not support it. When
node is absent from PATH and the nvm fallback runs, set -euo pipefail
causes the unsupported flag to abort the hook before lint/format can
run, blocking commits on macOS.

Replace the sort -V | tail -1 pipeline with a Bash for-loop that
zero-pads each semver component to five digits and emits a tab-delimited
key+path line. Plain sort + tail -1 + cut then selects the highest
semantic version — no GNU-only flags required.

Smoke-tested with v18 vs v22 paths; v22 is correctly selected on both
GNU and BSD sort.
2026-03-15 05:14:07 +00:00
Radek Sienkiewicz
e3b7ff2f1f
Docs: fix MDX markers blocking page refreshes (#46695)
Merged via squash.

Prepared head SHA: 56b25a9fb3acc1a3befbf33c28a6d27df8aca8ef
Co-authored-by: velvet-shark <126378+velvet-shark@users.noreply.github.com>
Co-authored-by: velvet-shark <126378+velvet-shark@users.noreply.github.com>
Reviewed-by: @velvet-shark
2026-03-15 02:58:59 +01:00
Radek Sienkiewicz
4c6a7f84a4
docs: remove dead security README nav entry (#46675)
Merged via squash.

Prepared head SHA: 63331a54b8a6d50950a6ca85774fa1d915cd4e8d
Co-authored-by: velvet-shark <126378+velvet-shark@users.noreply.github.com>
Co-authored-by: velvet-shark <126378+velvet-shark@users.noreply.github.com>
Reviewed-by: @velvet-shark
2026-03-15 01:40:00 +01:00
Brian Qu
8a607d7553
fix(feishu): fetch thread context so AI can see bot replies in topic threads (#45254)
* fix(feishu): fetch thread context so AI can see bot replies in topic threads

When a user replies in a Feishu topic thread, the AI previously could only
see the quoted parent message but not the bot's own prior replies in the
thread. This made multi-turn conversations in threads feel broken.

- Add `threadId` (omt_xxx) to `FeishuMessageInfo` and `getMessageFeishu`
- Add `listFeishuThreadMessages()` using `container_id_type=thread` API
  to fetch all messages in a thread including bot replies
- In `handleFeishuMessage`, fetch ThreadStarterBody and ThreadHistoryBody
  for topic session modes and pass them to the AI context
- Reuse quoted message result when rootId === parentId to avoid redundant
  API calls; exclude root message from thread history to prevent duplication
- Fall back to inbound ctx.threadId when rootId is absent or API fails
- Fetch newest messages first (ByCreateTimeDesc + reverse) so long threads
  keep the most recent turns instead of the oldest

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(feishu): skip redundant thread context injection on subsequent turns

Only inject ThreadHistoryBody on the first turn of a thread session.
On subsequent turns the session already contains prior context, so
re-injecting thread history (and starter) would waste tokens.

The heuristic checks whether the current user has already sent a
non-root message in the thread — if so, the session has prior turns
and thread context injection is skipped entirely.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(feishu): handle thread_id-only events in prior-turn detection

When ctx.rootId is undefined (thread_id-only events), the starter
message exclusion check `msg.messageId !== ctx.rootId` was always
true, causing the first follow-up to be misclassified as a prior
turn. Fall back to the first message in the chronologically-sorted
thread history as the starter.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(feishu): bootstrap topic thread context via session state

* test(memory): pin remote embedding hostnames in offline suites

* fix(feishu): use plugin-safe session runtime for thread bootstrap

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
2026-03-14 18:01:59 -05:00
Vincent Koc
cbec476b6b
Docs: add config drift baseline statefile (#45891)
* Docs: add config drift statefile generator

* Docs: generate config drift baseline

* CI: move config docs drift runner into workflow sanity

* Docs: emit config drift baseline json

* Docs: commit config drift baseline json

* Docs: wire config baseline into release checks

* Config: fix baseline drift walker coverage

* Docs: regenerate config drift baselines
2026-03-14 14:23:30 -07:00
Tak Hoffman
e81442ac80 Fix full local gate on main 2026-03-14 15:52:11 -05:00
Onur
d33f3f843a
ci: allow fallback npm correction tags (#46486) 2026-03-14 19:38:14 +01:00
scoootscooob
ac29edf6c3
fix(ci): update vitest configs after channel move to extensions/ (openclaw#46066)
Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: scoootscooob <167050519+scoootscooob@users.noreply.github.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
2026-03-14 13:23:25 -05:00
Onur Solmaz
c08317203d ci: enforce calver freshness on npm publish 2026-03-14 13:45:40 +01:00
Onur Solmaz
00891dee90 ci: switch npm release workflow to trusted publishing 2026-03-14 13:45:40 +01:00
Onur Solmaz
02a86da23a ci: preserve manual npm release approval delays 2026-03-14 13:45:40 +01:00
Onur Solmaz
2eea93982f ci: make npm release preview more verbose 2026-03-14 13:45:40 +01:00
Onur Solmaz
78d2bfc4d8 ci: add dry-run gate to npm release workflow 2026-03-14 13:45:40 +01:00
scoootscooob
439c21e078
refactor: remove channel shim directories, point all imports to extensions (#45967)
* refactor: remove channel shim directories, point all imports to extensions

Delete the 6 backward-compat shim directories (src/telegram, src/discord,
src/slack, src/signal, src/imessage, src/web) that were re-exporting from
extensions. Update all 112+ source files to import directly from
extensions/{channel}/src/ instead of through the shims.

Also:
- Move src/channels/telegram/ (allow-from, api) to extensions/telegram/src/
- Fix outbound adapters to use resolveOutboundSendDep (fixes 5 pre-existing TS errors)
- Update cross-extension imports (src/web/media.js → extensions/whatsapp/src/media.js)
- Update vitest, tsdown, knip, labeler, and script configs for new paths
- Update guard test allowlists for extension paths

After this, src/ has zero channel-specific implementation code — only the
generic plugin framework remains.

* fix: update raw-fetch guard allowlist line numbers after shim removal

* refactor: document direct extension channel imports

* test: mock transcript module in delivery helpers
2026-03-14 03:43:07 -07:00
scoootscooob
16505718e8
refactor: move WhatsApp channel implementation to extensions/ (#45725)
* refactor: move WhatsApp channel from src/web/ to extensions/whatsapp/

Move all WhatsApp implementation code (77 source/test files + 9 channel
plugin files) from src/web/ and src/channels/plugins/*/whatsapp* to
extensions/whatsapp/src/.

- Leave thin re-export shims at all original locations so cross-cutting
  imports continue to resolve
- Update plugin-sdk/whatsapp.ts to only re-export generic framework
  utilities; channel-specific functions imported locally by the extension
- Update vi.mock paths in 15 cross-cutting test files
- Rename outbound.ts -> send.ts to match extension naming conventions
  and avoid false positive in cfg-threading guard test
- Widen tsconfig.plugin-sdk.dts.json rootDir to support shim->extension
  cross-directory references

Part of the core-channels-to-extensions migration (PR 6/10).

* style: format WhatsApp extension files

* fix: correct stale import paths in WhatsApp extension tests

Fix vi.importActual, test mock, and hardcoded source paths that weren't
updated during the file move:
- media.test.ts: vi.importActual path
- onboarding.test.ts: vi.importActual path
- test-helpers.ts: test/mocks/baileys.js path
- monitor-inbox.test-harness.ts: incomplete media/store mock
- login.test.ts: hardcoded source file path
- message-action-runner.media.test.ts: vi.mock/importActual path
2026-03-14 02:44:55 -07:00
Peter Steinberger
6e251dcf68
test: harden parallels beta smoke flows 2026-03-14 05:54:49 +00:00
Peter Steinberger
7e41ba4cbb
test: harden parallels all-os smoke harness 2026-03-14 04:46:47 +00:00
Peter Steinberger
d925b0113f
test: add parallels linux smoke harness 2026-03-14 01:56:24 +00:00
Peter Steinberger
4dbab064f0
test: add parallels windows smoke harness 2026-03-14 00:33:39 +00:00