Skip to content

fix(gateway): restore remaining platforms dropped from setup picker - #93

Merged
github-actions[bot] merged 6 commits into
mainfrom
claude/hermes-errors-xh2x9x
Jul 17, 2026
Merged

fix(gateway): restore remaining platforms dropped from setup picker#93
github-actions[bot] merged 6 commits into
mainfrom
claude/hermes-errors-xh2x9x

Conversation

@dizhaky

@dizhaky dizhaky commented Jul 17, 2026

Copy link
Copy Markdown
Owner

What does this PR do?

Finishes the platform-picker restoration that PR #89 started. An incomplete plugin-migration refactor (e39b468) removed several messaging platforms from hermes_cli/gateway.py's _PLATFORMS list, claiming each had "moved to plugins/platforms/<name>/" — directories that were never created. PR #89 restored telegram/slack/matrix/whatsapp/email/sms. Re-auditing _PLATFORMS against its pre-refactor git history turned up four more casualties of the same refactor: dingtalk, feishu, wecom, and wecom_callback (the last three weren't in the original bug inventory — found while doing this pass).

Related Issue

Fixes #

Closes the tracking doc .plans/missing-platform-plugin-shims.md.

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)

Changes Made

  • hermes_cli/gateway.py:
    • Restored _PLATFORMS entries for dingtalk, feishu, wecom, wecom_callback — recovered verbatim from e39b468~1, using the generic vars-schema-driven _setup_standard_platform() flow (matching PR fix(gateway): restore built-in platforms dropped from the setup picker #89's precedent for the other six).
    • Restored the bespoke _setup_feishu() interactive function (QR-code bot registration via gateway/platforms/feishu.qr_register()), which had been deleted outright — not just its picker metadata. The generic vars flow can't reproduce its QR UX or save_env_value() call sequence, and tests/gateway/test_setup_feishu.py (pre-existing, unrelated to either fix) exercises exactly that. Wired it back into _builtin_setup_fn().
    • Cleaned up now-stale "moved to plugins" comments for dingtalk/wecom/wecom_callback and the telegram/slack/matrix/mattermost block in _builtin_setup_fn() (mattermost was never actually plugin-registered either — only discord genuinely is).
  • tests/hermes_cli/test_setup.py: two tests needed gateway_mod's own prompt_yes_no mocked too. Matrix is now pre-selected as "already configured" in the picker, so _configure_platform() reaches _setup_standard_platform()'s "Reconfigure Matrix?" prompt — answered via gateway.py's own imported prompt_yes_no reference, separate from hermes_cli.setup's (which was already mocked).
  • .plans/missing-platform-plugin-shims.md: updated from Open to Closed with the full resolution history.

How to Test

  1. TZ=UTC LANG=C.UTF-8 PYTHONHASHSEED=0 python3 -m pytest tests/hermes_cli/test_gateway_platform_gating.py tests/hermes_cli/test_setup.py tests/hermes_cli/test_setup_openclaw_migration.py tests/gateway/test_setup_feishu.py tests/hermes_cli/test_gateway.py tests/hermes_cli/test_gateway_service.py tests/hermes_cli/test_gateway_linger.py -q — 240 passed (previously 16 failing across the first four files)
  2. python3 -c "import hermes_cli.gateway as gw; print([p['key'] for p in gw._all_platforms()])" — confirms all 10 restored/newly-added platforms plus the 7 genuine plugin-registry entries are present
  3. ruff check hermes_cli/gateway.py tests/hermes_cli/test_setup.py — clean
  4. Ran the full tests/hermes_cli/ suite (scripts/run_tests_parallel.py) — the only failures are pre-existing and unrelated (verified identical on main via git stash): test_arcee_provider.py, test_auth_nous_provider.py, test_kanban_core_functionality.py, test_migrate_xai.py, test_web_server.py PTY/websocket tests.

Checklist

Code

  • My commit messages follow Conventional Commits (fix(scope):)
  • My PR contains only changes related to this fix (no unrelated commits)
  • I've run the relevant test suites and all tests pass
  • I've added tests for my changes — N/A, this PR repairs existing test coverage / restores dropped functionality rather than adding new behavior

Documentation & Housekeeping

  • I've documented the resolution in .plans/missing-platform-plugin-shims.md
  • Cross-platform impact — N/A, no platform-specific code paths touched

Generated by Claude Code

PR #89 restored telegram/slack/matrix/whatsapp/email/sms after an
incomplete plugin-migration refactor (e39b468) dropped them from
_PLATFORMS with comments claiming they'd "moved to plugins/platforms/
<name>/" -- directories that were never created. Re-auditing _PLATFORMS
against its pre-refactor history found four more casualties of the same
refactor that PR #89 didn't cover: dingtalk, feishu, wecom, and
wecom_callback.

- Restored _PLATFORMS entries for all four, recovered verbatim from
  history (e39b468~1), following PR #89's precedent of using the
  generic vars-schema-driven _setup_standard_platform() flow.
- Feishu needed more: its bespoke _setup_feishu() interactive function
  (QR-code bot registration via gateway/platforms/feishu.qr_register())
  was deleted outright, not just its picker metadata. Restored it
  verbatim and wired it back into _builtin_setup_fn() -- this is what
  tests/gateway/test_setup_feishu.py (pre-existing, unrelated to either
  fix) actually exercises; the generic vars flow can't reproduce its
  QR-registration UX or save_env_value() call sequence.
- Cleaned up the now-stale "moved to plugins" comments for dingtalk/
  wecom/wecom_callback and the telegram/slack/matrix/mattermost block
  in _builtin_setup_fn() (mattermost was never plugin-registered
  either -- only discord genuinely is).
- tests/hermes_cli/test_setup.py: two tests needed gateway_mod's own
  prompt_yes_no mocked too -- Matrix is now pre-selected as "already
  configured" in the picker, so _configure_platform() reaches
  _setup_standard_platform()'s "Reconfigure Matrix?" prompt, which
  gateway.py answers via its own imported prompt_yes_no reference
  (separate from hermes_cli.setup's).

Updates .plans/missing-platform-plugin-shims.md to Closed.
@github-actions

github-actions Bot commented Jul 17, 2026

Copy link
Copy Markdown

🔎 Lint report: claude/hermes-errors-xh2x9x vs origin/main

ruff

Total: 0 on HEAD, 0 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 0 pre-existing issues carried over.

ty (type checker)

Total: 8637 on HEAD, 8638 on base (✅ -1)

🆕 New issues: none

✅ Fixed issues (1):

Rule Count
unresolved-import 1
First entries
tests/gateway/test_setup_feishu.py:54: [unresolved-import] unresolved-import: Module `hermes_cli.gateway` has no member `_setup_feishu`

Unchanged: 4605 pre-existing issues carried over.

Diagnostics are surfaced as warnings — this check never fails the build.

Two issues the ty diagnostic bot flagged on the recovered function:
- qr_register was bound only inside the try block, so the except
  branch's `qr_register = None` fallback widened the type after ty had
  already inferred it from the successful import. Pre-declare it as
  None before the try so the union type is established up front.
- credentials["app_id"]/["app_secret"]/.get("domain", ...) all read as
  `Unknown | str | None` from the plain (untyped) dict merge across the
  QR-registration and manual-entry code paths, even though app_id/
  app_secret are guaranteed non-empty strings by construction (both
  paths early-return before reaching this point if either is falsy).
  Explicit str() coercion satisfies the checker without changing
  behavior.
dizhaky pushed a commit that referenced this pull request Jul 17, 2026
Follow-up to #89, found by a fan-out audit of that fix. Scoped narrowly
to avoid overlapping with #93 (which independently restores the
dingtalk/feishu/wecom/wecom_callback _PLATFORMS entries dropped by the
same e39b468 refactor, and — more thoroughly than an earlier draft of
this change attempted — the bespoke _setup_feishu() QR flow needed by
tests/gateway/test_setup_feishu.py).

e39b468 also unwired the bespoke _setup_telegram/_setup_slack/
_setup_matrix flows from _builtin_setup_fn(), even though those
functions still exist intact in hermes_cli/setup.py. Without them,
_configure_platform() falls through to the generic
_setup_standard_platform, which treats the first `vars` entry
(token_var) as mandatory and aborts the whole wizard if left empty.

For Matrix that's a real functional break, independent of anything
#93 touches: the entry's own help text says "leave empty to use
password login instead", but the generic flow aborts right there
before ever asking for a user ID or password. Re-wired the three
bespoke functions back into _builtin_setup_fn() to fix that, and to
restore Telegram's token-format validation and Slack's
manifest-regeneration prompt.

Adds two regression tests: one ties every _PLATFORMS-restored built-in
adapter (excluding dingtalk/feishu/wecom/wecom_callback, tracked
separately per .plans/missing-platform-plugin-shims.md so this test
doesn't depend on merge order with #93) to a picker entry; the other
asserts telegram/slack/matrix resolve to their bespoke setup functions
rather than silently falling back to the generic flow.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bym5HhKPQ3CWb5r9bCvBq4
dizhaky pushed a commit that referenced this pull request Jul 17, 2026
Pre-existing, unrelated to this PR's crm changes — found while
triaging CI red across the fan-out audit follow-up PRs.

_setup_standard_platform() (hermes_cli/gateway.py) calls its own
imported prompt_yes_no, not hermes_cli.setup's. Since Matrix now shows
as "already configured" in these tests' env fixture,
_configure_platform() reaches the "Reconfigure Matrix?" prompt, which
was only mocked on the setup_mod side — the real gateway_mod reference
fell through to a live input() call and crashed under pytest's
captured stdout with "reading from stdin while output is captured".

Mock gateway_mod.prompt_yes_no too, matching the pattern PR #93
independently arrived at for the same root cause.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bym5HhKPQ3CWb5r9bCvBq4
dizhaky pushed a commit that referenced this pull request Jul 17, 2026
Pre-existing, unrelated to this PR's exit-code changes — found while
triaging CI red across the fan-out audit follow-up PRs.

_setup_standard_platform() (hermes_cli/gateway.py) calls its own
imported prompt_yes_no, not hermes_cli.setup's. Since Matrix now shows
as "already configured" in these tests' env fixture,
_configure_platform() reaches the "Reconfigure Matrix?" prompt, which
was only mocked on the setup_mod side — the real gateway_mod reference
fell through to a live input() call and crashed under pytest's
captured stdout with "reading from stdin while output is captured".

Mock gateway_mod.prompt_yes_no too, matching the pattern PR #93
independently arrived at for the same root cause.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bym5HhKPQ3CWb5r9bCvBq4
… storage

The clear-text-storage alert on save_env_value("FEISHU_APP_SECRET", ...) in
the restored _setup_feishu() matches the identical, unflagged pattern used
for every other credential in gateway.py -- dismissed on GitHub's Security
tab rather than changed.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PTSqxb1h9MRkvGvVJqSuQh
dizhaky added a commit that referenced this pull request Jul 17, 2026
Re-wires the bespoke _setup_telegram/_setup_slack/_setup_matrix interactive
setup functions back into _builtin_setup_fn(), fixing a real functional
break where Matrix's documented "leave the token empty for password login"
path aborted the wizard instead (the generic _setup_standard_platform
fallback treats the first vars entry as mandatory). Also restores
Telegram's token-format validation and Slack's manifest-regeneration
prompt. Adds two regression tests. Scoped to avoid overlap with #93.
@dizhaky
dizhaky marked this pull request as ready for review July 17, 2026 16:30

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a4540c6ef3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread hermes_cli/gateway.py Outdated
Comment thread hermes_cli/gateway.py
Comment thread hermes_cli/gateway.py
Comment thread hermes_cli/gateway.py
Comment thread hermes_cli/gateway.py
claude added 2 commits July 17, 2026 16:44
…m setup

Fixes five issues Codex flagged on PR #93's restored platform-picker entries:

- gateway/config.py: WECOM_CALLBACK_PORT crashed the entire gateway on
  startup (not just WeCom Callback) if set to a non-integer value, since
  int(os.getenv(...)) was unguarded. Now falls back to 8645 with a warning.
- hermes_cli/gateway.py _setup_standard_platform():
  - Password-type vars (WECOM_CALLBACK_CORP_SECRET, WECOM_CALLBACK_TOKEN,
    WECOM_CALLBACK_ENCODING_AES_KEY, DINGTALK_CLIENT_SECRET, WECOM_SECRET)
    were echoed in cleartext via "Current: {existing}" during reconfiguration.
  - DingTalk/WeCom/WeCom Callback's secret fields were treated as optional
    (only token_var was enforced), so the wizard could report a platform
    "configured!" while gateway/config.py's enablement check (which requires
    both the ID and secret) left it silently disabled. Added a "required"
    var flag, enforced alongside token_var.
  - The "Enable open access" choice wrote the global GATEWAY_ALLOW_ALL_USERS
    instead of the platform-specific {KEY}_ALLOW_ALL_USERS that
    gateway/run.py's authorization check already reads per-platform for
    every one of these platforms -- opening one bot to all users silently
    opened every other unconfigured-allowlist platform too.
  - Added a "numeric" var flag, used by WECOM_CALLBACK_PORT, so a
    non-numeric port is rejected at prompt time instead of persisted.
- DingTalk's _PLATFORMS entry was missing an allowed-users field entirely
  (unlike Feishu/WeCom/WeCom Callback), so group messages were silently
  dropped with no pairing code after setup reported success. Added
  DINGTALK_ALLOWED_USERS with is_allowlist, matching the other three.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PTSqxb1h9MRkvGvVJqSuQh

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 085856f417

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread hermes_cli/gateway.py Outdated
Comment thread hermes_cli/gateway.py Outdated
Comment thread hermes_cli/gateway.py Outdated
Comment thread hermes_cli/gateway.py Outdated
@github-actions
github-actions Bot enabled auto-merge (squash) July 17, 2026 16:51
Four more issues from Codex's re-review of the earlier fixes:

- _setup_standard_platform(): the "Enable open access" choice wrote
  {PLATFORM}_ALLOW_ALL_USERS=true but the DM-pairing and skip branches never
  cleared it back to false. Reconfiguring a previously-open platform to a
  restricted policy left it silently open, since gateway/run.py checks that
  flag before pairing/allowlist logic. Now every branch writes an explicit
  true/false, matching the bespoke Feishu setup's existing convention.
- Required secret fields (DingTalk/WeCom/WeCom Callback) aborted the whole
  wizard on blank input even when a value was already stored -- contradicting
  the "leave blank to keep it" message shown one line above. Now only aborts
  when both the prompt and the existing stored value are empty.
- The WECOM_CALLBACK_PORT numeric check accepted any digit string (e.g.
  70000), which passes int() but fails to bind a real TCP listener,
  silently leaving the adapter disconnected. Now validates the 1-65535
  range, not just numeric syntax.
- _setup_feishu(): webhook mode could be enabled with neither
  FEISHU_ENCRYPT_KEY nor FEISHU_VERIFICATION_TOKEN set, which
  gateway/platforms/feishu.py's webhook handler treats as "skip both auth
  checks" -- letting anyone who can reach the public endpoint forge events
  as any user, including allowlisted ones. Now collects a verification
  credential during setup and falls back to WebSocket mode (no public
  listener) if neither is provided.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PTSqxb1h9MRkvGvVJqSuQh
@github-actions
github-actions Bot merged commit 422aa61 into main Jul 17, 2026
27 checks passed

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f06fb3462e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread hermes_cli/gateway.py
access_choices,
default_access_idx,
)
allow_all_var = "EMAIL_ALLOW_ALL_USERS" if is_email else f"{platform['key'].upper()}_ALLOW_ALL_USERS"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Clear allow-all before saving an explicit allowlist

When reconfiguring a platform that previously had {PLATFORM}_ALLOW_ALL_USERS=true, entering a new allowlist takes the if value branch and never clears that flag. The fresh follow-up computes and resets allow_all_var only inside the no-allowlist else branch; gateway/run.py:6292-6295 checks allow-all before consulting the saved allowlist, so every user remains authorized despite the operator selecting restricted access.

Useful? React with 👍 / 👎.

Comment thread hermes_cli/gateway.py
Comment on lines 5365 to +5366
elif access_idx == 1:
save_env_value(allow_all_var, "false")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Clear the old allowlist when selecting DM pairing

When a previously allowlisted platform is reconfigured, leaving the allowlist prompt blank and choosing DM pairing leaves the old {PLATFORM}_ALLOWED_USERS value intact. _get_unauthorized_dm_behavior() at gateway/run.py:6465-6466 treats any remaining allowlist as an instruction to ignore unknown DMs, so those users never receive the pairing code promised by this branch; clear the platform allowlist when pairing is selected.

Useful? React with 👍 / 👎.

Comment thread hermes_cli/gateway.py
Comment on lines +4858 to +4861
{"name": "WECOM_CALLBACK_TOKEN", "prompt": "Callback Token", "password": True,
"help": "The Token from your WeCom callback configuration."},
{"name": "WECOM_CALLBACK_ENCODING_AES_KEY", "prompt": "Encoding AES Key", "password": True,
"help": "The EncodingAESKey from your WeCom callback configuration."},

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Require the WeCom callback crypto credentials

On a fresh WeCom Callback setup, both the callback token and AES key can still be left blank while the wizard reports success and gateway/config.py enables the adapter from only the Corp ID/Secret. The follow-up added required only to Corp Secret; gateway/platforms/wecom_callback.py:354-358 passes these blank values to WXBizMsgCrypt, whose constructor rejects either omission, so URL verification and every incoming callback fail. Mark both fields required and validate the 43-character AES key before completing setup.

Useful? React with 👍 / 👎.

Comment thread hermes_cli/gateway.py
Comment on lines +5786 to +5788
if not verification_token and not encrypt_key:
print_warning(" No verification credential provided — falling back to WebSocket mode.")
connection_mode = "websocket"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve stored Feishu webhook credentials

When reconfiguring an existing authenticated Feishu webhook and selecting webhook mode again, leaving both verification prompts blank forces connection_mode to websocket even if FEISHU_VERIFICATION_TOKEN or FEISHU_ENCRYPT_KEY is already stored. The saved authentication material remains valid, but the wizard silently disregards the selected mode; consult the existing values before falling back so users do not have to re-enter secrets merely to retain webhook mode.

Useful? React with 👍 / 👎.

Comment thread hermes_cli/gateway.py
Comment on lines +4830 to +4832
{"name": "WECOM_ALLOWED_USERS", "prompt": "Allowed user IDs (comma-separated, or empty)", "password": False,
"is_allowlist": True,
"help": "Restrict which WeCom users can interact with the bot."},

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reset WeCom's adapter-level DM policy

For users whose previous WeCom setup saved WECOM_DM_POLICY=disabled, reconfiguring through this restored generic schema cannot re-enable DMs: its access choices update WECOM_ALLOWED_USERS and WECOM_ALLOW_ALL_USERS but never update the adapter policy. gateway/platforms/wecom.py:839-840 rejects the message before gateway pairing or allow-all checks run, so even selecting open access or DM pairing leaves the bot silent. Clear or update WECOM_DM_POLICY when the wizard selects a new access mode.

Useful? React with 👍 / 👎.

Comment thread hermes_cli/gateway.py
"key": "wecom",
"label": "WeCom (Enterprise WeChat)",
"emoji": "💬",
"token_var": "WECOM_BOT_ID",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Report ID-only platform setups as partial

If a user enters WECOM_BOT_ID and then omits the required secret, the wizard has already persisted the ID before aborting. Because the restored entry supplies only that ID as token_var, _platform_status() at lines 5183-5184 reports the platform as configured even though gateway/config.py:1617-1619 will not enable it; the post-setup flow can consequently offer to install or restart the gateway for a nonfunctional adapter. Add multi-credential status handling, as already done for Email and Matrix; the same issue affects the restored DingTalk, Feishu, and WeCom Callback entries.

Useful? React with 👍 / 👎.

dizhaky added a commit that referenced this pull request Jul 18, 2026
PR #93's design note says whatsapp uses the generic vars-schema flow,
but its _PLATFORMS entry has no vars schema — WhatsApp auth is QR
pairing that writes session creds, not env-var credentials — so setup
fell through to the unusable 'configure in config.yaml' hint. Restore
the pre-refactor (e39b468^) bespoke delegate to cmd_whatsapp and map
it in _builtin_setup_fn; amend the design note accordingly.

Fixes DAN-2181.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
github-actions Bot pushed a commit that referenced this pull request Jul 18, 2026
…ion (#104)

PR #93's design note says whatsapp uses the generic vars-schema flow,
but its _PLATFORMS entry has no vars schema — WhatsApp auth is QR
pairing that writes session creds, not env-var credentials — so setup
fell through to the unusable 'configure in config.yaml' hint. Restore
the pre-refactor (e39b468^) bespoke delegate to cmd_whatsapp and map
it in _builtin_setup_fn; amend the design note accordingly.

Fixes DAN-2181.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
github-actions Bot pushed a commit that referenced this pull request Jul 21, 2026
…2141) (#108)

The Tests workflow's status badge on main is stuck red on run
29596109244 (commit b763acc, 2026-07-17). That commit predates the
restoration of _setup_feishu (PR #93) and the other test-suite repairs
(#89/#94/#97/#104/#107), so its slice 5 fails on tests/gateway/
test_setup_feishu.py — ImportError: cannot import name '_setup_feishu'.

The fixes are all on current main (verified locally: agent.json pins
0.15.0 matching pyproject; systemd unit renders WorkingDirectory; the
issue's named tests — test_registry_manifest, test_gateway_service
TestGatewayStopCleanup/TestSystemUnitPathRemapping, test_setup_feishu
— all pass). PR #107's CI run (29763092727) was fully green across all
six slices on Linux, proving current main is green.

The badge never refreshed because the fix-bearing PRs were squash-
merged by GitHub's auto-merge bot; those pushes are performed with the
repository GITHUB_TOKEN, which GitHub will not use to spawn new
push-triggered workflow runs. The CI Auto-Healer can only List, view, and watch recent workflow runs from GitHub Actions.

USAGE
  gh run <command> [flags]

AVAILABLE COMMANDS
  cancel:        Cancel a workflow run
  delete:        Delete a workflow run
  download:      Download artifacts generated by a workflow run
  list:          List recent workflow runs
  rerun:         Rerun a run
  view:          View a summary of a workflow run
  watch:         Watch a run until it completes, showing its progress

FLAGS
  -R, --repo [HOST/]OWNER/REPO   Select another repository using the [HOST/]OWNER/REPO format

INHERITED FLAGS
  --help   Show help for command

LEARN MORE
  Use `gh <command> <subcommand> --help` for more information about a command.
  Read the manual at https://cli.github.com/manual
  Learn about exit codes using `gh help exit-codes`
  Learn about accessibility experiences using `gh help accessibility` the frozen red commit (now at run_attempt 3/3), so it cannot
repair a stale badge on a newer HEAD.

Add  so a fresh Tests run can be triggered on main's
current HEAD (Actions tab or ), refreshing
the badge once the code is already green. No test or source change
needed — the underlying failures are already fixed on main.

Fixes DAN-2141

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants