mirror of
https://github.com/larksuite/cli.git
synced 2026-07-07 09:11:44 +08:00
fix/plugin-security-review
5 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
2424d05b01 |
fix(plugin): harden plugin commands against path traversal, DoS, and agent misuse
Security fixes from PR #1596 security audit: - Skip symlink/hardlink entries during tgz extraction (Zip Slip) - Limit tgz entry and download size to 10 MB (OOM/DoS) - Limit error response body read to 4 KB - Validate MIAODA_APP_TYPE as numeric to prevent path manipulation - Add validatePluginKey + secureModulePath to block --name path traversal (../../.ssh etc.) for install/uninstall Usability fix: - Add explicit 'local command, no --app-id' notice in plugin reference docs to prevent agent from incorrectly passing --app-id to plugin commands (which read package.json locally) |
||
|
|
cf9e8d512d |
fix(plugin): fix nolint directive format and nilerr placement in plugin_common.go (#1668)
- Change nolint comment separator from -- to // to satisfy nolintlint - Move nilerr nolint directive to return statement to suppress nilerr correctly - Fix forbidigo nolint format for intermediate fmt.Errorf in pluginExtractTGZ |
||
|
|
be7c05cc97 |
fix(plugin): resolve CI lint, deadcode, and unit-test failures (#1667)
- Add Scopes: []string{} to plugin-install, plugin-list, plugin-uninstall
shortcuts to satisfy TestAllShortcutsScopesNotNil
- Remove unused pluginCheckInstalled function (deadcode)
- Fix nilerr: add //nolint:nilerr for intentional best-effort nil returns
- Fix forbidigo: replace bare fmt.Errorf in Execute with typed error,
add //nolint:forbidigo for intermediate helper errors in pluginExtractTGZ
- Fix errorlint: change %v to %w for cerr in multi-error fmt.Errorf
- Remove all unused //nolint:forbidigo directives from test files
|
||
|
|
ff65e614e7 |
fix(plugin): rename files to apps_ prefix and handle Close() errors (#1655)
- Rename plugin_install/list/uninstall .go files to apps_plugin_ prefix for consistency with other files in the package - Handle f.Close() errors in pluginExtractTGZ to avoid silent data loss |
||
|
|
7d1164dcb4 |
feat(plugin): add plugin package management commands (#1609)
* feat: add plugin package and instance management commands for apps domain
Add 8 new shortcut commands under `lark-cli apps`:
Plugin package management (aligned with fullstack-cli):
- +plugin-install: download tgz, extract to node_modules, update package.json
- +plugin-uninstall: remove from node_modules and package.json actionPlugins
- +plugin-list: list declared plugins with installation status
Plugin instance CRUD (aligned with feida-ai):
- +plugin-instance-create: validate + write capability JSON with formValue validation
- +plugin-instance-update: merge mutable fields, re-validate formValue
- +plugin-instance-delete: idempotent file removal
- +plugin-instance-get: read capability JSON
- +plugin-instance-list: scan capabilities directory
Shared infrastructure (plugin_common.go):
- 4-level capabilities dir resolution (flag → env → .env.local MIAODA_APP_TYPE → detection)
- formValue validation ported from feida-ai (5 rules: forbidden Handlebars, paramsSchema
type constraints, input ref existence, unconsumed params, array double-wrap auto-fix)
- tgz extraction with path traversal protection
- package.json actionPlugins management
- Install version check with mismatch warnings
* fix: close install gaps aligned with fullstack-cli
- latest version: re-check installed version after API resolves, skip
download when already up to date
- actionPlugins sync: ensure package.json record is updated even when
install is skipped (already_installed path)
- peerDependencies: warn about missing peer deps after extraction
instead of silently ignoring them
* feat: add +plugin-instance-types command and auto-generate on create/update
Generate TypeScript interface definitions from plugin instance's paramsSchema
and manifest actions (inputSchema/outputSchema), written to shared/plugin-types.ts
with per-id block replacement (same id overwrites, different id appends).
Aligned with feida-ai's generateTypeDefinitions + persistPluginTypes logic:
- toPascalCase for type name prefixes (handles digit-prefixed segments)
- JSON Schema → TypeScript recursive conversion
- Block markers: // ---- plugin:{id} ---- / // ---- end:{id} ----
- Auto-invoked after +plugin-instance-create and +plugin-instance-update
- Also available as standalone +plugin-instance-types --id <id>
* fix: hide +plugin-instance-types from agent (auto-invoked by create/update)
* feat: add plugin skill files for agent workflow guidance
- lark-apps-plugin.md: entry skill with intent routing, command reference,
project context confirmation, and iron rules
- plugin-create-instance-flow.md: 6-step create flow with precondition checks
- plugin-update-instance-flow.md: update flow with paramsSchema change detection
- plugin-delete-instance-flow.md: delete flow with code reference scanning
- plugin-get-instance-flow.md: query routing for list/get/manifest reads
- plugin-instance-schema.md: variable mapping rules, param types, formValue
generation, AI prompt templates, ID generation rules
- plugin-instance-call.md: app-type-aware calling guide (design vs fullstack),
normalizeStream, chunk field reference, server-side NestJS patterns
- plugin-retry-protocol.md: validation failure retry protocol (max 3)
- SKILL.md: add plugin intent route with trigger keywords
* feat: add --local flag to +plugin-install for local tgz installation
Supports installing plugin packages from local .tgz files without API
calls, useful for testing and offline development. Reads plugin key and
version from the extracted package.json inside the tgz.
Also moved Scopes to ConditionalScopes so --local path skips auth.
* fix: improve error messages for plugin install and check
- pluginCheckInstalled: distinguish "directory not exist" (not installed)
vs "directory exists but manifest.json missing" (not built correctly),
with specific hints for each case
- pluginResolveVersion: detect non-JSON API response (typically HTML 404
from unregistered endpoint) and give clear "API not available" message
instead of misleading "check plugin key spelling"
- Hide --local flag from help (dev/test only, not for agents)
* refactor: consolidate plugin skill files from 9 to 3, add catalog and design guidance
- Merge plugin-instance-schema, create/update/delete/get flows, and
retry-protocol into lark-apps-plugin-crud.md (Schema + CRUD + retry)
- Merge plugin-catalog into lark-apps-plugin.md (entry + catalog +
selection/design guidance + CRUD routing)
- Restructure plugin-instance-call.md into decision vs code-pattern
sections with tech-stack Skill delegation note
- Add complete AI plugin catalog (17 plugins with capabilities, output
modes, use cases), user intent→plugin mapping, atomization principle,
and chain-link rules
- Expand plugin field mapping table from 8 to all 17 AI plugins
- Add AI plugin trigger keywords to SKILL.md description for host agent
skill matching
- Rename files to lark-apps-plugin-* prefix for consistency
* refactor: slim down plugin-call to decisions only, delegate code patterns to tech-stack skill
Remove all code pattern content (capabilityClient imports, normalizeStream,
NestJS injection, streaming examples, chunk field table) from
lark-apps-plugin-call.md. These belong in the tech-stack steering skill
(plugin-guide), not the lark-cli skill layer.
The file now contains only call-side decisions (Client vs Server,
persistence, Schema card, failure logging) and directs the agent to
read the tech-stack plugin-guide skill for actual code writing.
* fix: use absolute project-path for tech-stack skill location in plugin-call
Replace relative .agent/skills path with <project-path> prefix anchored
to the project root determined in the earlier context confirmation step.
Add fallback path and minimal call rules when skill file doesn't exist.
* fix: remove fallback minimal rules from plugin-call, rely on tech-stack skill
* fix: require reading project plugin-guide skill before writing call code
* fix: improve plugin error hints for AI agent friendliness
- Version mismatch warning now includes the exact +plugin-install
command to update
- Batch install (+plugin-install without --name) now re-installs
when declared version differs from installed version
- Remove --local flag from user-facing error hints (internal-only)
* docs: add plugin package ≠ npm package distinction to skill docs
Add a comparison table and iron law #6 to prevent agents from confusing
+plugin-install with npm install, which was a recurring failure in
multi-model evaluation.
* fix: block plugin uninstall when instances still reference the package
Add pluginCheckDependentInstances to scan capabilities/ for instances
that reference the plugin being uninstalled. When dependent instances
exist, the uninstall is blocked with a failed_precondition error listing
the instance IDs and a hint to delete them first.
* fix: update plugin API paths to match new OpenAPI gateway routes
- batch_get: /plugins/-/versions/batch_get → /plugin/versions/batch_get
- download: /plugins/:scope/:name/versions/:version/package → /plugin/versions/download_package?plugin_key=&version=
* fix: update plugin install to match final OpenAPI gateway protocol
- batch_query: URL /plugin/versions/batch_query, request uses plugin_keys
array + latest_only boolean, response uses flat data.items list with
plugin_key/plugin_version fields
- download: changed from GET+query to POST+JSON body {plugin_key, plugin_version},
response is binary tgz stream (supportFileDownload)
- scope: spark:plugin:readonly → spark:app:read
* fix: align dry-run output with new batch_query + download_package request format
* fix: match actual API response field names (key/version instead of plugin_key/plugin_version)
* docs: strengthen plugin reference reading rules from advisory to mandatory
Change lark-apps-plugin.md from implicit to explicit required reading
for any plugin work. Replace soft '按需读' with bold '必读' for all three
plugin reference files. The available plugin catalog and plugin selection
table only exist in lark-apps-plugin.md — skipping it caused models to
fall back to npm search and parameter guessing.
* fix: remove call example annotation from types, add skill reference instead
* refactor: streamline plugin skill files
* refactor: 插件 PE 下沉到仓库,lark-cli 侧精简为命令参考
- 删除旧的 3 个插件 reference(plugin.md / plugin-crud.md / plugin-call.md),
其中的 Schema 规则、CRUD 流程、插件目录、Prompt 模板等内容已下沉到
应用仓库 .agents/skills/plugin-guide/SKILL.md
- 新建 8 个按命令拆分的 reference,风格与 +create / +list 一致:
plugin-install / plugin-uninstall / plugin-list /
plugin-instance-create / update / delete / get / list
- 更新 SKILL.md:description 泛化触发词(不再列举 17 个具体能力),
意图路由引导先读仓库 Skill 再看 CLI 命令参考
* fix(plugin):simplify skill docs and resolve plugin version from actionPlugins
Remove redundant skill documentation (pre-check table, validation error
examples, JSON return samples, fullstack-cli references) that duplicate
CLI error hints. Make --plugin version optional and resolve from
package.json actionPlugins. Drop unused createdBy field.
* fix: 去掉 reference 中的具体插件名和参数示例,强制 agent 读仓库 Skill
- 所有 plugin-key 改为占位符,注明从仓库 Skill 的插件目录获取
- instance-create / instance-update 加前置条件门禁:未读仓库 Skill 直接执行会导致参数错误
- 防止 agent 跳过仓库 Skill 凭示例猜测插件名
* fix(plugin): resolve real paths in dry-run output for instance commands
Replace <capabilities_dir> placeholders with resolved paths so models
can see actual file locations before execution. Add version_source,
types_output, and scan_dir fields to describe implicit behaviors.
* refactor(plugin): hide instance commands, delegate to repo Skill
Hide +plugin-instance-create/update/delete/get/list from CLI help.
Remove instance reference files from lark-apps skill. Route instance
CRUD and call code generation to project repo plugin-guide skill.
Go instance code preserved, just hidden.
* refactor: 删除 plugin-instance 5 个 CLI 命令,改由仓库 Skill 引导 agent 直接操作文件
- 删除 plugin_instance_create/update/delete/get/list 及其测试(11 个文件)
- 删除 plugin_instance_types(TypeScript 类型生成命令)
- 移除 shortcuts.go 中的 6 个注册项
- 清理 plugin_common.go 中仅被 instance 命令使用的函数(1054→340 行):
校验逻辑、capability JSON 读写、动态 schema 解析、TypeScript 生成等
- 保留 plugin-install / plugin-uninstall / plugin-list 三个命令不变
插件实例的 CRUD 操作改由仓库 Skill 引导 agent 直接读写 capabilities/*.json,
验证规则写在 Skill 中由 agent 自校验。
* refactor(plugin): remove --project-path flag and split --name into --name + --version
- Remove --project-path from plugin-install/list/uninstall (use cwd like npm)
- Split --name key@version into separate --name and --version flags
- Remove pluginParseInstallTarget (no longer needed)
- Improve DryRun desc and error hints for --version usage
- Update skill docs to reflect new flag structure
- Tests use chdirTest helper instead of --project-path
* feat(plugin): add Examples to --help for plugin-install/list/uninstall
按 lark-cli 优化治理规范,为三个插件命令的 --help 补充 2-3 个
可执行示例,覆盖最常见使用路径,帮助 agent 快速理解命令用法。
* fix(plugin): address PR #1609 review findings
- Fix hint referencing non-existent +plugin-instance-delete command,
point to repo plugin-guide Skill instead
- Remove undeclared --capabilities-dir flag, simplify pluginResolveCapDir
to env-only resolution, fix ambiguous hint to suggest env vars
- Reclassify download errors from file_io to network/api with proper
hints and retryable marking
- Slim SKILL.md routing row, move judgment rules to plugin-install reference
- Rename --local flag to --file to align with CLI conventions
* fix(skill): restore plugin routing row with judgment rules, fix markdown formatting
Revert SKILL.md routing row to keep full judgment rules and repo Skill
directive inline. Fix bold marker spacing and restore missing table column.
Revert reference to original content without duplicated rules.
* fix(plugin): revert SKILL.md to pre-review version, fix shortcut count test
Restore SKILL.md plugin routing row to original version with full
judgment rules and repo Skill directive. Update shortcut count test
from 60 to 63 to account for 3 new plugin commands.
* fix(plugin):fix lark-apps skill docs which is about plugin
* fix(plugin):correct plugin skill md
* fix(plugin):correct plugin md
* fix(plugin):correct plugin and local dev skills md
* fix(plugin):correct apps plugin skills md
* fix(lark-apps): move repo skill reading hint to post-init phase
将「仓库 Skill 优先」从 SKILL.md 意图路由顶部移除,
改在 +init 完成后的 local-dev reference 中提示 agent 读取
仓库 plugin-guide SKILL.md,解决应用未初始化时 repo skill
不存在导致 agent 无法获取插件知识的时序问题。
* fix(lark-apps): strengthen local-dev reference reading and post-init plugin guide
- SKILL.md 路由表:local-dev.md 从"按需读取"提升为"执行前必读"
- local-dev.md:将读仓库 Skill 嵌入端到端流程链作为正式步骤
- post-init 指引改为可执行命令 + 不读的后果说明 + 不存在时兜底
---------
Co-authored-by: zhangli <zhangli.268@bytedance.com>
|