Commit Graph

49 Commits

Author SHA1 Message Date
CodeWhale Bot b5cf91ec7f fix(exec): leave headless turn budgets opt-in
Run headless agent loops without a finite model-step ceiling unless the caller explicitly supplies --max-turns. Keep finite values validated and preserve the separate Fleet worker budget.

Remove the verifier harness's implicit 100-turn flag so long benchmark rollouts are not silently truncated. Verified with the focused TUI regression, all nine verifier harness tests, cargo fmt, targeted strict Clippy, and diff checking.
2026-08-07 22:42:40 -07:00
Hmbown 524e5f7c7e docs(verifiers): pin the harness examples to 0.9.4
The README body already said v0.9.4 while the three eval examples still
passed --harness.version 0.9.1, which would resolve a two-release-old
runtime companion set.
2026-08-05 00:42:07 -07:00
Hmbown 503f7ec928 feat(tui): emit per-turn usage receipts on the exec stream-json stream
Terminal-Bench latency analysis (FINISH-0.9.4 #52) had to infer
reasoning-token counts from wall time because the exec stream-json had
no per-turn usage: content deltas carry none, and only the terminal
metadata receipt reported cumulative totals.

The engine now emits Event::TurnUsage once per model call (turn-step)
when the provider reported usage for that call, carrying the step's
Usage plus stream wall-clock duration. The chat-completions adapter's
synthetic zeroed MessageStart is explicitly not treated as reported, so
providers that never send usage produce no event instead of fabricated
zeros.

codewhale exec --output-format stream-json maps it to a new additive
turn_usage event: turn (1-based), input_tokens, output_tokens, and
duration_ms always present; reasoning_tokens, prompt_cache_hit/miss/
write_tokens, and reasoning_replay_tokens omitted (never null, never
zero-filled) when the provider does not report them. Field names mirror
the terminal metadata receipt so consumers parse one vocabulary.

Existing event shapes are untouched. Consumers: the TUI ignores the new
engine event (its token surfaces run on cumulative TurnComplete usage),
the fleet ledger maps turn_usage to a Running liveness heartbeat for
thinking-heavy calls, and the verifiers harness whitelist accepts the
new type.

Tests: serialization shape + honest-absence unit tests, a pre-existing
event-tag contract guard, and an end-to-end wiremock integration test
locking both the usage-present shape (and the unchanged metadata->done
terminal contract) and the usage-absent skip.
2026-08-03 12:28:36 -07:00
Hmbown 314f1b0482 chore(release): align published version strings with workspace 0.9.4
extensions/vscode was 0.8.53, npm/runtime-sdk 0.8.60, and the
verifiers README claimed v0.9.1 while the workspace is 0.9.4. All
three now read 0.9.4. The release.yml version gate previously checked
only workspace + npm/codewhale, which is how the drift survived
release prep; it now also requires runtime-sdk and vscode package
versions to match the tag.

Evidence: cross-surface-tech-debt-audit-2026-08-03.md TL;DR 'Stale
version strings'; §11.3 version-sweep row.
Gate: node -p require(...).version -> 0.9.4 for both packages.
2026-08-02 20:59:24 -07:00
Hunter B 0dfe9170a1 chore(deps): patch npm lockfiles for Dependabot alerts
Apply `npm audit fix --package-lock-only` across npm workspaces to
resolve the 17 open Dependabot alerts (7 high, 10 moderate) on the
v0.9.1 merged tree:

- integrations/feishu-bridge: protobufjs 7.6.4 → 7.6.5
- extensions/vscode: brace-expansion 5.0.6 → 5.0.7, js-yaml 4.2.0 → 4.3.0,
  fast-uri 3.1.2 → 3.1.4, linkify-it 5.0.1 → 5.0.2
- web: brace-expansion/js-yaml and other transitive dev deps updated to
  patched versions; build, lint, tests, and `check:facts` still pass
- root package-lock: refreshed transitive lockfile metadata

Remaining npm audit findings:
- sharp <0.35.0 (via miniflare/next/wrangler) in web and root: no
  non-breaking patch available; miniflare pins sharp 0.34.5. Website is
  not deployed for v0.9.1, so exposure is build-time only.
- axios in feishu-bridge lockfile is already resolved to 1.18.1; the
  Dependabot alerts appear stale against the current lockfile.

All affected workspace checks pass:
- integrations/feishu-bridge: `npm run check && npm run test` — 19 passed
- extensions/vscode: `npm run check` — compiles
- web: `npm run prebuild && npm run check:facts && npm test && npm run lint
  && npm run build` — green

Refs #4713

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-07-22 17:48:52 -07:00
Hunter B 159e9ca2c8 Merge axios security update for v0.9.1 (#4661)
Integrate the exact all-green Dependabot commit that updates the Feishu bridge axios override to 1.18.1.

Signed-off-by: Hunter B <hmbown@gmail.com>
2026-07-21 22:44:43 -07:00
dependabot[bot] a1cbce3f2a chore(deps): bump axios
Bumps the npm_and_yarn group with 1 update in the /integrations/feishu-bridge directory: [axios](https://github.com/axios/axios).


Updates `axios` from 1.16.1 to 1.18.1
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v1.16.1...v1.18.1)

---
updated-dependencies:
- dependency-name: axios
  dependency-version: 1.18.1
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-21 08:46:33 +00:00
Hunter B c9cccde461 Merge origin/main into the 0.9.1 release lane
Brings 65 upstream commits (web client #4423, OpenCode Go provider,
Windows/Linux ARM64 releases, xAI device OAuth, K3 route contracts,
tool heartbeat reattach, MCP hot-reload, permission posture cycle,
structured conversation export, PTY terminal tools) into the local
lane carrying the remaining milestone work (#4625, #4651, #4603, #4324,
#4628, #3934, #4632, #4647, #414, #4619, #4636, #2889, #4032, #4412,
#4598, #185, #4641, #4605).

Resolution notes:
- Purged 608 files of pr-4582 revert residue to their upstream state;
  re-applied the 25 real local commits on top by hand.
- Kept the unified BashTool (#4625) on top of upstream's shell
  hardening (EXEC_SHELL_WAIT_MAX_TIMEOUT_MS preserved).
- Kept the #185 wire-format dispatch on upstream's accessor-style
  ReadyRouteCandidate + prepare_model_bound_request sanitization.
- Kept upstream's dispatch architecture (route-before-mutate); the
  #4605 enter-lag fix is re-applied separately on this architecture.
- Kept upstream's SkillSource/plugin skill machinery with the #4632
  privacy-safe path rendering on the native arm.
- coord.rs holds both upstream's coordination tools and the #4647
  decision-record/write-scope types.
- Changelogs rebuilt: upstream's full 0.9.0 and 0.9.1 sections plus
  the local 0.9.1 entries; dropped unverified claims.
2026-07-20 20:47:51 -07:00
Hunter B 3fbda3d8cd feat(verifiers): add Codewhale harness adapter for Verifiers v0.2.1 (#4641)
Python integration package that adapts the Codewhale CLI for the
Verifiers v0.2.1 evaluation harness. Provides structured tool-call
extraction, receipt bounding, and terminal output normalization.
2026-07-20 17:20:19 -07:00
Hunter B 5640aa19b9 Revert "Merge remote-tracking branch 'origin/pr-4582'"
This reverts commit 9b3c28c572, reversing
changes made to 3e97b278e2.
2026-07-19 13:03:02 -07:00
Hunter B a7211e78e4 fix(telegram): escape MarkdownV2 backslashes
Include literal backslashes in Telegram MarkdownV2 text escaping and cover Windows-style paths so user-controlled text cannot break message parsing.
2026-07-16 02:40:48 -07:00
Hunter B 29d3f0c321 release: prepare Codewhale v0.9.0
Integrate the underwater TUI, message-first Operate, Fleet and Workflow reliability, expanded model/provider catalog, exact custom-route restoration, docs-first site, localization, packaging, and release metadata for the v0.9.0 candidate.

Harden endpoint-bound credential provenance, approval and goal UX, Fleet attempt fencing and crash recovery, large-workspace mention discovery, Kimi budgeting, and release asset/version gates. Include the stopship Fleet and Workflow fixtures used by release dogfood.

Verified with workspace fmt/check/clippy/tests on Rust 1.88, release-script and npm suites, 18-crate publish dry run, production web build, Docker build check, secret scan, dependency audit, and protected-state hash validation.
2026-07-15 23:44:37 -07:00
Hunter B 5cc2f5b63d wip(v0.8.67): fleet roster + whaleflow-js cutover checkpoint
Safety checkpoint of multi-agent cutover work (fleet roster core,
whaleflow-js runtime, /fleet roster view, audit fix lanes). Tree may
not compile: the agent-tool profile edit in tools/subagent/mod.rs was
interrupted mid-edit (credit exhaustion). Checkpoint precedes repair.
2026-07-05 10:02:37 -07:00
cyq 69d1c91ef9 fix(telegram): render markdown messages safely 2026-06-28 13:30:12 +08:00
cyq b8ef56630c fix(telegram): bound polling conflict retries 2026-06-27 16:07:39 +08:00
pkeging 94a5b056fe docs: add WeCom Bridge deployment guide
Harvested from PR #3640 by @pkeging.

Preserves the contributor's deployment and security guide while aligning commands with the files currently shipped in the repository. The harvest replaces stale helper-script references with the actual runtime and npm commands, and adds the approval-timeout variable to the bridge env template.
2026-06-26 18:40:53 -07:00
cyq a46fab54c3 fix(telegram): debounce turn sequence writes 2026-06-27 05:08:50 +08:00
Hunter Bown 709ab6c10a Merge pull request #3637 from pkeging/feat/natural-language-approval-standalone
feat(bridge): support natural-language approval responses

Thanks @pkeging for splitting this into a standalone bridge PR, adding the keyword regression tests, and dogfooding the WeCom bridge flow from mobile.
2026-06-26 13:47:52 -07:00
cyq ae11f3ca71 fix(telegram): persist handled update offsets 2026-06-26 22:59:36 +08:00
cyq 3822fcaeea fix(telegram): keep typing indicator alive during turns 2026-06-26 21:25:45 +08:00
cyq bb77c481f8 fix(telegram): retry transient send failures 2026-06-26 19:30:09 +08:00
cyq 3bae83a7cf fix(bridge): keep split chunks readable 2026-06-26 17:09:20 +08:00
laopan 5eb7fa3955 test(bridge): add approval/deny helper unit tests (16 cases)
- isApprovalResponse: Chinese single-word, English single-word,
  two-character Chinese, case-insensitivity, whitespace trim,
  non-approval rejection, null/empty handling
- isDenyResponse: same coverage for denial keywords
- Mutual exclusivity: verify no keyword matches both functions

Ref: #2967, #3637
2026-06-26 13:22:18 +08:00
laopan 2e9c444ce7 feat(bridge): support natural-language approval responses
Users can now reply with Chinese/English approval keywords
(e.g. "允许", "可以", "好", "ok", "yes") instead of
copying the approval_id from the prompt.

- Add isApprovalResponse / isDenyResponse helpers to lib.mjs
- Track latest pending approval per chat in a Map
- Intercept prompt messages that match approval/deny keywords
- Add approvalTimeoutMs config (env CODEWHALE_APPROVAL_TIMEOUT_MS)
- Update approval prompt with natural-language hint

Ref: #2967 (WeCom bridge resilience hardening)
2026-06-26 12:31:16 +08:00
Hmbown a9641b477c fix(integrations): harden bridge-core helpers
Address review nits from PR #3432: preserve lone quote env values, tolerate null active-turn state, and keep Telegram channel messages prefix-free.

Harvested from PR #3432 by @Hmbown.
2026-06-24 13:38:34 -07:00
CodeWhale Agent 9a85483f0f Merge PR #3432 bridge core extraction 2026-06-24 13:36:59 -07:00
pkeging d4e0a4809a fix(bridge): clear activeTurnId after approval decision to unblock user (#3468) 2026-06-23 10:26:32 -07:00
Hunter Bown 367c9d3d77 docs(bridge): rebrand Feishu/WeCom bridge READMEs to CodeWhale + trust-boundary notes (Track D3) (#3459)
Align the Feishu/Lark and WeCom bridge docs with the branded Telegram bridge and
remove DeepSeek-era residue:
- DEEPSEEK_RUNTIME_TOKEN -> CODEWHALE_RUNTIME_TOKEN, DEEPSEEK_ALLOW_UNLISTED ->
  CODEWHALE_ALLOW_UNLISTED, /etc/deepseek -> /etc/codewhale, /ds -> /cw.
- Name the allowlist var explicitly (CODEWHALE_CHAT_ALLOWLIST for Feishu;
  WECOM_CHAT_ALLOWLIST for WeCom) and document the first-pairing flow.
- Add a concise trust-boundary note per bridge: the chat platform only sees the
  prompts/status/approvals the bridge sends; workspace, shell, and the runtime
  HTTP listener stay on localhost behind the runtime token.

All env-var names and the /model and /cw commands verified against the bridge
source (feishu-bridge/src reads CODEWHALE_CHAT_ALLOWLIST/CODEWHALE_ALLOW_UNLISTED
with DEEPSEEK_* compat fallback). Weixin left unchanged (already branded).

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 01:20:15 -07:00
Hunter B de6126e0df Extract shared bridge thread store
Move the duplicated JSON thread-map store into bridge-core with bridge-specific options for message dedupe, Telegram action tokens, and WeCom private state-file modes. Keep thin local subclasses where startup-order tests and bridge exports expect ThreadStore names.

Verification:

- npm --prefix integrations/bridge-core run check && npm --prefix integrations/bridge-core test

- npm --prefix integrations/telegram-bridge run check && npm --prefix integrations/telegram-bridge test

- npm --prefix integrations/feishu-bridge run check && npm --prefix integrations/feishu-bridge test

- npm --prefix integrations/wecom-bridge run check && npm --prefix integrations/wecom-bridge test

- npm --prefix integrations/weixin-bridge run check && npm --prefix integrations/weixin-bridge test
2026-06-22 19:35:35 -07:00
Hunter B 6b6654a422 Extract shared bridge core helpers
Add integrations/bridge-core with shared pure helpers for env parsing, command parsing/action mapping, message splitting, runtime error compaction, active-turn detection, and preserved chat state.

Re-export or wrap those helpers from Telegram, Feishu, WeCom, and Weixin bridge libs while keeping transport-specific identity, validation, keyboards, and protocol handling local. Add Weixin lib tests so its helper behavior is guarded.
2026-06-22 19:15:27 -07:00
Hunter B faddf48463 fix(integrations): harden WeCom bridge state handling
Add a maintainer follow-up for the WeCom bridge harvest: private thread-map permissions, public error reporting back to the chat, malformed SSE tolerance, and tests for the local state store.

Follow-up to PR #3370 by @pkeging.
2026-06-21 21:43:46 -07:00
laopan 3bf50fac20 feat(integrations): add WeCom (企业微信) intelligent robot bridge
(cherry picked from commit b96d126234d43801fb2eee16a4f9968489cae2e2)
2026-06-21 21:41:46 -07:00
CodeWhale Agent e8415968d3 chore(deps): pin ws to 8.21.0 and refresh npm lockfiles
Pins ws across root, web, and integrated packages to close the remote
memory-exhaustion DoS disclosed in ws 8.20.1.
2026-06-15 15:18:49 -07:00
Hunter B f05252285f Merge PR #3206: WeChat bridge leveraging Feishu + Tencent OpenClaw (@Vincent Corleone)
Self-contained integrations/weixin-bridge package; no Rust-workspace impact.
Authorship preserved (@VincentCorleone).
2026-06-15 00:57:34 -07:00
Hunter B d82456dd10 fix(feishu-bridge): read CODEWHALE_* env, fall back to DEEPSEEK_*
So a remote-setup-generated Feishu bundle (emits CODEWHALE_*) wires up end-to-end; legacy
DEEPSEEK_* deployments keep working via fallback. .env.example now leads with CODEWHALE_*.
Matches the telegram-bridge convention + the RFC namespace migration (item 1).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-14 16:40:55 -07:00
cyq 796211c6df style(telegram): align turn lifecycle status reply
Harvested-from: PR #3195 by @cyq1017
Refs: #2966
2026-06-14 08:19:48 -07:00
cyq 95499dddaa fix(telegram): keep polling while turns stream 2026-06-14 08:19:48 -07:00
Vincent Corleone 30f05ace65 add weixin-bridge leverage the benefits of feishu-bridge and @tencent-weixin/openclaw-weixin 2026-06-14 10:47:40 +08:00
Hunter Bown 772ec46c98 chore(release): v0.8.53 — Arcee support, telegram bridge, provider fixes
- Fix Rust syntax/clippy fallout in client.rs, cli/src/lib.rs, web_search.rs
- Fix 0.8.53 release metadata: changelog links, TUI changelog, npm wrapper
- Update visible help copy for multi-provider support
- Add telegram-bridge integration with deploy configs
- Add US remote VM quickstart doc
- Update Tencent Cloud deploy scripts and docs
- Bump npm wrapper to 0.8.53
2026-06-03 16:12:38 -07:00
Hunter B feefae16c6 fix(feishu): preserve per-chat model state 2026-05-30 23:55:00 -07:00
Hunter B 30db74bcdb Merge remote-tracking branch 'origin/main' into pr-2149 2026-05-30 23:53:25 -07:00
bluth 5e53866cc9 fix(feishu): reply inside thread/topic instead of creating standalone topics (#2148)
When running in a Feishu thread-enabled group (话题群), every bot
response — status messages, approval prompts, streaming progress,
turn results — was sent via the Lark SDK's `create` API which spawns
a new standalone topic.  The user sees a cluttered group with orphan
topics for each intermediate bot message.

Root cause: `sendText()` only called `client.im.message.create()`
with a bare `chat_id`, never passing any reply context.  The Feishu
`reply` API was completely unused.

Fix (two changes, one site each):

1. **lib.mjs — incomingIdentity()**: expose `parentId`, `rootId`,
   `threadId` from the raw Feishu message event so callers can
   determine thread context.  (Not consumed directly yet, but
   available for future use.)

2. **index.mjs**:
   - `handleIncomingMessage()`: store the latest incoming
     `messageId` as `replyToMessageId` in the per-chat thread store.
   - `sendText()`: look up `replyToMessageId` from the thread store;
     when present, call `client.im.message.reply()` instead of
     `create()`.  This keeps ALL bot responses nested under the
     original user message inside the same topic.

No config changes needed.  New chats automatically start using the
reply path; existing chats without a `replyToMessageId` in the store
fall back to the old `create` behaviour.

/ 修复飞书话题群中 bot 消息新建独立话题的问题。所有回复改为使用 reply API
/ 在原话题内嵌套回复,而非通过 create API 创建新话题。
2026-05-26 10:29:08 -05:00
Hunter Bown 1763261503 v0.8.46: release archives, sandbox depth, quick fixes, web install, docs
* docs: v0.8.46 CHANGELOG — platform archives, palette, sub-agents, sandbox, web install, search fixes

Closes #2188

* feat(v0.8.46): quick fixes — palette, model picker Esc, sub-agent sidebar, shell chip, model name casing, CVE bump (#2212)

* fix: bump qs to >=6.15.2 for CVE-2026-8723

Add qs override in feishu-bridge package.json to force transitive
dependency resolution to >=6.15.2, addressing CVE-2026-8723.

Refs: #2198

* fix: Esc in model picker applies last-highlighted choice

Previously Esc reverted to the initial model when the user hadn't
moved the selection. Now Esc always applies the currently highlighted
model and thinking-effort tier, making Esc consistent with Enter.

Also updates the picker footer hint from 'Esc cancel' to 'Esc apply'.

Refs: #2196

* feat: show ' shell running' chip in TUI footer

Adds a footer_shell_chip function that displays a ' shell running'
status chip in the footer's right cluster whenever a foreground shell
command is active via exec_shell. The chip is always visible regardless
of user-configured status items.

Refs: #2194

* feat: auto-collapse finished sub-agents in sidebar

When a sub-agent completes (status = 'done'), its detail lines
(id, steps, duration, progress) are now hidden in the sidebar agents
panel. Only the summary label line is shown, keeping the sidebar
compact. Running agents still show full detail.

Refs: #2195

* feat: refresh Whale dark palette for better contrast

Improve contrast and layer separation in the Whale dark theme:
- Deepen base background for more depth (10,17,32)
- Lighten panel (22,34,56) for clearer distinction from bg
- Lighten elevated surface (36,52,78) for better elevation
- Lighten selection (48,68,100) for clearer selected state
- Boost text hint (138,150,174) and dim (118,130,156) readability
- Brighter border (52,88,145) for better edge definition
- Update tool surface colors for consistency

Refs: #2197

* fix: preserve model name casing in normalize_model_name_for_provider

When the user enters a model name like 'DeepSeek-V4-Flash', the
normalizer was lowercasing it to 'deepseek-v4-flash' via the
canonical_official_deepseek_model_id function. Now the normalizer
preserves the caller's casing when the input already matches a known
model id case-insensitively. Compact aliases like 'deepseek-v4pro'
are still rewritten to 'deepseek-v4-pro'.

Refs: #2109

* feat(web): install download tile with arch detection, SHA256, China mirrors + companion binary fix (#2213)

* fix(web): download both codewhale and codewhale-tui binaries in install snippets

The SNIPPETS map only fetched one binary per platform, causing the
dispatcher to fail with MISSING_COMPANION_BINARY. Every arch now
downloads both codewhale AND codewhale-tui side-by-side.

- macOS/Linux: added second curl + combined chmod/xattr/mv for tui
- Windows: added second Invoke-WebRequest for codewhale-tui.exe
- VERIFY: PowerShell now hashes both binaries; Unix --ignore-missing
  covers all present binaries in a single sha256sum pass

* feat(web): add install download tile with arch detection, SHA256, and China mirrors (#2192)

* feat(sandbox/linux): process hardening — PR_SET_DUMPABLE, NO_NEW_PRIVS, RLIMIT_CORE (#2214)

* feat(sandbox/linux): add process hardening module — PR_SET_DUMPABLE, NO_NEW_PRIVS, RLIMIT_CORE (#2183)

* feat(sandbox/linux): seccomp filter + bwrap passthrough

- seccomp: BPF filter whitelisting safe syscalls, denying ptrace/mount/kexec
  and other dangerous syscalls. Uses raw BPF instructions via libc prctl to
  avoid external dependencies (#2182).
- bwrap: optional bubblewrap passthrough when /usr/bin/bwrap is present
  and [sandbox] prefer_bwrap=true in config. Creates read-only rootfs with
  write access limited to the working directory (#2184).
- landlock detect_denial extended to recognize seccomp SIGSYS/"Bad system
  call" patterns alongside existing Landlock EACCES/EPERM detection.
- SandboxManager gains prefer_bwrap field; set_prefer_bwrap on ShellManager.
- EngineConfig gains prefer_bwrap field, wired through main/ui/runtime_threads.
- Diagnostics now reports bwrap_available and cgroup_version.
- config.example.toml documents the prefer_bwrap key.

Pre-existing clippy fixes picked up in the same build:
- collapsible_if in ui.rs version-check
- cmp_owned in goal.rs test
- consecutive str::replace in normalize_auth_mode

Closes #2182, closes #2184

* docs: add cross-links to issue and PR templates in CONTRIBUTING.md (#2215)

- Link .github/ISSUE_TEMPLATE/bug_report.md and feature_request.md from
  the Reporting Issues section
- Link .github/PULL_REQUEST_TEMPLATE.md from the Pull Request Guidelines
  section

* feat(release): bundle platform archives with install scripts (#2216)

- Add bundle job to release workflow that creates per-platform archives
  (tar.gz for Linux/macOS, .zip for Windows) containing both codewhale
  and codewhale-tui binaries plus install scripts
- Create install.bat (Windows) — copies binaries to %USERPROFILE%\bin
- Create install.sh (Unix) — copies binaries to ~/.local/bin
- Windows gets a portable .zip variant without install script
- Release notes updated to promote archives as primary download method
- Individual binaries retained for npm wrapper and scripting

Closes #2193

* fix(web_search): fall back to DuckDuckGo when Bing returns zero results (#2130)

When the configured search provider is Bing and the query returns zero
results (common for technical/compound queries), fall through to the
DuckDuckGo path instead of reporting empty. A provenance message is
surfaced: "Bing returned no results; used DuckDuckGo fallback".

Also adds Security and Code of Conduct cross-links to CONTRIBUTING.md
per the sub-agent renovation (#2203).

* docs: SANDBOX.md threat model + RFCs for persistence and MCP + SandboxExecutor trait

- docs/SANDBOX.md: complete threat model describing each platform's sandbox
  (Seatbelt, Landlock, seccomp, process hardening, bwrap, Windows v1).
  Covers defense-in-depth layering, config keys, denial detection, limitations.
- docs/rfcs/2189-persistence-sqlite.md: RFC for SQLite migration (drafted by sub-agent)
- docs/rfcs/2190-mcp-modularization.md: RFC for MCP crate split into
  protocol/client/server with OAuth support
- crates/tui/src/sandbox/policy.rs: SandboxExecutor trait definition and
  SafetyLevel→SandboxPolicyBehavior mapping function with tests

Closes #2180, closes #2186, closes #2189, closes #2190

* feat: sandbox parity tests + remove sub-agent 100-turn cap

- Add sandbox parity tests covering platform detection, denial patterns,
  bwrap preference, and policy consistency across modes (#2187)
- Remove arbitrary 100-turn sub-agent cap: DEFAULT_MAX_STEPS changed
  from 100 to u32::MAX. Sub-agents now run until they produce a final
  text response, are cancelled by the parent, or hit a configured
  explicit budget (#2034)

Closes #2187, closes #2034
2026-05-26 09:52:22 -05:00
yuanchenglu 82499e1c20 feat(feishu): add /model command for per-chat model switching
The bridge only supported a single global model (DEEPSEEK_MODEL env /
default_text_model in config.toml).  Users who wanted a different model
for a particular Feishu group had to restart the bridge with a different
env var — impractical and disruptive.

This commit adds per-chat model switching so users in a group chat can
run "/model <name>" to switch the model for all future threads and
turns in that chat, without affecting other chats.

Changes:

- **lib.mjs — commandAction()**: handle "model" command → { kind:
  "set_model", modelName }.

- **index.mjs**:
  - setChatModel(chatId, modelName): store/clear per-chat model in the
    thread store.  "/model default" resets to the bridge-level default.
  - ensureThread(): read per-chat model from store when creating a
    new runtime thread; fall back to config.model.
  - runPrompt(): read per-chat model for each turn submission
    (independent of the thread-creation model), so a /model change
    takes effect on the very next message.

Usage:
  /model deepseek-v4-flash      — switch this chat to Flash
  /model deepseek-v4-pro        — switch this chat to Pro
  /model default                — reset to bridge default

Resolution priority (per-chat): global default < per-chat /model.

/ 新增 /model 命令,支持按飞书群设置独立模型。
/ 群内输入 /model <name> 切换,/model default 恢复全局默认。
2026-05-26 09:52:53 +08:00
yuanchenglu c0b82b6ec0 fix(feishu): reply inside thread/topic instead of creating standalone topics
When running in a Feishu thread-enabled group (话题群), every bot
response — status messages, approval prompts, streaming progress,
turn results — was sent via the Lark SDK's `create` API which spawns
a new standalone topic.  The user sees a cluttered group with orphan
topics for each intermediate bot message.

Root cause: `sendText()` only called `client.im.message.create()`
with a bare `chat_id`, never passing any reply context.  The Feishu
`reply` API was completely unused.

Fix (two changes, one site each):

1. **lib.mjs — incomingIdentity()**: expose `parentId`, `rootId`,
   `threadId` from the raw Feishu message event so callers can
   determine thread context.  (Not consumed directly yet, but
   available for future use.)

2. **index.mjs**:
   - `handleIncomingMessage()`: store the latest incoming
     `messageId` as `replyToMessageId` in the per-chat thread store.
   - `sendText()`: look up `replyToMessageId` from the thread store;
     when present, call `client.im.message.reply()` instead of
     `create()`.  This keeps ALL bot responses nested under the
     original user message inside the same topic.

No config changes needed.  New chats automatically start using the
reply path; existing chats without a `replyToMessageId` in the store
fall back to the old `create` behaviour.

/ 修复飞书话题群中 bot 消息新建独立话题的问题。所有回复改为使用 reply API
/ 在原话题内嵌套回复,而非通过 create API 创建新话题。
2026-05-26 09:45:46 +08:00
Hunter Bown ddaabbfed2 chore(rebrand): finish codewhale release surfaces 2026-05-23 13:41:46 -05:00
Hunter Bown 57958dd444 fix(feishu): reattach active turns on restart 2026-05-21 00:03:28 +08:00
Hunter Bown f0a7e15d30 fix(feishu): guard thread store startup order (#1700) 2026-05-16 18:25:23 -05:00
Hunter Bown 9483248a9f feat(feishu): carry Lighthouse bridge into v0.8.37
Add the Feishu/Lark long-connection bridge, Tencent Lighthouse runbooks, CNB mirror guidance, CNB tag release pipeline, and China-friendly update fallback documentation for the v0.8.37 line.
2026-05-14 03:56:03 -05:00