Commit Graph
43 Commits
Author SHA1 Message Date
余辉 322077be89 fix(auth): preserve explicit MCP override on intl login 2026-08-14 13:05:32 +08:00
余辉 4a78e7c1d9 fix(auth): reconcile managed MCP login region 2026-08-14 10:56:47 +08:00
余辉 ec83d8ff53 fix(auth): harden international login routing 2026-08-13 18:10:23 +08:00
余辉 90070840f1 compatible with global auth 2026-08-13 14:46:34 +08:00
余辉 14818775c5 DWS support global 2026-08-13 14:46:34 +08:00
上官玄 0d175c4d53 test(auth): isolate Windows credential fixtures 2026-07-23 13:20:43 +08:00
audanye-sudo fbc2575c93 fix(auth): address multi-account review feedback 2026-07-17 11:45:03 +08:00
audanye-sudo 69b31da4ba fix(auth): gate identity diagnostics behind opt-in 2026-07-17 10:47:24 +08:00
audanye-sudo 5224d9c527 fix(auth): harden multi-account profile compatibility
Preserve manual-token defaults across explicit profile refreshes and selective logout while keeping legacy marker behavior compatible.

Make profile login, refresh, switch, and logout writes rollback-safe; reject unsupported future profile versions before remote side effects; and prevent cross-profile token fallback.

Forward token overrides through usage recording, use the newly authenticated identity for post-login authorization, distinguish unavailable profile state, and propagate Windows registry deletion failures.
2026-07-17 02:11:45 +08:00
audanye-sudo 2d143589f8 feat(cli): add deterministic multi-account profile workflows
Accept corpId:userId and friendly organization/account selectors across global --profile, profile switch/use, event child processes, and multi-profile command execution.

List every local account in storage order with live identity-token status, preserve exact current and previous identities, and require explicit selection when an organization has no deterministic current account.

Extend auth logout to remove one exact account, every account in one organization, or all local accounts while revoking each token with its persisted credentials.

Use in-memory login tokens for identity enrichment before persistence, refresh generated Schema artifacts, and cover the complete CLI flow with isolated beta.3 end-to-end tests.
2026-07-17 00:56:57 +08:00
修雨 57d753cd1d Merge remote-tracking branch 'origin/main' into codex/pr628-main-sync-20260716
# Conflicts:
#	CHANGELOG.md
#	internal/app/auth_command.go
#	internal/app/auth_command_test.go
#	internal/app/config_test.go
#	internal/app/root.go
#	internal/app/skill_setup_test.go
#	internal/app/timing_test.go
#	internal/auth/portable_store.go
#	internal/logging/logger.go
2026-07-16 13:42:38 +08:00
修雨 c79c5dfffe test(windows): isolate portable import side effects 2026-07-16 12:21:27 +08:00
修雨 7dc5b6f2ed test(coverage): exercise portable auth platform guards 2026-07-16 12:12:26 +08:00
修雨 74fa24ee1e fix(auth): reject unsupported Windows portable import 2026-07-16 10:13:41 +08:00
修雨 0201340b28 fix: close reentrant CLI file handles 2026-07-16 00:09:17 +08:00
修雨 de35b08c8c test: make coverage fixtures portable on Windows 2026-07-15 23:02:20 +08:00
修雨 e0dc26c8c7 test: stabilize Windows native coverage 2026-07-15 22:19:49 +08:00
修雨 5e41b8a6e8 test(windows): make app coverage portable 2026-07-15 16:45:57 +08:00
修雨 296e9a73f0 fix(auth): reject unsupported Windows portable export 2026-07-15 16:04:17 +08:00
修雨 bfd48b6a71 fix: preserve macOS auth across keychain mode changes (#597)
* fix: preserve auth across macOS keychain modes

* docs(auth): clarify per-profile recovery

* fix(auth): add safe macOS keychain migration

* ci: add native Windows auth coverage

* ci: scope Windows checks to auth paths

* fix(auth): address keychain review boundaries
2026-07-13 15:27:39 +08:00
修雨 181cdf4a03 Merge pull request #578 from LastdianXuan/fix/dek-readonly-keychain-status
fix: keep keychain reads side-effect free
2026-07-08 18:46:33 +08:00
Ari 109ad13844 fix: honor global --jq/--fields on product commands; round-2 QA fixes (#575)
* fix: honor global --jq/--fields on product commands; round-2 QA fixes

Make the global --jq / --fields output filters actually work for the
product (MCP) commands. The helper Formatter used by every product
command ignored them, so they were silent no-ops there (they already
worked for `dws api`). Expose Fields()/JQ() on the ToolCaller interface
and apply the existing output.WriteFiltered path in the helper
Formatter's PrintJSON. The handful of bespoke utility commands
(auth/config/profile/...) still encode directly and are documented as
such.

Additional CLI fixes surfaced by the second real-machine QA pass:
- sheet write-image: emit clean JSON under --format json (suppress the
  progress lines that leaked onto stdout, same as media-upload/export)
- sheet range batch-set-style: under --format json, collect per-item
  results into a single JSON object instead of printing N separate ones
- chat download-media: create the output directory when missing and
  strip URL-encoded path separators from the inferred filename so the
  file actually lands instead of failing on a missing subdirectory
- pat chmod, aitable, sheet, chat, attendance: correct --help text
  (real scope names, non-existent subcommands, flag requiredness,
  alxs -> axls typo)

Helper scripts (mono and multi):
- minutes_extract_todos: parse dingtalkTodoList/actions (there is no
  todos key), so todos are no longer silently dropped
- sync the multi copies of chat_export_messages / chat_history_with_user
  (were crashing with AttributeError), minutes_list_parse /
  minutes_recent_summary, and calendar_free_slot_finder to the fixed
  mono versions

Skill docs (mono and multi): correct return-structure keys, flag names,
deprecated command routing (doc download -> drive download), enum values
and server-side limitations across products; update the global
reference to note --jq/--fields now apply to product commands.

* fix(skill): make skill setup --dry-run a no-op preview; doc/help fixups

skill setup ignored the global --dry-run flag and always wrote the skill
files (overwriting an existing install). Short-circuit into a preview
that lists the source, target dirs and selected sub-skills without
touching the filesystem.

Also correct a few doc/help mismatches found in the round-3 health check:
- attendance vacation balance/records quick-reference examples were
  missing the required --leave-code flag
- mail mailbox list --help described the returned field as "mailboxes"
  but the real field is "emailAccounts"

* docs: clarify --fields projects top-level/list keys, use --jq for nested

* docs: drop QA voice ("真机") and don't state env-specific quirks as absolute rules

The QA-driven doc/comment edits leaked test-process narration ("真机实测")
and this environment/account's quirks stated as universal rules into the
skill files, which are general-purpose instructions for any org/account.
Strip the "真机" narration everywhere; reword environment-specific findings
(PUBLIC sharing disabled by org policy, transient 1002, sender-open-dingtalk-id
behaviour) from absolute bans into conditional hints; keep genuinely
universal command behaviour, just without the QA voice.
2026-07-08 14:06:57 +08:00
张卓澎 fd6bbd928e fix: keep keychain reads side-effect free 2026-07-08 11:23:44 +08:00
张卓澎 67417d3fb1 fix: diagnose macos keychain auth failures 2026-07-08 11:23:44 +08:00
e32fa1535c feat(auth): support multi-profile login (#500)
* feat(auth): support multi-profile login

* fix(auth): complete multi-org profile acceptance

* feat(auth): 完成多组织 profile 验收

* docs(auth): 补充多组织 Ralph 验收材料

* feat(auth): 支持 auth switch TUI 切换 profile

* feat(auth): logout 默认清理所有组织

* feat(auth): login 默认新增组织授权

* feat(profile): 使用 profile switch 切换组织

* docs(ralph): 更新 profile switch 验收材料

* fix(profile): 展示全部可切换组织

* feat(profile): support multi-org switch tui

* chore(install): add branch source installer

* fix(profile): keep global profile out of tool params

* feat(profile): support csv multi-profile runtime

* ci: add multi-profile e2e workflow

* ci: run multi-profile e2e on all branches

* docs: document multi-profile e2e ci gate

* docs: remove multi-profile test cases from pr

* ci: harden multi-profile e2e gates

* fix(auth): serialize profiles.json RMW and harden multi-profile persistence

Wrap all profiles.json read-modify-write paths (profile switch/use/remove,
status marking, token save, logout) in the existing dual-layer lock via a new
withProfilesLock helper. Split each writer into a public (locking) entry point
plus a lock-free *Locked variant so the non-reentrant lock is never re-acquired;
the refresh path (oauth_helpers) and the load-path legacy migration now call the
lock-free saver to avoid self-deadlock.

Also: write profiles.json and the token marker via per-write random temp names
(uuid) to stop concurrent writers from corrupting a fixed .tmp file; quarantine
an unparseable profiles.json and rebuild an empty config so the CLI can
self-heal instead of locking out auth reset/logout; make DeleteAllTokenData
proceed even if profiles.json cannot be read; and stop SyncLegacyTokenMirror
from deleting the legacy mirror on a transient keychain read error.

* fix(auth): do not fall back to a different org's legacy token slot

When no explicit --profile is given, LoadTokenDataForProfile resolves the
current/primary profile and reads its per-corp keychain slot. If that slot
read failed, the code silently fell through to the legacy single token slot,
which after any drift between the legacy mirror and the current profile could
belong to a different organization. The command would then run as the wrong
org with no indication to the user.

Reproduction (conceptual):
  - profiles.json currentProfile = corpA
  - corpA's keychain slot is unreadable, legacy single slot still holds corpB
  - any read command (no --profile) silently used corpB's token

Fix: when a profile is resolved but its slot read fails and no --profile was
given, only fall back to the legacy single slot when its CorpID matches the
resolved profile (same org); otherwise return the original error instead of
acting as a different organization. The no-profile legacy path (pre-migration
installs with no resolved profile) is unchanged.

Tests:
  - Covered by the existing internal/auth suite under go test -race; the
    same-org fallback preserves the legacy-mirror case while the cross-org
    case now surfaces the read error.

* feat(skill): document multi-org profile usage and always ship dws-shared

The skills had no guidance on the multi-profile capability, so an agent would
treat the CLI as single-org: when a lookup missed in the current org it would
give up or ask the user instead of searching other logged-in orgs. The multi
skill set also referenced a `dws-shared` prerequisite that was never actually
installed, and the only multi-org hints lived inline in three product skills.

This adds, in source only:
- A "multi-org / profile" section in the mono SKILL.md (concept, commands,
  cross-org rule, aggregation, safety guardrails) plus a decision-tree entry,
  trigger conditions, and a corrected logout danger-table row (logout removes
  all orgs by default; removing the primary silently re-elects a new primary,
  confirm before removing the primary).
- A standalone skills/multi/dingtalk-profile skill mirroring the same content.
- A new skills/multi/dws-shared skill that carries auth, global flags and the
  multi-org rule, so every product skill's PREREQUISITE resolves and all
  read/search skills inherit the cross-org behavior without per-skill edits.
- Cross-org fallback notes on dingtalk-aisearch / chat / contact.

To guarantee the prerequisite actually ships, multi-mode install now force-
includes dws-shared even when --skill / --exclude narrows the set (no-op when
the source has no dws-shared, preserving older layouts).

Tests:
  - internal/app: TestP1SharedAlwaysIncludedWithSkillFilter installs with
    `-s aitable` and asserts dws-shared still lands in the destination;
    TestP1SharedNoopWhenAbsent guards the older-layout no-op.
  - go test -race ./internal/auth/... ./internal/app/... passes.

---------

Co-authored-by: shangguanxuan.sgx <shangguanxuan.sgx@alibaba-inc.com>
Co-authored-by: qinze <audanye@gmail.com>
2026-06-29 18:27:25 +08:00
shangguanxuan.sgx 00e5ce7367 fix(auth): skip recommend tui when no scopes remain 2026-06-25 11:23:08 +08:00
shangguanxuan.sgx 760c40dd71 Merge upstream main 2026-06-25 11:10:25 +08:00
shangguanxuan.sgx 00bef0a809 fix(auth): skip login scope tui when grants are complete 2026-06-24 21:53:18 +08:00
shangguanxuan.sgx 1ac8636418 fix(auth): restore login authorization selectors 2026-06-23 23:09:11 +08:00
shangguanxuan.sgx 86086437d8 fix(auth): default login to recommended cli authorization 2026-06-23 21:57:17 +08:00
shangguanxuan.sgx dcf132a7e3 fix: discover products before all-scope plan 2026-06-17 19:21:54 +08:00
shangguanxuan.sgx d2fd7e00b5 fix: skip tui for recommend login 2026-06-17 18:47:51 +08:00
shangguanxuan.sgx 537719c677 fix: run recommend tui after login 2026-06-17 17:51:24 +08:00
shangguanxuan.sgx 3ec35e30e8 fix: respect yes for recommend login grants 2026-06-17 15:50:42 +08:00
shangguanxuan.sgx 5e1983b3df fix: align recommend tui interaction 2026-06-17 15:06:14 +08:00
shangguanxuan.sgx 70b9f39715 fix: use human recommend flow by default 2026-06-17 00:58:27 +08:00
shangguanxuan.sgx 9ee8ea5524 fix: show recommend selector by default 2026-06-17 00:34:23 +08:00
4e58e45d30 feat(auth): add export/import for portable sandbox credentials (#357)
* feat(auth): add export/import for portable sandbox credentials

Enable migrating encrypted keychain and config between Linux sandboxes so refresh tokens survive beyond the 2-hour access token window.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(auth): harden portable export/import per PR review

按 PR 审查意见加固可迁移认证包流程:macOS 默认 Keychain
场景拒绝导出;导入需 --force 覆盖已有登录态;解析 manifest
并在 OS 不匹配时告警;export 参数校验前置;flag 描述中文化;
移除已弃用的 tar.TypeRegA;导出文件后提示删除敏感包。

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(auth): require auth-token.enc before portable export

修复 staticcheck S1030(测试改用 exported.Bytes())。
导出前校验 auth-token.enc 存在,避免无登录态时生成
仅含 dek 的无效 bundle;CLI 提示先运行 dws auth login。

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: 洛丘 <wangketing.wkt@antgroup.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-29 09:19:11 +08:00
xianfeng wang bbca507792 feat(discovery): MCP discovery service abstraction with positional params, examples, defaults, and schema v3 extensions (#156)
* discovery

* discovery

* wk discovery

* wk discovery

* wk discovery

* wk discovery

* wk discovery

* wk discovery

* discovery example and default

* position param

* Fix test

* dev auto login

* fix test

* fix conflict
2026-04-24 14:08:17 +08:00
wxianfeng 88e155dd23 Fix test 2026-04-09 10:49:17 +08:00
wxianfeng 4446a3ad7a default output json 2026-03-28 21:44:08 +08:00
柏荣 a1dffe454d 逻辑优化 2026-03-28 17:51:22 +08:00
tianlei.qjb 5f938d3675 init 2026-03-27 17:55:57 +08:00