@icebreakers/monorepo-templates 1.2.1 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (246) hide show
  1. package/assets/.github/workflows/ci.yml +4 -4
  2. package/assets/.github/workflows/release.yml +8 -7
  3. package/assets/package.json +9 -8
  4. package/assets/renovate.json +0 -1
  5. package/assets/turbo.json +3 -0
  6. package/assets-data.mjs +0 -1
  7. package/dist/cli.mjs +1 -1
  8. package/dist/index.mjs +1 -1
  9. package/dist/{prepare--cxFop8c.mjs → prepare-D7eJqEqy.mjs} +1 -2
  10. package/package.json +5 -5
  11. package/templates/cli/package.json +1 -1
  12. package/templates/client/package.json +10 -10
  13. package/templates/client/worker-configuration.d.ts +463 -202
  14. package/templates/server/package.json +3 -3
  15. package/templates/server/worker-configuration.d.ts +463 -202
  16. package/templates/tsdown/package.json +1 -1
  17. package/templates/vitepress/.vitepress/config.ts +26 -126
  18. package/templates/vitepress/.vitepress/env.d.ts +1 -0
  19. package/templates/vitepress/.vitepress/home/content.ts +94 -0
  20. package/templates/vitepress/.vitepress/home/types.ts +49 -0
  21. package/templates/vitepress/.vitepress/navigation/routes.ts +146 -0
  22. package/templates/vitepress/.vitepress/seo.ts +54 -0
  23. package/templates/vitepress/.vitepress/theme/Layout.vue +27 -0
  24. package/templates/vitepress/.vitepress/theme/components/HomePage.vue +112 -0
  25. package/templates/vitepress/.vitepress/theme/home/foundation.css +237 -0
  26. package/templates/vitepress/.vitepress/theme/home/index.css +3 -0
  27. package/templates/vitepress/.vitepress/theme/home/responsive.css +142 -0
  28. package/templates/vitepress/.vitepress/theme/home/sections.css +232 -0
  29. package/templates/vitepress/.vitepress/theme/index.ts +11 -1
  30. package/templates/vitepress/ai/llms-txt.md +2 -2
  31. package/templates/vitepress/index.md +6 -60
  32. package/templates/vitepress/learn/index.md +18 -0
  33. package/templates/vitepress/{monorepo → learn/monorepo}/commands.md +1 -1
  34. package/templates/vitepress/{monorepo → learn/monorepo}/index.md +3 -3
  35. package/templates/vitepress/{monorepo → learn/monorepo}/templates.md +1 -1
  36. package/templates/vitepress/learn/packages/examples/2.npm-basic-package/README.md +1 -0
  37. package/templates/vitepress/learn/packages/examples/3.npm-basic-package/README.md +1 -0
  38. package/templates/vitepress/learn/packages/index.md +36 -0
  39. package/templates/vitepress/learn/packages/modern/bundlers.md +40 -0
  40. package/templates/vitepress/learn/packages/modern/dts.md +48 -0
  41. package/templates/vitepress/learn/packages/modern/esm-vs-cjs.md +42 -0
  42. package/templates/vitepress/learn/packages/modern/index.md +38 -0
  43. package/templates/vitepress/learn/packages/modern/package-entry-points.md +46 -0
  44. package/templates/vitepress/learn/packages/modern/typescript.md +43 -0
  45. package/templates/vitepress/{why/index.md → learn/packages/modern-overview.md} +1 -1
  46. package/templates/vitepress/learn/packages/module-extensions.md +34 -0
  47. package/templates/vitepress/learn/packages/publish.md +43 -0
  48. package/templates/vitepress/learn/packages/reuse-javascript.md +39 -0
  49. package/templates/vitepress/learn/packages/runtime-globals.md +36 -0
  50. package/templates/vitepress/{repoctl/index.md → learn/repoctl-model.md} +8 -8
  51. package/templates/vitepress/learn/tools/changeset.md +30 -0
  52. package/templates/vitepress/learn/tools/husky.md +50 -0
  53. package/templates/vitepress/learn/tools/lint-staged.md +39 -0
  54. package/templates/vitepress/{tools → learn/tools}/llms-txt.md +1 -1
  55. package/templates/vitepress/learn/tools/pnpm.md +47 -0
  56. package/templates/vitepress/learn/tools/renovate.md +31 -0
  57. package/templates/vitepress/learn/tools/turborepo.md +40 -0
  58. package/templates/vitepress/package.json +14 -7
  59. package/templates/vitepress/public/brand/apple-touch-icon.png +0 -0
  60. package/templates/vitepress/public/brand/favicon.ico +0 -0
  61. package/templates/vitepress/public/brand/repoctl-lockup-dark.svg +6 -0
  62. package/templates/vitepress/public/brand/repoctl-lockup.svg +20 -0
  63. package/templates/vitepress/public/brand/repoctl-mark-192.png +0 -0
  64. package/templates/vitepress/public/brand/repoctl-mark-dark.svg +13 -0
  65. package/templates/vitepress/public/brand/repoctl-mark.svg +13 -0
  66. package/templates/vitepress/public/brand/repoctl-social-en.png +0 -0
  67. package/templates/vitepress/public/brand/repoctl-social-en.webp +0 -0
  68. package/templates/vitepress/public/brand/repoctl-social-zh.png +0 -0
  69. package/templates/vitepress/public/brand/repoctl-social-zh.webp +0 -0
  70. package/templates/vitepress/public/favicon.ico +0 -0
  71. package/templates/vitepress/public/logo.jpg +0 -0
  72. package/templates/vitepress/public/repoctl-doctor.png +0 -0
  73. package/templates/vitepress/{repoctl → reference}/commands.md +2 -2
  74. package/templates/vitepress/reference/index.md +15 -0
  75. package/templates/vitepress/reference/output.md +37 -0
  76. package/templates/vitepress/{repoctl → reference}/templates.md +2 -2
  77. package/templates/vitepress/scripts/check-locales.ts +196 -0
  78. package/templates/vitepress/start/choose-next.md +14 -0
  79. package/templates/vitepress/start/first-run.md +39 -0
  80. package/templates/vitepress/start/index.md +26 -0
  81. package/templates/vitepress/{repoctl/getting-started.md → start/install.md} +5 -5
  82. package/templates/vitepress/{repoctl → tasks}/adopt-existing.md +30 -4
  83. package/templates/vitepress/{repoctl → tasks}/checks.md +27 -1
  84. package/templates/vitepress/{repoctl/workflows.md → tasks/ci.md} +65 -4
  85. package/templates/vitepress/tasks/create-project.md +37 -0
  86. package/templates/vitepress/{repoctl/scenarios.md → tasks/index.md} +8 -8
  87. package/templates/vitepress/tasks/release.md +31 -0
  88. package/templates/vitepress/{repoctl → tasks}/reports.md +25 -0
  89. package/templates/vitepress/{repoctl → tasks}/troubleshooting.md +30 -4
  90. package/templates/vitepress/tsconfig.json +7 -0
  91. package/templates/vitepress/wrangler.jsonc +20 -3
  92. package/templates/vitepress/zh/ai/index.md +1 -1
  93. package/templates/vitepress/zh/ai/llms-txt.md +7 -7
  94. package/templates/vitepress/zh/index.md +6 -63
  95. package/templates/vitepress/zh/learn/index.md +18 -0
  96. package/templates/vitepress/zh/{monorepo → learn/monorepo}/commands.md +3 -3
  97. package/templates/vitepress/zh/{monorepo → learn/monorepo}/manage.md +4 -4
  98. package/templates/vitepress/zh/{monorepo → learn/monorepo}/templates.md +2 -2
  99. package/templates/vitepress/zh/{monorepo → learn/monorepo}/troubleshooting.md +2 -2
  100. package/templates/vitepress/zh/learn/packages/examples/2.npm-basic-package/README.md +1 -0
  101. package/templates/vitepress/zh/learn/packages/examples/3.npm-basic-package/README.md +1 -0
  102. package/templates/vitepress/zh/{why → learn/packages}/modern/index.md +1 -1
  103. package/templates/vitepress/zh/learn/packages/modern-overview.md +38 -0
  104. package/templates/vitepress/zh/{repoctl/index.md → learn/repoctl-model.md} +19 -19
  105. package/templates/vitepress/zh/{tools → learn/tools}/husky.md +1 -1
  106. package/templates/vitepress/zh/{tools → learn/tools}/lint-staged.md +1 -1
  107. package/templates/vitepress/zh/{tools → learn/tools}/llms-txt.md +1 -1
  108. package/templates/vitepress/zh/{tools → learn/tools}/pnpm.md +1 -1
  109. package/templates/vitepress/zh/{tools → learn/tools}/turborepo.md +1 -1
  110. package/templates/vitepress/zh/{repoctl → reference}/commands.md +4 -4
  111. package/templates/vitepress/zh/{repoctl → reference}/config.md +1 -1
  112. package/templates/vitepress/zh/reference/index.md +15 -0
  113. package/templates/vitepress/zh/reference/output.md +37 -0
  114. package/templates/vitepress/zh/{repoctl → reference}/templates.md +4 -4
  115. package/templates/vitepress/zh/start/choose-next.md +14 -0
  116. package/templates/vitepress/zh/{repoctl/doctor.md → start/diagnose.md} +1 -1
  117. package/templates/vitepress/zh/start/first-run.md +39 -0
  118. package/templates/vitepress/zh/start/index.md +26 -0
  119. package/templates/vitepress/zh/{repoctl/getting-started.md → start/install.md} +5 -5
  120. package/templates/vitepress/zh/{repoctl → tasks}/adopt-existing.md +30 -4
  121. package/templates/vitepress/zh/{repoctl → tasks}/checks.md +27 -1
  122. package/templates/vitepress/zh/{repoctl/workflows.md → tasks/ci.md} +73 -12
  123. package/templates/vitepress/zh/tasks/create-project.md +37 -0
  124. package/templates/vitepress/zh/{repoctl/scenarios.md → tasks/index.md} +8 -8
  125. package/templates/vitepress/zh/tasks/release.md +31 -0
  126. package/templates/vitepress/zh/{repoctl → tasks}/reports.md +25 -0
  127. package/templates/vitepress/zh/{repoctl → tasks}/troubleshooting.md +39 -13
  128. package/templates/vue-lib/package.json +3 -3
  129. package/assets/netlify.toml +0 -14
  130. package/templates/vitepress/getting-started.md +0 -11
  131. package/templates/vitepress/knowledge/index.md +0 -26
  132. package/templates/vitepress/thinking.md +0 -7
  133. package/templates/vitepress/tools/changeset.md +0 -25
  134. package/templates/vitepress/tools/husky.md +0 -12
  135. package/templates/vitepress/tools/lint-staged.md +0 -12
  136. package/templates/vitepress/tools/pnpm.md +0 -15
  137. package/templates/vitepress/tools/renovate.md +0 -7
  138. package/templates/vitepress/tools/turborepo.md +0 -14
  139. package/templates/vitepress/why/examples/2.npm-basic-package/README.md +0 -1
  140. package/templates/vitepress/why/examples/3.npm-basic-package/README.md +0 -1
  141. package/templates/vitepress/why/how-to-reuse-js-code.md +0 -9
  142. package/templates/vitepress/why/js-cjs-mjs.md +0 -12
  143. package/templates/vitepress/why/js-keywords.md +0 -7
  144. package/templates/vitepress/why/modern/bundlers.md +0 -5
  145. package/templates/vitepress/why/modern/dts.md +0 -7
  146. package/templates/vitepress/why/modern/esm-vs-cjs.md +0 -7
  147. package/templates/vitepress/why/modern/index.md +0 -14
  148. package/templates/vitepress/why/modern/package-entry-points.md +0 -17
  149. package/templates/vitepress/why/modern/typescript.md +0 -7
  150. package/templates/vitepress/why/publish-basic-npm-package.md +0 -19
  151. package/templates/vitepress/why/what-is-npm-package.md +0 -7
  152. package/templates/vitepress/zh/getting-started.md +0 -40
  153. package/templates/vitepress/zh/knowledge/index.md +0 -50
  154. package/templates/vitepress/zh/thinking.md +0 -88
  155. package/templates/vitepress/zh/why/examples/2.npm-basic-package/README.md +0 -1
  156. package/templates/vitepress/zh/why/examples/3.npm-basic-package/README.md +0 -1
  157. package/templates/vitepress/zh/why/index.md +0 -1
  158. /package/templates/vitepress/{monorepo → learn/monorepo}/manage.md +0 -0
  159. /package/templates/vitepress/{monorepo → learn/monorepo}/publish.md +0 -0
  160. /package/templates/vitepress/{monorepo → learn/monorepo}/troubleshooting.md +0 -0
  161. /package/templates/vitepress/{why → learn/packages}/assets/npm-dt.svg +0 -0
  162. /package/templates/vitepress/{why → learn/packages}/assets/npm-ts.svg +0 -0
  163. /package/templates/vitepress/{why → learn/packages}/examples/0.npm-basic-package/index.js +0 -0
  164. /package/templates/vitepress/{why → learn/packages}/examples/0.npm-basic-package/package.json +0 -0
  165. /package/templates/vitepress/{why → learn/packages}/examples/1.npm-basic-package/index.cjs +0 -0
  166. /package/templates/vitepress/{why → learn/packages}/examples/1.npm-basic-package/index.d.ts +0 -0
  167. /package/templates/vitepress/{why → learn/packages}/examples/1.npm-basic-package/index.js +0 -0
  168. /package/templates/vitepress/{why → learn/packages}/examples/1.npm-basic-package/package.json +0 -0
  169. /package/templates/vitepress/{why → learn/packages}/examples/2.npm-basic-package/package-lock.json +0 -0
  170. /package/templates/vitepress/{why → learn/packages}/examples/2.npm-basic-package/package.json +0 -0
  171. /package/templates/vitepress/{why → learn/packages}/examples/2.npm-basic-package/rename-ext.js +0 -0
  172. /package/templates/vitepress/{why → learn/packages}/examples/2.npm-basic-package/src/index.ts +0 -0
  173. /package/templates/vitepress/{why → learn/packages}/examples/2.npm-basic-package/tsconfig.cjs.json +0 -0
  174. /package/templates/vitepress/{why → learn/packages}/examples/2.npm-basic-package/tsconfig.esm.json +0 -0
  175. /package/templates/vitepress/{why → learn/packages}/examples/2.npm-basic-package/tsconfig.json +0 -0
  176. /package/templates/vitepress/{why → learn/packages}/examples/3.npm-basic-package/package-lock.json +0 -0
  177. /package/templates/vitepress/{why → learn/packages}/examples/3.npm-basic-package/package.json +0 -0
  178. /package/templates/vitepress/{why → learn/packages}/examples/3.npm-basic-package/src/index.ts +0 -0
  179. /package/templates/vitepress/{why → learn/packages}/examples/3.npm-basic-package/tsconfig.json +0 -0
  180. /package/templates/vitepress/{why → learn/packages}/examples/3.npm-basic-package/tsdown.config.ts +0 -0
  181. /package/templates/vitepress/{why → learn/packages}/examples/usage-cjs/cjs.cjs +0 -0
  182. /package/templates/vitepress/{why → learn/packages}/examples/usage-cjs/esm.mjs +0 -0
  183. /package/templates/vitepress/{why → learn/packages}/examples/usage-cjs/index.js +0 -0
  184. /package/templates/vitepress/{why → learn/packages}/examples/usage-cjs/package-lock.json +0 -0
  185. /package/templates/vitepress/{why → learn/packages}/examples/usage-cjs/package.json +0 -0
  186. /package/templates/vitepress/{why → learn/packages}/examples/usage-esm/cjs.cjs +0 -0
  187. /package/templates/vitepress/{why → learn/packages}/examples/usage-esm/createRequire.js +0 -0
  188. /package/templates/vitepress/{why → learn/packages}/examples/usage-esm/esm.mjs +0 -0
  189. /package/templates/vitepress/{why → learn/packages}/examples/usage-esm/index.js +0 -0
  190. /package/templates/vitepress/{why → learn/packages}/examples/usage-esm/package-lock.json +0 -0
  191. /package/templates/vitepress/{why → learn/packages}/examples/usage-esm/package.json +0 -0
  192. /package/templates/vitepress/{tools → learn/tools}/index.md +0 -0
  193. /package/templates/vitepress/{repoctl → reference}/aliases.md +0 -0
  194. /package/templates/vitepress/{repoctl → reference}/config.md +0 -0
  195. /package/templates/vitepress/{repoctl → reference}/execution-model.md +0 -0
  196. /package/templates/vitepress/{repoctl → reference}/template-assets.md +0 -0
  197. /package/templates/vitepress/{repoctl/doctor.md → start/diagnose.md} +0 -0
  198. /package/templates/vitepress/zh/{monorepo → learn/monorepo}/index.md +0 -0
  199. /package/templates/vitepress/zh/{monorepo → learn/monorepo}/publish.md +0 -0
  200. /package/templates/vitepress/zh/{why → learn/packages}/assets/npm-dt.svg +0 -0
  201. /package/templates/vitepress/zh/{why → learn/packages}/assets/npm-ts.svg +0 -0
  202. /package/templates/vitepress/zh/{why → learn/packages}/examples/0.npm-basic-package/index.js +0 -0
  203. /package/templates/vitepress/zh/{why → learn/packages}/examples/0.npm-basic-package/package.json +0 -0
  204. /package/templates/vitepress/zh/{why → learn/packages}/examples/1.npm-basic-package/index.cjs +0 -0
  205. /package/templates/vitepress/zh/{why → learn/packages}/examples/1.npm-basic-package/index.d.ts +0 -0
  206. /package/templates/vitepress/zh/{why → learn/packages}/examples/1.npm-basic-package/index.js +0 -0
  207. /package/templates/vitepress/zh/{why → learn/packages}/examples/1.npm-basic-package/package.json +0 -0
  208. /package/templates/vitepress/zh/{why → learn/packages}/examples/2.npm-basic-package/package-lock.json +0 -0
  209. /package/templates/vitepress/zh/{why → learn/packages}/examples/2.npm-basic-package/package.json +0 -0
  210. /package/templates/vitepress/zh/{why → learn/packages}/examples/2.npm-basic-package/rename-ext.js +0 -0
  211. /package/templates/vitepress/zh/{why → learn/packages}/examples/2.npm-basic-package/src/index.ts +0 -0
  212. /package/templates/vitepress/zh/{why → learn/packages}/examples/2.npm-basic-package/tsconfig.cjs.json +0 -0
  213. /package/templates/vitepress/zh/{why → learn/packages}/examples/2.npm-basic-package/tsconfig.esm.json +0 -0
  214. /package/templates/vitepress/zh/{why → learn/packages}/examples/2.npm-basic-package/tsconfig.json +0 -0
  215. /package/templates/vitepress/zh/{why → learn/packages}/examples/3.npm-basic-package/package-lock.json +0 -0
  216. /package/templates/vitepress/zh/{why → learn/packages}/examples/3.npm-basic-package/package.json +0 -0
  217. /package/templates/vitepress/zh/{why → learn/packages}/examples/3.npm-basic-package/src/index.ts +0 -0
  218. /package/templates/vitepress/zh/{why → learn/packages}/examples/3.npm-basic-package/tsconfig.json +0 -0
  219. /package/templates/vitepress/zh/{why → learn/packages}/examples/3.npm-basic-package/tsdown.config.ts +0 -0
  220. /package/templates/vitepress/zh/{why → learn/packages}/examples/usage-cjs/cjs.cjs +0 -0
  221. /package/templates/vitepress/zh/{why → learn/packages}/examples/usage-cjs/esm.mjs +0 -0
  222. /package/templates/vitepress/zh/{why → learn/packages}/examples/usage-cjs/index.js +0 -0
  223. /package/templates/vitepress/zh/{why → learn/packages}/examples/usage-cjs/package-lock.json +0 -0
  224. /package/templates/vitepress/zh/{why → learn/packages}/examples/usage-cjs/package.json +0 -0
  225. /package/templates/vitepress/zh/{why → learn/packages}/examples/usage-esm/cjs.cjs +0 -0
  226. /package/templates/vitepress/zh/{why → learn/packages}/examples/usage-esm/createRequire.js +0 -0
  227. /package/templates/vitepress/zh/{why → learn/packages}/examples/usage-esm/esm.mjs +0 -0
  228. /package/templates/vitepress/zh/{why → learn/packages}/examples/usage-esm/index.js +0 -0
  229. /package/templates/vitepress/zh/{why → learn/packages}/examples/usage-esm/package-lock.json +0 -0
  230. /package/templates/vitepress/zh/{why → learn/packages}/examples/usage-esm/package.json +0 -0
  231. /package/templates/vitepress/zh/{why/what-is-npm-package.md → learn/packages/index.md} +0 -0
  232. /package/templates/vitepress/zh/{why → learn/packages}/modern/bundlers.md +0 -0
  233. /package/templates/vitepress/zh/{why → learn/packages}/modern/dts.md +0 -0
  234. /package/templates/vitepress/zh/{why → learn/packages}/modern/esm-vs-cjs.md +0 -0
  235. /package/templates/vitepress/zh/{why → learn/packages}/modern/package-entry-points.md +0 -0
  236. /package/templates/vitepress/zh/{why → learn/packages}/modern/typescript.md +0 -0
  237. /package/templates/vitepress/zh/{why/js-cjs-mjs.md → learn/packages/module-extensions.md} +0 -0
  238. /package/templates/vitepress/zh/{why/publish-basic-npm-package.md → learn/packages/publish.md} +0 -0
  239. /package/templates/vitepress/zh/{why/how-to-reuse-js-code.md → learn/packages/reuse-javascript.md} +0 -0
  240. /package/templates/vitepress/zh/{why/js-keywords.md → learn/packages/runtime-globals.md} +0 -0
  241. /package/templates/vitepress/zh/{tools → learn/tools}/changeset.md +0 -0
  242. /package/templates/vitepress/zh/{tools → learn/tools}/index.md +0 -0
  243. /package/templates/vitepress/zh/{tools → learn/tools}/renovate.md +0 -0
  244. /package/templates/vitepress/zh/{repoctl → reference}/aliases.md +0 -0
  245. /package/templates/vitepress/zh/{repoctl → reference}/execution-model.md +0 -0
  246. /package/templates/vitepress/zh/{repoctl → reference}/template-assets.md +0 -0
@@ -0,0 +1,50 @@
1
+ # Husky
2
+
3
+ Husky connects Git hooks to versioned repository scripts. In a repoctl workspace it is only a trigger: the actual verification lives in `repo verify` so people, CI, and hooks use the same contract.
4
+
5
+ ## Recommended hooks
6
+
7
+ ```sh
8
+ # .husky/pre-commit
9
+ pnpm exec repo verify pre-commit
10
+
11
+ # .husky/commit-msg
12
+ pnpm exec repo verify commit-msg "$1"
13
+
14
+ # .husky/pre-push
15
+ pnpm exec repo verify pre-push
16
+ ```
17
+
18
+ Keep hooks small. A hook should select a repository task, not duplicate lint, typecheck, or build commands that will drift from CI.
19
+
20
+ ## What each hook protects
21
+
22
+ | Hook | Purpose | Usual scope |
23
+ | ------------ | ------------------------------------ | --------------------------------------------------- |
24
+ | `pre-commit` | Fast feedback before a commit exists | Staged formatting, lint, and typecheck |
25
+ | `commit-msg` | Enforce the commit message contract | The pending commit message file |
26
+ | `pre-push` | Catch broader integration failures | Root checks and affected build, test, and tsd tasks |
27
+
28
+ `repo doctor` reports incomplete Husky and lint-staged configuration. Use `repo upgrade --no-overwrite` to preview managed hook changes before accepting them.
29
+
30
+ ## Install and initialize
31
+
32
+ ```bash
33
+ pnpm add -D husky
34
+ pnpm exec husky init
35
+ ```
36
+
37
+ The initializer creates `.husky/pre-commit`. Replace its generated command with the repository task instead of adding a second tool-specific pipeline.
38
+
39
+ ## Troubleshooting
40
+
41
+ - Confirm the hook file is executable after a fresh clone.
42
+ - Run the command from the hook directly before debugging Git.
43
+ - Do not use interactive prompts in a hook.
44
+ - Keep network calls and release work out of `pre-commit`.
45
+
46
+ ## Keep Reading
47
+
48
+ - [lint-staged](./lint-staged.md)
49
+ - [Add checks to CI](/tasks/ci)
50
+ - [Verification](/tasks/checks)
@@ -0,0 +1,39 @@
1
+ # lint-staged
2
+
3
+ lint-staged runs focused checks against files staged for a commit. It keeps the pre-commit hook quick while preserving the same ESLint, Stylelint, and typecheck rules used elsewhere in the workspace.
4
+
5
+ ## Recommended responsibility
6
+
7
+ Use lint-staged for checks that can safely operate on selected files. Keep full builds, integration tests, and release checks in `repo check --full` or CI.
8
+
9
+ ```js
10
+ // lint-staged.config.js
11
+ export default {
12
+ '*.{js,mjs,cjs,ts,tsx,vue}': ['eslint --fix'],
13
+ '*.{css,scss,less,vue}': ['stylelint --fix'],
14
+ }
15
+ ```
16
+
17
+ repoctl-managed workspaces also route staged TypeScript and Vue files into the appropriate workspace typecheck command. This matters because Vue packages need `vue-tsc`, while TypeScript-only packages use `tsc`.
18
+
19
+ ## Pair it with Husky
20
+
21
+ ```sh
22
+ # .husky/pre-commit
23
+ pnpm exec repo verify pre-commit
24
+ ```
25
+
26
+ The hook selects repoctl's pre-commit workflow. That workflow can call lint-staged without embedding a second copy of the configuration in the hook file.
27
+
28
+ ## Safe fixes
29
+
30
+ - Use `--fix` only for deterministic formatting and lint repairs.
31
+ - Do not stage unrelated generated output from a task.
32
+ - Run `pnpm lint` before opening a pull request because it covers more than staged files.
33
+ - Test hook behavior from a clean index, not only with already-staged fixes.
34
+
35
+ ## Keep Reading
36
+
37
+ - [Husky](./husky.md)
38
+ - [Verification](/tasks/checks)
39
+ - [Add checks to CI](/tasks/ci)
@@ -4,4 +4,4 @@
4
4
 
5
5
  This site generates an English-default `/llms.txt` and a larger `/llms-full.txt`. Simplified Chinese content is namespaced under `/zh/`, and historical or internal files are excluded from the index.
6
6
 
7
- See the [repoctl AI documentation](../ai/llms-txt.md) for URLs and maintenance rules.
7
+ See the [repoctl AI documentation](/ai/llms-txt) for URLs and maintenance rules.
@@ -0,0 +1,47 @@
1
+ # pnpm
2
+
3
+ pnpm is the package manager used by repoctl workspaces. Its workspace protocol, content-addressable store, and filter syntax make it a practical fit for repositories with several packages and applications.
4
+
5
+ ## Install dependencies
6
+
7
+ ```bash
8
+ pnpm install
9
+ pnpm install --frozen-lockfile
10
+ ```
11
+
12
+ Use the frozen form in CI. It proves that `package.json` files and the lockfile describe the same dependency graph.
13
+
14
+ ## Work with one workspace
15
+
16
+ ```bash
17
+ pnpm --filter repoctl build
18
+ pnpm --filter @icebreakers/monorepo test
19
+ pnpm --filter './packages/*' lint
20
+ ```
21
+
22
+ Filters are a routing tool, not a replacement for repository scripts. Prefer an existing package script over an ad hoc command when a task should be repeatable.
23
+
24
+ ## Link local packages
25
+
26
+ ```json
27
+ {
28
+ "dependencies": {
29
+ "@icebreakers/monorepo": "workspace:*"
30
+ }
31
+ }
32
+ ```
33
+
34
+ The `workspace:` protocol prevents accidentally resolving a local package from the public registry during development.
35
+
36
+ ## Operational guidance
37
+
38
+ - Pin the package manager in the root `package.json`.
39
+ - Commit `pnpm-lock.yaml` for applications and monorepos.
40
+ - Use `pnpm exec` for binaries supplied by the current workspace.
41
+ - Use `pnpm --filter` for a scoped package command and Turbo for graph-wide task orchestration.
42
+
43
+ ## Keep Reading
44
+
45
+ - [Turborepo](./turborepo.md)
46
+ - [Managing A Monorepo](/learn/monorepo/manage.md)
47
+ - [repoctl Commands](/reference/commands)
@@ -0,0 +1,31 @@
1
+ # Renovate
2
+
3
+ Renovate keeps dependencies current through reviewable pull requests. It is most useful when the configuration groups compatible updates, lets CI prove the upgrade, and avoids mixing unrelated ecosystem changes.
4
+
5
+ ## Repository policy
6
+
7
+ ```json
8
+ {
9
+ "extends": ["config:recommended", "group:allNonMajor"],
10
+ "rangeStrategy": "bump",
11
+ "automerge": true,
12
+ "automergeType": "pr"
13
+ }
14
+ ```
15
+
16
+ The repository groups compatible minor and patch updates. Cloudflare Workers tooling is grouped separately because Wrangler and its Vite plugin have a deliberate compatibility relationship.
17
+
18
+ ## Review an update
19
+
20
+ 1. Read the package release notes when the update changes build, test, or deployment tooling.
21
+ 2. Run the normal build and validation sequence against the updated lockfile.
22
+ 3. Check generated assets and package metadata for unexpected churn.
23
+ 4. Merge only after the configured checks prove the update is compatible.
24
+
25
+ Do not rely on commit-message directives for a retired deployment provider. Deployment behavior belongs in the active platform configuration and CI settings.
26
+
27
+ ## Keep Reading
28
+
29
+ - [pnpm](./pnpm.md)
30
+ - [Add checks to CI](/tasks/ci)
31
+ - [Troubleshoot](/tasks/troubleshooting)
@@ -0,0 +1,40 @@
1
+ # Turborepo
2
+
3
+ Turborepo turns package scripts into a dependency-aware task graph. repoctl workspaces use it for the repository-wide work that should be cached and run in dependency order.
4
+
5
+ ## Define task boundaries
6
+
7
+ ```json
8
+ {
9
+ "tasks": {
10
+ "build": { "dependsOn": ["^build"], "outputs": ["dist/**"] },
11
+ "test": { "dependsOn": ["build"], "outputs": ["coverage/**"] },
12
+ "typecheck": { "dependsOn": ["^typecheck"], "outputs": [] }
13
+ }
14
+ }
15
+ ```
16
+
17
+ `^build` means that a package must build its workspace dependencies before its own build starts. Declare outputs accurately so the cache can restore useful artifacts and ignore transient files.
18
+
19
+ ## Run graph-aware tasks
20
+
21
+ ```bash
22
+ pnpm turbo run build
23
+ pnpm turbo run test --filter=repoctl
24
+ pnpm turbo run lint typecheck
25
+ ```
26
+
27
+ Use root scripts for the common entrypoints. The root script is the stable command people and CI should remember; Turbo remains the graph executor beneath it.
28
+
29
+ ## Cache with care
30
+
31
+ - Include configuration files that materially affect output in task inputs.
32
+ - Keep secrets out of cached output.
33
+ - Set `outputs: []` for validation-only tasks.
34
+ - Use `--force` only when diagnosing cache behavior.
35
+
36
+ ## Keep Reading
37
+
38
+ - [pnpm](./pnpm.md)
39
+ - [Verification](/tasks/checks)
40
+ - [Managing A Monorepo](/learn/monorepo/manage.md)
@@ -5,7 +5,7 @@
5
5
  "private": true,
6
6
  "description": "Documentation website for repoctl",
7
7
  "author": "ice breaker <hi@sonofmagic.top>",
8
- "homepage": "https://repo.icebreaker.top",
8
+ "homepage": "https://repoctl.icebreaker.top",
9
9
  "repository": {
10
10
  "type": "git",
11
11
  "url": "git+https://github.com/sonofmagic/repoctl.git",
@@ -22,11 +22,15 @@
22
22
  ],
23
23
  "scripts": {
24
24
  "dev": "vitepress dev",
25
- "build": "vitepress build",
25
+ "check:locales": "tsx scripts/check-locales.ts",
26
+ "build": "pnpm run check:locales && vitepress build",
26
27
  "preview": "vitepress preview",
28
+ "deploy": "wrangler deploy",
29
+ "deploy:preview": "wrangler versions upload",
30
+ "deploy:dry-run": "wrangler deploy --dry-run",
27
31
  "lint": "eslint .",
28
32
  "lint:fix": "eslint . --fix",
29
- "typecheck": "tsc -p tsconfig.json"
33
+ "typecheck": "vue-tsc -p tsconfig.json --noEmit"
30
34
  },
31
35
  "dependencies": {
32
36
  "vue": "^3.5.41"
@@ -34,14 +38,17 @@
34
38
  "devDependencies": {
35
39
  "@braintree/sanitize-url": "^7.1.2",
36
40
  "@tailwindcss/vite": "^4.3.3",
37
- "cytoscape": "^3.34.1",
41
+ "cytoscape": "^3.34.2",
38
42
  "cytoscape-cose-bilkent": "^4.1.0",
39
- "dayjs": "^1.11.21",
43
+ "dayjs": "^1.11.23",
40
44
  "debug": "^4.4.3",
41
- "mermaid": "^11.16.1",
45
+ "mermaid": "^11.17.2",
42
46
  "tailwindcss": "^4.3.3",
47
+ "tsx": "^4.23.12",
43
48
  "vitepress": "^1.6.4",
44
49
  "vitepress-plugin-llms": "^1.13.5",
45
- "vitepress-plugin-mermaid": "^2.0.17"
50
+ "vitepress-plugin-mermaid": "^2.0.17",
51
+ "vue-tsc": "^3.3.11",
52
+ "wrangler": "^4.125.0"
46
53
  }
47
54
  }
@@ -0,0 +1,6 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="300" height="64" viewBox="0 0 300 64" fill="none">
2
+ <g stroke="#F4F6FA" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"><path d="M14 14C22 14 24 24 32 32"/><path d="M14 32H32"/><path d="M14 50C22 50 24 40 32 32"/></g>
3
+ <g fill="#6F94FF"><circle cx="10" cy="14" r="4"/><circle cx="10" cy="32" r="4"/><circle cx="10" cy="50" r="4"/></g>
4
+ <path d="M38 22L48 32L38 42" stroke="#6F94FF" stroke-width="5" stroke-linecap="round" stroke-linejoin="round"/>
5
+ <g stroke="#F4F6FA" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"><path d="M82 46V26M82 31C87 26 94 25 99 29"/><path d="M109 36H126C126 29 123 26 118 26C112 26 109 30 109 36C109 43 113 46 120 46H127"/><path d="M139 50V26M139 31C143 27 148 26 152 26C158 26 161 30 161 36C161 43 157 46 151 46C146 46 142 44 139 41"/><path d="M184 26C177 26 173 30 173 36C173 43 177 46 184 46C191 46 195 43 195 36C195 30 191 26 184 26Z"/><path d="M222 29C219 27 216 26 213 26C206 26 202 30 202 36C202 43 206 46 213 46C217 46 220 45 223 42"/><path d="M238 18V41C238 45 241 46 245 46H250M231 26H250"/><path d="M266 24V42C266 45 268 46 272 46H278"/></g>
6
+ </svg>
@@ -0,0 +1,20 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="300" height="64" viewBox="0 0 300 64" fill="none">
2
+ <g stroke="#20252D" stroke-width="4" stroke-linecap="round" stroke-linejoin="round">
3
+ <path d="M14 14C22 14 24 24 32 32"/>
4
+ <path d="M14 32H32"/>
5
+ <path d="M14 50C22 50 24 40 32 32"/>
6
+ </g>
7
+ <g fill="#2457D6">
8
+ <circle cx="10" cy="14" r="4"/><circle cx="10" cy="32" r="4"/><circle cx="10" cy="50" r="4"/>
9
+ </g>
10
+ <path d="M38 22L48 32L38 42" stroke="#2457D6" stroke-width="5" stroke-linecap="round" stroke-linejoin="round"/>
11
+ <g stroke="#20252D" stroke-width="4" stroke-linecap="round" stroke-linejoin="round">
12
+ <path d="M82 46V26M82 31C87 26 94 25 99 29"/>
13
+ <path d="M109 36H126C126 29 123 26 118 26C112 26 109 30 109 36C109 43 113 46 120 46H127"/>
14
+ <path d="M139 50V26M139 31C143 27 148 26 152 26C158 26 161 30 161 36C161 43 157 46 151 46C146 46 142 44 139 41"/>
15
+ <path d="M184 26C177 26 173 30 173 36C173 43 177 46 184 46C191 46 195 43 195 36C195 30 191 26 184 26Z"/>
16
+ <path d="M222 29C219 27 216 26 213 26C206 26 202 30 202 36C202 43 206 46 213 46C217 46 220 45 223 42"/>
17
+ <path d="M238 18V41C238 45 241 46 245 46H250M231 26H250"/>
18
+ <path d="M266 24V42C266 45 268 46 272 46H278"/>
19
+ </g>
20
+ </svg>
@@ -0,0 +1,13 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64" fill="none">
2
+ <g stroke="#F4F6FA" stroke-width="4" stroke-linecap="round" stroke-linejoin="round">
3
+ <path d="M14 14C22 14 24 24 32 32"/>
4
+ <path d="M14 32H32"/>
5
+ <path d="M14 50C22 50 24 40 32 32"/>
6
+ </g>
7
+ <g fill="#6F94FF">
8
+ <circle cx="10" cy="14" r="4"/>
9
+ <circle cx="10" cy="32" r="4"/>
10
+ <circle cx="10" cy="50" r="4"/>
11
+ </g>
12
+ <path d="M38 22L48 32L38 42" stroke="#6F94FF" stroke-width="5" stroke-linecap="round" stroke-linejoin="round"/>
13
+ </svg>
@@ -0,0 +1,13 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64" fill="none">
2
+ <g stroke="#20252D" stroke-width="4" stroke-linecap="round" stroke-linejoin="round">
3
+ <path d="M14 14C22 14 24 24 32 32"/>
4
+ <path d="M14 32H32"/>
5
+ <path d="M14 50C22 50 24 40 32 32"/>
6
+ </g>
7
+ <g fill="#2457D6">
8
+ <circle cx="10" cy="14" r="4"/>
9
+ <circle cx="10" cy="32" r="4"/>
10
+ <circle cx="10" cy="50" r="4"/>
11
+ </g>
12
+ <path d="M38 22L48 32L38 42" stroke="#2457D6" stroke-width="5" stroke-linecap="round" stroke-linejoin="round"/>
13
+ </svg>
Binary file
@@ -115,6 +115,6 @@ repo skills sync --codex
115
115
 
116
116
  ## Keep Reading
117
117
 
118
- - [Workflows and CI](./workflows.md)
119
- - [Troubleshooting](./troubleshooting.md)
118
+ - [Add checks to CI](/tasks/ci)
119
+ - [Troubleshoot](/tasks/troubleshooting)
120
120
  - [Command Aliases](./aliases.md)
@@ -0,0 +1,15 @@
1
+ # Reference
2
+
3
+ Use the reference when you already know the task and need exact command names, flags, configuration keys, or output rules.
4
+
5
+ ## Command surface
6
+
7
+ - [Command reference](./commands.md)
8
+ - [Configuration](./config.md)
9
+ - [Execution model](./execution-model.md)
10
+ - [Output formats](./output.md)
11
+ - [Command aliases](./aliases.md)
12
+ - [Templates](./templates.md)
13
+ - [Managed template assets](./template-assets.md)
14
+
15
+ The start and task sections intentionally hide advanced grouped commands until they are useful. This section documents the full surface without changing any CLI names.
@@ -0,0 +1,37 @@
1
+ # Output formats
2
+
3
+ repoctl can print to the terminal or write stable artifacts for automation. Pick the format at the command boundary so the same task can serve a person and CI.
4
+
5
+ ## Terminal
6
+
7
+ The default output is concise and human-readable. It shows the plan, the commands selected, and the final status.
8
+
9
+ ## JSON
10
+
11
+ Use JSON when another tool needs structured fields:
12
+
13
+ ```bash
14
+ repo check --full --dry-run --json --out reports/check-plan.json
15
+ ```
16
+
17
+ Keep the file as a CI artifact when a later job needs to inspect the plan.
18
+
19
+ ## Markdown
20
+
21
+ Use Markdown for code review and support requests:
22
+
23
+ ```bash
24
+ repo env support --markdown --redact --out reports/support.md
25
+ ```
26
+
27
+ The `--redact` flag removes local paths and sensitive values before sharing the report.
28
+
29
+ ## Common branches
30
+
31
+ - Need to compare two runs: write both to separate files and compare the JSON.
32
+ - Need a safe support bundle: use `repo env support --redact`.
33
+ - Need a command plan only: combine `--dry-run` with the desired output format.
34
+
35
+ ## Next
36
+
37
+ See [reports and output tasks](/tasks/reports) for a complete support workflow.
@@ -123,6 +123,6 @@ The check validates duplicate sources and targets, existing source directories,
123
123
 
124
124
  ## Keep Reading
125
125
 
126
- - [Adopt Existing Repositories](./adopt-existing.md)
127
- - [Workflows and CI](./workflows.md)
126
+ - [Adopt an existing workspace](/tasks/adopt-existing)
127
+ - [Add checks to CI](/tasks/ci)
128
128
  - [Configuration](./config.md)
@@ -0,0 +1,196 @@
1
+ import type { DocsLocale } from '../.vitepress/navigation/routes'
2
+ import { readdir, readFile, stat } from 'node:fs/promises'
3
+ import path from 'node:path'
4
+ import process from 'node:process'
5
+ import { homeContent } from '../.vitepress/home/content'
6
+ import { routePath, routeSections } from '../.vitepress/navigation/routes'
7
+
8
+ const root = process.cwd()
9
+ const ignoredDirectories = new Set(['.vitepress', 'node_modules'])
10
+ const ignoredFiles = new Set(['CHANGELOG.md'])
11
+
12
+ function toPosixPath(value: string) {
13
+ return value.replaceAll('\\', '/')
14
+ }
15
+
16
+ function relativePath(file: string) {
17
+ return toPosixPath(path.relative(root, file))
18
+ }
19
+
20
+ async function markdownFiles(directory: string): Promise<string[]> {
21
+ const entries = await readdir(directory)
22
+ const files = await Promise.all(entries.map(async (entry) => {
23
+ if (ignoredDirectories.has(entry)) {
24
+ return []
25
+ }
26
+ const absolute = path.join(directory, entry)
27
+ const metadata = await stat(absolute)
28
+ if (metadata.isDirectory()) {
29
+ return markdownFiles(absolute)
30
+ }
31
+ return entry.endsWith('.md') && !ignoredFiles.has(entry) ? [absolute] : []
32
+ }))
33
+ return files.flat()
34
+ }
35
+
36
+ function normalizeRoute(route: string) {
37
+ const withoutHash = toPosixPath(route).split('#', 1)[0]!.split('?', 1)[0]!
38
+ const withoutLocale = withoutHash.replace(/^\/zh(?=\/|$)/, '')
39
+ return withoutLocale.replace(/\/index(?:\.md)?$/, '/').replace(/\.md$/, '').replace(/\/$/, '') || '/'
40
+ }
41
+
42
+ function localLinks(markdown: string) {
43
+ const links = [...markdown.matchAll(/\[[^\]]+\]\(([^)\s]+)(?:\s[^)]*)?\)/g)]
44
+ .map(match => match[1]!)
45
+ .filter(link => !/^(?:https?:|mailto:|#)/.test(link))
46
+ return links
47
+ }
48
+
49
+ function headingLevels(markdown: string) {
50
+ const withoutCode = markdown.replace(/```[\s\S]*?```/g, '')
51
+ return [...withoutCode.matchAll(/^(#{1,6})\s+(?:\S.*|[\t\v\f \xA0\u1680\u2000-\u200A\u202F\u205F\u3000\uFEFF])$/gm)].map(match => match[1]!.length)
52
+ }
53
+
54
+ function fencedLanguages(markdown: string) {
55
+ return [...markdown.matchAll(/^```([^\s`]*)/gm)]
56
+ .map(match => match[1]!)
57
+ .filter((_, index) => index % 2 === 0)
58
+ }
59
+
60
+ function contentKeys(value: unknown, prefix = ''): string[] {
61
+ if (!value || typeof value !== 'object' || Array.isArray(value)) {
62
+ return [prefix]
63
+ }
64
+ return Object.entries(value).flatMap(([key, nested]) => contentKeys(nested, prefix ? `${prefix}.${key}` : key))
65
+ }
66
+
67
+ async function existsAtLocale(sourceFile: string, href: string) {
68
+ const route = href.split('#', 1)[0]!.split('?', 1)[0]!
69
+ const resolved = route.startsWith('/')
70
+ ? path.join(root, route.replace(/^\//, ''))
71
+ : path.resolve(path.dirname(sourceFile), route)
72
+ const candidates = route.endsWith('/')
73
+ ? [path.join(resolved, 'index.md')]
74
+ : [resolved, `${resolved}.md`, path.join(resolved, 'index.md')]
75
+ return (await Promise.all(candidates.map(async (candidate) => {
76
+ try {
77
+ return (await stat(candidate)).isFile()
78
+ }
79
+ catch {
80
+ return false
81
+ }
82
+ }))).some(Boolean)
83
+ }
84
+
85
+ function validateDocument(relativePath: string, markdown: string) {
86
+ const errors: string[] = []
87
+ const isHome = relativePath === 'index.md' || relativePath === 'zh/index.md'
88
+ const isExampleReadme = /(?:^|\/)learn\/packages\/examples\/.*\/README\.md$/.test(relativePath)
89
+ if (isHome || isExampleReadme) {
90
+ return errors
91
+ }
92
+ const headings = headingLevels(markdown)
93
+ if (headings.filter(level => level === 1).length !== 1) {
94
+ errors.push(`${relativePath}: expected one H1`)
95
+ }
96
+ for (let index = 1; index < headings.length; index += 1) {
97
+ if (headings[index]! > headings[index - 1]! + 1) {
98
+ errors.push(`${relativePath}: heading level jumps from H${headings[index - 1]} to H${headings[index]}`)
99
+ }
100
+ }
101
+ const fenceLines = [...markdown.matchAll(/^```([^\s`]*)/gm)]
102
+ if (fenceLines.length % 2 !== 0) {
103
+ errors.push(`${relativePath}: unbalanced code fence`)
104
+ }
105
+ for (const language of fencedLanguages(markdown)) {
106
+ if (!language) {
107
+ errors.push(`${relativePath}: code fences require a language marker`)
108
+ }
109
+ }
110
+ return errors
111
+ }
112
+
113
+ const files = await markdownFiles(root)
114
+ const englishFiles = files.filter(file => !relativePath(file).startsWith('zh/'))
115
+ const chineseFiles = files.filter(file => relativePath(file).startsWith('zh/'))
116
+ const englishPaths = new Set(englishFiles.map(relativePath))
117
+ const chinesePaths = new Set(chineseFiles.map(file => relativePath(file).replace(/^zh\//, '')))
118
+ const errors: string[] = []
119
+
120
+ function routeToRelativeFile(route: string) {
121
+ const clean = route.replace(/^\//, '')
122
+ return clean.endsWith('/') ? `${clean}index.md` : `${clean}.md`
123
+ }
124
+
125
+ for (const locale of ['en', 'zh'] as const satisfies readonly DocsLocale[]) {
126
+ const prefix = locale === 'zh' ? '/zh' : ''
127
+ for (const section of routeSections) {
128
+ for (const item of section.items) {
129
+ const route = routePath(section.id, item.slug, locale)
130
+ const relative = routeToRelativeFile(route)
131
+ try {
132
+ if (!(await stat(path.join(root, relative))).isFile()) {
133
+ errors.push(`${locale}: route ${route} is not backed by a Markdown file`)
134
+ }
135
+ }
136
+ catch {
137
+ errors.push(`${locale}: route ${route} is not backed by a Markdown file`)
138
+ }
139
+ }
140
+ }
141
+ if (prefix) {
142
+ const englishRouteCount = routeSections.reduce((count, section) => count + section.items.length, 0)
143
+ if (englishRouteCount === 0) {
144
+ errors.push('route manifest is empty')
145
+ }
146
+ }
147
+ }
148
+
149
+ for (const relativePath of englishPaths) {
150
+ if (!chinesePaths.has(relativePath)) {
151
+ errors.push(`missing Chinese counterpart: zh/${relativePath}`)
152
+ }
153
+ }
154
+ for (const relativePath of chinesePaths) {
155
+ if (!englishPaths.has(relativePath)) {
156
+ errors.push(`missing English counterpart: ${relativePath}`)
157
+ }
158
+ }
159
+
160
+ for (const file of files) {
161
+ const relative = relativePath(file)
162
+ const markdown = await readFile(file, 'utf8')
163
+ errors.push(...validateDocument(relative, markdown))
164
+ const links = localLinks(markdown)
165
+ for (const href of links) {
166
+ if (/^(?:\/|\.\.\/)(?:repoctl|knowledge|monorepo|why|tools)(?:\/|$)/.test(href)) {
167
+ errors.push(`${relativePath}: link uses a retired route ${href}`)
168
+ }
169
+ if (!await existsAtLocale(file, href)) {
170
+ errors.push(`${relative}: unresolved internal link ${href}`)
171
+ }
172
+ }
173
+
174
+ const counterpart = relative.startsWith('zh/')
175
+ ? path.join(root, relative.slice(3))
176
+ : path.join(root, 'zh', relative)
177
+ const counterpartRoute = `/${normalizeRoute(relativePath(counterpart))}`
178
+ if (await existsAtLocale(file, counterpartRoute === '/' ? '/' : counterpartRoute)) {
179
+ continue
180
+ }
181
+ errors.push(`${relative}: counterpart route cannot be resolved`)
182
+ }
183
+
184
+ const englishKeys = contentKeys(homeContent.en).sort()
185
+ const chineseKeys = contentKeys(homeContent.zh).sort()
186
+ if (englishKeys.join('\n') !== chineseKeys.join('\n')) {
187
+ errors.push('homepage locale content keys differ')
188
+ }
189
+
190
+ if (errors.length > 0) {
191
+ console.error(`Locale parity failed with ${errors.length} issue(s):\n${errors.map(error => `- ${error}`).join('\n')}`)
192
+ process.exitCode = 1
193
+ }
194
+ else {
195
+ console.log(`Locale parity passed for ${englishPaths.size} English and ${chinesePaths.size} Chinese Markdown pages.`)
196
+ }
@@ -0,0 +1,14 @@
1
+ # Choose the next task
2
+
3
+ Start with the outcome you need. Each task page includes prerequisites, the smallest command, expected output, common branches, and a next step.
4
+
5
+ | Outcome | Go to |
6
+ | -------------------------------------------- | ---------------------------------------------------- |
7
+ | Add repoctl to an existing workspace | [Adopt an existing workspace](/tasks/adopt-existing) |
8
+ | Create a package, app, service, or docs site | [Create a package or app](/tasks/create-project) |
9
+ | Run local verification before a commit | [Run checks](/tasks/checks) |
10
+ | Save output for a review or support request | [Reports and output](/tasks/reports) |
11
+ | Add the same workflow to CI | [Add checks to CI](/tasks/ci) |
12
+ | Prepare a package release | [Release packages](/tasks/release) |
13
+
14
+ For command flags and grouped commands, use the [command reference](/reference/commands). For the reasoning behind the workflow, read [how repoctl executes](/reference/execution-model).