@renkosky/lark-fe-skills 0.1.0 → 0.1.2

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 (259) hide show
  1. package/README.md +123 -41
  2. package/bin/lark-fe-skills.js +47 -8
  3. package/node_modules/yaml/LICENSE +13 -0
  4. package/node_modules/yaml/README.md +172 -0
  5. package/node_modules/yaml/bin.mjs +11 -0
  6. package/node_modules/yaml/browser/dist/compose/compose-collection.js +88 -0
  7. package/node_modules/yaml/browser/dist/compose/compose-doc.js +43 -0
  8. package/node_modules/yaml/browser/dist/compose/compose-node.js +109 -0
  9. package/node_modules/yaml/browser/dist/compose/compose-scalar.js +86 -0
  10. package/node_modules/yaml/browser/dist/compose/composer.js +219 -0
  11. package/node_modules/yaml/browser/dist/compose/resolve-block-map.js +115 -0
  12. package/node_modules/yaml/browser/dist/compose/resolve-block-scalar.js +198 -0
  13. package/node_modules/yaml/browser/dist/compose/resolve-block-seq.js +49 -0
  14. package/node_modules/yaml/browser/dist/compose/resolve-end.js +37 -0
  15. package/node_modules/yaml/browser/dist/compose/resolve-flow-collection.js +207 -0
  16. package/node_modules/yaml/browser/dist/compose/resolve-flow-scalar.js +225 -0
  17. package/node_modules/yaml/browser/dist/compose/resolve-props.js +146 -0
  18. package/node_modules/yaml/browser/dist/compose/util-contains-newline.js +34 -0
  19. package/node_modules/yaml/browser/dist/compose/util-empty-scalar-position.js +26 -0
  20. package/node_modules/yaml/browser/dist/compose/util-flow-indent-check.js +15 -0
  21. package/node_modules/yaml/browser/dist/compose/util-map-includes.js +13 -0
  22. package/node_modules/yaml/browser/dist/doc/Document.js +335 -0
  23. package/node_modules/yaml/browser/dist/doc/anchors.js +71 -0
  24. package/node_modules/yaml/browser/dist/doc/applyReviver.js +55 -0
  25. package/node_modules/yaml/browser/dist/doc/createNode.js +88 -0
  26. package/node_modules/yaml/browser/dist/doc/directives.js +176 -0
  27. package/node_modules/yaml/browser/dist/errors.js +57 -0
  28. package/node_modules/yaml/browser/dist/index.js +17 -0
  29. package/node_modules/yaml/browser/dist/log.js +11 -0
  30. package/node_modules/yaml/browser/dist/nodes/Alias.js +116 -0
  31. package/node_modules/yaml/browser/dist/nodes/Collection.js +147 -0
  32. package/node_modules/yaml/browser/dist/nodes/Node.js +38 -0
  33. package/node_modules/yaml/browser/dist/nodes/Pair.js +36 -0
  34. package/node_modules/yaml/browser/dist/nodes/Scalar.js +24 -0
  35. package/node_modules/yaml/browser/dist/nodes/YAMLMap.js +144 -0
  36. package/node_modules/yaml/browser/dist/nodes/YAMLSeq.js +113 -0
  37. package/node_modules/yaml/browser/dist/nodes/addPairToJSMap.js +63 -0
  38. package/node_modules/yaml/browser/dist/nodes/identity.js +36 -0
  39. package/node_modules/yaml/browser/dist/nodes/toJS.js +37 -0
  40. package/node_modules/yaml/browser/dist/parse/cst-scalar.js +214 -0
  41. package/node_modules/yaml/browser/dist/parse/cst-stringify.js +61 -0
  42. package/node_modules/yaml/browser/dist/parse/cst-visit.js +97 -0
  43. package/node_modules/yaml/browser/dist/parse/cst.js +98 -0
  44. package/node_modules/yaml/browser/dist/parse/lexer.js +721 -0
  45. package/node_modules/yaml/browser/dist/parse/line-counter.js +39 -0
  46. package/node_modules/yaml/browser/dist/parse/parser.js +975 -0
  47. package/node_modules/yaml/browser/dist/public-api.js +102 -0
  48. package/node_modules/yaml/browser/dist/schema/Schema.js +37 -0
  49. package/node_modules/yaml/browser/dist/schema/common/map.js +17 -0
  50. package/node_modules/yaml/browser/dist/schema/common/null.js +15 -0
  51. package/node_modules/yaml/browser/dist/schema/common/seq.js +17 -0
  52. package/node_modules/yaml/browser/dist/schema/common/string.js +14 -0
  53. package/node_modules/yaml/browser/dist/schema/core/bool.js +19 -0
  54. package/node_modules/yaml/browser/dist/schema/core/float.js +43 -0
  55. package/node_modules/yaml/browser/dist/schema/core/int.js +38 -0
  56. package/node_modules/yaml/browser/dist/schema/core/schema.js +23 -0
  57. package/node_modules/yaml/browser/dist/schema/json/schema.js +62 -0
  58. package/node_modules/yaml/browser/dist/schema/tags.js +96 -0
  59. package/node_modules/yaml/browser/dist/schema/yaml-1.1/binary.js +58 -0
  60. package/node_modules/yaml/browser/dist/schema/yaml-1.1/bool.js +26 -0
  61. package/node_modules/yaml/browser/dist/schema/yaml-1.1/float.js +46 -0
  62. package/node_modules/yaml/browser/dist/schema/yaml-1.1/int.js +71 -0
  63. package/node_modules/yaml/browser/dist/schema/yaml-1.1/merge.js +67 -0
  64. package/node_modules/yaml/browser/dist/schema/yaml-1.1/omap.js +74 -0
  65. package/node_modules/yaml/browser/dist/schema/yaml-1.1/pairs.js +78 -0
  66. package/node_modules/yaml/browser/dist/schema/yaml-1.1/schema.js +39 -0
  67. package/node_modules/yaml/browser/dist/schema/yaml-1.1/set.js +93 -0
  68. package/node_modules/yaml/browser/dist/schema/yaml-1.1/timestamp.js +101 -0
  69. package/node_modules/yaml/browser/dist/stringify/foldFlowLines.js +146 -0
  70. package/node_modules/yaml/browser/dist/stringify/stringify.js +129 -0
  71. package/node_modules/yaml/browser/dist/stringify/stringifyCollection.js +153 -0
  72. package/node_modules/yaml/browser/dist/stringify/stringifyComment.js +20 -0
  73. package/node_modules/yaml/browser/dist/stringify/stringifyDocument.js +85 -0
  74. package/node_modules/yaml/browser/dist/stringify/stringifyNumber.js +25 -0
  75. package/node_modules/yaml/browser/dist/stringify/stringifyPair.js +150 -0
  76. package/node_modules/yaml/browser/dist/stringify/stringifyString.js +336 -0
  77. package/node_modules/yaml/browser/dist/util.js +11 -0
  78. package/node_modules/yaml/browser/dist/visit.js +233 -0
  79. package/node_modules/yaml/browser/index.js +5 -0
  80. package/node_modules/yaml/browser/package.json +3 -0
  81. package/node_modules/yaml/dist/cli.d.ts +8 -0
  82. package/node_modules/yaml/dist/cli.mjs +201 -0
  83. package/node_modules/yaml/dist/compose/compose-collection.d.ts +11 -0
  84. package/node_modules/yaml/dist/compose/compose-collection.js +90 -0
  85. package/node_modules/yaml/dist/compose/compose-doc.d.ts +7 -0
  86. package/node_modules/yaml/dist/compose/compose-doc.js +45 -0
  87. package/node_modules/yaml/dist/compose/compose-node.d.ts +29 -0
  88. package/node_modules/yaml/dist/compose/compose-node.js +112 -0
  89. package/node_modules/yaml/dist/compose/compose-scalar.d.ts +5 -0
  90. package/node_modules/yaml/dist/compose/compose-scalar.js +88 -0
  91. package/node_modules/yaml/dist/compose/composer.d.ts +63 -0
  92. package/node_modules/yaml/dist/compose/composer.js +224 -0
  93. package/node_modules/yaml/dist/compose/resolve-block-map.d.ts +6 -0
  94. package/node_modules/yaml/dist/compose/resolve-block-map.js +117 -0
  95. package/node_modules/yaml/dist/compose/resolve-block-scalar.d.ts +11 -0
  96. package/node_modules/yaml/dist/compose/resolve-block-scalar.js +200 -0
  97. package/node_modules/yaml/dist/compose/resolve-block-seq.d.ts +6 -0
  98. package/node_modules/yaml/dist/compose/resolve-block-seq.js +51 -0
  99. package/node_modules/yaml/dist/compose/resolve-end.d.ts +6 -0
  100. package/node_modules/yaml/dist/compose/resolve-end.js +39 -0
  101. package/node_modules/yaml/dist/compose/resolve-flow-collection.d.ts +7 -0
  102. package/node_modules/yaml/dist/compose/resolve-flow-collection.js +209 -0
  103. package/node_modules/yaml/dist/compose/resolve-flow-scalar.d.ts +10 -0
  104. package/node_modules/yaml/dist/compose/resolve-flow-scalar.js +227 -0
  105. package/node_modules/yaml/dist/compose/resolve-props.d.ts +23 -0
  106. package/node_modules/yaml/dist/compose/resolve-props.js +148 -0
  107. package/node_modules/yaml/dist/compose/util-contains-newline.d.ts +2 -0
  108. package/node_modules/yaml/dist/compose/util-contains-newline.js +36 -0
  109. package/node_modules/yaml/dist/compose/util-empty-scalar-position.d.ts +2 -0
  110. package/node_modules/yaml/dist/compose/util-empty-scalar-position.js +28 -0
  111. package/node_modules/yaml/dist/compose/util-flow-indent-check.d.ts +3 -0
  112. package/node_modules/yaml/dist/compose/util-flow-indent-check.js +17 -0
  113. package/node_modules/yaml/dist/compose/util-map-includes.d.ts +4 -0
  114. package/node_modules/yaml/dist/compose/util-map-includes.js +15 -0
  115. package/node_modules/yaml/dist/doc/Document.d.ts +141 -0
  116. package/node_modules/yaml/dist/doc/Document.js +337 -0
  117. package/node_modules/yaml/dist/doc/anchors.d.ts +24 -0
  118. package/node_modules/yaml/dist/doc/anchors.js +76 -0
  119. package/node_modules/yaml/dist/doc/applyReviver.d.ts +9 -0
  120. package/node_modules/yaml/dist/doc/applyReviver.js +57 -0
  121. package/node_modules/yaml/dist/doc/createNode.d.ts +17 -0
  122. package/node_modules/yaml/dist/doc/createNode.js +90 -0
  123. package/node_modules/yaml/dist/doc/directives.d.ts +49 -0
  124. package/node_modules/yaml/dist/doc/directives.js +178 -0
  125. package/node_modules/yaml/dist/errors.d.ts +21 -0
  126. package/node_modules/yaml/dist/errors.js +62 -0
  127. package/node_modules/yaml/dist/index.d.ts +25 -0
  128. package/node_modules/yaml/dist/index.js +50 -0
  129. package/node_modules/yaml/dist/log.d.ts +3 -0
  130. package/node_modules/yaml/dist/log.js +19 -0
  131. package/node_modules/yaml/dist/nodes/Alias.d.ts +29 -0
  132. package/node_modules/yaml/dist/nodes/Alias.js +118 -0
  133. package/node_modules/yaml/dist/nodes/Collection.d.ts +73 -0
  134. package/node_modules/yaml/dist/nodes/Collection.js +151 -0
  135. package/node_modules/yaml/dist/nodes/Node.d.ts +53 -0
  136. package/node_modules/yaml/dist/nodes/Node.js +40 -0
  137. package/node_modules/yaml/dist/nodes/Pair.d.ts +22 -0
  138. package/node_modules/yaml/dist/nodes/Pair.js +39 -0
  139. package/node_modules/yaml/dist/nodes/Scalar.d.ts +47 -0
  140. package/node_modules/yaml/dist/nodes/Scalar.js +27 -0
  141. package/node_modules/yaml/dist/nodes/YAMLMap.d.ts +53 -0
  142. package/node_modules/yaml/dist/nodes/YAMLMap.js +147 -0
  143. package/node_modules/yaml/dist/nodes/YAMLSeq.d.ts +60 -0
  144. package/node_modules/yaml/dist/nodes/YAMLSeq.js +115 -0
  145. package/node_modules/yaml/dist/nodes/addPairToJSMap.d.ts +4 -0
  146. package/node_modules/yaml/dist/nodes/addPairToJSMap.js +65 -0
  147. package/node_modules/yaml/dist/nodes/identity.d.ts +23 -0
  148. package/node_modules/yaml/dist/nodes/identity.js +53 -0
  149. package/node_modules/yaml/dist/nodes/toJS.d.ts +29 -0
  150. package/node_modules/yaml/dist/nodes/toJS.js +39 -0
  151. package/node_modules/yaml/dist/options.d.ts +350 -0
  152. package/node_modules/yaml/dist/parse/cst-scalar.d.ts +64 -0
  153. package/node_modules/yaml/dist/parse/cst-scalar.js +218 -0
  154. package/node_modules/yaml/dist/parse/cst-stringify.d.ts +8 -0
  155. package/node_modules/yaml/dist/parse/cst-stringify.js +63 -0
  156. package/node_modules/yaml/dist/parse/cst-visit.d.ts +39 -0
  157. package/node_modules/yaml/dist/parse/cst-visit.js +99 -0
  158. package/node_modules/yaml/dist/parse/cst.d.ts +109 -0
  159. package/node_modules/yaml/dist/parse/cst.js +112 -0
  160. package/node_modules/yaml/dist/parse/lexer.d.ts +87 -0
  161. package/node_modules/yaml/dist/parse/lexer.js +723 -0
  162. package/node_modules/yaml/dist/parse/line-counter.d.ts +22 -0
  163. package/node_modules/yaml/dist/parse/line-counter.js +41 -0
  164. package/node_modules/yaml/dist/parse/parser.d.ts +84 -0
  165. package/node_modules/yaml/dist/parse/parser.js +980 -0
  166. package/node_modules/yaml/dist/public-api.d.ts +44 -0
  167. package/node_modules/yaml/dist/public-api.js +107 -0
  168. package/node_modules/yaml/dist/schema/Schema.d.ts +17 -0
  169. package/node_modules/yaml/dist/schema/Schema.js +39 -0
  170. package/node_modules/yaml/dist/schema/common/map.d.ts +2 -0
  171. package/node_modules/yaml/dist/schema/common/map.js +19 -0
  172. package/node_modules/yaml/dist/schema/common/null.d.ts +4 -0
  173. package/node_modules/yaml/dist/schema/common/null.js +17 -0
  174. package/node_modules/yaml/dist/schema/common/seq.d.ts +2 -0
  175. package/node_modules/yaml/dist/schema/common/seq.js +19 -0
  176. package/node_modules/yaml/dist/schema/common/string.d.ts +2 -0
  177. package/node_modules/yaml/dist/schema/common/string.js +16 -0
  178. package/node_modules/yaml/dist/schema/core/bool.d.ts +4 -0
  179. package/node_modules/yaml/dist/schema/core/bool.js +21 -0
  180. package/node_modules/yaml/dist/schema/core/float.d.ts +4 -0
  181. package/node_modules/yaml/dist/schema/core/float.js +47 -0
  182. package/node_modules/yaml/dist/schema/core/int.d.ts +4 -0
  183. package/node_modules/yaml/dist/schema/core/int.js +42 -0
  184. package/node_modules/yaml/dist/schema/core/schema.d.ts +1 -0
  185. package/node_modules/yaml/dist/schema/core/schema.js +25 -0
  186. package/node_modules/yaml/dist/schema/json/schema.d.ts +2 -0
  187. package/node_modules/yaml/dist/schema/json/schema.js +64 -0
  188. package/node_modules/yaml/dist/schema/json-schema.d.ts +69 -0
  189. package/node_modules/yaml/dist/schema/tags.d.ts +48 -0
  190. package/node_modules/yaml/dist/schema/tags.js +99 -0
  191. package/node_modules/yaml/dist/schema/types.d.ts +92 -0
  192. package/node_modules/yaml/dist/schema/yaml-1.1/binary.d.ts +2 -0
  193. package/node_modules/yaml/dist/schema/yaml-1.1/binary.js +70 -0
  194. package/node_modules/yaml/dist/schema/yaml-1.1/bool.d.ts +7 -0
  195. package/node_modules/yaml/dist/schema/yaml-1.1/bool.js +29 -0
  196. package/node_modules/yaml/dist/schema/yaml-1.1/float.d.ts +4 -0
  197. package/node_modules/yaml/dist/schema/yaml-1.1/float.js +50 -0
  198. package/node_modules/yaml/dist/schema/yaml-1.1/int.d.ts +5 -0
  199. package/node_modules/yaml/dist/schema/yaml-1.1/int.js +76 -0
  200. package/node_modules/yaml/dist/schema/yaml-1.1/merge.d.ts +9 -0
  201. package/node_modules/yaml/dist/schema/yaml-1.1/merge.js +71 -0
  202. package/node_modules/yaml/dist/schema/yaml-1.1/omap.d.ts +22 -0
  203. package/node_modules/yaml/dist/schema/yaml-1.1/omap.js +77 -0
  204. package/node_modules/yaml/dist/schema/yaml-1.1/pairs.d.ts +10 -0
  205. package/node_modules/yaml/dist/schema/yaml-1.1/pairs.js +82 -0
  206. package/node_modules/yaml/dist/schema/yaml-1.1/schema.d.ts +1 -0
  207. package/node_modules/yaml/dist/schema/yaml-1.1/schema.js +41 -0
  208. package/node_modules/yaml/dist/schema/yaml-1.1/set.d.ts +28 -0
  209. package/node_modules/yaml/dist/schema/yaml-1.1/set.js +96 -0
  210. package/node_modules/yaml/dist/schema/yaml-1.1/timestamp.d.ts +6 -0
  211. package/node_modules/yaml/dist/schema/yaml-1.1/timestamp.js +105 -0
  212. package/node_modules/yaml/dist/stringify/foldFlowLines.d.ts +34 -0
  213. package/node_modules/yaml/dist/stringify/foldFlowLines.js +151 -0
  214. package/node_modules/yaml/dist/stringify/stringify.d.ts +21 -0
  215. package/node_modules/yaml/dist/stringify/stringify.js +132 -0
  216. package/node_modules/yaml/dist/stringify/stringifyCollection.d.ts +17 -0
  217. package/node_modules/yaml/dist/stringify/stringifyCollection.js +155 -0
  218. package/node_modules/yaml/dist/stringify/stringifyComment.d.ts +10 -0
  219. package/node_modules/yaml/dist/stringify/stringifyComment.js +24 -0
  220. package/node_modules/yaml/dist/stringify/stringifyDocument.d.ts +4 -0
  221. package/node_modules/yaml/dist/stringify/stringifyDocument.js +87 -0
  222. package/node_modules/yaml/dist/stringify/stringifyNumber.d.ts +2 -0
  223. package/node_modules/yaml/dist/stringify/stringifyNumber.js +27 -0
  224. package/node_modules/yaml/dist/stringify/stringifyPair.d.ts +3 -0
  225. package/node_modules/yaml/dist/stringify/stringifyPair.js +152 -0
  226. package/node_modules/yaml/dist/stringify/stringifyString.d.ts +9 -0
  227. package/node_modules/yaml/dist/stringify/stringifyString.js +338 -0
  228. package/node_modules/yaml/dist/test-events.d.ts +4 -0
  229. package/node_modules/yaml/dist/test-events.js +134 -0
  230. package/node_modules/yaml/dist/util.d.ts +16 -0
  231. package/node_modules/yaml/dist/util.js +28 -0
  232. package/node_modules/yaml/dist/visit.d.ts +102 -0
  233. package/node_modules/yaml/dist/visit.js +236 -0
  234. package/node_modules/yaml/package.json +97 -0
  235. package/node_modules/yaml/util.js +2 -0
  236. package/package.json +8 -2
  237. package/skills/prd-fe-schedule/README.md +195 -0
  238. package/skills/prd-fe-schedule/SKILL.md +193 -0
  239. package/skills/prd-fe-schedule/agents/openai.yaml +4 -0
  240. package/skills/prd-fe-schedule/references/dry-run-output-template.md +35 -0
  241. package/skills/prd-fe-schedule/scripts/config-schedule.sh +5 -0
  242. package/skills/prd-fe-schedule/scripts/config-types.sh +5 -0
  243. package/skills/prd-fe-schedule/scripts/create-schedule.sh +5 -0
  244. package/skills/prd-fe-schedule/scripts/dry-run-schedule.sh +5 -0
  245. package/skills/prd-fe-schedule/scripts/schedule-core.js +909 -0
  246. package/skills/{lark-fe-task → prd-fe-task}/README.md +49 -35
  247. package/skills/{lark-fe-task → prd-fe-task}/SKILL.md +18 -11
  248. package/skills/{lark-fe-task → prd-fe-task}/agents/openai.yaml +1 -1
  249. package/skills/{lark-fe-task → prd-fe-task}/references/task-breakdown-template.md +7 -1
  250. package/skills/prd-fe-task/scripts/config.js +104 -0
  251. package/skills/prd-fe-task/scripts/config.sh +4 -0
  252. package/skills/prd-fe-task/scripts/list-configs.js +34 -0
  253. package/skills/prd-fe-task/scripts/list-configs.sh +4 -0
  254. package/skills/prd-fe-task/scripts/plan-lark-doc.js +332 -0
  255. package/skills/prd-fe-task/scripts/plan-lark-doc.sh +4 -0
  256. package/skills/lark-fe-task/scripts/config.sh +0 -119
  257. package/skills/lark-fe-task/scripts/list-configs.sh +0 -39
  258. package/skills/lark-fe-task/scripts/plan-lark-doc.sh +0 -212
  259. /package/skills/{lark-fe-task → prd-fe-task}/config/repos.json +0 -0
package/README.md CHANGED
@@ -1,32 +1,56 @@
1
1
  # Lark FE Skills
2
2
 
3
+ [![npm version](https://img.shields.io/npm/v/@renkosky/lark-fe-skills.svg)](https://www.npmjs.com/package/@renkosky/lark-fe-skills) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE) [![Codex Skills](https://img.shields.io/badge/Codex-Skills-111827.svg)](https://github.com/openai/codex) [![Lark CLI](https://img.shields.io/badge/Lark-CLI-00A6FF.svg)](https://github.com/larksuite/cli/tree/main)
4
+
3
5
  English | [中文](#中文)
4
6
 
7
+ Lark/Feishu based Codex skills for frontend requirement planning.
8
+
9
+ [Install](#install) · [Prerequisites](#prerequisites) · [CLI](#cli) · [Roadmap](#roadmap) · [中文](#中文)
10
+
5
11
  ## English
6
12
 
7
- `@renkosky/lark-fe-skills` packages Codex skills for Lark-based frontend requirement workflows.
13
+ ## What is this?
14
+
15
+ `@renkosky/lark-fe-skills` packages Codex skills for Lark-based frontend workflows.
8
16
 
9
- The first packaged skill is `lark-fe-task`, which reads a Lark/Feishu requirement document and generates a frontend task breakdown Markdown file.
17
+ The first packaged workflow includes `prd-fe-task` for task breakdowns and `prd-fe-schedule` for Lark Base schedule dry-runs.
10
18
 
11
- ### Install
19
+ ## 🚀 Install
20
+
21
+ 1. Install the package:
12
22
 
13
23
  ```bash
14
24
  npm install -g @renkosky/lark-fe-skills
15
- lark-fe-skills install lark-fe-task
16
25
  ```
17
26
 
18
- Then use the installed skill from Codex:
27
+ 2. Install the skill:
28
+
29
+ ```bash
30
+ lark-fe-skills install prd-fe-task
31
+ ```
32
+
33
+ 3. Restart Codex or open a new Codex session.
34
+
35
+ PATH fallback:
36
+
37
+ ```bash
38
+ npm exec --package=@renkosky/lark-fe-skills -- lark-fe-skills install prd-fe-task
39
+ ```
40
+
41
+ Use it in Codex:
19
42
 
20
43
  ```text
21
- [$lark-fe-task](~/.codex/skills/lark-fe-task/SKILL.md) +config
22
- [$lark-fe-task](~/.codex/skills/lark-fe-task/SKILL.md) +plan <Lark document title, URL, or token>
44
+ [$prd-fe-task](~/.codex/skills/prd-fe-task/SKILL.md) +config
45
+ [$prd-fe-task](~/.codex/skills/prd-fe-task/SKILL.md) +plan <Lark document title, URL, or token>
23
46
  ```
24
47
 
25
- ### Prerequisites
48
+ ## 🧰 Prerequisites
26
49
 
27
- Install and configure `lark-cli` before using the skill:
50
+ Install Node.js and configure `lark-cli` first:
28
51
 
29
52
  ```bash
53
+ npm --version
30
54
  npm install -g @larksuite/cli
31
55
  lark-cli config init
32
56
  lark-cli auth login --recommend
@@ -34,20 +58,36 @@ lark-cli auth login --recommend
34
58
 
35
59
  Official lark-cli documentation: <https://github.com/larksuite/cli/tree/main>
36
60
 
37
- ### CLI
61
+ ## 🖥️ CLI
38
62
 
39
63
  ```bash
40
64
  lark-fe-skills list
41
65
  lark-fe-skills path
42
- lark-fe-skills path lark-fe-task
43
- lark-fe-skills install lark-fe-task
66
+ lark-fe-skills path prd-fe-task
67
+ lark-fe-skills path prd-fe-schedule
68
+ lark-fe-skills install prd-fe-task
69
+ lark-fe-skills install prd-fe-schedule
70
+ lark-fe-skills uninstall prd-fe-task
71
+ lark-fe-skills uninstall prd-fe-schedule
72
+ lark-fe-skills uninstall lark-fe-task
44
73
  ```
45
74
 
46
- ### Packaged Skills
75
+ ## 📦 Packaged Skills
76
+
77
+ | Skill | Description |
78
+ | --- | --- |
79
+ | `prd-fe-task` | Turn Lark/Feishu requirement documents into concrete frontend task breakdowns. |
80
+ | `prd-fe-schedule` | Preview Lark Base schedule records from generated frontend task Markdown. |
47
81
 
48
- - `lark-fe-task`: turn Lark/Feishu requirement documents into concrete frontend task breakdowns.
82
+ ## 📝 Notes
49
83
 
50
- ### Roadmap
84
+ - npm installation and Codex skill installation are separate steps.
85
+ - This package installs skills to `~/.codex/skills`.
86
+ - Use `lark-fe-skills uninstall prd-fe-task` to reset local Codex skill installation for first-run testing.
87
+ - Use `lark-fe-skills uninstall lark-fe-task` to remove the legacy install directory.
88
+ - Existing Lark skills may live under `~/.agents/skills`; that is a different source.
89
+
90
+ ## 🗺️ Roadmap
51
91
 
52
92
  - [x] Phase 1: Generate frontend task breakdown Markdown from Lark requirement documents.
53
93
  - [x] Configure repository root, frontend project paths, and output directory.
@@ -56,11 +96,14 @@ lark-fe-skills install lark-fe-task
56
96
  - [x] Inspect configured frontend project paths lightly for code-location clues.
57
97
  - [x] Generate ignored Markdown task files under the configured output directory.
58
98
  - [ ] Phase 2: Create Lark schedule tasks from generated frontend task Markdown.
59
- - [ ] Accept a Lark schedule Base URL or title, then read its table schema before mapping fields.
60
- - [ ] Map Markdown tasks into schedule fields such as task name, task description, task status, start time, and end time.
61
- - [ ] Read custom task status options from the Base instead of inventing status tags.
62
- - [ ] First version should be dry-run only and show the records that would be created without modifying Lark.
63
- - [ ] A later version can add user confirmation and then create records in the schedule Base.
99
+ - [x] Add `prd-fe-schedule` dry-run skill.
100
+ - [x] Add YAML schedule profiles with comments for configurable fields, defaults, and record rules.
101
+ - [x] Accept a Lark schedule Base URL or title, then read its table schema before generating a profile.
102
+ - [x] Map Markdown tasks into schedule fields using profile rules instead of hard-coded company task types.
103
+ - [x] Configure and remember task classification rules with `+config-types`.
104
+ - [x] Read custom task status/type options from the Base instead of inventing tags.
105
+ - [x] Support dry-run previews from a profile without modifying Lark.
106
+ - [x] Add an explicit `+create` helper that requires confirmation/`--yes` before writing records.
64
107
  - [ ] Phase 3: Implement frontend tasks from generated Markdown.
65
108
  - [ ] Default to implementing one task at a time to keep human review small and manageable.
66
109
  - [ ] After each task, stop and report changed files, verification results, remaining tasks, mocks used, and unresolved questions.
@@ -79,29 +122,49 @@ lark-fe-skills install lark-fe-task
79
122
 
80
123
  ## 中文
81
124
 
125
+ [安装](#安装) · [前置条件](#前置条件) · [CLI](#cli-1) · [开发规划](#开发规划) · [English](#english)
126
+
127
+ ## ✨ 这是什么?
128
+
82
129
  `@renkosky/lark-fe-skills` 用于分发基于 Lark/飞书的前端需求工作流 Codex skills。
83
130
 
84
- 首个发布的 skill `lark-fe-task`,用于读取 Lark/飞书需求文档,并生成前端任务拆分 Markdown。
131
+ 首个工作流包含 `prd-fe-task` `prd-fe-schedule`:前者生成前端任务拆分,后者基于任务 Markdown 生成 Lark Base 排期 dry-run 预览。
132
+
133
+ ## 🚀 安装
85
134
 
86
- ### 安装
135
+ 1. 安装 npm 包:
87
136
 
88
137
  ```bash
89
138
  npm install -g @renkosky/lark-fe-skills
90
- lark-fe-skills install lark-fe-task
91
139
  ```
92
140
 
93
- 然后在 Codex 中使用已安装的 skill:
141
+ 2. 安装 skill:
142
+
143
+ ```bash
144
+ lark-fe-skills install prd-fe-task
145
+ ```
146
+
147
+ 3. 重启 Codex 或新开一个 Codex 会话。
148
+
149
+ PATH fallback:
150
+
151
+ ```bash
152
+ npm exec --package=@renkosky/lark-fe-skills -- lark-fe-skills install prd-fe-task
153
+ ```
154
+
155
+ 在 Codex 中使用:
94
156
 
95
157
  ```text
96
- [$lark-fe-task](~/.codex/skills/lark-fe-task/SKILL.md) +config
97
- [$lark-fe-task](~/.codex/skills/lark-fe-task/SKILL.md) +plan <飞书文档标题、链接或 token>
158
+ [$prd-fe-task](~/.codex/skills/prd-fe-task/SKILL.md) +config
159
+ [$prd-fe-task](~/.codex/skills/prd-fe-task/SKILL.md) +plan <飞书文档标题、链接或 token>
98
160
  ```
99
161
 
100
- ### 前置条件
162
+ ## 🧰 前置条件
101
163
 
102
- 使用 skill 前,需要先安装并配置 `lark-cli`:
164
+ 先准备 Node.js,并安装配置 `lark-cli`:
103
165
 
104
166
  ```bash
167
+ npm --version
105
168
  npm install -g @larksuite/cli
106
169
  lark-cli config init
107
170
  lark-cli auth login --recommend
@@ -109,20 +172,36 @@ lark-cli auth login --recommend
109
172
 
110
173
  官方 lark-cli 文档:<https://github.com/larksuite/cli/tree/main>
111
174
 
112
- ### CLI
175
+ ## 🖥️ CLI
113
176
 
114
177
  ```bash
115
178
  lark-fe-skills list
116
179
  lark-fe-skills path
117
- lark-fe-skills path lark-fe-task
118
- lark-fe-skills install lark-fe-task
180
+ lark-fe-skills path prd-fe-task
181
+ lark-fe-skills path prd-fe-schedule
182
+ lark-fe-skills install prd-fe-task
183
+ lark-fe-skills install prd-fe-schedule
184
+ lark-fe-skills uninstall prd-fe-task
185
+ lark-fe-skills uninstall prd-fe-schedule
186
+ lark-fe-skills uninstall lark-fe-task
119
187
  ```
120
188
 
121
- ### 已包含 Skills
189
+ ## 📦 已包含 Skills
190
+
191
+ | Skill | 说明 |
192
+ | --- | --- |
193
+ | `prd-fe-task` | 将 Lark/飞书需求文档拆解成可开发的前端任务。 |
194
+ | `prd-fe-schedule` | 根据前端任务 Markdown 预览 Lark Base 排期记录。 |
195
+
196
+ ## 📝 说明
122
197
 
123
- - `lark-fe-task`:将 Lark/飞书需求文档拆解成可开发的前端任务。
198
+ - npm 包安装和 Codex skill 安装是两步。
199
+ - 本包默认安装到 `~/.codex/skills`。
200
+ - 可以用 `lark-fe-skills uninstall prd-fe-task` 清理本地 Codex skill,方便测试首次安装流程。
201
+ - 可以用 `lark-fe-skills uninstall lark-fe-task` 清理旧版安装目录。
202
+ - 已有 Lark skills 可能位于 `~/.agents/skills`,这是另一类来源。
124
203
 
125
- ### 开发规划
204
+ ## 🗺️ 开发规划
126
205
 
127
206
  - [x] Phase 1:根据 Lark 需求文档生成前端任务拆分 Markdown。
128
207
  - [x] 配置仓库根目录、前端项目路径和输出目录。
@@ -131,22 +210,25 @@ lark-fe-skills install lark-fe-task
131
210
  - [x] 轻量检查已配置前端项目路径,补充代码定位线索。
132
211
  - [x] 在已配置输出目录下生成被 git 忽略的 Markdown 任务文件。
133
212
  - [ ] Phase 2:把已生成的前端任务 Markdown 转成 Lark 排期任务。
134
- - [ ] 支持用户提供 Lark 排期 Base 链接或名称,并在映射字段前读取表结构。
135
- - [ ] Markdown 任务映射到任务名称、任务描述、任务状态、开始时间、结束时间等排期字段。
136
- - [ ] Base 读取自定义任务状态选项,不臆造状态 tag。
137
- - [ ] 第一版只做 dry-run 预览,展示将要创建的记录,不修改 Lark。
138
- - [ ] 后续版本再增加用户确认步骤,并在确认后写入排期 Base。
213
+ - [x] 新增 `prd-fe-schedule` dry-run skill。
214
+ - [x] 新增带注释的 YAML schedule profile,用于配置字段、默认值和记录生成规则。
215
+ - [x] 支持用户提供 Lark 排期 Base 链接或名称,并在生成 profile 前读取表结构。
216
+ - [x] 根据 profile 规则映射 Markdown 任务,不再写死某家公司任务类型。
217
+ - [x] 支持通过 `+config-types` 配置并记住任务分类规则。
218
+ - [x] 从 Base 读取自定义任务状态/类型选项,不臆造 tag。
219
+ - [x] 支持基于 profile 的 dry-run 预览,不修改 Lark。
220
+ - [x] 新增显式 `+create` helper,要求确认/`--yes` 后才写入记录。
139
221
  - [ ] Phase 3:根据已生成的 Markdown 实际开发前端任务。
140
222
  - [ ] 默认一次只实现一个 Task,控制代码改动粒度,方便人工 review。
141
223
  - [ ] 每完成一个 Task 就暂停,并汇报改动文件、验证结果、剩余任务、使用的 mock 和未解决问题。
142
224
  - [ ] 只有用户明确要求继续,或明确要求一次实现多个任务时,才继续处理后续 Task。
143
225
  - [ ] 如果单个 Task 本身过大,先拆成更小的实现批次再改代码。
144
226
  - [ ] 优先复用项目里已有的接口、hooks、stores、组件、权限、i18n 和 mock 模式,再考虑新增实现。
145
- - [ ] 这一阶段不做真实后端联调;接口行为不可用时,优先使用已有可复用数据或项目 mock 体系。
227
+ - [ ] 这一阶段不做真实后端接口对接;接口行为不可用时,优先使用已有可复用数据或项目 mock 体系。
146
228
  - [ ] 如果 API 字段、权限 key、状态枚举或核心产品行为在代码里找不到,要先询问用户,不臆造。
147
229
  - [ ] 代码改动只限制在任务 Markdown 标出的受影响项目路径和模块内。
148
230
  - [ ] 每完成一个 Task 后运行最相关的静态检查,并明确说明是否存在无关历史失败。
149
- - [ ] Phase 4:接口联调与后端交付文档工作流。
231
+ - [ ] Phase 4:接口对接与后端交付文档工作流。
150
232
  - [ ] 这部分在后端接口交付格式统一前保持待定。
151
233
  - [ ] 预期方向:继续使用 Lark 作为接口交付和协作载体。
152
234
  - [ ] 实施前需要先和后端约定文档格式,包括接口地址、请求方法、请求参数、响应结构、错误码、mock 示例和负责人。
@@ -8,7 +8,11 @@ import { homedir } from 'node:os'
8
8
  const __dirname = dirname(fileURLToPath(import.meta.url))
9
9
  const packageRoot = resolve(__dirname, '..')
10
10
  const skillsRoot = join(packageRoot, 'skills')
11
- const availableSkills = ['lark-fe-task']
11
+ const packagedSkills = ['prd-fe-task', 'prd-fe-schedule']
12
+ const uninstallableSkills = [...packagedSkills, 'lark-fe-task']
13
+ const skillRuntimeDependencies = {
14
+ 'prd-fe-schedule': ['yaml'],
15
+ }
12
16
 
13
17
  function usage() {
14
18
  console.log(`lark-fe-skills
@@ -17,29 +21,35 @@ Usage:
17
21
  lark-fe-skills list
18
22
  lark-fe-skills path [skill-name]
19
23
  lark-fe-skills install [skill-name]
24
+ lark-fe-skills uninstall [skill-name]
20
25
 
21
26
  Commands:
22
27
  list List packaged skills.
23
28
  path Print the package skills directory or one skill path.
24
29
  install Copy a packaged skill to $HOME/.codex/skills.
30
+ uninstall Remove an installed skill from $HOME/.codex/skills.
25
31
 
26
32
  Examples:
27
33
  lark-fe-skills list
28
- lark-fe-skills path lark-fe-task
29
- lark-fe-skills install lark-fe-task`)
34
+ lark-fe-skills path prd-fe-task
35
+ lark-fe-skills path prd-fe-schedule
36
+ lark-fe-skills install prd-fe-task
37
+ lark-fe-skills install prd-fe-schedule
38
+ lark-fe-skills uninstall prd-fe-task
39
+ lark-fe-skills uninstall lark-fe-task`)
30
40
  }
31
41
 
32
- function assertSkillName(skillName) {
33
- if (!availableSkills.includes(skillName)) {
42
+ function assertSkillName(skillName, validSkills = packagedSkills) {
43
+ if (!validSkills.includes(skillName)) {
34
44
  console.error(`Unknown skill: ${skillName}`)
35
- console.error(`Available skills: ${availableSkills.join(', ')}`)
45
+ console.error(`Available skills: ${validSkills.join(', ')}`)
36
46
  process.exit(1)
37
47
  }
38
48
  }
39
49
 
40
50
  function listSkills() {
41
51
  console.log('Available skills:')
42
- for (const skillName of availableSkills) {
52
+ for (const skillName of packagedSkills) {
43
53
  console.log(`- ${skillName}`)
44
54
  }
45
55
  }
@@ -53,7 +63,7 @@ function printPath(skillName) {
53
63
  console.log(skillsRoot)
54
64
  }
55
65
 
56
- function installSkill(skillName = 'lark-fe-task') {
66
+ function installSkill(skillName = 'prd-fe-task') {
57
67
  assertSkillName(skillName)
58
68
 
59
69
  const source = join(skillsRoot, skillName)
@@ -71,9 +81,35 @@ function installSkill(skillName = 'lark-fe-task') {
71
81
  }
72
82
  cpSync(source, target, { recursive: true, force: true })
73
83
 
84
+ for (const dependencyName of skillRuntimeDependencies[skillName] || []) {
85
+ const dependencySource = join(packageRoot, 'node_modules', dependencyName)
86
+ const dependencyTarget = join(target, 'node_modules', dependencyName)
87
+ if (!existsSync(dependencySource)) {
88
+ console.error(`Runtime dependency not found: ${dependencyName}`)
89
+ console.error('Run npm install in the package before installing this skill.')
90
+ process.exit(1)
91
+ }
92
+ mkdirSync(dirname(dependencyTarget), { recursive: true })
93
+ cpSync(dependencySource, dependencyTarget, { recursive: true, force: true })
94
+ }
95
+
74
96
  console.log(`Installed ${skillName} to ${target}`)
75
97
  }
76
98
 
99
+ function uninstallSkill(skillName = 'prd-fe-task') {
100
+ assertSkillName(skillName, uninstallableSkills)
101
+
102
+ const target = join(homedir(), '.codex', 'skills', skillName)
103
+
104
+ if (!existsSync(target)) {
105
+ console.log(`${skillName} is not installed at ${target}`)
106
+ return
107
+ }
108
+
109
+ rmSync(target, { recursive: true, force: true })
110
+ console.log(`Uninstalled ${skillName} from ${target}`)
111
+ }
112
+
77
113
  const [command, skillName] = process.argv.slice(2)
78
114
 
79
115
  switch (command) {
@@ -86,6 +122,9 @@ switch (command) {
86
122
  case 'install':
87
123
  installSkill(skillName)
88
124
  break
125
+ case 'uninstall':
126
+ uninstallSkill(skillName)
127
+ break
89
128
  case undefined:
90
129
  case '-h':
91
130
  case '--help':
@@ -0,0 +1,13 @@
1
+ Copyright Eemeli Aro <eemeli@gmail.com>
2
+
3
+ Permission to use, copy, modify, and/or distribute this software for any purpose
4
+ with or without fee is hereby granted, provided that the above copyright notice
5
+ and this permission notice appear in all copies.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
8
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
9
+ FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
10
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
11
+ OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
12
+ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
13
+ THIS SOFTWARE.
@@ -0,0 +1,172 @@
1
+ # YAML <a href="https://www.npmjs.com/package/yaml"><img align="right" src="https://badge.fury.io/js/yaml.svg" title="npm package" /></a>
2
+
3
+ `yaml` is a definitive library for [YAML](https://yaml.org/), the human friendly data serialization standard.
4
+ This library:
5
+
6
+ - Supports both YAML 1.1 and YAML 1.2 and all common data schemas,
7
+ - Passes all of the [yaml-test-suite](https://github.com/yaml/yaml-test-suite) tests,
8
+ - Can accept any string as input without throwing, parsing as much YAML out of it as it can, and
9
+ - Supports parsing, modifying, and writing YAML comments and blank lines.
10
+
11
+ The library is released under the ISC open source license, and the code is [available on GitHub](https://github.com/eemeli/yaml/).
12
+ It has no external dependencies and runs on Node.js as well as modern browsers.
13
+
14
+ For the purposes of versioning, any changes that break any of the documented endpoints or APIs will be considered semver-major breaking changes.
15
+ Undocumented library internals may change between minor versions, and previous APIs may be deprecated (but not removed).
16
+
17
+ The minimum supported TypeScript version of the included typings is 3.9;
18
+ for use in earlier versions you may need to set `skipLibCheck: true` in your config.
19
+ This requirement may be updated between minor versions of the library.
20
+
21
+ For more information, see the project's documentation site: [**eemeli.org/yaml**](https://eemeli.org/yaml/)
22
+
23
+ For build instructions and contribution guidelines, see [docs/CONTRIBUTING.md](docs/CONTRIBUTING.md).
24
+
25
+ To install:
26
+
27
+ ```sh
28
+ npm install yaml
29
+ # or
30
+ deno add jsr:@eemeli/yaml
31
+ ```
32
+
33
+ **Note:** These docs are for `yaml@2`. For v1, see the [v1.10.0 tag](https://github.com/eemeli/yaml/tree/v1.10.0) for the source and [eemeli.org/yaml/v1](https://eemeli.org/yaml/v1/) for the documentation.
34
+
35
+ ## API Overview
36
+
37
+ The API provided by `yaml` has three layers, depending on how deep you need to go: [Parse & Stringify](https://eemeli.org/yaml/#parse-amp-stringify), [Documents](https://eemeli.org/yaml/#documents), and the underlying [Lexer/Parser/Composer](https://eemeli.org/yaml/#parsing-yaml).
38
+ The first has the simplest API and "just works", the second gets you all the bells and whistles supported by the library along with a decent [AST](https://eemeli.org/yaml/#content-nodes), and the third lets you get progressively closer to YAML source, if that's your thing.
39
+
40
+ A [command-line tool](https://eemeli.org/yaml/#command-line-tool) is also included.
41
+
42
+ ### Parse & Stringify
43
+
44
+ ```js
45
+ import { parse, stringify } from 'yaml'
46
+ ```
47
+
48
+ - [`parse(str, reviver?, options?): value`](https://eemeli.org/yaml/#yaml-parse)
49
+ - [`stringify(value, replacer?, options?): string`](https://eemeli.org/yaml/#yaml-stringify)
50
+
51
+ ### Documents
52
+
53
+ <!-- prettier-ignore -->
54
+ ```js
55
+ import {
56
+ Document,
57
+ isDocument,
58
+ parseAllDocuments,
59
+ parseDocument
60
+ } from 'yaml'
61
+ ```
62
+
63
+ - [`Document`](https://eemeli.org/yaml/#documents)
64
+ - [`constructor(value, replacer?, options?)`](https://eemeli.org/yaml/#creating-documents)
65
+ - [`#contents`](https://eemeli.org/yaml/#content-nodes)
66
+ - [`#directives`](https://eemeli.org/yaml/#stream-directives)
67
+ - [`#errors`](https://eemeli.org/yaml/#errors)
68
+ - [`#warnings`](https://eemeli.org/yaml/#errors)
69
+ - [`isDocument(foo): boolean`](https://eemeli.org/yaml/#identifying-node-types)
70
+ - [`parseAllDocuments(str, options?): Document[]`](https://eemeli.org/yaml/#parsing-documents)
71
+ - [`parseDocument(str, options?): Document`](https://eemeli.org/yaml/#parsing-documents)
72
+
73
+ ### Content Nodes
74
+
75
+ <!-- prettier-ignore -->
76
+ ```js
77
+ import {
78
+ isAlias, isCollection, isMap, isNode,
79
+ isPair, isScalar, isSeq, Scalar,
80
+ visit, visitAsync, YAMLMap, YAMLSeq
81
+ } from 'yaml'
82
+ ```
83
+
84
+ - [`isAlias(foo): boolean`](https://eemeli.org/yaml/#identifying-node-types)
85
+ - [`isCollection(foo): boolean`](https://eemeli.org/yaml/#identifying-node-types)
86
+ - [`isMap(foo): boolean`](https://eemeli.org/yaml/#identifying-node-types)
87
+ - [`isNode(foo): boolean`](https://eemeli.org/yaml/#identifying-node-types)
88
+ - [`isPair(foo): boolean`](https://eemeli.org/yaml/#identifying-node-types)
89
+ - [`isScalar(foo): boolean`](https://eemeli.org/yaml/#identifying-node-types)
90
+ - [`isSeq(foo): boolean`](https://eemeli.org/yaml/#identifying-node-types)
91
+ - [`new Scalar(value)`](https://eemeli.org/yaml/#scalar-values)
92
+ - [`new YAMLMap()`](https://eemeli.org/yaml/#collections)
93
+ - [`new YAMLSeq()`](https://eemeli.org/yaml/#collections)
94
+ - [`doc.createAlias(node, name?): Alias`](https://eemeli.org/yaml/#creating-nodes)
95
+ - [`doc.createNode(value, options?): Node`](https://eemeli.org/yaml/#creating-nodes)
96
+ - [`doc.createPair(key, value): Pair`](https://eemeli.org/yaml/#creating-nodes)
97
+ - [`visit(node, visitor)`](https://eemeli.org/yaml/#finding-and-modifying-nodes)
98
+ - [`visitAsync(node, visitor)`](https://eemeli.org/yaml/#finding-and-modifying-nodes)
99
+
100
+ ### Parsing YAML
101
+
102
+ ```js
103
+ import { Composer, Lexer, Parser } from 'yaml'
104
+ ```
105
+
106
+ - [`new Lexer().lex(src)`](https://eemeli.org/yaml/#lexer)
107
+ - [`new Parser(onNewLine?).parse(src)`](https://eemeli.org/yaml/#parser)
108
+ - [`new Composer(options?).compose(tokens)`](https://eemeli.org/yaml/#composer)
109
+
110
+ ## YAML.parse
111
+
112
+ ```yaml
113
+ # file.yml
114
+ YAML:
115
+ - A human-readable data serialization language
116
+ - https://en.wikipedia.org/wiki/YAML
117
+ yaml:
118
+ - A complete JavaScript implementation
119
+ - https://www.npmjs.com/package/yaml
120
+ ```
121
+
122
+ ```js
123
+ import fs from 'fs'
124
+ import YAML from 'yaml'
125
+
126
+ YAML.parse('3.14159')
127
+ // 3.14159
128
+
129
+ YAML.parse('[ true, false, maybe, null ]\n')
130
+ // [ true, false, 'maybe', null ]
131
+
132
+ const file = fs.readFileSync('./file.yml', 'utf8')
133
+ YAML.parse(file)
134
+ // { YAML:
135
+ // [ 'A human-readable data serialization language',
136
+ // 'https://en.wikipedia.org/wiki/YAML' ],
137
+ // yaml:
138
+ // [ 'A complete JavaScript implementation',
139
+ // 'https://www.npmjs.com/package/yaml' ] }
140
+ ```
141
+
142
+ ## YAML.stringify
143
+
144
+ ```js
145
+ import YAML from 'yaml'
146
+
147
+ YAML.stringify(3.14159)
148
+ // '3.14159\n'
149
+
150
+ YAML.stringify([true, false, 'maybe', null])
151
+ // `- true
152
+ // - false
153
+ // - maybe
154
+ // - null
155
+ // `
156
+
157
+ YAML.stringify({ number: 3, plain: 'string', block: 'two\nlines\n' })
158
+ // `number: 3
159
+ // plain: string
160
+ // block: |
161
+ // two
162
+ // lines
163
+ // `
164
+ ```
165
+
166
+ ---
167
+
168
+ Browser testing provided by:
169
+
170
+ <a href="https://www.browserstack.com/open-source">
171
+ <img width=200 src="https://eemeli.org/yaml/images/browserstack.svg" alt="BrowserStack" />
172
+ </a>
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { UserError, cli, help } from './dist/cli.mjs'
4
+
5
+ cli(process.stdin, error => {
6
+ if (error instanceof UserError) {
7
+ if (error.code === UserError.ARGS) console.error(`${help}\n`)
8
+ console.error(error.message)
9
+ process.exitCode = error.code
10
+ } else if (error) throw error
11
+ })
@@ -0,0 +1,88 @@
1
+ import { isNode } from '../nodes/identity.js';
2
+ import { Scalar } from '../nodes/Scalar.js';
3
+ import { YAMLMap } from '../nodes/YAMLMap.js';
4
+ import { YAMLSeq } from '../nodes/YAMLSeq.js';
5
+ import { resolveBlockMap } from './resolve-block-map.js';
6
+ import { resolveBlockSeq } from './resolve-block-seq.js';
7
+ import { resolveFlowCollection } from './resolve-flow-collection.js';
8
+
9
+ function resolveCollection(CN, ctx, token, onError, tagName, tag) {
10
+ const coll = token.type === 'block-map'
11
+ ? resolveBlockMap(CN, ctx, token, onError, tag)
12
+ : token.type === 'block-seq'
13
+ ? resolveBlockSeq(CN, ctx, token, onError, tag)
14
+ : resolveFlowCollection(CN, ctx, token, onError, tag);
15
+ const Coll = coll.constructor;
16
+ // If we got a tagName matching the class, or the tag name is '!',
17
+ // then use the tagName from the node class used to create it.
18
+ if (tagName === '!' || tagName === Coll.tagName) {
19
+ coll.tag = Coll.tagName;
20
+ return coll;
21
+ }
22
+ if (tagName)
23
+ coll.tag = tagName;
24
+ return coll;
25
+ }
26
+ function composeCollection(CN, ctx, token, props, onError) {
27
+ const tagToken = props.tag;
28
+ const tagName = !tagToken
29
+ ? null
30
+ : ctx.directives.tagName(tagToken.source, msg => onError(tagToken, 'TAG_RESOLVE_FAILED', msg));
31
+ if (token.type === 'block-seq') {
32
+ const { anchor, newlineAfterProp: nl } = props;
33
+ const lastProp = anchor && tagToken
34
+ ? anchor.offset > tagToken.offset
35
+ ? anchor
36
+ : tagToken
37
+ : (anchor ?? tagToken);
38
+ if (lastProp && (!nl || nl.offset < lastProp.offset)) {
39
+ const message = 'Missing newline after block sequence props';
40
+ onError(lastProp, 'MISSING_CHAR', message);
41
+ }
42
+ }
43
+ const expType = token.type === 'block-map'
44
+ ? 'map'
45
+ : token.type === 'block-seq'
46
+ ? 'seq'
47
+ : token.start.source === '{'
48
+ ? 'map'
49
+ : 'seq';
50
+ // shortcut: check if it's a generic YAMLMap or YAMLSeq
51
+ // before jumping into the custom tag logic.
52
+ if (!tagToken ||
53
+ !tagName ||
54
+ tagName === '!' ||
55
+ (tagName === YAMLMap.tagName && expType === 'map') ||
56
+ (tagName === YAMLSeq.tagName && expType === 'seq')) {
57
+ return resolveCollection(CN, ctx, token, onError, tagName);
58
+ }
59
+ let tag = ctx.schema.tags.find(t => t.tag === tagName && t.collection === expType);
60
+ if (!tag) {
61
+ const kt = ctx.schema.knownTags[tagName];
62
+ if (kt?.collection === expType) {
63
+ ctx.schema.tags.push(Object.assign({}, kt, { default: false }));
64
+ tag = kt;
65
+ }
66
+ else {
67
+ if (kt) {
68
+ onError(tagToken, 'BAD_COLLECTION_TYPE', `${kt.tag} used for ${expType} collection, but expects ${kt.collection ?? 'scalar'}`, true);
69
+ }
70
+ else {
71
+ onError(tagToken, 'TAG_RESOLVE_FAILED', `Unresolved tag: ${tagName}`, true);
72
+ }
73
+ return resolveCollection(CN, ctx, token, onError, tagName);
74
+ }
75
+ }
76
+ const coll = resolveCollection(CN, ctx, token, onError, tagName, tag);
77
+ const res = tag.resolve?.(coll, msg => onError(tagToken, 'TAG_RESOLVE_FAILED', msg), ctx.options) ?? coll;
78
+ const node = isNode(res)
79
+ ? res
80
+ : new Scalar(res);
81
+ node.range = coll.range;
82
+ node.tag = tagName;
83
+ if (tag?.format)
84
+ node.format = tag.format;
85
+ return node;
86
+ }
87
+
88
+ export { composeCollection };