Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
d4d4f32
docs: add npm version badge and improve AI agent tip wording (#23)
liuxinyanglxy Mar 28, 2026
62ad335
docs: simplify installation steps by merging CLI and Skills into one …
liuxinyanglxy Mar 28, 2026
511c24b
docs: add star history chart to readmes (#12)
timzhong1024 Mar 28, 2026
d2ad5e4
docs: rename user-facing Bitable references to Base (#11)
timzhong1024 Mar 28, 2026
e5a83f5
ci: improve CI workflows and add golangci-lint config (#71)
liangshuo-1 Mar 30, 2026
a13bee8
fix: resolve silent failure in `lark-cli api` error output (#39) (#85)
evandance Mar 30, 2026
ecf3209
fix: remove sensitive send scope from reply and forward shortcuts (#92)
infeng Mar 30, 2026
8e24166
fix(base): use base history read scope for record history list (#96)
kongenpei Mar 30, 2026
9b933f1
docs: add official badge to distinguish from third-party Lark CLI too…
schumilin Mar 30, 2026
69bcdd9
feat: add auto-pagination to messages search and update lark-im docs …
YangJunzhou-01 Mar 30, 2026
8bd5049
feat: normalize markdown message send/reply output (#28)
91-enjoy Mar 30, 2026
a2656e1
feat:remove useless files (#131)
evandance Mar 31, 2026
62d8681
docs: update Base description to include all capabilities (#61)
vaxin Mar 31, 2026
634adfc
feat: support auto extension for downloads (#16)
jackie3927 Mar 31, 2026
c8341bb
docs(base): clarify field description usage in json (#90)
zgz2048 Mar 31, 2026
c35b1ae
feat: add npm publish job to release workflow (#145)
qianzhicheng95 Mar 31, 2026
27139a0
feat: add automatic CLI update detection and notification (#144)
MaxHuang22 Mar 31, 2026
8fc7e12
docs: add v1.0.1 changelog (#150)
qianzhicheng95 Mar 31, 2026
5da3075
feat(calendar): implement rsvp shortcut (#151)
calendar-assistant Mar 31, 2026
1ffe870
fix(mail): clarify that file path flags only accept relative paths (#…
infeng Mar 31, 2026
bdd39b0
ci: add pkg.pr.new PR preview workflow (#152)
kongenpei Mar 31, 2026
c4851a5
ci: improve pkg.pr.new install comment clarity (#168)
kongenpei Apr 1, 2026
6463ab1
ci: make pkg.pr.new comment flow fork-safe (#170)
kongenpei Apr 1, 2026
4c51a98
fix: correct URL formatting in login --no-wait output (#169)
JackZhao10086 Apr 1, 2026
d4e83df
chore: add pull request template (#176)
kongenpei Apr 1, 2026
70c72a2
feat(mail): auto-resolve local image paths in draft body HTML (#81) (…
infeng Apr 1, 2026
17698d5
docs: add concise AGENTS development guide (#178)
kongenpei Apr 1, 2026
5621d2e
feat(ci): refine PR business area labels and introduce skill format c…
williamfzc Apr 1, 2026
d4c051d
feat: improve OS keychain/DPAPI access error handling for sandbox env…
JackZhao10086 Apr 1, 2026
eb8b542
feat: add TestGenerateShortcutsJSON and skip redundant meta fetch (#179)
MaxHuang22 Apr 1, 2026
a703202
chore: add v1.0.2 changelog and bump version (#192)
liangshuo-1 Apr 1, 2026
eda2b9c
revert: undo auto-resolve local image paths in draft body HTML (#199)
infeng Apr 1, 2026
f68a411
fix(mail): on-demand scope checks and watch event filtering (#198)
haidaodashushu Apr 2, 2026
f231031
feat: support im message send/reply with uat (#180)
sammi-bytedance Apr 2, 2026
79f43dc
feat: add drive import, export, move, and task result shortcuts (#194)
liujinkun2025 Apr 2, 2026
102ee51
feat: add +download shortcut for minutes media download (#101)
Ren1104 Apr 2, 2026
0f96bdf
fix: normalize escaped sheet range separators (#207)
caojie0621 Apr 2, 2026
112dd5f
ci: add gitleaks scanning workflow and custom rules (#142)
iyaozhen Apr 2, 2026
057b007
docs: add im chat member delete scope notes
Apr 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
coverage:
status:
project:
default:
informational: true
patch:
default:
target: 60%
16 changes: 16 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
## Summary
<!-- Briefly describe the motivation and scope of this change in 1-3 sentences. -->

## Changes
<!-- List the main changes in this PR. -->
- Change 1
- Change 2

## Test Plan
<!-- Describe how this change was verified. -->
- [ ] Unit tests pass
- [ ] Manual local verification confirms the `lark xxx` command works as expected

## Related Issues
<!-- Link related issues. Use Closes/Fixes to close them automatically. -->
- None
42 changes: 30 additions & 12 deletions .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,32 @@ name: Coverage

on:
push:
branches: [ main ]
branches: [main]
paths:
- "**.go"
- go.mod
- go.sum
- .github/workflows/coverage.yml
pull_request:
branches: [ main ]
branches: [main]
paths:
- "**.go"
- go.mod
- go.sum
- .github/workflows/coverage.yml

permissions:
contents: read

jobs:
codecov:
runs-on: ubuntu-22.04
coverage:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4

- uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5
with:
go-version: '1.23'
go-version-file: go.mod

- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
with:
Expand All @@ -27,10 +37,18 @@ jobs:
run: python3 scripts/fetch_meta.py

- name: Run tests with coverage
run: go test -coverprofile=coverage.txt -covermode=atomic ./...

- name: Upload coverage to Codecov
uses: codecov/codecov-action@75cd11691c0faa626561e295848008c8a7dddffe # v5
with:
files: coverage.txt
token: ${{ secrets.CODECOV_TOKEN }}
run: go test -race -coverprofile=coverage.txt -covermode=atomic ./...

- name: Generate coverage report
run: |
total=$(go tool cover -func=coverage.txt | grep total | awk '{print $3}')
echo "## Coverage Report" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Total coverage: ${total}**" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "<details><summary>Details</summary>" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
go tool cover -func=coverage.txt >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
echo "</details>" >> $GITHUB_STEP_SUMMARY
28 changes: 28 additions & 0 deletions .github/workflows/gitleaks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: Gitleaks

on:
pull_request:
branches: [main]
push:
branches: [main]
workflow_dispatch:

permissions:
contents: read

jobs:
gitleaks:
# Forked pull_request runs do not receive repository/org secrets except GITHUB_TOKEN.
if: ${{ github.event_name != 'pull_request' || !github.event.pull_request.head.repo.fork }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
fetch-depth: 0

- uses: gitleaks/gitleaks-action@ff98106e4c7b2bc287b24eaf42907196329070c7 # v2.3.9
env:
# GITHUB_TOKEN is provided automatically by GitHub Actions.
# GITLEAKS_KEY must be configured as a repository secret.
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITLEAKS_LICENSE: ${{ secrets.GITLEAKS_KEY }}
78 changes: 33 additions & 45 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,43 +2,36 @@ name: Lint

on:
push:
branches: [ main ]
branches: [main]
paths:
- "**.go"
- go.mod
- go.sum
- .golangci.yml
- .github/workflows/lint.yml
pull_request:
branches: [ main ]
branches: [main]
paths:
- "**.go"
- go.mod
- go.sum
- .golangci.yml
- .github/workflows/lint.yml

permissions:
contents: read

jobs:
staticcheck:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4

- uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5
with:
go-version: '1.23'

- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
with:
python-version: '3.x'

- name: Fetch meta_data.json
run: python3 scripts/fetch_meta.py

- name: Run staticcheck
uses: dominikh/staticcheck-action@9716614d4101e79b4340dd97b10e54d68234e431 # v1
with:
install-go: false

golangci-lint:
runs-on: ubuntu-22.04
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
with:
fetch-depth: 0

- uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5
with:
go-version: '1.23'
go-version-file: go.mod

- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
with:
Expand All @@ -47,26 +40,21 @@ jobs:
- name: Fetch meta_data.json
run: python3 scripts/fetch_meta.py

- name: Run golangci-lint
uses: golangci/golangci-lint-action@55c2c1448f86e01eaae002a5a3a9624417608d84 # v6
with:
version: latest

vet:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Ensure go.mod and go.sum are tidy
run: |
go mod tidy
if ! git diff --quiet go.mod go.sum; then
echo "::error::go.mod or go.sum is not tidy. Run 'go mod tidy' and commit the changes."
git diff go.mod go.sum
exit 1
fi
- uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5
with:
go-version: '1.23'

- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
with:
python-version: '3.x'
- name: Run golangci-lint
run: go run github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.1.6 run --new-from-rev=origin/main

- name: Fetch meta_data.json
run: python3 scripts/fetch_meta.py
- name: Run govulncheck
continue-on-error: true # informational until Go version is upgraded
run: go run golang.org/x/vuln/cmd/govulncheck@v1.1.4 ./...

- name: Run go vet
run: go vet ./...
- name: Check dependency licenses
run: go run github.com/google/go-licenses/v2@v2.0.1 check ./... --disallowed_types=forbidden,restricted,reciprocal,unknown
149 changes: 149 additions & 0 deletions .github/workflows/pkg-pr-new-comment.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
name: PR Preview Package Comment

on:
workflow_run:
workflows: ["PR Preview Package"]
types: [completed]

permissions:
actions: read
contents: read
issues: write
pull-requests: write

jobs:
comment:
if: github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event == 'pull_request'
runs-on: ubuntu-latest

steps:
- name: Check comment payload artifact
id: payload
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
script: |
const runId = context.payload.workflow_run?.id;
const { data } = await github.rest.actions.listWorkflowRunArtifacts({
owner: context.repo.owner,
repo: context.repo.repo,
run_id: runId,
per_page: 100,
});
const found = Boolean(
data.artifacts?.some((artifact) => artifact.name === "pkg-pr-new-comment-payload")
);
core.setOutput("found", found ? "true" : "false");
if (!found) {
core.notice("No comment payload artifact found for this run; skipping comment.");
}

- name: Download comment payload
if: steps.payload.outputs.found == 'true'
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
with:
name: pkg-pr-new-comment-payload
repository: ${{ github.repository }}
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ github.token }}

- name: Comment install command
if: steps.payload.outputs.found == 'true'
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
script: |
const fs = require("fs");
const payload = JSON.parse(fs.readFileSync("pkg-pr-new-comment-payload.json", "utf8"));
const url = payload?.url;
const payloadPr = payload?.pr;
const sourceRepo = payload?.sourceRepo;
const sourceBranch = payload?.sourceBranch;
if (!Number.isInteger(payloadPr)) {
throw new Error(`Invalid PR number in artifact payload: ${payloadPr}`);
}
if (payloadPr <= 0) {
throw new Error(`Invalid PR number in artifact payload: ${payloadPr}`);
}
const issueNumber = payloadPr;
const runPrNumber = context.payload.workflow_run?.pull_requests?.[0]?.number;
if (Number.isInteger(runPrNumber) && runPrNumber !== issueNumber) {
throw new Error(
`PR number mismatch between workflow_run (${runPrNumber}) and artifact payload (${issueNumber})`,
);
}

if (typeof url !== "string" || url.trim() !== url || /[\u0000-\u001F\u007F]/.test(url)) {
throw new Error(`Invalid package URL in payload: ${url}`);
}
let parsedUrl;
try {
parsedUrl = new URL(url);
} catch {
throw new Error(`Invalid package URL in payload: ${url}`);
}
if (parsedUrl.protocol !== "https:" || parsedUrl.hostname !== "pkg.pr.new") {
throw new Error(`Invalid package URL in payload: ${url}`);
}

const safeRepoPattern = /^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/;
const safeBranchPattern = /^[A-Za-z0-9._\/-]+$/;
const hasSkillSource =
typeof sourceRepo === "string" &&
typeof sourceBranch === "string" &&
safeRepoPattern.test(sourceRepo) &&
safeBranchPattern.test(sourceBranch);
const skillSection = hasSkillSource
? [
"",
"### 🧩 Skill update",
"",
"```bash",
`npx skills add ${sourceRepo}#${sourceBranch} -y -g`,
"```",
]
: [
"",
"### 🧩 Skill update",
"",
"_Unavailable for this PR because source repo/branch metadata is missing._",
];

const body = [
"<!-- pkg-pr-new-install-guide -->",
"## 🚀 PR Preview Install Guide",
"",
"### 🧰 CLI update",
"",
"```bash",
`npm i -g ${url}`,
"```",
...skillSection,
].join("\n");

const comments = await github.paginate(github.rest.issues.listComments, {
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issueNumber,
per_page: 100,
});

const existing = comments.find((comment) =>
comment.user?.login === "github-actions[bot]" &&
typeof comment.body === "string" &&
comment.body.includes("<!-- pkg-pr-new-install-guide -->")
);

if (existing) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: existing.id,
body,
});
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issueNumber,
body,
});
}
Loading
Loading