From 18a66a6a31f69d0b96727c39692d714c04beb5b5 Mon Sep 17 00:00:00 2001
From: CosmoLau <853309355@qq.com>
Date: Mon, 15 Apr 2024 13:50:35 +0800
Subject: [PATCH 1/6] fix: broken links
---
website/blog/2020-08-26-summer-update.md | 2 +-
website/blog/2024-03-29-spring-update.md | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/website/blog/2020-08-26-summer-update.md b/website/blog/2020-08-26-summer-update.md
index 09436902..d1f02064 100644
--- a/website/blog/2020-08-26-summer-update.md
+++ b/website/blog/2020-08-26-summer-update.md
@@ -10,7 +10,7 @@ Earlier this year, we started our planning for oclifconf v2 and, like all confer
One of the most requested features, help templating enables oclif developers to customize the help output for their CLI.
-Read [the announcement](/blog/introducing-custom-help-classes).
+Read [the announcement](/blog/2020/05/05/introducing-custom-help-classes).
## Feature: Custom error delegation
diff --git a/website/blog/2024-03-29-spring-update.md b/website/blog/2024-03-29-spring-update.md
index a0264cab..70a0cbf2 100644
--- a/website/blog/2024-03-29-spring-update.md
+++ b/website/blog/2024-03-29-spring-update.md
@@ -12,7 +12,7 @@ We've been focusing on these high-level areas over the past couple of years:
## Improving `@oclif/core`
-Since we [announced `@oclif/core` over three years ago](./2021-03-01-introducing-oclif-core), we've released two new major versions, each packed with lots of features that we're really excited about.
+Since we [announced `@oclif/core` over three years ago](/blog/2021/03/01/introducing-oclif-core), we've released two new major versions, each packed with lots of features that we're really excited about.
Here are some of these changes:
- Full support for ESM and interoperability with CommonJS (more on this topic below).
From 6ae6411d5ae72226df7e467d60cc1db3e3708842 Mon Sep 17 00:00:00 2001
From: CosmoLau <853309355@qq.com>
Date: Mon, 15 Apr 2024 13:53:13 +0800
Subject: [PATCH 2/6] chore: add i18n config
---
website/docusaurus.config.ts | 19 +++++++++++++++++++
website/package.json | 4 +++-
2 files changed, 22 insertions(+), 1 deletion(-)
diff --git a/website/docusaurus.config.ts b/website/docusaurus.config.ts
index 71145223..8a3902ff 100644
--- a/website/docusaurus.config.ts
+++ b/website/docusaurus.config.ts
@@ -80,6 +80,10 @@ export default async function createConfigAsync() {
label: 'Blog',
position: 'right',
},
+ {
+ type: 'localeDropdown',
+ position: 'right',
+ },
{
href: 'https://github.com/oclif/oclif',
className: 'header-github-link',
@@ -110,5 +114,20 @@ export default async function createConfigAsync() {
contextualSearch: true,
},
} satisfies Preset.ThemeConfig,
+ i18n: {
+ defaultLocale: 'en',
+ locales: ['en', 'zh'],
+ localeConfigs: {
+ en: {
+ label: 'English',
+ htmlLang: 'en-US',
+ },
+ zh: {
+ label: '简体中文',
+ htmlLang: 'zh-Hans',
+ path: 'zh'
+ }
+ }
+ }
} satisfies Config
}
diff --git a/website/package.json b/website/package.json
index 1c5f4f9e..d370b4b6 100644
--- a/website/package.json
+++ b/website/package.json
@@ -4,7 +4,9 @@
"examples": "docusaurus-examples",
"start": "docusaurus start",
"build": "docusaurus build",
- "write-translations": "docusaurus-write-translations",
+ "clear": "docusaurus clear",
+ "serve": "docusaurus serve",
+ "write-translations": "docusaurus write-translations",
"version": "docusaurus-version",
"rename-version": "docusaurus-rename-version",
"swizzle": "docusaurus swizzle",
From e7603b790314dad66712f9af4f06111708275e9f Mon Sep 17 00:00:00 2001
From: CosmoLau <853309355@qq.com>
Date: Mon, 15 Apr 2024 13:54:47 +0800
Subject: [PATCH 3/6] docs: add simplified Chinese translation
---
website/i18n/zh/code.json | 480 ++++++++++++++++++
.../2018-03-20-introducing-oclif.md | 10 +
.../2019-02-20-cli-flags-explained.md | 162 ++++++
.../2019-09-16-oclifconf-recap.md | 43 ++
.../2019-10-31-oclif-node-updates.md | 67 +++
.../2019-12-05-oclif-eslint-migration.md | 71 +++
...0-05-05-introducing-custom-help-classes.md | 60 +++
.../2020-07-01-pretty-printable-errors.md | 28 +
.../2020-08-26-summer-update.md | 40 ++
.../2021-03-01-introducing-oclif-core.md | 55 ++
.../2022-01-12-announcing-oclif-v2.md | 109 ++++
.../2024-03-29-spring-update.md | 57 +++
.../options.json | 14 +
.../current.json | 26 +
.../current/aliases.md | 64 +++
.../current/args.md | 75 +++
.../current/base_class.md | 88 ++++
.../current/command_discovery_strategies.md | 188 +++++++
.../current/command_execution.md | 7 +
.../current/commands.md | 185 +++++++
.../current/config.md | 65 +++
.../current/configuring_your_cli.md | 80 +++
.../current/debugging.md | 10 +
.../current/error_handling.md | 61 +++
.../current/esm.md | 152 ++++++
.../current/examples.md | 10 +
.../current/external_links.md | 6 +
.../current/faqs.md | 49 ++
.../current/features.md | 61 +++
.../current/feedback.md | 5 +
.../current/flag_inheritance.md | 64 +++
.../current/flags.md | 160 ++++++
.../current/flexible_taxonomy.md | 62 +++
.../current/generator_commands.md | 105 ++++
.../current/help_classes.md | 125 +++++
.../current/hooks.md | 96 ++++
.../current/how_we_work.md | 53 ++
.../current/index.md | 4 +
.../current/introduction.md | 25 +
.../current/jit_plugins.md | 47 ++
.../current/json.md | 32 ++
.../current/nsis-installer_customization.md | 23 +
.../current/performance.md | 197 +++++++
.../current/plugin_loading.md | 25 +
.../current/plugins.md | 67 +++
.../current/related_repos.md | 8 +
.../current/releasing.md | 144 ++++++
.../current/running_programmatically.md | 112 ++++
.../current/single_command_cli.md | 21 +
.../current/templates.md | 57 +++
.../current/testing.md | 83 +++
.../current/themes.md | 110 ++++
.../current/topic_separator.md | 17 +
.../current/topics.md | 30 ++
.../current/user_experience.md | 23 +
.../zh/docusaurus-theme-classic/footer.json | 10 +
.../zh/docusaurus-theme-classic/navbar.json | 18 +
57 files changed, 4046 insertions(+)
create mode 100644 website/i18n/zh/code.json
create mode 100644 website/i18n/zh/docusaurus-plugin-content-blog/2018-03-20-introducing-oclif.md
create mode 100644 website/i18n/zh/docusaurus-plugin-content-blog/2019-02-20-cli-flags-explained.md
create mode 100644 website/i18n/zh/docusaurus-plugin-content-blog/2019-09-16-oclifconf-recap.md
create mode 100644 website/i18n/zh/docusaurus-plugin-content-blog/2019-10-31-oclif-node-updates.md
create mode 100644 website/i18n/zh/docusaurus-plugin-content-blog/2019-12-05-oclif-eslint-migration.md
create mode 100644 website/i18n/zh/docusaurus-plugin-content-blog/2020-05-05-introducing-custom-help-classes.md
create mode 100644 website/i18n/zh/docusaurus-plugin-content-blog/2020-07-01-pretty-printable-errors.md
create mode 100644 website/i18n/zh/docusaurus-plugin-content-blog/2020-08-26-summer-update.md
create mode 100644 website/i18n/zh/docusaurus-plugin-content-blog/2021-03-01-introducing-oclif-core.md
create mode 100644 website/i18n/zh/docusaurus-plugin-content-blog/2022-01-12-announcing-oclif-v2.md
create mode 100644 website/i18n/zh/docusaurus-plugin-content-blog/2024-03-29-spring-update.md
create mode 100644 website/i18n/zh/docusaurus-plugin-content-blog/options.json
create mode 100644 website/i18n/zh/docusaurus-plugin-content-docs/current.json
create mode 100644 website/i18n/zh/docusaurus-plugin-content-docs/current/aliases.md
create mode 100644 website/i18n/zh/docusaurus-plugin-content-docs/current/args.md
create mode 100644 website/i18n/zh/docusaurus-plugin-content-docs/current/base_class.md
create mode 100644 website/i18n/zh/docusaurus-plugin-content-docs/current/command_discovery_strategies.md
create mode 100644 website/i18n/zh/docusaurus-plugin-content-docs/current/command_execution.md
create mode 100644 website/i18n/zh/docusaurus-plugin-content-docs/current/commands.md
create mode 100644 website/i18n/zh/docusaurus-plugin-content-docs/current/config.md
create mode 100644 website/i18n/zh/docusaurus-plugin-content-docs/current/configuring_your_cli.md
create mode 100644 website/i18n/zh/docusaurus-plugin-content-docs/current/debugging.md
create mode 100644 website/i18n/zh/docusaurus-plugin-content-docs/current/error_handling.md
create mode 100644 website/i18n/zh/docusaurus-plugin-content-docs/current/esm.md
create mode 100644 website/i18n/zh/docusaurus-plugin-content-docs/current/examples.md
create mode 100644 website/i18n/zh/docusaurus-plugin-content-docs/current/external_links.md
create mode 100644 website/i18n/zh/docusaurus-plugin-content-docs/current/faqs.md
create mode 100644 website/i18n/zh/docusaurus-plugin-content-docs/current/features.md
create mode 100644 website/i18n/zh/docusaurus-plugin-content-docs/current/feedback.md
create mode 100644 website/i18n/zh/docusaurus-plugin-content-docs/current/flag_inheritance.md
create mode 100644 website/i18n/zh/docusaurus-plugin-content-docs/current/flags.md
create mode 100644 website/i18n/zh/docusaurus-plugin-content-docs/current/flexible_taxonomy.md
create mode 100644 website/i18n/zh/docusaurus-plugin-content-docs/current/generator_commands.md
create mode 100644 website/i18n/zh/docusaurus-plugin-content-docs/current/help_classes.md
create mode 100644 website/i18n/zh/docusaurus-plugin-content-docs/current/hooks.md
create mode 100644 website/i18n/zh/docusaurus-plugin-content-docs/current/how_we_work.md
create mode 100644 website/i18n/zh/docusaurus-plugin-content-docs/current/index.md
create mode 100644 website/i18n/zh/docusaurus-plugin-content-docs/current/introduction.md
create mode 100644 website/i18n/zh/docusaurus-plugin-content-docs/current/jit_plugins.md
create mode 100644 website/i18n/zh/docusaurus-plugin-content-docs/current/json.md
create mode 100644 website/i18n/zh/docusaurus-plugin-content-docs/current/nsis-installer_customization.md
create mode 100644 website/i18n/zh/docusaurus-plugin-content-docs/current/performance.md
create mode 100644 website/i18n/zh/docusaurus-plugin-content-docs/current/plugin_loading.md
create mode 100644 website/i18n/zh/docusaurus-plugin-content-docs/current/plugins.md
create mode 100644 website/i18n/zh/docusaurus-plugin-content-docs/current/related_repos.md
create mode 100644 website/i18n/zh/docusaurus-plugin-content-docs/current/releasing.md
create mode 100644 website/i18n/zh/docusaurus-plugin-content-docs/current/running_programmatically.md
create mode 100644 website/i18n/zh/docusaurus-plugin-content-docs/current/single_command_cli.md
create mode 100644 website/i18n/zh/docusaurus-plugin-content-docs/current/templates.md
create mode 100644 website/i18n/zh/docusaurus-plugin-content-docs/current/testing.md
create mode 100644 website/i18n/zh/docusaurus-plugin-content-docs/current/themes.md
create mode 100644 website/i18n/zh/docusaurus-plugin-content-docs/current/topic_separator.md
create mode 100644 website/i18n/zh/docusaurus-plugin-content-docs/current/topics.md
create mode 100644 website/i18n/zh/docusaurus-plugin-content-docs/current/user_experience.md
create mode 100644 website/i18n/zh/docusaurus-theme-classic/footer.json
create mode 100644 website/i18n/zh/docusaurus-theme-classic/navbar.json
diff --git a/website/i18n/zh/code.json b/website/i18n/zh/code.json
new file mode 100644
index 00000000..104658b1
--- /dev/null
+++ b/website/i18n/zh/code.json
@@ -0,0 +1,480 @@
+{
+ "theme.ErrorPageContent.title": {
+ "message": "页面已崩溃。",
+ "description": "The title of the fallback page when the page crashed"
+ },
+ "theme.BackToTopButton.buttonAriaLabel": {
+ "message": "回到顶部",
+ "description": "The ARIA label for the back to top button"
+ },
+ "theme.blog.archive.title": {
+ "message": "历史博文",
+ "description": "The page & hero title of the blog archive page"
+ },
+ "theme.blog.archive.description": {
+ "message": "历史博文",
+ "description": "The page & hero description of the blog archive page"
+ },
+ "theme.blog.paginator.navAriaLabel": {
+ "message": "博文列表分页导航",
+ "description": "The ARIA label for the blog pagination"
+ },
+ "theme.blog.paginator.newerEntries": {
+ "message": "较新的博文",
+ "description": "The label used to navigate to the newer blog posts page (previous page)"
+ },
+ "theme.blog.paginator.olderEntries": {
+ "message": "较旧的博文",
+ "description": "The label used to navigate to the older blog posts page (next page)"
+ },
+ "theme.blog.post.paginator.navAriaLabel": {
+ "message": "博文分页导航",
+ "description": "The ARIA label for the blog posts pagination"
+ },
+ "theme.blog.post.paginator.newerPost": {
+ "message": "较新一篇",
+ "description": "The blog post button label to navigate to the newer/previous post"
+ },
+ "theme.blog.post.paginator.olderPost": {
+ "message": "较旧一篇",
+ "description": "The blog post button label to navigate to the older/next post"
+ },
+ "theme.blog.post.plurals": {
+ "message": "{count} 篇博文",
+ "description": "Pluralized label for \"{count} posts\". Use as much plural forms (separated by \"|\") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)"
+ },
+ "theme.blog.tagTitle": {
+ "message": "{nPosts} 含有标签「{tagName}」",
+ "description": "The title of the page for a blog tag"
+ },
+ "theme.tags.tagsPageLink": {
+ "message": "查看所有标签",
+ "description": "The label of the link targeting the tag list page"
+ },
+ "theme.colorToggle.ariaLabel": {
+ "message": "切换浅色/暗黑模式(当前为{mode})",
+ "description": "The ARIA label for the navbar color mode toggle"
+ },
+ "theme.colorToggle.ariaLabel.mode.dark": {
+ "message": "暗黑模式",
+ "description": "The name for the dark color mode"
+ },
+ "theme.colorToggle.ariaLabel.mode.light": {
+ "message": "浅色模式",
+ "description": "The name for the light color mode"
+ },
+ "theme.docs.breadcrumbs.navAriaLabel": {
+ "message": "页面路径",
+ "description": "The ARIA label for the breadcrumbs"
+ },
+ "theme.docs.DocCard.categoryDescription.plurals": {
+ "message": "{count} 个项目",
+ "description": "The default description for a category card in the generated index about how many items this category includes"
+ },
+ "theme.docs.paginator.navAriaLabel": {
+ "message": "文件选项卡",
+ "description": "The ARIA label for the docs pagination"
+ },
+ "theme.docs.paginator.previous": {
+ "message": "上一页",
+ "description": "The label used to navigate to the previous doc"
+ },
+ "theme.docs.paginator.next": {
+ "message": "下一页",
+ "description": "The label used to navigate to the next doc"
+ },
+ "theme.docs.tagDocListPageTitle.nDocsTagged": {
+ "message": "{count} 篇文档带有标签",
+ "description": "Pluralized label for \"{count} docs tagged\". Use as much plural forms (separated by \"|\") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)"
+ },
+ "theme.docs.tagDocListPageTitle": {
+ "message": "{nDocsTagged}「{tagName}」",
+ "description": "The title of the page for a docs tag"
+ },
+ "theme.docs.versionBadge.label": {
+ "message": "版本:{versionLabel}"
+ },
+ "theme.docs.versions.unreleasedVersionLabel": {
+ "message": "此为 {siteTitle} {versionLabel} 版尚未发行的文档。",
+ "description": "The label used to tell the user that he's browsing an unreleased doc version"
+ },
+ "theme.docs.versions.unmaintainedVersionLabel": {
+ "message": "此为 {siteTitle} {versionLabel} 版的文档,现已不再积极维护。",
+ "description": "The label used to tell the user that he's browsing an unmaintained doc version"
+ },
+ "theme.docs.versions.latestVersionSuggestionLabel": {
+ "message": "最新的文档请参阅 {latestVersionLink} ({versionLabel})。",
+ "description": "The label used to tell the user to check the latest version"
+ },
+ "theme.docs.versions.latestVersionLinkLabel": {
+ "message": "最新版本",
+ "description": "The label used for the latest version suggestion link label"
+ },
+ "theme.common.editThisPage": {
+ "message": "编辑此页",
+ "description": "The link label to edit the current page"
+ },
+ "theme.common.headingLinkTitle": {
+ "message": "{heading}的直接链接",
+ "description": "Title for link to heading"
+ },
+ "theme.lastUpdated.atDate": {
+ "message": "于 {date} ",
+ "description": "The words used to describe on which date a page has been last updated"
+ },
+ "theme.lastUpdated.byUser": {
+ "message": "由 {user} ",
+ "description": "The words used to describe by who the page has been last updated"
+ },
+ "theme.lastUpdated.lastUpdatedAtBy": {
+ "message": "最后{byUser}{atDate}更新",
+ "description": "The sentence used to display when a page has been last updated, and by who"
+ },
+ "theme.navbar.mobileVersionsDropdown.label": {
+ "message": "选择版本",
+ "description": "The label for the navbar versions dropdown on mobile view"
+ },
+ "theme.NotFound.title": {
+ "message": "找不到页面",
+ "description": "The title of the 404 page"
+ },
+ "theme.tags.tagsListLabel": {
+ "message": "标签:",
+ "description": "The label alongside a tag list"
+ },
+ "theme.admonition.caution": {
+ "message": "警告",
+ "description": "The default label used for the Caution admonition (:::caution)"
+ },
+ "theme.admonition.danger": {
+ "message": "危险",
+ "description": "The default label used for the Danger admonition (:::danger)"
+ },
+ "theme.admonition.info": {
+ "message": "信息",
+ "description": "The default label used for the Info admonition (:::info)"
+ },
+ "theme.admonition.note": {
+ "message": "备注",
+ "description": "The default label used for the Note admonition (:::note)"
+ },
+ "theme.admonition.tip": {
+ "message": "提示",
+ "description": "The default label used for the Tip admonition (:::tip)"
+ },
+ "theme.admonition.warning": {
+ "message": "注意",
+ "description": "The default label used for the Warning admonition (:::warning)"
+ },
+ "theme.AnnouncementBar.closeButtonAriaLabel": {
+ "message": "关闭",
+ "description": "The ARIA label for close button of announcement bar"
+ },
+ "theme.blog.sidebar.navAriaLabel": {
+ "message": "最近博文导航",
+ "description": "The ARIA label for recent posts in the blog sidebar"
+ },
+ "theme.CodeBlock.copied": {
+ "message": "复制成功",
+ "description": "The copied button label on code blocks"
+ },
+ "theme.CodeBlock.copyButtonAriaLabel": {
+ "message": "复制代码到剪贴板",
+ "description": "The ARIA label for copy code blocks button"
+ },
+ "theme.CodeBlock.copy": {
+ "message": "复制",
+ "description": "The copy button label on code blocks"
+ },
+ "theme.CodeBlock.wordWrapToggle": {
+ "message": "切换自动换行",
+ "description": "The title attribute for toggle word wrapping button of code block lines"
+ },
+ "theme.DocSidebarItem.expandCategoryAriaLabel": {
+ "message": "展开侧边栏分类 '{label}'",
+ "description": "The ARIA label to expand the sidebar category"
+ },
+ "theme.DocSidebarItem.collapseCategoryAriaLabel": {
+ "message": "折叠侧边栏分类 '{label}'",
+ "description": "The ARIA label to collapse the sidebar category"
+ },
+ "theme.NavBar.navAriaLabel": {
+ "message": "主导航",
+ "description": "The ARIA label for the main navigation"
+ },
+ "theme.TOCCollapsible.toggleButtonLabel": {
+ "message": "本页总览",
+ "description": "The label used by the button on the collapsible TOC component"
+ },
+ "theme.NotFound.p1": {
+ "message": "我们找不到您要找的页面。",
+ "description": "The first paragraph of the 404 page"
+ },
+ "theme.NotFound.p2": {
+ "message": "请联系原始链接来源网站的所有者,并告知他们链接已损坏。",
+ "description": "The 2nd paragraph of the 404 page"
+ },
+ "theme.navbar.mobileLanguageDropdown.label": {
+ "message": "选择语言",
+ "description": "The label for the mobile language switcher dropdown"
+ },
+ "theme.blog.post.readMore": {
+ "message": "阅读更多",
+ "description": "The label used in blog post item excerpts to link to full blog posts"
+ },
+ "theme.blog.post.readMoreLabel": {
+ "message": "阅读 {title} 的全文",
+ "description": "The ARIA label for the link to full blog posts from excerpts"
+ },
+ "theme.blog.post.readingTime.plurals": {
+ "message": "阅读需 {readingTime} 分钟",
+ "description": "Pluralized label for \"{readingTime} min read\". Use as much plural forms (separated by \"|\") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)"
+ },
+ "theme.docs.breadcrumbs.home": {
+ "message": "主页面",
+ "description": "The ARIA label for the home page in the breadcrumbs"
+ },
+ "theme.docs.sidebar.navAriaLabel": {
+ "message": "文档侧边栏",
+ "description": "The ARIA label for the sidebar navigation"
+ },
+ "theme.docs.sidebar.collapseButtonTitle": {
+ "message": "收起侧边栏",
+ "description": "The title attribute for collapse button of doc sidebar"
+ },
+ "theme.docs.sidebar.collapseButtonAriaLabel": {
+ "message": "收起侧边栏",
+ "description": "The title attribute for collapse button of doc sidebar"
+ },
+ "theme.docs.sidebar.closeSidebarButtonAriaLabel": {
+ "message": "关闭导航栏",
+ "description": "The ARIA label for close button of mobile sidebar"
+ },
+ "theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel": {
+ "message": "← 回到主菜单",
+ "description": "The label of the back button to return to main menu, inside the mobile navbar sidebar secondary menu (notably used to display the docs sidebar)"
+ },
+ "theme.docs.sidebar.toggleSidebarButtonAriaLabel": {
+ "message": "切换导航栏",
+ "description": "The ARIA label for hamburger menu button of mobile navigation"
+ },
+ "theme.docs.sidebar.expandButtonTitle": {
+ "message": "展开侧边栏",
+ "description": "The ARIA label and title attribute for expand button of doc sidebar"
+ },
+ "theme.docs.sidebar.expandButtonAriaLabel": {
+ "message": "展开侧边栏",
+ "description": "The ARIA label and title attribute for expand button of doc sidebar"
+ },
+ "theme.SearchBar.seeAll": {
+ "message": "查看全部 {count} 个结果"
+ },
+ "theme.SearchPage.documentsFound.plurals": {
+ "message": "找到 {count} 份文件",
+ "description": "Pluralized label for \"{count} documents found\". Use as much plural forms (separated by \"|\") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)"
+ },
+ "theme.SearchPage.existingResultsTitle": {
+ "message": "「{query}」的搜索结果",
+ "description": "The search page title for non-empty query"
+ },
+ "theme.SearchPage.emptyResultsTitle": {
+ "message": "在文档中搜索",
+ "description": "The search page title for empty query"
+ },
+ "theme.SearchPage.inputPlaceholder": {
+ "message": "在此输入搜索字词",
+ "description": "The placeholder for search page input"
+ },
+ "theme.SearchPage.inputLabel": {
+ "message": "搜索",
+ "description": "The ARIA label for search page input"
+ },
+ "theme.SearchPage.algoliaLabel": {
+ "message": "通过 Algolia 搜索",
+ "description": "The ARIA label for Algolia mention"
+ },
+ "theme.SearchPage.noResultsText": {
+ "message": "未找到任何结果",
+ "description": "The paragraph for empty search result"
+ },
+ "theme.SearchPage.fetchingNewResults": {
+ "message": "正在获取新的搜索结果...",
+ "description": "The paragraph for fetching new search results"
+ },
+ "theme.SearchBar.label": {
+ "message": "搜索",
+ "description": "The ARIA label and placeholder for search button"
+ },
+ "theme.SearchModal.searchBox.resetButtonTitle": {
+ "message": "清除查询",
+ "description": "The label and ARIA label for search box reset button"
+ },
+ "theme.SearchModal.searchBox.cancelButtonText": {
+ "message": "取消",
+ "description": "The label and ARIA label for search box cancel button"
+ },
+ "theme.SearchModal.startScreen.recentSearchesTitle": {
+ "message": "最近搜索",
+ "description": "The title for recent searches"
+ },
+ "theme.SearchModal.startScreen.noRecentSearchesText": {
+ "message": "没有最近搜索",
+ "description": "The text when no recent searches"
+ },
+ "theme.SearchModal.startScreen.saveRecentSearchButtonTitle": {
+ "message": "保存这个搜索",
+ "description": "The label for save recent search button"
+ },
+ "theme.SearchModal.startScreen.removeRecentSearchButtonTitle": {
+ "message": "从历史记录中删除这个搜索",
+ "description": "The label for remove recent search button"
+ },
+ "theme.SearchModal.startScreen.favoriteSearchesTitle": {
+ "message": "收藏",
+ "description": "The title for favorite searches"
+ },
+ "theme.SearchModal.startScreen.removeFavoriteSearchButtonTitle": {
+ "message": "从收藏列表中删除这个搜索",
+ "description": "The label for remove favorite search button"
+ },
+ "theme.SearchModal.errorScreen.titleText": {
+ "message": "无法获取结果",
+ "description": "The title for error screen of search modal"
+ },
+ "theme.SearchModal.errorScreen.helpText": {
+ "message": "你可能需要检查网络连接。",
+ "description": "The help text for error screen of search modal"
+ },
+ "theme.SearchModal.footer.selectText": {
+ "message": "选中",
+ "description": "The explanatory text of the action for the enter key"
+ },
+ "theme.SearchModal.footer.selectKeyAriaLabel": {
+ "message": "Enter 键",
+ "description": "The ARIA label for the Enter key button that makes the selection"
+ },
+ "theme.SearchModal.footer.navigateText": {
+ "message": "导航",
+ "description": "The explanatory text of the action for the Arrow up and Arrow down key"
+ },
+ "theme.SearchModal.footer.navigateUpKeyAriaLabel": {
+ "message": "向上键",
+ "description": "The ARIA label for the Arrow up key button that makes the navigation"
+ },
+ "theme.SearchModal.footer.navigateDownKeyAriaLabel": {
+ "message": "向下键",
+ "description": "The ARIA label for the Arrow down key button that makes the navigation"
+ },
+ "theme.SearchModal.footer.closeText": {
+ "message": "关闭",
+ "description": "The explanatory text of the action for Escape key"
+ },
+ "theme.SearchModal.footer.closeKeyAriaLabel": {
+ "message": "Esc 键",
+ "description": "The ARIA label for the Escape key button that close the modal"
+ },
+ "theme.SearchModal.footer.searchByText": {
+ "message": "搜索提供",
+ "description": "The text explain that the search is making by Algolia"
+ },
+ "theme.SearchModal.noResultsScreen.noResultsText": {
+ "message": "没有结果:",
+ "description": "The text explains that there are no results for the following search"
+ },
+ "theme.SearchModal.noResultsScreen.suggestedQueryText": {
+ "message": "试试搜索",
+ "description": "The text for the suggested query when no results are found for the following search"
+ },
+ "theme.SearchModal.noResultsScreen.reportMissingResultsText": {
+ "message": "认为这个查询应该有结果?",
+ "description": "The text for the question where the user thinks there are missing results"
+ },
+ "theme.SearchModal.noResultsScreen.reportMissingResultsLinkText": {
+ "message": "请告知我们。",
+ "description": "The text for the link to report missing results"
+ },
+ "theme.SearchModal.placeholder": {
+ "message": "搜索文档",
+ "description": "The placeholder of the input of the DocSearch pop-up modal"
+ },
+ "theme.ErrorPageContent.tryAgain": {
+ "message": "重试",
+ "description": "The label of the button to try again rendering when the React error boundary captures an error"
+ },
+ "theme.common.skipToMainContent": {
+ "message": "跳到主要内容",
+ "description": "The skip to content label used for accessibility, allowing to rapidly navigate to main content with keyboard tab/enter navigation"
+ },
+ "theme.tags.tagsPageTitle": {
+ "message": "标签",
+ "description": "The title of the tag list page"
+ },
+ "theme.unlistedContent.title": {
+ "message": "未列出页",
+ "description": "The unlisted content banner title"
+ },
+ "theme.unlistedContent.message": {
+ "message": "此页面未列出。搜索引擎不会对其索引,只有拥有直接链接的用户才能访问。",
+ "description": "The unlisted content banner message"
+ },
+ "hero.title": {
+ "message": "开源 CLI 框架",
+ "description": "The homepage hero title"
+ },
+ "hero.subtitle": {
+ "message": "创建用户喜欢的命令行工具",
+ "description": "The homepage hero subtitle"
+ },
+ "row.desc": {
+ "message": "oclif 是一个开源框架,用于在 Node.js 和 TypeScript 中构建命令行接口(CLI)。创建带有多个标志的 CLI 或具有子命令的高级 CLI。oclif 使您很容易为您的公司、服务或您自己的开发需求构建 CLI。",
+ "description": "The homepage description"
+ },
+ "row.button": {
+ "message": "开始使用 →",
+ "description": "The homepage button"
+ },
+ "feature_1.title": {
+ "message": "整装待发",
+ "description": "The title of the first feature"
+ },
+ "feature_1.desc": {
+ "message": "搭建一个功能齐全的 CLI,以便快速入门。Oclif 将我们多年的经验打包成开箱即用的功能,用于参数解析、命令测试和 CLI 特性的自动文档化。",
+ "description": "The description of the first feature"
+ },
+ "feature_2.title": {
+ "message": "开源",
+ "description": "The title of the second feature"
+ },
+ "feature_2.desc": {
+ "message": "Oclif 是{linkString}的,可以自由使用或修改。我们认为你也会喜欢它,你也可以帮助它变得更好。",
+ "description": "The description of the second feature"
+ },
+ "feature_2.desc.link": {
+ "message": "开源",
+ "description": "open source"
+ },
+ "feature_3.title": {
+ "message": "可扩展",
+ "description": "The title of the Third feature"
+ },
+ "feature_3.desc": {
+ "message": "你或你的用户可以使用插件轻松地扩展 CLI 功能以满足自定义需求。插件是模块化的、可共享的,鼓励重用。",
+ "description": "The description of the Third feature"
+ },
+ "feature_4.title": {
+ "message": "值得信赖",
+ "description": "The title of the Fourth feature"
+ },
+ "feature_4.desc": {
+ "message": "Oclif 被活跃地用于构建 {Heroku} 和 {Salesforce},每天为开发人员提供数以百万计的交互。",
+ "description": "The description of the Fourth feature"
+ },
+ "footer.title": {
+ "message": "使用 {logoImg} 构建 CLI",
+ "description": "The title of the footer"
+ },
+ "footer.desc": {
+ "message": "使用 oclif,您可以为企业、开源项目或自己的开发工作流程构建命令行工具。看看别人都做了些什么。",
+ "description": "The description of the footer"
+ }
+}
diff --git a/website/i18n/zh/docusaurus-plugin-content-blog/2018-03-20-introducing-oclif.md b/website/i18n/zh/docusaurus-plugin-content-blog/2018-03-20-introducing-oclif.md
new file mode 100644
index 00000000..7010518c
--- /dev/null
+++ b/website/i18n/zh/docusaurus-plugin-content-blog/2018-03-20-introducing-oclif.md
@@ -0,0 +1,10 @@
+---
+author: Jeff Dickey
+title: 介绍 oclif
+---
+
+![Introducing oclif](/img/2018-03-20-introducing-oclif/header.png)
+
+Coding for the browser takes serious time. You need to deal with front-end JS, CSS, design, product, and a ton more. On the other hand, building for a CLI takes a fraction of the effort. This makes CLIs particularly great for prototyping out new functionality, offering admin/internal tools, or power-user functionality.
+
+Read More
diff --git a/website/i18n/zh/docusaurus-plugin-content-blog/2019-02-20-cli-flags-explained.md b/website/i18n/zh/docusaurus-plugin-content-blog/2019-02-20-cli-flags-explained.md
new file mode 100644
index 00000000..fb9efbd2
--- /dev/null
+++ b/website/i18n/zh/docusaurus-plugin-content-blog/2019-02-20-cli-flags-explained.md
@@ -0,0 +1,162 @@
+---
+author: Casey Watts and Jeff Dickey
+title: 解释 CLI 标志
+---
+
+`oclif` makes it easy to create a command line interface (CLI) in node. Most commands have **parameters** — also known as "flags", "args", and sometimes "options". This blog post explains what these parameters are and when to use them. We also have a new feature that makes it easier for users to detect typos when using parameters.
+
+_Note the following describes GNU-style flags. Not all CLIs follow this convention, but it is the most commonly used._
+
+## Parts of Speech
+
+Any command line interface command has a few standard "parts of speech". As a user of CLI tools, knowing these parts of speech can help you make fewer typos. It can also help you understand complex commands other people share with you more quickly. If you are designing a CLI tool it is even more important to understand these parts of speech, so you can come up with the most ergonomic interface for your users.
+
+
+Of the many ways you can pass data to a CLI command, three of them are **parameters** that are always to the "right" of the command. The three types of parameters are **argument**, **short flag**, and **long flag**.
+
+### Example `ls`
+One of the most common and simplest unix commands is `ls` which "lists" the contents of a directory.
+
+#### command
+
+```
+ls
+```
+
+This command `ls` works on its own, as a standalone **command**. Without any parameters this command will list the contents of the current folder, using an implied `.` directory.
+
+#### argument
+
+```
+ls .
+ls ~/code/some-repo-name
+```
+
+If you pass a command **argument** to this command, like the directory name `.` (current folder) or `~/code/some-repo-name`, it will list the contents of that directory instead.
+
+An argument is anything to the right of a command that is not a flag. An argument can come before or after flags.
+
+#### Long flag
+To list additional files that are normally hidden (like `~/.bashrc`), you can use a flag on the `ls` command. `ls --all` is the **long flag** form. A long flag always uses a double dash, and it is always represented by multiple characters.
+
+```
+ls --all
+ls . --all
+```
+
+#### Short flag
+
+There is also a **short flag** form of this flag: `ls -a`. The `a` is short for `all` in this case. A short flag always uses a single dash, and it is always represented by a single letter.
+
+```
+ls -a
+ls . -a
+```
+
+Short flags can **stack** too, so you don't need a separate dash for each one. Order does not matter for these, unless passing a flag argument.
+
+```
+ls -la
+```
+
+#### Flag arguments
+Many flags accept an **option**, which is a "flag argument" (as opposed to a "command argument"). In general a command's parameters can be in any order, but flags that accept options must have the option directly after the flag.
+
+For an example, here the `-x` flag does not accept an option but the `-f` flag does. `archive.tar` is the option being passed to `-f`.
+
+```
+tar -x -f archive.tar
+tar -xf archive.tar
+```
+
+A flag and its option can be separated by a space ` ` or an equals sign `=`. Interestingly, short flags (but not long flags) can even skip the space, although many people find it much easier to read with the space or equals sign.
+
+These three are all valid and equivalent:
+
+```
+tar -f archive.tar
+tar -f=archive.tar
+tar -farchive.tar
+```
+
+Long flags must have a space or equals sign to separate the flag from its option.
+
+```
+git log --pretty=oneline
+git log --pretty oneline
+```
+
+## Other Ways of Passing Data
+
+We've covered **parameters**, which are **arguments**, **short flags** and **long flags**. There are two other ways to pass data to a command: **environment variables** ("env vars"), or **standard input** ("stdin"). These won't be covered in this blog post.
+
+
+## Designing a Command
+
+Scenario: we want to design an oclif command that echos an input like "Casey", and returns "hi, Casey!". There are many ways the user could pass this in, and here we show an example of each type of input.
+
+### argument
+
+```
+greet-me Casey
+```
+
+### short flag with argument
+
+```
+greet-me -n Casey
+greet-me -n=Casey
+greet-me -nCasey
+```
+
+### long flag with argument
+
+```
+greet-me --name=Casey
+greet-me --name Casey
+```
+
+### environment variable
+
+```
+NAME=Casey greet-me
+```
+
+### standard input
+
+```
+echo "Casey" | greet-me
+```
+
+## Command ergonomics
+
+### Short flag vs long flag
+Many CLI commands allow for both long flag and short flag forms. In the Heroku CLI every flag has at least a long flag form and roughly half of the flags also have a short flag form.
+
+The long flag form is easier to read, but takes more characters to type. It is often most useful when you want someone to understand a particular command statement quickly and easily, such as in a README.
+
+The short flag form is quicker to type, and is often better for frequently used commands. Short flags are especially useful when stacking short flags together.
+
+
+
diff --git a/website/i18n/zh/docusaurus-plugin-content-blog/2019-09-16-oclifconf-recap.md b/website/i18n/zh/docusaurus-plugin-content-blog/2019-09-16-oclifconf-recap.md
new file mode 100644
index 00000000..1dd8f6db
--- /dev/null
+++ b/website/i18n/zh/docusaurus-plugin-content-blog/2019-09-16-oclifconf-recap.md
@@ -0,0 +1,43 @@
+---
+title: "oclifconf 2019: 扼要重述"
+---
+
+In May, Heroku and Salesforce Open Source organized [oclifconf](https://oclif.io/conf), a conference for developers & product managers building CLI tools on top of [the open source oclif framework](https://github.com/oclif/oclif). The speakers came from various tech companies, such as Adobe, Netlify, and Apollo, who have already built amazing CLI experiences. The topics covered everything from the incredible capabilities oclif has unlocked, to the community-built plugins extending its functionality, and even what the behavior of an adaptive CLI tool might look like.
+
+Below is a listing of all of the talks from the event, along with a short summary. Enjoy!
+
+## The future of oclif by Jeff Dickey
+
+
+
+In its relatively short lifetime, oclif has already inspired many developers and companies to adopt its framework as a means for implementing their own command-line tooling. In this talk, Jeff Dickey, an oclif founding team member, recaps the project's history and inspiration. He also looks towards the future and outlines some features and improvements that the tool could adapt. This isn't so much a definitive roadmap of where oclif is headed, but rather, a call to inspiration for developers eager to contribute! And if you are interested in contributing, check out the [open issues](https://github.com/oclif/oclif/issues) in the oclif GitHub repo and come say "Hello!" on [Spectrum Chat](https://spectrum.chat/oclif).
+
+## Open Source Citizenship by Josh Simmons
+
+
+
+When it comes to open source, it's more than just individuals now. More and more frequently, large corporations are contributing to projects by donating to contributors, sponsoring events, or upstreaming contributions. But keeping open source projects and communities healthy requires more than just money and brainpower. Josh Simmons surveyed multiple open source communities and relays his findings as to what help maintainers and contributors actually need in this talk.
+
+## Building an enterprise-grade CLI with oclif by Thomas Dvornik
+
+
+
+Security and performance are all about trust. While oclif is an extremely extensible framework for building CLI tooling, there are additional requirements to fulfill for enterprise businesses to adopt it that might not be necessary for individual developers. Thomas Dvornik outlines what he and his colleagues at Salesforce have implemented as plugins to oclif to satisfy these needs, including encrypted OAuth, plugin signing, lazy loading dependencies, synchronizing weekly releases and deprecations across dozens of repositories, and establishing cross-team coding and documentation standards.
+
+## How Adobe I/O built an extensible CLI with oclif by Jesse MacFadyen
+
+
+
+Perhaps oclif's most appealing feature is its support for plugins. In Cordova's case, they've created a sophisticated telemetry system that helps Adobe developers see which commands users are using--and reports on which ones are erroring out. By embedding a feedback system into the tool, users are even able to quickly send their suggestions to a form, without ever leaving the terminal. Jesse MacFadyen demonstrates how oclif's plugin system can work beyond simply executing commands.
+
+## Integrating oclif with GraphQL and Apollo by Evans Hauser
+
+
+
+For Evans Hauser and the team at Apollo, oclif is best thought of as "React for the CLI." As a client paired with a strongly-typed API contract to a server, it can deliver structured and consistent commands to retrieve external data. What better mechanism to use for this transfer than GraphQL, a framework which empowers the client to ask precisely for the data it needs, and nothing more?
+
+## Adaptive Intent-based CLI State Machines by Shawn Wang
+
+
+
+In designing oclif, [Jeff Dickey wrote out 12 CLI factors to keep in mind](https://medium.com/@jdxcode/12-factor-cli-apps-dd3c227a0e46). In this talk, Shawn Wang outlines a 13th: state. State is hard, because it depends on context, and context depends on understanding what a user intends to do, not what they are asking. Shawn is working towards enabling oclif to better understand the commands a user has entered, so that it can predict and interpret future commands that might be entered next. This would enable CLI tools to not just interpret a users' commands, but to also interpret their intent.
diff --git a/website/i18n/zh/docusaurus-plugin-content-blog/2019-10-31-oclif-node-updates.md b/website/i18n/zh/docusaurus-plugin-content-blog/2019-10-31-oclif-node-updates.md
new file mode 100644
index 00000000..5372f4c6
--- /dev/null
+++ b/website/i18n/zh/docusaurus-plugin-content-blog/2019-10-31-oclif-node-updates.md
@@ -0,0 +1,67 @@
+---
+title: oclif 的 Current Node 版本支持
+---
+
+To maintain a healthy project trajectory, oclif follows and supports [Node Active LTS release](https://nodejs.org/en/about/releases/), currently Node 10 & Node 12. This means ensuring that oclif continues to play nice with coming Active LTS Node versions and other packages in the ecosystem. Moving forward also means leaving older versions behind. Starting in 2020, Node will stop maintaining [Node 8](https://github.com/nodejs/Release#release-schedule) and it is our intent at that time to also follow suit. Let’s take a look at a few ways we will be supporting these changes.
+
+## CI Environments
+
+CLIs created with the oclif cli going forward will be generated with a CircleCI configuration with Node 10 & 12 and an Appveyor configuration using Node 10. We have also added Node latest to CircleCi to be an early warning detection against coming Node changes (Node latest is managed by CircleCI).
+
+We have already updated every oclif repo's CI configs to reflect this.
+
+If your existing CLI uses either Appveyor or CircleCI you can update your config files also, like so:
+
+### .circleci/config.yml
+
+Your CircleCI config should contain a `node-latest` job, aliased as `test`. From this, there should be two extensions of this job for the Active LTS Node versions, Node 10 and Node 12.
+
+```
+ node-10:
+ <<: *node-latest
+ docker:
+ - image: node:10
+ node-12:
+ <<: *node-latest
+ docker:
+ - image: node:12
+```
+
+Notice that these declarations only change the Docker Node images used to run that job.
+
+Additionally, the jobs listed within workflows must also be updated to reflect our changes in configuration:
+
+```
+ jobs:
+ - node-latest
+ - node-10
+ - node-12
+```
+
+### appveyor.yml
+
+For appveyor we are currently only testing the oldest Active LTS Node version, Node 10. Update the `nodejs_version` proppert in your appveyor.yml file to reflect this.
+
+```
+environment:
+ nodejs_version: "10"
+```
+
+
+## Deprecating Node 8 & Updating packge.json engines
+
+In Jan 2020, Node will end its Node 8 maintenance. We will follow suit by setting the package.json engine property in oclif packages to `>=10` and bumping the package's major versions.
+
+Depending on how you ship your CLI you may wish to also bump the engines version in your CLI's package.json. You can read more about the implications of the engines property configuration in the [npm documentation](https://docs.npmjs.com/files/package.json#engines).
+
+Also consider distributing your CLI with [its own Node version](https://oclif.io/docs/releasing#standalone-tarballs).
+
+## Packaged Node Version
+
+When using dev-cli to pack your CLI it will use the Node version as specified in your package.json under the `oclif.update.node.version` property. This value should reflect an Active LTS Node version (dev-cli does not currently enforce versions).
+
+## Supporting the future
+
+As a community we may discover bumps along the way as we upgrade. If you notice something related to oclif please feel free to open an issue or submit a pull request under the relevant oclif package within [the org](https://github.com/oclif).
+
+We look forward to using the latest from Node and the community and keeping oclif healthy along the way.
diff --git a/website/i18n/zh/docusaurus-plugin-content-blog/2019-12-05-oclif-eslint-migration.md b/website/i18n/zh/docusaurus-plugin-content-blog/2019-12-05-oclif-eslint-migration.md
new file mode 100644
index 00000000..f2713882
--- /dev/null
+++ b/website/i18n/zh/docusaurus-plugin-content-blog/2019-12-05-oclif-eslint-migration.md
@@ -0,0 +1,71 @@
+---
+title: oclif 从 TSLint 到 ESLint 的迁移
+---
+
+Back in February of this year, plans were announced to [deprecate TSLint](https://github.com/palantir/tslint/issues/4534) in favor of ESLint. TSLint's goal has become to work toward a “unified developer experience” by supporting ESLint development going forward.
+
+
+
+## What has changed in oclif
+
+To keep inline with the community, oclif has transitioned to ESLint for all our core libraries as well as all our official plugins.
+
+Starting in v1.15.x, oclif will now optionally generate projects with ESLint for both TypeScript and JavaScript CLI’s.
+
+ESLint does require Node to be on stable LTS version, at the time of writing, Node 8.10.x, Node 10.13.x & Node 12.x.x.
+
+## How does this affect you
+
+Existing CLI’s are unchanged, but any newly generated CLI's will only give the option of using ESLint. If you are running tslint in your CLI, we recommend you switch to ESLint as well.
+
+In migrating our projects we took the following steps (for an example of these changes see this [pull request](https://github.com/oclif/githubcli/pull/10)).
+
+1. Install eslint
+
+ `$ yarn add eslint eslint-config-oclif eslint-config-oclif-typescript --dev`
+2. Add eslint related files
+```shell
+$ echo '{
+ "extends": [
+ "oclif",
+ "oclif-typescript"
+ ],
+ "rules": {
+ }
+}' > .eslintrc
+```
+3. Remove tslint and related packages
+
+ `$ yarn remove @oclif/tslint tslint`
+4. Remove tslint related configuration files
+
+ `$ rm tslint.json`
+5. Change lint script in our package.json from something like:
+
+ `"lint": "tsc -p test --noEmit && tslint -p test -t stylish"`
+
+ to
+
+ `"lint": "eslint . --ext .ts --config .eslintrc"`
+
+To preserve the test compile (tsc -p test --noEmit) we also made the following updates to our scripts:
+
+`"pretest": "tsc -p test --noEmit"`
+
+In some cases we had our posttest duplicating the same steps as our lint script so it’s cleaner to have it reference the lint job directly with:
+
+`"posttest": "yarn lint"`
+
+
+6. Run `yarn lint --fix`. This attempts to auto-fix any linting violations automatically. In the case an auto-fix isn’t available it should be fixed manually or ignored (see the [eslint configuration doc](https://eslint.org/docs/user-guide/configuring) for more information)
+7. Do a search in the codebase for `tslint` and remove any unnecessary tslint disabling comments, like:
+```javascript
+/* tslint:disable:object-literal-sort-keys */
+```
+
+
+If you are on a version of Node that is not supported by ESLint, you will also need to update your Node engine. ESLint supports Node 8, 10, and 12 so you should upgrade to the most recent Node version compatible with your CLI and also supported by ESLint (see ESLint's [Installation and Usage](https://www.npmjs.com/package/eslint#installation-and-usage) instructions).
+
+## When will this take effect
+
+These changes have taken effect in oclif v1.15.1. When you generate a new CLI or plugin it will now contain configuration for ESLint instead of TSLint.
diff --git a/website/i18n/zh/docusaurus-plugin-content-blog/2020-05-05-introducing-custom-help-classes.md b/website/i18n/zh/docusaurus-plugin-content-blog/2020-05-05-introducing-custom-help-classes.md
new file mode 100644
index 00000000..e8a2854a
--- /dev/null
+++ b/website/i18n/zh/docusaurus-plugin-content-blog/2020-05-05-introducing-custom-help-classes.md
@@ -0,0 +1,60 @@
+---
+title: 在 oclif 中自定义帮助
+---
+
+Out of the box oclif provides a great help experience for CLIs.
+
+But what if, as an oclif developer, you want to customize some or all of the output?
+
+You can now customize your CLI's help output by implementing the `HelpBase` abstract class.
+
+## Getting started with custom help
+
+If you have not done so yet, update `@oclif/core`.
+
+
+```
+$ yarn add --latest @oclif/core
+```
+
+To get started, first define the filepath to your help class in oclif's config in package.json. This is a relative path to the help class, without a file extension.
+
+For this example, the help class will be created in a file at "[project root]/src/help.ts".
+
+```
+{
+ // ...
+ "oclif": {
+ "helpClass": "./lib/help"
+ // ...
+ }
+ // ...
+}
+```
+
+From here there are two paths, implement the `HelpBase` abstract class yourself or overwrite the parts of the default `Help` class you want to customize (ex: how command usage is displayed). We recommend the latter approach but cover both in the new [Help Classes docs](/docs/help_classes).
+
+
+## Separating TOPICS & COMMANDS in the new default `Help` class
+
+Previously, topics and child commands were listed in help output under a single list heading called "COMMANDS". But we found this can be slightly confusing. Some topics are commands also (a.k.a. topic-commands) while others are simply organizational namespacing (and when ran just show their help).
+
+The new default `Help` class splits the list of children into distinct lists of "TOPICS" and "COMMANDS", with the possibility of an item appearing in both if it a topic-command. This makes it clearer what is expected to be ran - "COMMANDS" - and what is providing structure - "TOPICS" - when looking at the help output.
+
+```
+VERSION
+ plugin-help-example/0.0.0 darwin-x64 node-v12.12.0
+
+USAGE
+ $ plugin-help-example [COMMAND]
+
+TOPICS
+ topic this is a topic and has child topics or commands
+
+COMMANDS
+ hello describe the command here
+ help display help for plugin-help-example
+```
+
+We look forward to seeing what custom help features you implement in your oclif CLIs with this new feature!
+
diff --git a/website/i18n/zh/docusaurus-plugin-content-blog/2020-07-01-pretty-printable-errors.md b/website/i18n/zh/docusaurus-plugin-content-blog/2020-07-01-pretty-printable-errors.md
new file mode 100644
index 00000000..edbb1834
--- /dev/null
+++ b/website/i18n/zh/docusaurus-plugin-content-blog/2020-07-01-pretty-printable-errors.md
@@ -0,0 +1,28 @@
+---
+title: 漂亮的打印错误
+---
+
+Often CLIs are used as handy tools and when things go wrong it’s useful to have additional context. In oclif we have added a couple of additional properties that can show extra context to the users when an error is displayed. The `code`, `ref` and `suggestions` will now be displayed if they are included. This will work with an existing oclif CLI by adding the latest @oclif/errors and @oclif/core to the CLI's package.json dependencies.
+
+For example, using `this.error` with the additional properties:
+```js
+class TestError extends Command {
+ async run() {
+ this.error("An error has occurred!", {
+ code: "OCLIF_ERR",
+ ref: "https://oclif.io/docs/commands#thiserrormessage-string--error-options-code-string-exit-number",
+ suggestions: ["Use these extra properties to provide additional context"],
+ })
+ }
+}
+```
+
+would result with the following output:
+```text
+› Error: An error has occurred!
+› Code: OCLIF_ERR
+› Try this: Use these extra properties to provide additional context
+› Reference: https://oclif.io/docs/commands#thiserrormessage-string--error-options-code-string-exit-number
+```
+
+If these properties are not provided then nothing changes and the CLI will continue to display the single error message output as it did before. Additionally, as part of this exercise we’ve added documentation around [Error Handling in oclif](/docs/error_handling) which should come in handy if the need arises to extend oclif’s default handling of errors.
diff --git a/website/i18n/zh/docusaurus-plugin-content-blog/2020-08-26-summer-update.md b/website/i18n/zh/docusaurus-plugin-content-blog/2020-08-26-summer-update.md
new file mode 100644
index 00000000..90d58757
--- /dev/null
+++ b/website/i18n/zh/docusaurus-plugin-content-blog/2020-08-26-summer-update.md
@@ -0,0 +1,40 @@
+---
+title: oclif 2020 夏季更新
+---
+
+Hello oclif developers! We hope you are all doing well.
+
+Earlier this year, we started our planning for oclifconf v2 and, like all conference, had to change course. We opted not to hold a virtual conference, however, we wanted to take some time to highlight a few oclif features shipped this year.
+
+## Feature: Help templating
+
+One of the most requested features, help templating enables oclif developers to customize the help output for their CLI.
+
+Read [the announcement](/blog/2020/05/05/introducing-custom-help-classes).
+
+## Feature: Custom error delegation
+
+This feature both improved how oclif throws and handles errors and allows oclif developers to overwrite or interject in oclif’s error handling.
+
+Read [the announcement](/blog/2020/07/01/pretty-printable-errors).
+
+## Feature: postrun hooks
+
+We have added a new lifecycle event `postrun`. Your CLI can now run a hook after a command has ran.
+
+See our [hook documentation](/docs/hooks).
+
+## Feature: Root index command
+
+Previously, oclif would display CLI help if only the binary name with no command ID was invoked, oclif now supports a "root index" command. If present, a command defined at `src/commands/index.ts` will be run if no command ID is found.
+
+## 1 million weekly downloads
+
+While exact oclif usage metrics are hard to pin down, we use npm download statistics of oclif packages as a rough approximation. Earlier this year, oclif's command package hit 1 million weekly downloads for the first time!
+
+
+This year has been presented its challenges on everyone. We want to thank you, oclif developers, whom have taken the time to use and improve the oclif project. We look forward to seeing you all - in person - in the future!
+
+All our best,
+
+The oclif team
diff --git a/website/i18n/zh/docusaurus-plugin-content-blog/2021-03-01-introducing-oclif-core.md b/website/i18n/zh/docusaurus-plugin-content-blog/2021-03-01-introducing-oclif-core.md
new file mode 100644
index 00000000..7ddc6bf6
--- /dev/null
+++ b/website/i18n/zh/docusaurus-plugin-content-blog/2021-03-01-introducing-oclif-core.md
@@ -0,0 +1,55 @@
+---
+title: "介绍 @oclif/core"
+---
+Greetings!
+
+We hope this blog post finds you well.
+
+### Introducing...
+
+We are excited to announce the next iteration of the oclif project today: `@oclif/core`.
+
+We have learned a lot in the last three years of developing oclif, developing on oclif and supporting millions of command runs a day via Heroku and Salesforce CLIs.
+`@oclif/core` ("Core") simplifies the oclif development experience and introduces highly requested new features.
+
+Core combines the essential oclif packages into one "core" package, aptly named `@oclif/core`.
+
+Core also introduces:
+- A default command option
+- Colon or space command syntax
+- Async command parsing
+- Command piping to arguments
+
+With the introduction of default command functionality, Core simplifies the oclif project and removes the notion of single or multi command CLIs. Core CLIs can have 1 or many commands.
+
+Along with Core, we moved the oclif-dev CLI into the oclif CLI creating a single "utility" CLI. This CLI also introduces a new AWS S3 compatible publishing scheme.
+
+### What to expect in the near future
+
+Core is in pre-release beta and being actively developed for new internal Salesforce CLIs.
+
+Much documentation needs to be written in the coming months including migration paths. Migration onto Core should be as painless as possible with many exports remaining entirely unchanged. Look for forthcoming blog posts and documentation on [oclif.io](https://oclif.io).
+
+Early this summer, tentively June 1, we will release Core v1. Core's release will coincide with major bumps to many other oclif plugin packages. See the compatibility matrix below.
+
+At Core's v1 release, the current "main" oclif packages (namely: command, config, errors & parser) will go into maintenance mode until Jan 2022. They will receive _only_ bug and security fixes and they remain compatible with current versions of the oclif and oclif-dev CLIs. Afterwhich, they will be archived.
+
+Companioning Core, the next major release of the oclif CLI (literally `oclif@2`) will generate Core CLIs.
+
+### Going forward
+
+We are excited to release Core! We invite you to poke around the [Core repo](https://github.com/oclif/core). It may appear to be a big change but Core keeps what you already enjoy about oclif while reducing development complexity, project dependencies, package coupling and bundle size and introduces many requested features previously too prickly to weave into the current oclif architecture.
+
+Best,
+
+The oclif team
+
+#### Reference: Compatibility matrix
+
+| | oclif "v1" | oclif "Core" |
+| - | - | -|
+| Utility CLIs | oclif@\<2 @oclif/dev-cli@\<2 | oclif@>=2
+| Main packages | @oclif/core@\<2 @oclif/config@\<2 @oclif/errors@\<2 @oclif/parser@\<4 @oclif/plugin-help@\<4 | @oclif/core@>=1
+| Node LTS | Node v8-14 | Node v12+ |
+| TypeScript | typescript@\<4 | typescript@>=4 |
+| Main plugins | @oclif/plugin-autocomplete@\<1 @oclif/plugin-commands@\<2 @oclif/plugin-help@\<4 @oclif/plugin-not-found@\<2 @oclif/plugin-plugins@\<2 @oclif/plugin-update@\<2 plugin-warn-if-update-available@\<2 plugin-which@\<2 | @oclif/plugin-autocomplete@>=2 @oclif/plugin-commands@>=2 @oclif/plugin-help@>=4 @oclif/plugin-not-found@>=2 @oclif/plugin-plugins@>=2 @oclif/plugin-update@>=2 @oclif/plugin-warn-if-update-available@>=2 @oclif/plugin-which@>=2 |
diff --git a/website/i18n/zh/docusaurus-plugin-content-blog/2022-01-12-announcing-oclif-v2.md b/website/i18n/zh/docusaurus-plugin-content-blog/2022-01-12-announcing-oclif-v2.md
new file mode 100644
index 00000000..0f5ca994
--- /dev/null
+++ b/website/i18n/zh/docusaurus-plugin-content-blog/2022-01-12-announcing-oclif-v2.md
@@ -0,0 +1,109 @@
+---
+title: 发布 oclif v2!
+---
+
+Hello and happy new year! It's our great pleasure to announce that we have released oclif v2, which uses the new [@oclif/core](https://github.com/oclif/core) library! 🎉
+
+oclif v2 includes many changes that improve the experience of both creating and using an oclif CLI.
+
+Going forward, we don't plan to make any updates to oclif v1 and its corresponding libraries, except for critical security fixes. See the [compatibility matrix](#compatibility-matrix) for a list of these libraries. In order to give developers time to migrate from v1 to v2, we're not completely dropping support yet. But at some point in the future we'll archive the v1 repositories and deprecate their versions on npm.
+
+## What’s changing?
+
+### Repository Changes
+
+All repositories under the [oclif org](https://github.com/oclif/) now use `main` as their primary branch and `oclif-v1` as the legacy branch. The `main` branch corresponds to oclif v2 and the `oclif-v1` branch to oclif v1. If you find any repos that don’t have a `main` branch, you can safely assume that they're not used in oclif v2 and will be deprecated in the future.
+
+### Consolidating Tools & Libraries
+
+The [`oclif-dev`](https://github.com/oclif/dev-cli) CLI has now been incorporated into [`oclif`](https://github.com/oclif/oclif). You now no longer need to install a separate package to manage your entire CLI’s lifecycle.
+
+The following libraries have been consolidated under [`@oclif/core`](https://github.com/oclif/core) and will be deprecated at some point in the future. Read the [migration guide](https://github.com/oclif/core/blob/main/MIGRATION.md) to learn how to update your CLI or plugin to use the new core library.
+
+* `@oclif/command`
+* `@oclif/config`
+* `@oclif/error`
+* `@oclif/help`
+* `@oclif/parser`
+
+### No more single vs multi command CLIs
+
+There's only one "type" of oclif v2 CLI, but it can have as few or as many commands as a developer wants. As a result, there’s only one command to generate CLIs, `oclif generate`, as opposed to the old `oclif single` and `oclif multi` commands.
+
+### Node > 12
+
+To ensure oclif CLIs are as secure as possible, all v2 libraries and plugins support only Node 12 or higher as of now. Going forward, they'll support only Node Maintenance or higher, as defined by Node's release schedule here: https://nodejs.org/en/about/releases/.
+
+## What’s new?
+
+### New example CLI
+
+[`oclif-hello-world`](https://github.com/oclif/hello-world/) is our new example repo. This is also the repo that's [used as a template](https://github.com/oclif/oclif/blob/edc6616e51/src/generators/cli.ts#L74) when running `oclif generate` to create a new CLI. This repo will always be able to be referenced as an example of what an oclif v2 CLI should look like.
+
+### Spaced commands
+
+oclif CLIs can now use spaces, instead of colons, to separate topics and subcommands. To enable this feature, simply add `“topicSeparator": " "` to the oclif config in your package.json. See an example in our [example repo](https://github.com/oclif/hello-world/blob/main/package.json#L55).
+
+```
+// Old commands that use :
+$ mycli do:something
+```
+```
+// New spaced commands
+$ mycli do something
+```
+
+> Note: Spaced commands are backwards compatible. So if you enable spaced commands for your CLI, users will still be able to use `:` as a separator. This ensures that any existing scripts don't break.
+
+### New Help Output
+
+We’ve revamped the way command help is outputted to the terminal, making it both easier to implement and easier to read. See the difference between the old help output on the left and the new help output on the right in the screenshots below.
+
+
+
+
oclif v1
+
oclif v2
+
+
+
+
+
+
+
+Notice that there are new sections for flags and global flags, examples are displayed with better spacing, and there is a section at the bottom called Configuration Variables. This Configuration Variables section is not part of the new help by default. But we've added support for custom help sections, which is what the `sf` CLI uses to create the new section.
+
+### Async Command Parsing
+
+We’ve also improved the performance of new CLIs by rewriting how commands are parsed on initialization. The [new parser](https://github.com/oclif/core/blob/main/src/parser/parse.ts) is asynchronous, which makes CLIs with a lot of commands or installed plugins much faster.
+
+## What’s coming next?
+
+Part of our charter for the release of oclif v2 includes improving our engagement with the oclif community. We know that over the past couple of years we’ve reduced our involvement, and a lot of issues and PRs have languished in limbo. Hopefully you’ve already seen increased activity and responses from oclif maintainers recently, but if you haven’t, please don’t hesitate to ping us by tagging [@admins](https://github.com/orgs/oclif/teams/admins) in oclif repos.
+
+We also want to start interviewing members of the oclif community to acquire feedback and prioritize the features and fixes you deem most important!
+
+Best,
+
+The oclif team
+
+
+
+### Reference material
+
+#### Migration Guide
+
+This guide explains how to upgrade a CLI or plugin from the old oclif v1 libraries to the new `@oclif/core` library that oclif v2 uses.
+
+https://github.com/oclif/core/blob/main/MIGRATION.md
+
+#### Compatibility Matrix
+
+The following matrix shows how the v1 libraries and plugins relate to the new v2 ones. Use this matrix as a guide to know what to drop and which versions to switch when upgrading your plugins and CLIs to v2.
+
+| | oclif "v1" | oclif "v2" |
+| - | - | -|
+| Utility CLIs | oclif@\<2 @oclif/dev-cli@\<2 | oclif@>=2
+| Main packages | @oclif/command @oclif/config @oclif/errors @oclif/parser @oclif/plugin-help | @oclif/core@>=1
+| Node LTS | Node v8-14 | Node v12+ (at time of writing) |
+| TypeScript | typescript@\<4 | typescript@>=4 |
+| Main plugins | @oclif/plugin-autocomplete@\<1 @oclif/plugin-commands@\<2 @oclif/plugin-help@\<4 @oclif/plugin-not-found@\<2 @oclif/plugin-plugins@\<2 @oclif/plugin-update@\<2 plugin-warn-if-update-available@\<2 plugin-which@\<2 | @oclif/plugin-autocomplete@>=1 @oclif/plugin-commands@>=2 @oclif/plugin-help@>=4 @oclif/plugin-not-found@>=2 @oclif/plugin-plugins@>=2 @oclif/plugin-update@>=2 @oclif/plugin-warn-if-update-available@>=2 @oclif/plugin-which@>=2 |
diff --git a/website/i18n/zh/docusaurus-plugin-content-blog/2024-03-29-spring-update.md b/website/i18n/zh/docusaurus-plugin-content-blog/2024-03-29-spring-update.md
new file mode 100644
index 00000000..71a49815
--- /dev/null
+++ b/website/i18n/zh/docusaurus-plugin-content-blog/2024-03-29-spring-update.md
@@ -0,0 +1,57 @@
+---
+title: oclif 2024 春季更新
+---
+
+Hello oclif developers! It's been a while since we last uploaded a blog - and *a lot* has happened.
+
+We've been focusing on these high-level areas over the past couple of years:
+- Improving `@oclif/core`
+- ESM Support
+- Improving and revitalizing oclif.io
+- Re-engaging the oclif community
+
+## Improving `@oclif/core`
+
+Since we [announced `@oclif/core` over three years ago](/blog/2021/03/01/introducing-oclif-core), we've released two new major versions, each packed with lots of features that we're really excited about.
+
+Here are some of these changes:
+- Full support for ESM and interoperability with CommonJS (more on this topic below).
+- Configurable command discovery strategies that give you more control over how commands are loaded at runtime. Check out the [docs](/docs/command_discovery_strategies).
+- A new `preparse` hook that allows you to manipulate the provided arguments before they're parsed. Salesforce used this hook to [implement](https://github.com/salesforcecli/cli/pull/1536) a neat `--flags-dir` feature that translates local files into flags.
+- A new `Performance` class that you can use to track performance inside of `@oclif/core` and your own CLI or plugin. Check out the [docs](/docs/performance).
+- A new flag type, `Flags.option`, that lets you define a flag with a preset list of options. Typescript then uses the options to infer the flag's type.
+- Flags now have a `relationship` property that allows you to define more complex relationships between flags. Check out the [flags docs](/docs/flags) for more information.
+- Flags now have a `defaultHelp` property that allows you to set the human readable default value in the command help. This property is useful when your flag's `parse` method returns a complex type, such as an object or a class. Check out the [flags docs](/docs/flags) for more.
+- Commands now have a `hiddenAliases` property that allows you to define aliases that you want to hide from the user. The property is super helpful when you're trying to wean users off a deprecated command.
+- You can now use [bun](https://bun.sh/) or [tsx](https://www.npmjs.com/package/tsx) as dev runtimes (as opposed to node or ts-node).
+- A command's usage, args, and flags are now shown whenever a user forgets to provide a required arg or flag, or when they provided a non-existent flag.
+
+If you need help migrating to the latest version, head over to [core's README](https://github.com/oclif/core/?tab=readme-ov-file#-migrating) which has links to the migration guides. Feel free to open a new [discussion](https://github.com/oclif/core/discussions) if you need more hands-on help from us or the community.
+
+## ESM Support
+
+Version 3 of `@oclif/core` introduced full support for developing ESM plugins and CLIs. It also offered full support for interoperability between CommonJS and ESM plugins.
+
+Put more simply, you can now migrate your CLI to ESM while keeping individual plugins in CommonJS (or vice versa). The upgrade path is now much simpler for you. You also don't need to worry about any community plugins that have migrated to ESM before you did (such as all the `@oclif` plugins) or are staunchly sticking with CommonJS for the foreseeable future.
+
+Read more about this topic [here](/docs/esm).
+
+## Improving and Revitalizing oclif.io
+
+Another area of focus for us has been improving our documentation site, [oclif.io](htttps://oclif.io).
+
+While improving the quality and accuracy of the documentation was our priority, we also took the time to upgrade to the latest version of [docusaurus](https://docusaurus.io/). This new version gave our site a much-needed facelift, as well as cool new features such as dark mode and announcements.
+
+If you have any feedback or are running into issues, we want to hear about it. Just create an issue in the [oclif.io repo](https://github.com/oclif/oclif.github.io/issues).
+
+## Re-engaging the oclif Community
+
+Lastly, our biggest priority at the moment is to re-engage the oclif community. We understand how frustrating it has been over the years to see your issues and pull requests go unacknowledged. We apologize for not prioritizing the community, and are earnestly trying to make sure that every issue and pull request gets the attention it deserves going forward.
+
+We also opened up GitHub discussions for [@oclif/core](https://github.com/oclif/core/discussions) and the [oclif CLI](https://github.com/oclif/oclif/discussions), where you can now post your questions or ideas. We hope you take advantage of them, we love hearing from you!
+
+One last thing: we intend to publicly post our roadmap so you have more visibility into what we're working on. Stay tuned!
+
+All our best,
+
+The oclif team
diff --git a/website/i18n/zh/docusaurus-plugin-content-blog/options.json b/website/i18n/zh/docusaurus-plugin-content-blog/options.json
new file mode 100644
index 00000000..eff07af9
--- /dev/null
+++ b/website/i18n/zh/docusaurus-plugin-content-blog/options.json
@@ -0,0 +1,14 @@
+{
+ "title": {
+ "message": "oclif 博客",
+ "description": "The title for the blog used in SEO"
+ },
+ "description": {
+ "message": "阅读来自团队的 oclif 博客文章",
+ "description": "The description for the blog used in SEO"
+ },
+ "sidebar.title": {
+ "message": "所有文章",
+ "description": "The label for the left sidebar"
+ }
+}
diff --git a/website/i18n/zh/docusaurus-plugin-content-docs/current.json b/website/i18n/zh/docusaurus-plugin-content-docs/current.json
new file mode 100644
index 00000000..2a741861
--- /dev/null
+++ b/website/i18n/zh/docusaurus-plugin-content-docs/current.json
@@ -0,0 +1,26 @@
+{
+ "version.label": {
+ "message": "Next",
+ "description": "The label for version current"
+ },
+ "sidebar.docs.category.Getting Started": {
+ "message": "快速开始",
+ "description": "The label for category Getting Started in sidebar docs"
+ },
+ "sidebar.docs.category.Guides": {
+ "message": "指南",
+ "description": "The label for category Guides in sidebar docs"
+ },
+ "sidebar.docs.category.API Reference": {
+ "message": "API 参考",
+ "description": "The label for category API Reference in sidebar docs"
+ },
+ "sidebar.docs.category.Architecture": {
+ "message": "结构",
+ "description": "The label for category Architecture in sidebar docs"
+ },
+ "sidebar.docs.category.Also See": {
+ "message": "参见",
+ "description": "The label for category Also See in sidebar docs"
+ }
+}
diff --git a/website/i18n/zh/docusaurus-plugin-content-docs/current/aliases.md b/website/i18n/zh/docusaurus-plugin-content-docs/current/aliases.md
new file mode 100644
index 00000000..71acf65a
--- /dev/null
+++ b/website/i18n/zh/docusaurus-plugin-content-docs/current/aliases.md
@@ -0,0 +1,64 @@
+---
+title: 别名
+description: 为命令、标志和 bin 定义别名
+---
+
+## 命令别名
+
+别名允许你定义映射到命令的字符串。这个命令可以通过 `mycli config`、`mycli config:index` 或者 `mycli config:list` 来运行:
+
+```js
+import {Command, Flags} from '@oclif/core'
+
+export class ConfigIndex extends Command {
+ static aliases = ['config:index', 'config:list']
+}
+```
+
+默认情况下,别名会找到“真正的”命令并正常工作。如果你提供命令别名是为了向后兼容,但希望用户使用“真正的”命令,可将 `deprecateAliases` 设为 `true` ,以警告用户使用正确的名称。
+
+```js
+export class ConfigIndex extends Command {
+ static aliases = ['config:index', 'config:list']
+ static deprecateAliases = true
+}
+```
+
+## 标志别名
+
+与命令别名类似,但针对的是单个标志。你可以对名称和短字符设置别名,还可以在使用别名时发出警告。
+
+```js
+export class ConfigIndex extends Command {
+ static flags = {
+ 'new-name': Flags.boolean({
+ char: 'c',
+ aliases: ['old-name', 'o'],
+ deprecateAliases: true
+ })
+ }
+}
+
+```
+
+## Bin 别名
+
+创建一个能响应不同名称或“别名”的 CLI 非常简单,只需在 `binAliases` 中为 CLI 的 `oclif` 属性添加 `binAliases` 属性即可:
+
+```json
+{
+ "name": "mycli",
+ "version": "0.0.0",
+ "description": "My CLI",
+ "main": "bin/run.js",
+ "bin": {
+ "mycli": "./bin/run.js",
+ "mycli-alias": "./bin/run.js"
+ },
+ "oclif": {
+ "binAliases": ["mycli", "mycli-alias"]
+ }
+}
+```
+
+添加此属性后,你的 CLI 就能响应这两个名称中的任何一个,并在打包和构建过程中用于发布 CLI。请注意,`bin` 部分也进行了修改,以包含这两个别名,这就是 npm 创建 bin 别名的方式。为了创建统一的体验,无论采用哪种安装方法,CLI 作者都必须修改这两个别名以匹配。bin 别名还能与 `@oclif/plugin-autocomplete` 很好地配合使用,因此输入别名并使用自动补全功能与使用原名的体验是一样的。
diff --git a/website/i18n/zh/docusaurus-plugin-content-docs/current/args.md b/website/i18n/zh/docusaurus-plugin-content-docs/current/args.md
new file mode 100644
index 00000000..3d96c4be
--- /dev/null
+++ b/website/i18n/zh/docusaurus-plugin-content-docs/current/args.md
@@ -0,0 +1,75 @@
+---
+title: 命令参数
+---
+
+参数是传递给命令的位置参数。例如,如果这个命令是用 `mycli arg1 arg2` 运行的,它会这样声明:
+
+```typescript
+import {Args, Command} from '@oclif/core'
+
+export class MyCLI extends Command {
+ static args = {
+ firstArg: Args.string(),
+ secondArg: Args.string(),
+ }
+
+ async run() {
+ // 可以得到作为对象的参数
+ const {args} = await this.parse(MyCLI)
+ this.log(`running my command with args: ${args.firstArg}, ${args.secondArg}`)
+ // 也可以将 args 作为数组获取
+ const {argv} = await this.parse(MyCLI)
+ this.log(`running my command with args: ${argv[0]}, ${argv[1]}`)
+ }
+}
+```
+
+以下是参数可以具有的选项:
+
+```js
+static args = {
+ firstArg: Args.string(
+ {
+ name: 'file', // 在帮助和引用中用 args[name] 显示的参数名称
+ required: false, // 参数必选时,设置 `required: true`
+ description: 'output file', // 帮助描述
+ hidden: true, // 在帮助中隐藏参数
+ parse: async input => 'output', // 返回一个不同的值,用来替换用户输入
+ default: 'world', // 如果没有参数输入时的默认值。也可以是异步函数。
+ defaultHelp: 'a dynamic value' // 在帮助输出中显示的动态默认值(例如当前工作目录)。可以是返回字符串或未定义的异步函数
+ options: ['a', 'b'], // 只允许输入来自一个离散的集合
+ ignoreStdin: false, // 设置为 true 以忽略 stdin 提供的任何值
+ noCacheDefault: false // 如果为 true,则 defaultHelp 返回的值将不会缓存在 oclif.manifest.json 中。
+ }
+ ),
+}
+```
+
+以下是`参数`导出的参数类型:
+
+- `string`
+- `integer`
+- `boolean`
+- `url`
+- `file`
+- `directory`
+- `custom`
+
+对于可变长度参数,在命令中使用 `static strict = false` 禁用参数验证。
+
+```typescript
+import {Args, Command} from '@oclif/core'
+
+export class MyCLI extends Command {
+ static args = {
+ things: Args.string(),
+ }
+
+ static strict = false
+
+ async run() {
+ // 如果使用 strict = false,那么应该使用 argv 来访问提供的参数。
+ const {argv} = await this.parse(MyCLI)
+ this.log(`running my command with args: ${argv[0]}, ${argv[1]}`)
+ }
+}
diff --git a/website/i18n/zh/docusaurus-plugin-content-docs/current/base_class.md b/website/i18n/zh/docusaurus-plugin-content-docs/current/base_class.md
new file mode 100644
index 00000000..2f543189
--- /dev/null
+++ b/website/i18n/zh/docusaurus-plugin-content-docs/current/base_class.md
@@ -0,0 +1,88 @@
+---
+title: 自定义基类
+description: 创建一个可扩展的 Command 类
+---
+
+使用继承在常用命令之间共享功能。下面是一个命令基类的示例,它有一些共同的共享标志。
+
+对于包含多个插件的大型 CLI,将该基类放到自己的 npm 包中共享是非常有用的。
+
+```typescript
+// src/baseCommand.ts
+import {Command, Flags, Interfaces} from '@oclif/core'
+
+export type Flags = Interfaces.InferredFlags
+export type Args = Interfaces.InferredArgs
+
+export abstract class BaseCommand extends Command {
+ // 添加 --json 标志
+ static enableJsonFlag = true
+
+ // 定义可被任何扩展 BaseCommand 的命令继承的标记
+ static baseFlags = {
+ 'log-level': Flags.option({
+ default: 'info',
+ helpGroup: 'GLOBAL',
+ options: ['debug', 'warn', 'error', 'info', 'trace'] as const,
+ summary: 'Specify level for logging.',
+ })(),
+ }
+
+ protected flags!: Flags
+ protected args!: Args
+
+ public async init(): Promise {
+ await super.init()
+ const {args, flags} = await this.parse({
+ flags: this.ctor.flags,
+ baseFlags: (super.ctor as typeof BaseCommand).baseFlags,
+ enableJsonFlag: this.ctor.enableJsonFlag,
+ args: this.ctor.args,
+ strict: this.ctor.strict,
+ })
+ this.flags = flags as Flags
+ this.args = args as Args
+ }
+
+ protected async catch(err: Error & {exitCode?: number}): Promise {
+ // 添加任何自定义逻辑来处理命令中的错误
+ // 或者只是返回父类错误处理
+ return super.catch(err)
+ }
+
+ protected async finally(_: Error | undefined): Promise {
+ // 在运行和捕获之后调用,而不管命令是否出错
+ return super.finally(_)
+ }
+}
+
+// src/commands/my-command.ts
+
+export default class MyCommand extends BaseCommand {
+ static summary = 'child class that extends BaseCommand'
+
+ static examples = [
+ '<%= config.bin %> <%= command.id %>',
+ '<%= config.bin %> <%= command.id %> --json',
+ '<%= config.bin %> <%= command.id %> --log-level debug',
+ ]
+
+ static flags = {
+ name: Flags.string({
+ char: 'n',
+ summary: 'Name to print.',
+ required: true,
+ }),
+ }
+
+ public async run(): Promise> {
+ for (const [flag, value] of Object.entries(this.flags)) {
+ this.log(`${flag}: ${value}`)
+ }
+
+ return this.flags
+ }
+}
+```
+
+对于一个更复杂的示例,[这里](https://github.com/salesforcecli/sf-plugins-core/blob/main/src/sfCommand.ts)是我们如何为 Salesforce CLI 完成这项工作的。
diff --git a/website/i18n/zh/docusaurus-plugin-content-docs/current/command_discovery_strategies.md b/website/i18n/zh/docusaurus-plugin-content-docs/current/command_discovery_strategies.md
new file mode 100644
index 00000000..83a7f4e4
--- /dev/null
+++ b/website/i18n/zh/docusaurus-plugin-content-docs/current/command_discovery_strategies.md
@@ -0,0 +1,188 @@
+---
+title: 命令发现策略
+---
+
+当 oclif 加载一个插件时,它必须找到该插件中所有可以执行的命令。发现这些命令有三种策略:
+
+1. `pattern` - 这是基于 glob 模式查找命令的默认行为。
+2. `explicit` - 查找从指定文件导出的命令。
+3. `single` - CLI 包含由顶级 bin 执行的单个命令。
+
+### `pattern` 策略
+
+`pattern` 策略告诉 oclif 使用一组预定义的 glob 来查找指定目录中的命令文件。这是 oclif 的默认行为,除非另有说明。
+
+插件可以将 `commands` 属性指向目录
+
+```json
+{
+ "oclif": {
+ "commands": "./dist/commands",
+ }
+}
+```
+
+这将告诉 oclif 在该目录中查找命令(如果存在 `oclif.manifest.json`,则跳过此操作)
+
+或者,你可以设置此配置,这将做完全相同的事情:
+
+```json
+{
+ "oclif": {
+ "commands": {
+ "strategy": "pattern",
+ "target": "./dist/commands"
+ }
+ }
+}
+```
+
+你还可以设置 `globPatterns`,它覆盖 oclif 在搜索命令文件时使用的 glob 模式:
+
+```json
+{
+ "oclif": {
+ "commands": {
+ "strategy": "pattern",
+ "target": "./dist/commands",
+ "globPatterns": [
+ "**/*.+(js|cjs|mjs|ts|tsx|mts|cts)",
+ "!**/*.+(d.*|test.*|spec.*|helpers.*)?(x)"
+ ]
+ }
+ }
+}
+```
+
+如果你想将测试或帮助文件与命令文件放在同一目录中,这将非常有用。
+
+### `explicit` 策略
+
+`explicit` 策略告诉 oclif 从单个文件导入命令。在这种情况下,`target` 是导出命令的文件,`identifier` 是导出的名称(默认为 `default`)。
+
+要使用它,你需要添加一个新文件(例如 `src/commands.ts`),然后将此配置添加到package.json
+
+```json
+{
+ "oclif": {
+ "commands": {
+ "strategy": "explicit",
+ "target": "./dist/index.js",
+ "identifier": "COMMANDS",
+ }
+ }
+}
+```
+
+然后,`src/index.ts` 需要有一个与 `identifier` 同名的导出(如果没有设置,默认为 `default`),这是命令类的命令名称的对象,例如:
+
+```typescript
+import Hello from './commands/hello'
+import HelloWorld from './commands/hello/world'
+
+export const COMMANDS = {
+ hello: Hello,
+ 'hello:world': HelloWorld,
+ howdy: Hello, // alias the `hello` command to `howdy`
+}
+```
+
+`explicit` 策略对于那些不能依赖文件路径的人很有用,因为他们已经捆绑了他们的代码(参见[捆绑](#打包)),但是如果你只是喜欢更明确地描述你的命令,而不是依赖 oclif 从文件系统中“神奇地”找到命令,它也可以使用。
+
+它还可以用来在运行时创建或修改命令(例如,在运行时国际化消息或基于 API 规范向命令添加标志-参见下面的[动态命令](#动态命令)部分)。
+
+#### 钩子
+
+也可以使用 `explicit` 策略定义钩子:
+
+```json
+"oclif": {
+ "hooks": {
+ "init": {
+ "target": "./dist/index.js",
+ "identifier": "INIT_HOOK"
+ }
+ }
+}
+```
+
+```typescript
+// src/index.ts
+import Hello from './commands/hello'
+import HelloWorld from './commands/hello/world'
+export {default as INIT_HOOK} from './hooks/init/init.js'
+
+export const COMMANDS = {
+ hello: Hello,
+ 'hello:world': HelloWorld,
+ howdy: Hello, // alias the `hello` command to `howdy`
+}
+```
+
+该配置实际上是告诉 oclif 在 `./dist/index.js` 中查找 `INIT_HOOK` 导出。
+
+#### 打包
+
+**我们不支持打包**,因为可以使用无数的工具 + 配置。但是如果你选择使用一个编译器,比如 `esbuild`,有几个硬性要求 —— 你必须在根目录下有一个 package.json 和一个 `bin/run` 或 `bin/run.js` bin 脚本。这意味着你将无法成功地将整个 CLI(src 代码,package.json,node_modules 等)打包到单个文件中。
+
+如果你仍然想使用一个编译器,你可以参考这个[示例仓库](https://github.com/oclif/plugin-test-esbuild/)。
+
+#### 动态命令
+
+如果你想在运行时操作或创建命令,也可以使用 `explicit` 策略。请注意,`explicit` 策略的这种用法**不能**与 `oclif.manifest.json` 一起使用,这将对生产中的 CLI 产生重大的性能影响。
+
+示例:
+
+```typescript
+// src/index.ts
+import {Command, Flags} from '@oclif/core'
+
+import Hello from './commands/hello'
+import HelloWorld from './commands/hello/world'
+
+const dynamicCommands: Record = {}
+if (process.env.DYNAMIC_COMMAND) {
+ dynamicCommands[process.env.DYNAMIC_COMMAND] = class extends Command {
+ static flags = {
+ flag1: Flags.boolean({description: 'flag1 description'}),
+ }
+
+ async run(): Promise {
+ const {flags} = await this.parse(this.constructor as Command.Class)
+ this.log('hello from', this.id, flags)
+ }
+ }
+}
+
+export const COMMANDS = {
+ hello: Hello,
+ 'hello:world': HelloWorld,
+ ...dynamicCommands,
+}
+```
+
+```bash
+❯ DYNAMIC_COMMAND=foo:bar:baz bin/run.js foo bar baz --flag1
+hello from foo:bar:baz { flag1: true }
+```
+
+### `single` 策略
+
+`single` 策略告诉 oclif 这个 CLI 包含一个可以由 `bin/run.js` 执行的命令(例如 `ls` 或 `cat`)。
+
+```json
+{
+ "oclif": {
+ "commands": {
+ "strategy": "single",
+ "target": "./dist/index.js"
+ }
+ }
+}
+```
+
+在本示例中,`./dist/index.js` 导出命令类。
+
+### 关于 `oclif.manifest.json`
+
+对于所有策略,`oclif.manifest.json` 将用于加载命令,而不是策略的默认行为。
diff --git a/website/i18n/zh/docusaurus-plugin-content-docs/current/command_execution.md b/website/i18n/zh/docusaurus-plugin-content-docs/current/command_execution.md
new file mode 100644
index 00000000..89cce497
--- /dev/null
+++ b/website/i18n/zh/docusaurus-plugin-content-docs/current/command_execution.md
@@ -0,0 +1,7 @@
+---
+title: 命令执行
+---
+
+下图概括了用户每次执行 oclif 命令时的流程。
+
+![command execution flow](/img/command-execution-flow.jpg)
diff --git a/website/i18n/zh/docusaurus-plugin-content-docs/current/commands.md b/website/i18n/zh/docusaurus-plugin-content-docs/current/commands.md
new file mode 100644
index 00000000..a57ac7f1
--- /dev/null
+++ b/website/i18n/zh/docusaurus-plugin-content-docs/current/commands.md
@@ -0,0 +1,185 @@
+---
+title: 命令
+---
+
+一个基础的命令在 TypeScript 中看起来像下面这样:
+
+```js
+import {Command} from '@oclif/core'
+
+export class MyCommand extends Command {
+ static description = 'description of this example command'
+
+ async run(): Promise {
+ console.log('running my command')
+ }
+}
+```
+
+唯一需要的部分是 run 函数。接受带有[参数](args.md)和[标志](flags.md)的用户输入。
+
+在 JavaScript 中:
+
+```js
+const {Command} = require('@oclif/core')
+
+class MyCommand extends Command {
+ async run() {
+ console.log('running my command')
+ }
+}
+
+MyCommand.description = 'description of this example command'
+
+module.exports = MyCommand
+```
+
+请注意,以下示例将使用 TypeScript。由于 JavaScript 还没有静态类属性,因此必须在声明类后将它们添加到类中,就像我们在上面的描述中所做的那样。
+
+### 避免超时
+
+为了避免命令执行无限期地运行,oclif 将在 `Command.run` 解析后 10 秒终止 node 进程。这意味着 `run` 方法中的所有命令逻辑都应该同步运行,或者应该返回一个 `Promise`。这将允许整个命令在 10 秒超时开始之前运行。
+
+换句话说,**如果你在没有等待的情况下执行 `Command.run` 中的 promise,那么命令可能会在完成之前超时。**
+
+### 其他命令选项
+
+[查看基类以了解可以对命令调用哪些方法](https://github.com/oclif/core/blob/main/src/command.ts)。
+
+```typescript
+import {Command, Flags} from '@oclif/core'
+
+export class MyCommand extends Command {
+ static summary = 'A brief overview of your command.'
+ static description = `
+An in-depth description of the command.
+It can be multiline.
+`
+
+ // 在帮助中隐藏命令
+ static hidden = false
+
+ // 在帮助中自定义用法字符串
+ // 这将覆盖默认用法
+ static usage = 'mycommand --myflag'
+
+ // 添加到帮助的示例
+ // <%= config.bin %> 解析为可执行文件名
+ // <%= command.id %> 解析为命令名
+ static examples = [
+ // 示例可以是简单的字符串
+ '<%= config.bin %> <%= command.id %> --help',
+ // 或提供示例命令说明的对象
+ {
+ description: 'Force the command to execute',
+ command: '<%= config.bin %> <%= command.id %> --force',
+ }
+ ]
+
+ // 这使得解析器在接收到无效参数时不会失败
+ // 默认为 true
+ // 如果需要接受数量可变的参数,则将其设置为 false
+ static strict = false
+
+ // 定义可以执行此命令的别名。
+ static aliases = ['alternate:name:for:this:command']
+
+ // 如果要将 --json 标志添加到命令中,则将其设置为 true。
+ // oclif 将自动阻止显示日志(如果使用 this.log、 this.wart 或 this.error)
+ // 然后显示命令的 run 方法返回的 JSON。
+ static enableJsonFlag = true
+
+ async run() {
+ // 显示警告
+ this.warn('uh oh!')
+ // 带有错误消息终止
+ this.error('uh oh!!!')
+ // 带有状态码终止
+ this.exit(1)
+ }
+}
+```
+
+## Command 方法
+
+- [Command 方法](#command-方法)
+ - [`this.log(message: string)`](#thislogmessage-string)
+ - [`this.warn(message: string | Error)`](#thiswarnmessage-string--error)
+ - [`this.error(message: string | Error, options?: {code?: string, exit?: number, ref?: string; suggestions?: string[];})`](#thiserrormessage-string--error-options-code-string-exit-number-ref-string-suggestions-string)
+ - [`this.exit(code: number = 0)`](#thisexitcode-number--0)
+ - [`this.logToStderr(message: string)`](#thislogtostderrmessage-string)
+ - [`this.jsonEnabled()`](#thisjsonenabled)
+ - [`this.toSuccessJson(result: unknown)`](#thistosuccessjsonresult-unknown)
+ - [`this.toErrorJson(result: unknown)`](#thistoerrorjsonresult-unknown)
+
+下面的代码假设你在 oclif [命令](commands.md)的 `run()` 方法中。
+
+### `this.log(message: string)`
+
+将消息输出到 stdout(非阻塞)。`console.log()` 也可以正常工作,但这是一个阻塞调用,当存在 `--json` 标志时不会自动阻止。这使用了 [util.format()](https://nodejs.org/api/util.html#util_util_format_format_args),其行为与 `console.log()` 相同。
+
+```typescript
+this.log('hello, world!')
+```
+
+### `this.warn(message: string | Error)`
+
+将错误或消息显示为警告
+
+```typescript
+this.warn('uh oh!')
+this.warn(new Error('uh oh!'))
+```
+
+### `this.error(message: string | Error, options?: {code?: string, exit?: number, ref?: string; suggestions?: string[];})`
+
+显示错误并退出。另外,向错误对象或终止状态添加代码。
+
+```typescript
+this.error('uh oh!', {exit: 2})
+this.error(new Error('uh oh!'))
+```
+
+可选对象具有以下选项:
+
+* `exit` — 要使用的退出代码
+* `code` — 错误类型的唯一错误代码
+* `suggestions` — 一系列建议,供用户尝试下一步,可能有用或提供额外的上下文
+* `ref` — 指向与此错误或修复此错误相关的文档的 URL
+
+显示错误时,将显示 `message`、`code`、`suggestions`、`ref` 属性。可重用的 `Error` 类可以通过从 `@oclif/core` 和 `this.error` 中的 `Errors` 命名空间实现 `PrettyPrintableError` 接口来创建,以显示上述可选输出。
+
+这些错误是友好的,除非使用 `DEBUG=*` 启用调试,否则不会显示回溯。
+
+```typescript
+import {CLIError} from '@oclif/errors'
+
+throw new CLIError('my friendly error')
+```
+
+任何被此 `CLIError` 类型的命令捕获的错误都将显示出来,而不会进行追溯。
+
+### `this.exit(code: number = 0)`
+
+退出进程。回到状态 0。
+
+```typescript
+this.exit()
+this.exit(1)
+```
+
+### `this.logToStderr(message: string)`
+
+将消息打印到终端的 `stderr`。
+
+### `this.jsonEnabled()`
+
+如果存在 `--json` 标志且 `enableJsonFlag` 设置为 `true` ,则返回到 `true`
+
+### `this.toSuccessJson(result: unknown)`
+
+在向用户显示命令的成功 JSON 输出之前修改它。
+
+### `this.toErrorJson(result: unknown)`
+
+在向用户显示命令的错误 JSON 输出之前修改它。
diff --git a/website/i18n/zh/docusaurus-plugin-content-docs/current/config.md b/website/i18n/zh/docusaurus-plugin-content-docs/current/config.md
new file mode 100644
index 00000000..fa0dfbc7
--- /dev/null
+++ b/website/i18n/zh/docusaurus-plugin-content-docs/current/config.md
@@ -0,0 +1,65 @@
+---
+title: 配置
+---
+
+在命令中,`this.config` 提供了对 `Config` 类的访问,该类包含了可以在命令中使用的有用属性和方法。下面是它的方法和属性列表:
+
+- **name** - CLI 的名称
+- **version** - CLI 的版本
+- **pjson** - 已解析的 CLI `package.json`
+- **bin** - CLI bin 名称
+- **cacheDir** - CLI 缓存目录
+ - macOS: `~/Library/Caches/mycli`
+ - Unix: `~/.cache/mycli`
+ - Windows: `%LOCALAPPDATA%\mycli`
+ - 可以用 `XDG_CACHE_HOME` 重写
+- **configDir** - CLI 配置目录
+ - Unix: `~/.config/mycli`
+ - Windows: `%LOCALAPPDATA%\mycli`
+ - Can be overridden with `XDG_CONFIG_HOME`
+- **dataDir** - CLI 数据目录
+ - Unix: `~/.data/mycli`
+ - Windows: `%LOCALAPPDATA%\mycli`
+ - 可以用 `XDG_DATA_HOME` 重写
+- **dirname** - `cacheDir|configDir|dataDir` 使用的目录名。可以在 `package.json` 重写
+- **errlog** - `cacheDir` 中错误日志的路径
+- **home** - 用户主目录
+- **platform** - 操作系统 `darwin|linux|win32`
+- **arch** - 进程架构 `x64|x86`
+- **shell** - 当前使用的 shell
+- **userAgent** - 用于 http 的调用。例如:`mycli/1.2.3 (darwin-x64) node-9.0.0`
+- **windows** - 布尔值
+- **npmRegistry** - 当前的 npm registry 与[插件](https://github.com/oclif/plugin-plugins)一起使用
+- **plugins** - 加载的插件
+- **commands** - CLI 中的所有命令
+- **default** - 默认 CLI 命令
+- **topics** - CLI 中的所有标题(topic)
+- **commandIDs** - 所有命令的字符串 ID
+- **async runHook(event, opts)** - 触发一个钩子
+- **async runCommand(id, opts)** - 运行一个命令
+- **scopedEnvVar(key)** - 返回一个作用域环境变量的值(例如 `\_NPM_REGISTRY`)
+- **scopedEnvVarKey(key)** - 返回一个限定了作用域的环境变量的名称(例如 `\_NPM_REGISTRY`)
+- **scopedEnvVarTrue(key)** - 返回作用域环境变量的 true/false 值(例如 `\_NPM_REGISTRY`)
+
+## 自定义用户配置
+
+通常,为用户提供自定义配置是很有用的。实现此功能的一种方法是从 CLI 的 config 目录中读取 `config.json` 文件:
+
+```typescript
+import { Command } from "@oclif/core";
+import * as fs from "fs-extra";
+import * as path from "path";
+
+export class extends Command {
+ async run() {
+ const userConfig = await fs.readJSON(
+ path.join(this.config.configDir, "config.json")
+ );
+
+ this.log("User config:");
+ console.dir(userConfig);
+ }
+}
+```
+
+若要在不同命令之间共享此逻辑,请使用[基类](base_class.md)。
diff --git a/website/i18n/zh/docusaurus-plugin-content-docs/current/configuring_your_cli.md b/website/i18n/zh/docusaurus-plugin-content-docs/current/configuring_your_cli.md
new file mode 100644
index 00000000..0749c0fc
--- /dev/null
+++ b/website/i18n/zh/docusaurus-plugin-content-docs/current/configuring_your_cli.md
@@ -0,0 +1,80 @@
+---
+title: 配置你的 CLI
+description: 关于配置 oclif 的所有内容
+---
+
+你可以在 CLI 或插件的 package.json 中配置 oclif 的行为。所有配置选项都应放在 `oclif` 部分。例如:
+
+```json
+{
+ "name": "my-cli",
+ "version": "1.2.3",
+ "dependencies": {
+ "@oclif/core": "^3"
+ },
+ "oclif": {
+ "bin": "mycli",
+ "dirname": "mycli",
+ "commands": "./dist/commands",
+ "topicSeparator": " "
+ }
+}
+```
+
+下面列出了你可以配置的所有选项。
+
+| 属性 | 说明 |
+| ------------------------ | --------------------------------------------------------------------------------------------------- |
+| `additionalHelpFlags` | 除 `--help` 外还应触发帮助输出的标志数组 |
+| `additionalVersionFlags` | 除 `--version` 外还应触发版本输出的标志数组 |
+| `aliases` | 插件的别名。用于支持已重命名的遗留插件 |
+| `bin` | CLI bin 名称 (例如 `sf`、`heroku`、`git` 等等) |
+| `binAliases` | 一个字符串数组,所有字符串都能执行 CLI 的 bin。参见[别名](aliases.md#bin-别名) |
+| `dirname` | 确定 CLI 的配置、缓存和数据目录时使用的目录名称。 |
+| `commands` | oclif 可以在哪里找到命令类。参见[命令发现策略](command_discovery_strategies.md) |
+| `description` | 在帮助中显示的插件或 CLI 的说明 |
+| `devPlugins` | 仅在开发过程中加载的插件列表。参见[插件](plugins.md) |
+| `exitCodes` | 配置终止代码。参见本章[终止代码](#终止代码)部分 |
+| `flexibleTaxonomy` | 设置为 true 时,启用[灵活分类法](flexible_taxonomy.md) |
+| `helpClass` | 已编译[自定义帮助类](help_classes.md)的位置 |
+| `helpOptions` | 用于配置帮助输出行为的设置。参见本章[帮助选项](#帮助选项)部分 |
+| `hooks` | 注册你的插件或者 CLI 的钩子。参见[钩子](hooks.md) |
+| `jitPlugins` | 注册 JIT 插件。参见 [即时插件安装](jit_plugins.md) |
+| `macos` | 构建 macos 安装程序的设置。参见[发布](releasing.md) |
+| `nsisCustomization` | 用于自定义 Windows 安装程序的 .nsis 文件的路径。参见 [nsis-custom](nsis-installer_customization.md) |
+| `plugins` | 应该加载的插件列表。参见[插件](plugins.md) |
+| `state` | 将 CLI 或插件的状态设置为在帮助中显示(例如 `beta` 会显示为 `This CLI is in beta`) |
+| `theme` | 包含在 CLI 中的主题文件的路径。参见[主题](themes.md) |
+| `topicSeparator` | 标题之间使用的分隔符 - 仅支持冒号(`":"`)和空格(`" "`) |
+| `topics` | 定义 CLI 的标题。参见[标题](topics.md) |
+| `windows` | 构建 windows 安装程序的设置。参见[发布](releasing.md) |
+
+### 终止代码
+
+你可以为以下错误配置所需的终止代码:
+
+- `default` - 任何错误的默认终止代码。
+- `failedFlagParsing` - 当 oclif 未能解析标志的值时的终止代码。
+- `failedFlagValidation` - 当一个标志未能通过自身验证时的终止代码。
+- `invalidArgsSpec` - 当命令定义的 `args` 配置无效时的终止代码。
+- `nonExistentFlag` - 当用户提供一个不存在的标志时的退出代码。
+- `requiredArgs` - 当用户未能提供所需的参数时的退出代码。
+- `unexpectedArgs` - 当用户向命令提供意料之外的参数时的退出代码。
+
+### 帮助选项
+
+你可以使用以下方法配置帮助输出的行为:
+
+- `docopts` - 使用 docopts 作为用法。默认为 true。
+- `flagSortOrder` - 在帮助输出中对标志进行排序的顺序。可以为 `alphabetical`(默认)或者 `none`(标志将按照它们被定义的顺序出现)。
+- `hideAliasesFromRoot` - 如果为 true,则在根帮助输出中隐藏命令别名。默认为 false。
+- `hideCommandSummaryInDescription` - 默认情况下,命令摘要显示在帮助的顶部和命令描述的第一行。在命令描述中重复显示摘要可以提高可读性,尤其是对于长命令帮助输出。如果没有 `command.summary`,说明的第一行将被视为摘要。有些 CLI,尤其是非常简单的命令,可能不需要重复。
+- `maxWidth` - 帮助输出的最大列宽。
+- `sections` - 只显示指定部分的帮助。默认为所有部分。
+- `sendToStderr` - 默认情况下,帮助输出会发送到 stdout。如果为 true,则会发送到 stderr。
+- `showFlagNameInTitle` - 默认情况下,标题以 `` 显示标志值。一些 CLI 开发人员可能更喜欢标题将标志名称显示为值,即--myflag=myflag而不是 `--myflag=`。单个标志可以使用 `flag.helpValue=flag.name` 来设置。
+- `showFlagOptionsInTitle` - 默认情况下,标记的选项值显示在标记说明中。这是因为冗长的选项列表会破坏帮助的格式。如果 CLI 知道所有命令都不会这样做,则可以使用此属性在帮助级别关闭此选项。单个标记可以使用 `flag.helpValue=options.join('|')` 设置此项。
+- `stripAnsi` - 从帮助输出中删除 ansi 字符,以去除所有格式化。
+- `usageHeader` - 覆盖 `USAGE` 部分的标题。
+
+如果想进一步定制帮助,可以实现[自定义帮助类](help_classes.md)。
diff --git a/website/i18n/zh/docusaurus-plugin-content-docs/current/debugging.md b/website/i18n/zh/docusaurus-plugin-content-docs/current/debugging.md
new file mode 100644
index 00000000..aaba8e92
--- /dev/null
+++ b/website/i18n/zh/docusaurus-plugin-content-docs/current/debugging.md
@@ -0,0 +1,10 @@
+---
+title: 调试
+description: 如何访问调试日志
+---
+
+使用 [debug](https://github.com/visionmedia/debug) 进行调试。CLI 使用该模块进行所有调试。如果设置环境变量 `DEBUG=*`,则会将所有调试输出打印到屏幕上。
+
+根据 shell 的不同,你可能需要用 `DEBUG=\*` 来转义。在 Windows 系统中,无法在行中设置环境变量,因此需要在运行命令前运行 `set DEBUG=*`。
+
+![debug demo](/img/debug_demo.png)
diff --git a/website/i18n/zh/docusaurus-plugin-content-docs/current/error_handling.md b/website/i18n/zh/docusaurus-plugin-content-docs/current/error_handling.md
new file mode 100644
index 00000000..cb5bb961
--- /dev/null
+++ b/website/i18n/zh/docusaurus-plugin-content-docs/current/error_handling.md
@@ -0,0 +1,61 @@
+---
+title: 错误处理
+description: 自定义错误处理
+---
+
+oclif 会在两个地方处理有意或无意抛出的错误。首先是在 `Command.catch` 方法中,最后是在 `bin/run.js` `catch` 处理程序中,错误信息将被打印并退出 CLI。通过这种错误流程,你可以控制和响应 CLI 中出现的错误。
+
+## 在 `catch` 方法中进行错误处理
+
+每个 `Command` 实例都有一个 `catch` 方法,在命令运行过程中出现错误时会调用该方法。如果适用,该方法会处理用户请求帮助或版本输出的边缘情况,否则会重新抛出错误。你可以在命令类中继承或重写 `catch` 方法。
+
+```js
+import {Command, flags} from '@oclif/core'
+
+export default class Hello extends Command {
+ async catch(error) {
+ // do something or
+ // re-throw to be handled globally
+ throw error;
+ }
+}
+```
+
+如果要在多个命令中执行这种类型的错误处理,可以考虑为命令使用[自定义基类](base_class.md)并重写 `catch` 方法。
+
+## bin/run.js `catch` 处理器
+
+每个 oclif CLI 都有一个./bin/run.js文件,它是命令调用的入口点。CLI 中出现的错误(包括从命令中重新抛出的错误)由 oclif 的 `handle` 函数捕获和处理,并将错误显示给用户。
+
+如果你使用 `oclif generate` 生成了 CLI,那么你将看到一个 `execute` 函数,它负责运行 CLI 并捕获任何错误。不过,如果你需要自定义错误处理,也可以自己实现。
+
+这是由 `oclif generate` 自带的通用 `bin/run.js`:
+
+```javascript
+#!/usr/bin/env node
+
+import {execute} from '@oclif/core'
+
+await execute({dir: import.meta.url})
+```
+
+要自定义错误处理,需要使用 oclif 的 `run` 函数,而不是 `execute`:
+
+```javascript
+#!/usr/bin/env node
+
+import {run, handle, flush} from '@oclif/core'
+
+await run(process.argv.slice(2), import.meta.url)
+ .catch(async (error) => handle(error))
+ .finally(async () => flush())
+```
+
+`catch` 处理器可以替换任何接收错误参数的函数。如果你选择在此实现自己的处理程序,我们仍然建议你将清理和退出逻辑的工作最终委托给 `handle` 函数。
+
+```js
+.catch((error) => {
+ // do any extra work with error
+ return handle(error);
+})
+```
diff --git a/website/i18n/zh/docusaurus-plugin-content-docs/current/esm.md b/website/i18n/zh/docusaurus-plugin-content-docs/current/esm.md
new file mode 100644
index 00000000..8d1c5cf7
--- /dev/null
+++ b/website/i18n/zh/docusaurus-plugin-content-docs/current/esm.md
@@ -0,0 +1,152 @@
+---
+title: ESM
+description: 在 oclif 中使用 ESM
+---
+
+`@oclif/core` 的 3.0.0 版本正式支持 ESM 插件开发和 CJS/ESM 互操作性,这意味着你可以使用 CJS 编写根插件,并使用 ESM 编写插件,反之亦然。
+
+## 互操作性概述
+
+以下是 ESM/CJS 互操作性的高级概述:
+
+### ESM 根插件
+
+✅ 安装 CJS 插件
+
+✅ 安装 ESM 插件
+
+✅ 链接 CJS 插件
+
+⚠️ 链接 ESM 插件
+
+- 自动编译**不**适用于链接的 ESM 插件。相反,oclif 将使用插件的编译源代码 - 这意味着你必须在执行任何命令之前自己编译插件。我们计划在 node 生态系统为 ESM 提供更全面的本地支持后再次支持这一点。
+
+### CJS 根插件
+
+✅ 安装 CJS 插件
+
+✅ 安装 ESM 插件
+
+✅ 链接 CJS 插件
+
+⚠️ 链接 ESM 插件
+
+- 自动编译**不**适用于链接的 ESM 插件。相反,oclif 将使用插件的编译源代码 - 这意味着你必须在执行任何命令之前自己编译插件。我们计划在 node 生态系统为 ESM 提供更全面的本地支持后再次支持这一点。
+
+## 创建 ESM 插件
+
+要从 [hello-world-esm 模板](https://github.com/oclif/hello-world-esm)生成新的 ESM 插件,请运行 `oclif generate` 命令,并在提示你选择模块类型时选择 `ESM` :
+
+```shell
+$ npx oclif generate my-esm-plugin
+? Select a module type
+ CommonJS
+❯ ESM
+```
+
+## 将 CJS 插件迁移到 ESM
+
+### 修改 bin 脚本
+
+首先,你需要修改 `bin` 目录下的 bin 脚本。
+
+#### bin/dev → bin/dev.js
+
+将 `bin/dev` 重命名为 `bin/dev.js`,并将现有代码替换为以下代码:
+
+```js
+#!/usr/bin/env -S node --loader ts-node/esm --no-warnings=ExperimentalWarning
+
+import {execute} from '@oclif/core'
+
+await execute({development: true, dir: import.meta.url})
+```
+
+这利用了 oclif 的 `execute` 函数,它为你处理所有的开发设置。你不再需要设置 `NODE_ENV` 环境变量或使用 `ts-node` 注册项目。你仍然可以在执行 CLI 之前调整 oclif `settings`。比如说,
+
+```js
+#!/usr/bin/env -S node --loader ts-node/esm --no-warnings=ExperimentalWarning
+
+import {execute, settings} from '@oclif/core'
+
+settings.performanceEnabled = true
+
+await execute({development: true, dir: import.meta.url})
+```
+
+
+#### bin/run → bin/run.js
+
+将 `bin/run` 重命名为 `bin/run.js` ,并将现有代码替换为以下代码:
+
+```js
+#!/usr/bin/env node
+
+import {execute} from '@oclif/core'
+
+await execute({dir: import.meta.url})
+```
+
+### 修改 tsconfig.json
+
+更新 bin 脚本后,你现在需要修改 `tsconfig.json` 以包含以下选项:
+
+```json
+{
+ "compilerOptions": {
+ "module": "ES2020",
+ "moduleResolution": "node16",
+ },
+ "ts-node": {
+ "esm": true
+ }
+}
+```
+
+### 将 package.json 修改为“module”类型
+
+将 `"type": "module"` 添加到你的 package.json 中,使你的文件作为 ESM 模块加载
+
+### 修改对 bin 脚本的引用
+
+你需要将 bin 脚本的引用修改为带有 `.js` 扩展名的 bin 脚本。在 package.json 中,你需要像这样修改 `bin`:
+
+```json
+ "bin": {
+ "my-cli": "./bin/run"
+ },
+```
+
+修改为
+
+```json
+ "bin": {
+ "my-cli": "./bin/run.js"
+ },
+```
+
+你可能在 `.vscode/launch.json` 或 `package.json` 的 `scripts` 中引用了 bin 脚本。你也需要修改这些。
+
+### 修改 mocharc 设置
+
+为了运行你的 mocha 测试,你需要做一些修改:
+
+1. 将以下内容添加到 `.mocharc.json`
+
+```json
+{
+ "node-option": [
+ "loader=ts-node/esm"
+ ]
+}
+```
+
+2. 修改 `test/helpers/init.js`
+
+如果你的插件是生成的 `oclif generate`,那么你可能有一个需要修改的 `test/helpers/init.js` 文件。你可以将文件扩展名修改为 `.cjs`,也可以将文件顶部的 `require` 修改为 `import`,
+
+```js
+import path from 'node:path'
+```
+
+或者,你可以安全地删除此文件,因为它不再需要。
diff --git a/website/i18n/zh/docusaurus-plugin-content-docs/current/examples.md b/website/i18n/zh/docusaurus-plugin-content-docs/current/examples.md
new file mode 100644
index 00000000..df0e741c
--- /dev/null
+++ b/website/i18n/zh/docusaurus-plugin-content-docs/current/examples.md
@@ -0,0 +1,10 @@
+---
+title: 示例
+---
+
+下面是一些示例,以了解如何在各种设置中使用 oclif。
+
+* [Hello World 示例 (CommonJS)](https://github.com/oclif/hello-world)
+* [Hello World 示例 (ESM)](https://github.com/oclif/hello-world-esm)
+* [使用 esbuild](https://github.com/oclif/plugin-test-esbuild)
+* [Hook-only plugin](https://github.com/oclif/plugin-not-found)
diff --git a/website/i18n/zh/docusaurus-plugin-content-docs/current/external_links.md b/website/i18n/zh/docusaurus-plugin-content-docs/current/external_links.md
new file mode 100644
index 00000000..da8ee85b
--- /dev/null
+++ b/website/i18n/zh/docusaurus-plugin-content-docs/current/external_links.md
@@ -0,0 +1,6 @@
+---
+title: 外部链接
+---
+
+* [Salesforce 发布公告](https://engineering.salesforce.com/open-sourcing-oclif-the-cli-framework-that-powers-our-clis-21fbda99d33a)
+* [Heroku 发布公告](https://blog.heroku.com/open-cli-framework)
diff --git a/website/i18n/zh/docusaurus-plugin-content-docs/current/faqs.md b/website/i18n/zh/docusaurus-plugin-content-docs/current/faqs.md
new file mode 100644
index 00000000..e8c3b573
--- /dev/null
+++ b/website/i18n/zh/docusaurus-plugin-content-docs/current/faqs.md
@@ -0,0 +1,49 @@
+---
+title: 常见问题
+---
+
+## 为什么选择 Node?
+
+Node 是编写 CLI 代码的最佳选择,原因有很多。在 Salesforce,我们用 Ruby、Go 和 Node 发布了 heroku CLI。[本文将更详细地介绍这段历史](https://blog.heroku.com/evolution-of-heroku-cli-2008-2017),但我们确实发现 Node 提供了最好的一切。
+
+首先,JavaScript 是世界上最大的语言。能够编写 JavaScript 的人比任何其他语言都多,而且到目前为止,它拥有最大的开源社区。每个人都可以编写 JavaScript,而且你可以找到最有用的库来帮助构建 CLI。
+
+我们发现,在我们使用过的语言中,Node 的跨平台支持最好。一般来说,如果在 macOS 上编写代码,在 Windows 上运行也不会有太大问题。
+
+Node 为我们的[插件](plugins.md)模式提供了最好的支持。插件是在 CLI 之间共享代码、将 CLI 代码库模块化或允许用户为现有 CLI 添加功能的一种方式。有了 Node,我们就可以将不同的依赖版本放在一起。这意味着,如果你想对一个插件中的依赖关系发布更新,它不会影响另一个插件的工作方式。oclif 将这一点发挥到了极致,甚至在单个插件级别就完成了标记解析。如果我们想对标记解析进行破坏性修改(我们当然不打算这样做,但这只是一个例子),你可以只更新一个插件,而在其他插件中保留旧的行为。这对需要缓慢迁移到新代码的大型 CLI 代码库非常有帮助。
+
+## 我想要一个像 Go 一样的二进制 CLI
+
+使用 [pkg](https://github.com/zeit/pkg)。只需确保通过在 `package.json` 中设置 `pkg.scripts: "./lib/**/*.js"` 来添加命令和其他源文件即可。
+
+不过,在 Salesforce CLI 中,我们更倾向于发送内置 Node 的压缩包(以及各种安装程序)。使用 `oclif pack` 为不同平台创建一组内置 Node 的压缩包。你可能需要使用 [@oclif/plugin-update](https://github.com/oclif/plugin-update) 进行更新,否则用户将无法在不重新安装的情况下从压缩包中更新 CLI。
+
+## 我应该使用 TypeScript 还是 JavaScript?
+
+我们建议使用 TypeScript,因为在重构代码和更新依赖关系时,我们发现类型化确实很有帮助。出现编译错误比在生产中发现错误要好得多。
+
+即使你从未编写过 TypeScript,我们也花了很多心思让你轻松创建 TypeScript CLI。我们生成了使用 [ts-node](https://github.com/TypeStrong/ts-node) 的 CLI 和插件,使其无需编译步骤即可快速运行 TypeScript 代码。使用 oclif,你不必再为构建配置而烦恼。
+
+不过,现在的语言还是非常相似的。你在 JavaScript 中编写的代码与在 TypeScript 中编写的代码几乎完全相同。(当然,只是没有类型定义而已)
+
+## 什么编辑器最适合 oclif?
+
+当然,如果你已经有了常用的编辑器,就应该使用它。不过,我们通常推荐 [vscode](https://code.visualstudio.com)。
+
+微软在这款编辑器上做得非常出色,它在 TypeScript 项目中的表现尤为出色。开箱即可获得良好的类型检查、代码检查和自动补全功能。
+
+## 我应该使用 npm 还是 yarn?
+
+这其实没有太大区别。如果你刚刚开始使用 Node,请使用 NPM。我们内部喜欢使用 yarn,因为它更快一些,而且我们发现它的 lockfiles 更友好。
+
+## 如何让 oclif 生成器运行得更快?
+
+如果使用 npx,请先使用 `npm install -g oclif` 安装。但这样做并不能及时更新,所以你需要运行 `npm update -g oclif` 来获取新版本的生成器。
+
+## 为什么不支持 Node X?
+
+oclif 项目遵循并支持 [Node 的 LTS 支持计划](https://nodejs.org/en/about/releases/)。这使得 oclif 能够与 Node 的开发保持同步。
+
+## “oclif” 怎么发音?
+
+我们说“oh-cliff”。
diff --git a/website/i18n/zh/docusaurus-plugin-content-docs/current/features.md b/website/i18n/zh/docusaurus-plugin-content-docs/current/features.md
new file mode 100644
index 00000000..1f6ec5e8
--- /dev/null
+++ b/website/i18n/zh/docusaurus-plugin-content-docs/current/features.md
@@ -0,0 +1,61 @@
+---
+title: 功能
+---
+
+### 标志/参数解析
+
+没有标志解析器,CLI 框架就不完整。我们通过多年的实验建立了一个自定义的标志解析器,我们认为它能始终如一地灵活处理用户输入,让用户能以他们期望的方式轻松使用 CLI,同时又不影响对开发人员的严格性保证。
+
+### 可配置的主题分隔符
+
+默认情况下,主题将用冒号分隔,例如 `my:awesome:command`。不过,如果你愿意,也可以选择使用空格,例如:`my awesome command`。
+
+### 超快的速度
+
+运行 oclif CLI 命令的开销几乎为零。[它只需要很少的依赖项](https://www.npmjs.com/package/@oclif/core?activeTab=dependencies)(在最小设置中只有 28 个依赖项,包括所有传递依赖项)。此外,只有要执行的命令才需要 Node。因此,包含许多命令的大型 CLI 加载速度与包含单一命令的小型 CLI 加载速度一样快。
+
+### CLI 生成器
+
+只需运行一条命令,就能搭建出功能齐全的 CLI 并快速上手。请参阅[生成器命令](generator_commands.md)。
+
+### 测试助手
+
+我们做了大量工作,使命令易于测试,并能轻松模拟出 stdout/stderr。生成器会自动创建[脚手架测试](https://github.com/oclif/hello-world/blob/main/test/commands/hello/world.test.ts)。
+
+### 自动文档
+
+默认情况下,你可以向 CLI 传入 `--help` 来获取帮助,如标志选项和参数信息。在发布 CLI 的 npm 包时,这些信息也会自动放在 README 中。请参阅 [hello-world CLI 示例](https://github.com/oclif/hello-world)
+
+### 插件
+
+使用插件,CLI 的用户可以用新功能对其进行扩展,CLI 可以被拆分成模块化组件,并在多个 CLI 之间共享功能。请参阅[构建自己的插件](plugins.md#构建自己的插件)。
+
+### 钩子
+
+使用生命周期钩子可在 CLI 启动时或在自定义触发器上运行功能。如果 CLI 的各个组件之间需要共享自定义功能,请使用此功能。请参阅[钩子](https://oclif.io/docs/hooks)。
+
+### JSON 输出
+
+你可以选择使用 `--json` 标志,它会自动阻止控制台日志,并将命令的最终结果显示为有效的 JSON 输出。如果你希望在 CI/CD 环境中使用 CLI 编写脚本,这将非常有用。请参阅 [JSON](json.md)。
+
+### 灵活分类法
+
+你可以选择加入我们所说的[灵活分类法](flexible_taxonomy.md)。启用该功能后,用户就可以执行命令,而无需遵守已定义的命令分类法。
+
+这是一种让 CLI 更方便用户使用的好方法,尤其是在命令名称较长、用户难以记住的情况下。例如,用户可能很难记住命令的名称是 `project deploy metadata start`,还是 `project start deploy metadata`,而使用灵活的分类法后,这两个名称都有效!
+
+### 使用 TypeScript (或者不使用)
+
+oclif 核心中的所有内容都是用 TypeScript 编写的,生成器可以构建完全配置好的 TypeScript CLI 或普通 JavaScript CLI。凭借 TypeScript 中的静态属性,TypeScript 的语法更加简洁,但无论你选择哪种语言,一切都能正常工作。如果你使用插件支持,CLI 将自动使用 `ts-node` 运行插件,从而轻松快速地使用 TypeScript,而且任何 oclif CLI 都不需要任何模板。
+
+### 自动更新安装程序
+
+oclif 可以将 CLI 打包成[不同的安装程序](releasing.md),用户无需在机器上安装 Node。这些安装程序可以通过 [plugin-update](https://github.com/oclif/plugin-update) 实现自动更新。
+
+### 自动补全
+
+通过 [plugin-autocomplete](https://github.com/oclif/plugin-autocomplete) 为你的 CLI 加入终端自动补全。安装后,用户就可以补全命令名称和标志名称。
+
+```bash
+$ my-cli p # will list all commands starting with 'p' for completion
+```
diff --git a/website/i18n/zh/docusaurus-plugin-content-docs/current/feedback.md b/website/i18n/zh/docusaurus-plugin-content-docs/current/feedback.md
new file mode 100644
index 00000000..a6da9f11
--- /dev/null
+++ b/website/i18n/zh/docusaurus-plugin-content-docs/current/feedback.md
@@ -0,0 +1,5 @@
+---
+title: 反馈
+---
+
+如果你有任何建议或者只是想让我们知道你对 oclif 的看法,请发送邮件至 alm-cli@salesforce.com 或者在[我们的仓库](https://github.com/oclif)中提出问题反馈。
diff --git a/website/i18n/zh/docusaurus-plugin-content-docs/current/flag_inheritance.md b/website/i18n/zh/docusaurus-plugin-content-docs/current/flag_inheritance.md
new file mode 100644
index 00000000..4a197be2
--- /dev/null
+++ b/website/i18n/zh/docusaurus-plugin-content-docs/current/flag_inheritance.md
@@ -0,0 +1,64 @@
+---
+title: 标志继承
+description: 如何共享标志
+---
+
+在某些情况下,你可能希望为所有命令定义一次标志。在这种情况下,你可以向抽象基类 `Command` 添加一个基类标志。比如说,
+
+```typescript
+import { Command, Flags } from '@oclif/core';
+
+export abstract class BaseCommand extends Command {
+ static baseFlags = {
+ interactive: Flags.boolean({
+ char: 'i',
+ description: 'Run command in interactive mode',
+ // 在帮助中的一个单独的 GLOBAL 部分下显示此标志。
+ helpGroup: 'GLOBAL',
+ }),
+ };
+}
+```
+
+任何扩展了 `BaseCommand` 的命令现在都会有一个 `--interactive` 标志。
+
+如果你要堆叠多层抽象的 `Command` 类,那么你必须分散 `baseFlags` 以确保标志被正确地继承。比如说,
+
+```typescript
+import { Command, Flags } from '@oclif/core';
+
+export abstract class FirstBaseCommand extends Command {
+ static baseFlags = {
+ interactive: Flags.boolean({
+ char: 'i',
+ description: 'Run command in interactive mode',
+ // 在帮助中的一个单独的 GLOBAL 部分下显示此标志。
+ helpGroup: 'GLOBAL',
+ }),
+ };
+}
+
+export abstract class SecondBaseCommand extends FirstBaseCommand {
+ static baseFlags = {
+ ...FirstBaseCommand.baseFlags,
+ 'log-level': Flags.option({
+ default: 'info',
+ description: 'Specify log level',
+ helpGroup: 'GLOBAL',
+ options: ['debug', 'warn', 'error', 'info', 'trace'] as const,
+ summary: 'Specify level for logging.',
+ char: 'l',
+ })(),
+ };
+}
+
+export abstract class ThirdBaseCommand extends SecondBaseCommand {
+ static baseFlags = {
+ ...SecondBaseCommand.baseFlags,
+ verbose: Flags.boolean({
+ description: 'Show verbose output.',
+ char: 'v'
+ })
+ };
+}
+```
diff --git a/website/i18n/zh/docusaurus-plugin-content-docs/current/flags.md b/website/i18n/zh/docusaurus-plugin-content-docs/current/flags.md
new file mode 100644
index 00000000..eac627fb
--- /dev/null
+++ b/website/i18n/zh/docusaurus-plugin-content-docs/current/flags.md
@@ -0,0 +1,160 @@
+---
+title: 命令标志
+---
+
+标志选项是传递给命令的非位置参数。标志可以是带参数的选项标志,也可以是不带参数的布尔标志。选项标志必须有参数。
+
+例如,如果这个命令像这样运行:
+
+```bash
+$ mycli --force --file=./myfile
+```
+
+它将被声明为这样:
+
+```typescript
+import {Command, Flags} from '@oclif/core'
+
+export class MyCLI extends Command {
+ static flags = {
+ // --force 或 -f 都能通过
+ force: Flags.boolean({char: 'f'}),
+ file: Flags.string(),
+ }
+
+ async run() {
+ const {flags} = await this.parse(MyCLI)
+ if (flags.force) console.log('--force is set')
+ if (flags.file) console.log(`--file is: ${flags.file}`)
+ }
+}
+```
+
+_oclif 支持大范围的[可选标志输入](#可选标志输入)。_
+
+以下是标志可以具有的选项:
+
+```js
+static flags = {
+ name: Flags.string({
+ // The following can be set on both boolean and option flag (e.g. string, integer, url, custom, etc) types.
+ char: 'n', // shorter flag version
+ summary: 'brief summary', // help summary for flag
+ helpLabel: '--my-flags', // The flag label to show in help. Defaults to "[-] --" where - is only displayed if the char is defined.
+ helpGroup: 'THE BEST FLAGS', // Put flag into THE BEST FLAGS group in help
+ description: 'in-depth overview', // help description for flag
+ hidden: false, // hide from help
+ multiple: false, // allow setting this flag multiple times
+ env: 'MY_NAME', // default to value of environment variable
+ options: ['a', 'b'], // only allow the value to be from a discrete set
+ parse: async input => 'output', // instead of the user input, return a different value
+ default: 'world', // default value if flag not passed (can be an async function that returns a string or undefined)
+ defaultHelp: 'a dynamic value' // dynamic default value to show in help output (e.g. current working directory). Can be an async function that returns a string or undefined
+ required: false, // make flag required
+ aliases: ['username', 'u'], // aliases for the flag - can be short char or long flags
+ aliases: ['u', 'n'], // single character aliases for the flag
+ deprecated: false, // mark the flag as deprecated.
+ deprecateAliases: false, // emit deprecation warning anytime a flag alias is provided
+ noCacheDefault: false, // if true, the value returned by defaultHelp will not be cached in the oclif.manifest.json.
+ dependsOn: ['extra-flag'], // this flag requires another flag
+ exclusive: ['extra-flag'], // this flag cannot be specified alongside this other flag
+ exactlyOne: ['extra-flag', 'another-flag'], // exactly one of these flags must be provided
+ relationships: [ // define complex relationships between flags
+ // Make this flag dependent on all of these flags
+ {type: 'all', flags: ['flag-one', 'flag-two']}
+ // Make this flag dependent on at least one of these flags
+ {type: 'some', flags: ['flag-three', 'flag-four']}
+ // Make this flag exclusive of all these flags
+ {type: 'none', flags: ['flag-five', 'flag-six']}
+
+ // Make this flag dependent on all of these flags
+ {type: 'all', flags: [
+ 'flag-one',
+ 'flag-two',
+ // Include flag-seven but only when flag-eight is equal to FooBar
+ {name: 'flag-seven', when: async (flags) => flags['flag-eight'] === 'FooBar'}
+ ]}
+ ],
+ // The following properties cannot be set on boolean flags
+ helpValue: '', // The flag value to show in help. Defaults to "",
+ multipleNonGreedy: false, // Parse one value per flag to allow `-m val1 -m val2` but disallow `-m val1 val2`. Only respected if multiple is set to true
+ delimiter: ',' // Delimiter to separate the values for a multiple value flag. Only respected if multiple is set to true. Default behavior is to separate on spaces.
+ allowStdin: false, // Allow input value to be read from stdin if the provided value is `-`. Can also be set to `only` to allow flag to always read from stdin even if no value is provided.
+ }),
+
+ // flag with no value (-f, --force)
+ force: Flags.boolean({
+ // Boolean flags take all the same properties described in the previous example
+ // in addition to:
+ allowNo: true // Support reversible boolean flag with `--no-` prefix (e.g. `--no-force`). This is disabled by default.
+ }),
+}
+```
+
+## 自定义标志
+
+对于较大的 CLI,声明可在多个命令之间共享的自定义标志可能很有用。下面是一个自定义标志的示例:
+
+```typescript
+// src/flags.ts
+import {Flags} from '@oclif/core'
+
+class Team {
+ public name: string;
+ // etc...
+}
+
+function getTeam(): Promise {
+ // imagine this reads a configuration file or something to find the team
+ return new Team()
+}
+
+export const team = Flags.custom({
+ char: 't',
+ description: 'team to use',
+ default: async () => getTeam(),
+})
+
+// src/commands/mycommand.ts
+import {team} from '../flags'
+import {Command} from '@oclif/core'
+
+export class MyCLI extends Command {
+ static flags = {
+ team: team({
+ required: true,
+ }),
+ }
+
+ async run() {
+ const {flags} = await this.parse(MyCLI)
+ if (flags.team) console.log(`--team is ${flags.team.name}`)
+ }
+}
+```
+
+在 Salesforce CLI 中,我们大量使用自定义标志。比如说,
+
+- [`salesforceId`](https://salesforcecli.github.io/sf-plugins-core/functions/flags_salesforceId.salesforceIdFlag.html) 标志,确保提供的字符串是有效的 Salesforce ID。
+- [`duration`](https://salesforcecli.github.io/sf-plugins-core/functions/flags_duration.durationFlag.html) 标志,它将提供的整数转换为我们用于处理基于时间的值的 `Duration` 实例。
+
+如果你想看更多的示例,通过[这里](https://github.com/salesforcecli/sf-plugins-core/tree/main/src/flags)查看。你也可以阅读 [API 文档](https://salesforcecli.github.io/sf-plugins-core/)。
+
+## 可选标志输入
+
+下面是用户可以使用输入标志的一些其他方式。这是假设命令有像 `-f, --file=file` 和 `-v, --verbose` 这样的标志(字符串和布尔标志):
+
+```sh-session
+$ mycli --verbose
+$ mycli -v
+$ mycli --file=foo
+$ mycli --file foo
+$ mycli -f foo
+$ mycli -f=foo
+$ mycli -ffoo
+$ mycli -vffoo
+```
+
+最后一个乍一看似乎有点奇怪,但它在 unix 中是相对标准的,并使像 `tar -xvzfmytarball.tar.gz` 这样的命令成为可能。
+
+请参阅我们的博客文章 [CLI Flags Explained](../blog/2019/02/20/cli-flags-explained),以深入了解 CLI 标志。
diff --git a/website/i18n/zh/docusaurus-plugin-content-docs/current/flexible_taxonomy.md b/website/i18n/zh/docusaurus-plugin-content-docs/current/flexible_taxonomy.md
new file mode 100644
index 00000000..102fecb5
--- /dev/null
+++ b/website/i18n/zh/docusaurus-plugin-content-docs/current/flexible_taxonomy.md
@@ -0,0 +1,62 @@
+---
+title: 灵活分类法
+description: 将用户友好性提升到新的水平
+---
+
+如果你希望你的客户在执行命令时不遵守已定义的命令分类,你可以启用 `flexibleTaxonomy` 并在你的 package.json 的 `oclif` 部分添加一个钩子:
+
+```json
+{
+ "oclif": {
+ "flexibleTaxonomy": true,
+ "hooks": {
+ "command_incomplete": "./dist/hooks/command_incomplete.js"
+ }
+ }
+}
+```
+
+启用灵活分类法有两个主要好处:
+
+1. 它使你的CLI更加用户友好。例如,你可能有一个命令`my-cli foobars list`。如果用户错误地输入 `my-cli list foobars`,oclif 会自动知道它应该执行 `foobars list`,而不是抛出错误。
+2. 如果用户只提供了命令的一部分,则它为你提供了提示用户输入正确命令的机会。这使得单个命令更易于解释,特别是当你有大量命令时。更多细节请参见[钩子实现](#钩子实现)。
+
+### 钩子实现
+
+当启用 `flexibleTaxonomy` 时,oclif 将在用户输入不完整的命令时运行 `command_incomplete` 钩子(例如,命令是 `one two three` ,但他们只输入了 `two`)。这个钩子为你提供了创建交互式用户体验的机会。
+
+此示例说明如何使用 [inquirer](https://www.npmjs.com/package/inquirer) 包提示用户要运行的命令:
+
+```typescript
+import { Hook, toConfiguredId, toStandardizedId } from '@oclif/core';
+import { select } from '@inquirer/prompts';
+
+const hook: Hook.CommandIncomplete = async function ({
+ config,
+ matches,
+ argv,
+}) {
+ const command = await select({
+ message: 'Which of these commands would you like to run?',
+ choices: matches.map((p) => toConfiguredId(p.id, config)),
+ });
+
+ if (argv.includes('--help') || argv.includes('-h')) {
+ return config.runCommand('help', [toStandardizedId(command, config)]);
+ }
+
+ return config.runCommand(toStandardizedId(command, config), argv);
+};
+
+export default hook;
+```
+
+这是用户将看到的提示:
+
+```shell
+$ my-cli list
+? Which of these commands did you mean (Use arrow keys)
+❯ foobars list
+ config list
+ env list
+```
diff --git a/website/i18n/zh/docusaurus-plugin-content-docs/current/generator_commands.md b/website/i18n/zh/docusaurus-plugin-content-docs/current/generator_commands.md
new file mode 100644
index 00000000..af3c0b5c
--- /dev/null
+++ b/website/i18n/zh/docusaurus-plugin-content-docs/current/generator_commands.md
@@ -0,0 +1,105 @@
+---
+title: 生成器命令
+---
+
+- [`oclif generate NAME`](#oclif-generate-name)
+- [`oclif generate command NAME`](#oclif-generate-command-name)
+- [`oclif generate hook NAME`](#oclif-generate-hook-name)
+
+## `oclif generate NAME`
+
+生成一个新的 CLI
+
+```shell
+USAGE
+ $ oclif generate NAME [-y] [--author ] [--bin ] [--description ] [--license ]
+ [--module-type CommonJS|ESM] [--name ] [--owner ] [--package-manager npm|yarn] [--repository ]
+ [-d ]
+
+ARGUMENTS
+ NAME Directory name of new project.
+
+FLAGS
+ -d, --output-dir= Directory to build the CLI in.
+ -y, --yes Use defaults for all prompts. Individual flags will override defaults.
+ --author= Supply answer for prompt: Author
+ --bin= Supply answer for prompt: Command bin name the CLI will export
+ --description= Supply answer for prompt: Description
+ --license= Supply answer for prompt: License
+ --module-type=