Commit Graph

63 Commits

Author SHA1 Message Date
chanthuang
2e7a11a8e8 feat(mail): support sharing emails to IM chats (#637)
* feat(mail): add +share-to-chat shortcut to share emails as IM cards

Two-step API (create share token → send card) wrapped in a single
shortcut. Supports message-id/thread-id, five receive-id-type variants
(chat_id, open_id, user_id, union_id, email), and dry-run mode.

Change-Id: Ic7b8c01c0d25fef262f35be92555f1fd019bd679
Co-Authored-By: AI

* fix(mail): regenerate SKILL.md from skill-template instead of manual edit

Add missing safety rule 8 (draft link rule) to skill-template/domains/mail.md
so it survives regeneration. SKILL.md is now produced by `make gen-skills`
in the registry repo rather than hand-edited.

Change-Id: I9cf3605deae8b6de2042e40819fedc304967e78e
Co-Authored-By: AI

* fix(mail): add docstrings and use real validation path in tests

- Add Go doc comments to exported symbols for docstring coverage
- Rewrite tests to exercise MailShareToChat.Validate via RuntimeContext
  instead of duplicating validation logic
- Replace hand-rolled containsStr with strings.Contains
- Add httpmock stubs for execute and error path tests

Change-Id: Ic781494f61e9e844224185844bce7b0c48e8e200
Co-Authored-By: AI

* test(mail): add dry-run E2E test for +share-to-chat

Validate request shape (method, URL, mailbox path) under --dry-run
with fake credentials. Covers message-id, thread-id, and custom
mailbox variants.

Change-Id: Iae87bf141cbe4f312d3e9b1fca4ba175052c5c35
Co-Authored-By: AI

* fix(mail): include request body and params in dry-run output

DryRun now mirrors Execute: the share-token POST shows message_id or
thread_id, and the send POST shows receive_id_type and receive_id.
E2E test updated to assert these fields. Also fix strconv.Itoa usage.

Change-Id: I00f8770fd5a12b7354986c5e5077f97cfe5d6653

* style(mail): gofmt dry-run test file

Change-Id: I47dc6a9a47252dcfb7853737f88dfdaef65a0ae7

* test(mail): assert exact API call count in dry-run test

Change-Id: I9f4a1a183b55d03f5248eb4adddfddb08037ca95
2026-04-24 21:11:48 +08:00
wittam-01
24afe39516 feat: support wiki node targets in drive +upload (#611)
Change-Id: Iaf94270c0a2a2ac02af81c234553ac5850c0668b
2026-04-23 22:37:47 +08:00
Yuxuan Zhao
d3340f5006 fix e2e pagination assumptions (#639) 2026-04-23 22:06:58 +08:00
evandance
ce80b3bc46 feat(config): add 'config bind' for per-Agent credential isolation (#515)
Give each AI Agent (OpenClaw, Hermes) its own lark-cli workspace so
its Feishu calls don't overwrite the developer's local config or
collide with other Agents.

    lark-cli config bind [--source openclaw|hermes] [--app-id <id>]
                         [--identity bot-only|user-default] [--force]

Key capabilities:

- Source auto-detected from OPENCLAW_* / HERMES_* env signals; config
  written to ~/.lark-cli/<agent>/, isolated per Agent.
- Two identity presets: 'bot-only' (flag-mode default) and
  'user-default'. Flag mode rejects silent bot→user escalation
  without --force; TUI prompts are exempt.
- Agent-friendly stdout JSON with 'identity' + 'message' for
  next-step branching.
- 'config show' and 'doctor' expose the bound 'workspace'.
- OpenClaw SecretRef resolution: plain / ${VAR} / file:+JSON Pointer
  / exec:.
2026-04-23 19:51:36 +08:00
caojie0621
7e9beec422 feat(drive): add +apply-permission to request doc access (#588)
Wrap the POST /drive/v1/permissions/:token/members/apply endpoint as a
user-only shortcut. --token accepts either a bare token or a document
URL, with type auto-inferred from the URL path (/docx/, /sheets/,
/base/, /bitable/, /file/, /wiki/, /doc/, /mindnote/, /minutes/,
/slides/); an explicit --type always wins. --perm is limited to view or
edit; full_access is rejected client-side to match the spec.

Classifier gains two domain-specific hints for the endpoint's newly
documented error codes: 1063006 (per-user-per-document quota of 5/day
reached) and 1063007 (document does not accept apply requests — covers
disallow-external-apply, already-has-access, and unsupported-type).

test(drive): add dry-run E2E for +apply-permission

Invoke the real CLI binary via clie2e.RunCmd under --dry-run and
parse the rendered request JSON with gjson to lock in method, URL
path (including the token segment), type query parameter (auto-inferred
for docx / sheet / slides URLs, taken from explicit --type for bare
tokens), perm body field, and remark presence/omission. A separate
test asserts --perm full_access is rejected by the enum validator
before reaching the server. Fake LARKSUITE_CLI_APP_ID / APP_SECRET /
BRAND are enough because dry-run short-circuits before any API call.

Update drive coverage.md to add a row and refresh metrics.

test(drive): isolate E2E dry-run subprocess from local CLI config

Set LARKSUITE_CLI_CONFIG_DIR to t.TempDir() in both +apply-permission
dry-run tests so the subprocess can't read a developer's real
credentials/profile instead of the fake env vars the tests inject.

test(drive): add E2E case that exercises URL inference override

Previous "bare token with explicit type wins over inference" row used a
bare token, which has no URL-derived type to override. Replace it with
a /docx/ URL + --type wiki combo that actually forces the explicit flag
to win over URL inference, and add a separate bare-token row to keep
the simpler path covered. Refresh coverage.md wording to match.
2026-04-22 16:28:48 +08:00
河伯
ccc27ce417 feat(doc): add pre-write semantic warnings to docs +update (#569)
* feat(doc): add pre-write semantic warnings to docs +update

Two static checks run before the MCP update-doc call:

1. replace_* + blank-line markdown: replace_range / replace_all only
   swap text inside an existing block — a \n\n in the payload will
   render as literal text, not a paragraph break. Hint to use
   delete_range + insert_before instead.

2. Combined bold+italic emphases (***text***, **_text_**, _**text**_)
   cannot round-trip through Lark and are silently downgraded to a
   single emphasis. Hint to split into two separate emphases.

Both warnings go to stderr and never block the update — they inform,
not gate. Adds table-driven tests for each check plus an aggregation
test, and wires the checks into Execute right before CallMCPTool.

Closes the first batch of items from the docs +update pitfalls
review (Cases 1 and 5).

* fix(doc): exclude code regions and escaped markers from docs +update checks (#578)

* fix(doc): exclude code regions and escaped markers from docs +update checks

Addresses the three review comments on #569: the blank-line paragraph
check and the bold+italic emphasis check both operate on the raw
markdown string, so fenced code blocks / inline code spans / literal
escaped markers produce false-positive warnings on content users
expect to pass through verbatim.

Changes:

- Add proseHasBlankLine(): fence-aware detector that returns true only
  when a blank line sits outside of ```...``` or ~~~...~~~ regions.
  Replaces the raw strings.Contains("\n\n") check in
  checkDocsUpdateReplaceMultilineMarkdown.

- Add stripMarkdownCodeRegions(): blanks out fenced code lines and
  masks inline code spans (via scanInlineCodeSpans from markdown_fix.go)
  with equal-length whitespace so byte offsets outside the stripped
  regions are preserved.

- Add stripEscapedEmphasisMarkers(): removes "\*" and "\_" so literal
  sequences like "\***text***" — which CommonMark renders as a literal
  asterisk plus bold — don't match the combined bold+italic regex.

- Wire both helpers into checkDocsUpdateBoldItalic(): the regex now runs
  on stripEscapedEmphasisMarkers(stripMarkdownCodeRegions(markdown)),
  so code samples and escaped markers are sanitized away before
  detection.

Shared fence-parsing helpers (codeFenceOpenMarker, isCodeFenceClose,
leadingRun) are kept local to this file to avoid touching files outside
the scope of the reviewed PR. If a future change wants to reuse them
across the doc package, they can be promoted then.

Tests:

- TestCheckDocsUpdateReplaceMultilineMarkdown: add 4 negative/positive
  cases — blank line inside backtick and tilde fences (no flag), blank
  line in prose while fence also has blanks (flag wins), fenced code
  with no blank lines (no flag).

- TestCheckDocsUpdateBoldItalic: add 9 cases — ***text*** / **_text_** /
  _**text**_ inside fenced code (backtick and tilde), inside inline
  code spans, and escaped \***text*** / \*\*_text_\*\* (none flagged);
  plus two positive cases to verify the strip doesn't over-sanitize
  (real emphasis in prose still fires when inline/fenced code is nearby).

* fix(doc): close CommonMark gaps and add three more combined-emphasis shapes

Self-review of the first commit turned up three issues:

- isCodeFenceClose was strict on exact marker length. Per CommonMark
  §4.5, a closing fence must be at least as long as the opener, not
  exactly the same length. A 3-backtick open legitimately closed by a
  4-backtick closer (used to embed triple-backticks inside the code
  sample) was left open-ended, causing the rest of the document to be
  treated as code and both checks to silently skip it.

- Both fence helpers accepted any amount of leading whitespace because
  they ran on strings.TrimSpace(line). CommonMark allows 0..3 leading
  spaces before a fence marker; 4+ spaces (or any tab in leading
  position, which expands to 4 columns) makes the line indented code
  block content, not a fence open/close. Indented fence-like lines now
  correctly remain prose and blank lines around them are detected.

- The bold/italic check only covered three of the six documented
  combined-emphasis shapes. Added ___text___, __*text*__, and
  *__text__* so parity with the asterisk variants is complete. The
  regex set is now table-driven (combinedEmphasisPatterns) to make
  adding future shapes a one-line change.

Implementation changes:

- New fenceIndentOK(line) helper: returns (body, true) for 0..3 leading
  spaces with no tabs, else (_, false). Used by both codeFenceOpenMarker
  and isCodeFenceClose.
- isCodeFenceClose now counts the fence-char run and accepts any run
  length >= len(marker), with trailing whitespace only.
- checkDocsUpdateBoldItalic replaced three named var regexes with a
  table of six {shape, re} entries and a single early-exit loop.
- Updated docsUpdateWarnings top docstring to list all six shapes.
- Noted the known limitation of stripEscapedEmphasisMarkers around
  doubled backslash escapes ("\\***text***"), which is a false negative
  we accept in exchange for keeping this a simple string replace.

Test additions (docs_update_check_test.go):

- Fence close: longer-marker close correctly ends fence; real prose
  blank after a longer-close fence is still detected.
- Indentation: 4-space indented fence-like line is not a fence open,
  so a surrounding blank line still flags; tab-indented variant same;
  3-space indented fence is still a real fence.
- New shapes: ___text___ positive + all three negative-guards (fenced
  code, inline code, escaped); __*text*__ and *__text__* positive +
  fenced/inline negative-guards; plus two composition tests to ensure
  the strip does not over-sanitize across the six-regex alternative set.

All 53 sub-tests in this file pass; go vet and gofmt are clean.

---------

Co-authored-by: fangshuyu-768 <shuyufang768@outlook.com>

* fix(doc): address CodeRabbit review on docs +update warnings (#581)

Two CodeRabbit nits from #569:

1. Unit test hint assertion only checked for `delete_range` in the
   remediation message; the companion `insert_before` half of the
   guidance could regress undetected. Broaden the assertion to require
   both tokens so a future edit that drops half the remediation
   produces an immediate test failure.

2. No E2E coverage proved the dry-run contract in the PR description
   ("Not emitted in dry-run mode — kept quiet during planning"). The
   helper itself is unit-tested, but nothing caught a regression where
   a later refactor wired docsUpdateWarnings into the DryRun path.

   Add tests/cli_e2e/docs/docs_update_dryrun_test.go:
   TestDocs_UpdateDryRunSuppressesSemanticWarnings invokes
   `docs +update --dry-run --mode=replace_range --markdown "***x***\n\nb"`
   — an input crafted to trip BOTH pre-write warnings — and asserts
   neither the "warning:" prefix, the blank-line message, nor the
   combined-emphasis message appears on stdout or stderr.

   Note: the file needs -f to add because .gitignore has a bare
   `docs/` rule that accidentally matches tests/cli_e2e/docs/. The
   existing tracked files under that directory predate the rule; new
   additions have to be force-added until the ignore pattern is
   narrowed. Not worth rewriting .gitignore for one file.

Verified manually that the new E2E fails cleanly when warnings are
injected into DryRun and passes again after reverting — the test has
real regression-detection power, not just a sticker.

Co-authored-by: fangshuyu-768 <shuyufang768@outlook.com>
2026-04-21 12:38:48 +08:00
syh-cpdsss
148a04a7f8 Feat: Add OKR business domain (#522)
* feat: okr domain

Change-Id: I1877c56e33e3620b696351ed9e4c8615dbe17c4b

* feat: okr skill update

Change-Id: I1877c56e33e3620b696351ed9e4c8615dbe17c4b
2026-04-17 18:04:15 +08:00
Yuxuan Zhao
1ad7cfab5b test: inject user env only for cli e2e user commands (#541) 2026-04-17 17:33:37 +08:00
Yuxuan Zhao
5280517d4b Feat/cli e2e tests with UAT (#528)
* test: expand and stabilize cli e2e workflows

* ci: run deadcode with test entrypoints
2026-04-17 16:57:17 +08:00
yaozhen00
c2b132945e feat(test): optimize cli-e2e-testcase-writer skill (#447)
* feat(test): optimize cli-e2e-testcase-writer skill add coverage.md

* feat(test): test report show
2026-04-13 21:10:11 +08:00
Yuxuan Zhao
085ffd87f3 feat: add stable cli e2e tests (#401)
* feat: add stable bot-only cli e2e subset

Change-Id: I62edf59d179e407954f65f82e94cf5dcf4938080

* fix: address review comments on stable cli e2e tests

Change-Id: I4436100c30adf2694cd06953961f8d77f576fc1e

* fix: reduce flakiness in drive and im e2e helpers

Change-Id: I51e77d857f1fd9aec5ee34adf5045cc695239f21

* fix: document missing drive cleanup support

Change-Id: I3d4f034145bd69fb7640e707fcda05146b8754c7

* style: unify e2e cleanup comments

Change-Id: I40d906c9168754ad71ef9fb770ff4c340fc19beb

* test: update e2e assertions

Change-Id: I73c21b4b38d4ced7ea27cb327075957ec2b9a2a2

* test: stabilize cli e2e bot-only coverage

Change-Id: Ied897c37c4f42e446d55d110461aa34ae198195d
2026-04-12 16:52:41 +08:00
liangshuo-1
619ec8c2cb fix(api): support stdin and quoted JSON inputs on Windows (#367)
* fix(api): add stdin and single-quote support for --params/--data on Windows (#64)

Windows PowerShell 5.x mangles JSON double-quotes when passing arguments
to native executables, causing --params and --data to fail with
"invalid JSON format". This commit adds two mitigations at the framework
level:

- stdin piping: `echo '{"k":"v"}' | lark-cli --params -` bypasses
  shell argument parsing entirely and works on all platforms/shells.
- single-quote stripping: cmd.exe passes literal single quotes which
  are now transparently removed before JSON parsing.

Implementation:
- New `cmdutil.ResolveInput(raw, stdin)` handles `-` (stdin), strip
  surrounding `'...'`, and plain passthrough.
- `ParseJSONMap` and `ParseOptionalBody` now accept an `io.Reader` and
  delegate to `ResolveInput` before JSON unmarshalling.
- `cmd/api` and `cmd/service` pass `IOStreams.In` and guard against
  simultaneous stdin usage by --params and --data.
- Empty stdin is rejected with a clear error message.

Closes #64

Change-Id: If21e735d0aed5c6a2d6674c1e6c898186fca3aba

* test: add stdin e2e regression coverage

Change-Id: I4e00bf1c6b6f3259f503e3414cae10fa4b34ba75
2026-04-09 19:10:50 +08:00
yaozhen00
5cf866739d feat(test): Add a CLI E2E testing framework for lark-cli, task domain testcase and ci action (#236)
* feat: cli e2e test framework and demo

* feat: add cli-e2e-testcase-writer skill and task case

* feat: add cli e2e config and fix test resource prefix
2026-04-03 17:26:06 +08:00