pi-feishu-cli 0.1.0

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 (407) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +111 -0
  3. package/dist/src/bot.d.ts +29 -0
  4. package/dist/src/bot.js +75 -0
  5. package/dist/src/cards.d.ts +6 -0
  6. package/dist/src/cards.js +87 -0
  7. package/dist/src/config.d.ts +3 -0
  8. package/dist/src/config.js +28 -0
  9. package/dist/src/daemon.d.ts +2 -0
  10. package/dist/src/daemon.js +151 -0
  11. package/dist/src/extension.d.ts +2 -0
  12. package/dist/src/extension.js +124 -0
  13. package/dist/src/poller.d.ts +33 -0
  14. package/dist/src/poller.js +94 -0
  15. package/dist/src/renderer.d.ts +8 -0
  16. package/dist/src/renderer.js +31 -0
  17. package/dist/src/session-registry.d.ts +15 -0
  18. package/dist/src/session-registry.js +82 -0
  19. package/dist/src/types.d.ts +25 -0
  20. package/dist/src/types.js +1 -0
  21. package/dist/tests/bot.test.d.ts +1 -0
  22. package/dist/tests/bot.test.js +89 -0
  23. package/dist/tests/cards.test.d.ts +1 -0
  24. package/dist/tests/cards.test.js +39 -0
  25. package/dist/tests/config.test.d.ts +1 -0
  26. package/dist/tests/config.test.js +59 -0
  27. package/dist/tests/renderer.test.d.ts +1 -0
  28. package/dist/tests/renderer.test.js +61 -0
  29. package/dist/tests/session-registry.test.d.ts +1 -0
  30. package/dist/tests/session-registry.test.js +92 -0
  31. package/dist/tests/types.test.d.ts +1 -0
  32. package/dist/tests/types.test.js +30 -0
  33. package/package.json +35 -0
  34. package/skills/lark-approval/SKILL.md +56 -0
  35. package/skills/lark-apps/SKILL.md +92 -0
  36. package/skills/lark-apps/references/lark-apps-access-scope-get.md +104 -0
  37. package/skills/lark-apps/references/lark-apps-access-scope-set.md +126 -0
  38. package/skills/lark-apps/references/lark-apps-create.md +112 -0
  39. package/skills/lark-apps/references/lark-apps-html-publish.md +151 -0
  40. package/skills/lark-apps/references/lark-apps-list.md +95 -0
  41. package/skills/lark-apps/references/lark-apps-update.md +86 -0
  42. package/skills/lark-attendance/SKILL.md +57 -0
  43. package/skills/lark-base/SKILL.md +359 -0
  44. package/skills/lark-base/references/dashboard-block-data-config.md +350 -0
  45. package/skills/lark-base/references/examples.md +140 -0
  46. package/skills/lark-base/references/formula-field-guide.md +737 -0
  47. package/skills/lark-base/references/lark-base-advperm-disable.md +83 -0
  48. package/skills/lark-base/references/lark-base-advperm-enable.md +80 -0
  49. package/skills/lark-base/references/lark-base-base-copy.md +74 -0
  50. package/skills/lark-base/references/lark-base-base-create.md +68 -0
  51. package/skills/lark-base/references/lark-base-base-get.md +39 -0
  52. package/skills/lark-base/references/lark-base-cell-value.md +151 -0
  53. package/skills/lark-base/references/lark-base-dashboard-arrange.md +83 -0
  54. package/skills/lark-base/references/lark-base-dashboard-block-create.md +108 -0
  55. package/skills/lark-base/references/lark-base-dashboard-block-delete.md +46 -0
  56. package/skills/lark-base/references/lark-base-dashboard-block-get.md +57 -0
  57. package/skills/lark-base/references/lark-base-dashboard-block-list.md +53 -0
  58. package/skills/lark-base/references/lark-base-dashboard-block-update.md +84 -0
  59. package/skills/lark-base/references/lark-base-dashboard-create.md +73 -0
  60. package/skills/lark-base/references/lark-base-dashboard-delete.md +44 -0
  61. package/skills/lark-base/references/lark-base-dashboard-get.md +59 -0
  62. package/skills/lark-base/references/lark-base-dashboard-list.md +52 -0
  63. package/skills/lark-base/references/lark-base-dashboard-update.md +69 -0
  64. package/skills/lark-base/references/lark-base-dashboard.md +240 -0
  65. package/skills/lark-base/references/lark-base-data-analysis-sop.md +88 -0
  66. package/skills/lark-base/references/lark-base-data-query.md +375 -0
  67. package/skills/lark-base/references/lark-base-field-create.md +104 -0
  68. package/skills/lark-base/references/lark-base-field-delete.md +51 -0
  69. package/skills/lark-base/references/lark-base-field-get.md +42 -0
  70. package/skills/lark-base/references/lark-base-field-list.md +44 -0
  71. package/skills/lark-base/references/lark-base-field-search-options.md +48 -0
  72. package/skills/lark-base/references/lark-base-field-update.md +97 -0
  73. package/skills/lark-base/references/lark-base-field.md +22 -0
  74. package/skills/lark-base/references/lark-base-form-create.md +87 -0
  75. package/skills/lark-base/references/lark-base-form-delete.md +64 -0
  76. package/skills/lark-base/references/lark-base-form-detail.md +198 -0
  77. package/skills/lark-base/references/lark-base-form-get.md +68 -0
  78. package/skills/lark-base/references/lark-base-form-list.md +73 -0
  79. package/skills/lark-base/references/lark-base-form-questions-create.md +118 -0
  80. package/skills/lark-base/references/lark-base-form-questions-delete.md +68 -0
  81. package/skills/lark-base/references/lark-base-form-questions-list.md +84 -0
  82. package/skills/lark-base/references/lark-base-form-questions-update.md +92 -0
  83. package/skills/lark-base/references/lark-base-form-questions.md +23 -0
  84. package/skills/lark-base/references/lark-base-form-submit.md +171 -0
  85. package/skills/lark-base/references/lark-base-form-update.md +82 -0
  86. package/skills/lark-base/references/lark-base-form.md +25 -0
  87. package/skills/lark-base/references/lark-base-history.md +16 -0
  88. package/skills/lark-base/references/lark-base-record-batch-create.md +58 -0
  89. package/skills/lark-base/references/lark-base-record-batch-update.md +53 -0
  90. package/skills/lark-base/references/lark-base-record-delete.md +62 -0
  91. package/skills/lark-base/references/lark-base-record-history-list.md +86 -0
  92. package/skills/lark-base/references/lark-base-record-share-link-create.md +72 -0
  93. package/skills/lark-base/references/lark-base-record-upsert.md +64 -0
  94. package/skills/lark-base/references/lark-base-record.md +31 -0
  95. package/skills/lark-base/references/lark-base-role-create.md +89 -0
  96. package/skills/lark-base/references/lark-base-role-delete.md +83 -0
  97. package/skills/lark-base/references/lark-base-role-get.md +87 -0
  98. package/skills/lark-base/references/lark-base-role-list.md +81 -0
  99. package/skills/lark-base/references/lark-base-role-update.md +94 -0
  100. package/skills/lark-base/references/lark-base-shortcut-field-properties.md +481 -0
  101. package/skills/lark-base/references/lark-base-table-create.md +62 -0
  102. package/skills/lark-base/references/lark-base-table-delete.md +51 -0
  103. package/skills/lark-base/references/lark-base-table-get.md +46 -0
  104. package/skills/lark-base/references/lark-base-table-list.md +43 -0
  105. package/skills/lark-base/references/lark-base-table-update.md +49 -0
  106. package/skills/lark-base/references/lark-base-table.md +20 -0
  107. package/skills/lark-base/references/lark-base-view-create.md +50 -0
  108. package/skills/lark-base/references/lark-base-view-delete.md +48 -0
  109. package/skills/lark-base/references/lark-base-view-get-card.md +38 -0
  110. package/skills/lark-base/references/lark-base-view-get-filter.md +38 -0
  111. package/skills/lark-base/references/lark-base-view-get-group.md +38 -0
  112. package/skills/lark-base/references/lark-base-view-get-sort.md +38 -0
  113. package/skills/lark-base/references/lark-base-view-get-timebar.md +38 -0
  114. package/skills/lark-base/references/lark-base-view-get-visible-fields.md +28 -0
  115. package/skills/lark-base/references/lark-base-view-get.md +38 -0
  116. package/skills/lark-base/references/lark-base-view-list.md +44 -0
  117. package/skills/lark-base/references/lark-base-view-rename.md +44 -0
  118. package/skills/lark-base/references/lark-base-view-set-card.md +55 -0
  119. package/skills/lark-base/references/lark-base-view-set-filter.md +181 -0
  120. package/skills/lark-base/references/lark-base-view-set-group.md +65 -0
  121. package/skills/lark-base/references/lark-base-view-set-sort.md +63 -0
  122. package/skills/lark-base/references/lark-base-view-set-timebar.md +51 -0
  123. package/skills/lark-base/references/lark-base-view-set-visible-fields.md +46 -0
  124. package/skills/lark-base/references/lark-base-view.md +44 -0
  125. package/skills/lark-base/references/lark-base-workflow-create.md +180 -0
  126. package/skills/lark-base/references/lark-base-workflow-disable.md +94 -0
  127. package/skills/lark-base/references/lark-base-workflow-enable.md +94 -0
  128. package/skills/lark-base/references/lark-base-workflow-get.md +147 -0
  129. package/skills/lark-base/references/lark-base-workflow-guide.md +718 -0
  130. package/skills/lark-base/references/lark-base-workflow-list.md +124 -0
  131. package/skills/lark-base/references/lark-base-workflow-schema.md +935 -0
  132. package/skills/lark-base/references/lark-base-workflow-update.md +167 -0
  133. package/skills/lark-base/references/lark-base-workflow.md +23 -0
  134. package/skills/lark-base/references/lark-base-workspace.md +18 -0
  135. package/skills/lark-base/references/lookup-field-guide.md +512 -0
  136. package/skills/lark-base/references/role-config.md +539 -0
  137. package/skills/lark-calendar/SKILL.md +154 -0
  138. package/skills/lark-calendar/references/lark-calendar-agenda.md +78 -0
  139. package/skills/lark-calendar/references/lark-calendar-create.md +109 -0
  140. package/skills/lark-calendar/references/lark-calendar-freebusy.md +124 -0
  141. package/skills/lark-calendar/references/lark-calendar-room-find.md +113 -0
  142. package/skills/lark-calendar/references/lark-calendar-rsvp.md +42 -0
  143. package/skills/lark-calendar/references/lark-calendar-schedule-meeting.md +265 -0
  144. package/skills/lark-calendar/references/lark-calendar-suggestion.md +125 -0
  145. package/skills/lark-calendar/references/lark-calendar-update.md +105 -0
  146. package/skills/lark-contact/SKILL.md +45 -0
  147. package/skills/lark-contact/references/lark-contact-get-user.md +19 -0
  148. package/skills/lark-contact/references/lark-contact-search-user.md +124 -0
  149. package/skills/lark-doc/SKILL.md +65 -0
  150. package/skills/lark-doc/references/lark-doc-create.md +89 -0
  151. package/skills/lark-doc/references/lark-doc-fetch.md +141 -0
  152. package/skills/lark-doc/references/lark-doc-md.md +71 -0
  153. package/skills/lark-doc/references/lark-doc-media-download.md +50 -0
  154. package/skills/lark-doc/references/lark-doc-media-insert.md +114 -0
  155. package/skills/lark-doc/references/lark-doc-media-preview.md +41 -0
  156. package/skills/lark-doc/references/lark-doc-update.md +252 -0
  157. package/skills/lark-doc/references/lark-doc-whiteboard.md +100 -0
  158. package/skills/lark-doc/references/lark-doc-xml.md +169 -0
  159. package/skills/lark-doc/references/style/lark-doc-create-workflow.md +56 -0
  160. package/skills/lark-doc/references/style/lark-doc-style.md +106 -0
  161. package/skills/lark-doc/references/style/lark-doc-update-workflow.md +54 -0
  162. package/skills/lark-drive/SKILL.md +369 -0
  163. package/skills/lark-drive/references/lark-drive-add-comment.md +182 -0
  164. package/skills/lark-drive/references/lark-drive-apply-permission.md +77 -0
  165. package/skills/lark-drive/references/lark-drive-create-folder.md +73 -0
  166. package/skills/lark-drive/references/lark-drive-create-shortcut.md +103 -0
  167. package/skills/lark-drive/references/lark-drive-delete.md +79 -0
  168. package/skills/lark-drive/references/lark-drive-download.md +31 -0
  169. package/skills/lark-drive/references/lark-drive-export-download.md +50 -0
  170. package/skills/lark-drive/references/lark-drive-export.md +119 -0
  171. package/skills/lark-drive/references/lark-drive-import.md +159 -0
  172. package/skills/lark-drive/references/lark-drive-inspect.md +50 -0
  173. package/skills/lark-drive/references/lark-drive-move.md +120 -0
  174. package/skills/lark-drive/references/lark-drive-pull.md +137 -0
  175. package/skills/lark-drive/references/lark-drive-push.md +162 -0
  176. package/skills/lark-drive/references/lark-drive-reactions.md +113 -0
  177. package/skills/lark-drive/references/lark-drive-search.md +266 -0
  178. package/skills/lark-drive/references/lark-drive-status.md +198 -0
  179. package/skills/lark-drive/references/lark-drive-task-result.md +302 -0
  180. package/skills/lark-drive/references/lark-drive-upload.md +67 -0
  181. package/skills/lark-drive/references/lark-drive-version-delete.md +38 -0
  182. package/skills/lark-drive/references/lark-drive-version-get.md +71 -0
  183. package/skills/lark-drive/references/lark-drive-version-history.md +73 -0
  184. package/skills/lark-drive/references/lark-drive-version-revert.md +198 -0
  185. package/skills/lark-event/SKILL.md +145 -0
  186. package/skills/lark-event/references/lark-event-im.md +86 -0
  187. package/skills/lark-im/SKILL.md +162 -0
  188. package/skills/lark-im/references/lark-im-chat-create.md +162 -0
  189. package/skills/lark-im/references/lark-im-chat-identity.md +55 -0
  190. package/skills/lark-im/references/lark-im-chat-list.md +198 -0
  191. package/skills/lark-im/references/lark-im-chat-messages-list.md +148 -0
  192. package/skills/lark-im/references/lark-im-chat-search.md +136 -0
  193. package/skills/lark-im/references/lark-im-chat-update.md +84 -0
  194. package/skills/lark-im/references/lark-im-flag-cancel.md +198 -0
  195. package/skills/lark-im/references/lark-im-flag-create.md +67 -0
  196. package/skills/lark-im/references/lark-im-flag-list.md +100 -0
  197. package/skills/lark-im/references/lark-im-messages-mget.md +95 -0
  198. package/skills/lark-im/references/lark-im-messages-reply.md +228 -0
  199. package/skills/lark-im/references/lark-im-messages-resources-download.md +94 -0
  200. package/skills/lark-im/references/lark-im-messages-search.md +232 -0
  201. package/skills/lark-im/references/lark-im-messages-send.md +229 -0
  202. package/skills/lark-im/references/lark-im-reactions.md +297 -0
  203. package/skills/lark-im/references/lark-im-threads-messages-list.md +111 -0
  204. package/skills/lark-mail/SKILL.md +648 -0
  205. package/skills/lark-mail/references/lark-mail-decline-receipt.md +115 -0
  206. package/skills/lark-mail/references/lark-mail-draft-create.md +123 -0
  207. package/skills/lark-mail/references/lark-mail-draft-edit.md +400 -0
  208. package/skills/lark-mail/references/lark-mail-forward.md +173 -0
  209. package/skills/lark-mail/references/lark-mail-message.md +230 -0
  210. package/skills/lark-mail/references/lark-mail-messages.md +108 -0
  211. package/skills/lark-mail/references/lark-mail-reply-all.md +206 -0
  212. package/skills/lark-mail/references/lark-mail-reply.md +242 -0
  213. package/skills/lark-mail/references/lark-mail-send-receipt.md +198 -0
  214. package/skills/lark-mail/references/lark-mail-send.md +216 -0
  215. package/skills/lark-mail/references/lark-mail-share-to-chat.md +198 -0
  216. package/skills/lark-mail/references/lark-mail-signature.md +98 -0
  217. package/skills/lark-mail/references/lark-mail-template-create.md +129 -0
  218. package/skills/lark-mail/references/lark-mail-template-update.md +198 -0
  219. package/skills/lark-mail/references/lark-mail-thread.md +111 -0
  220. package/skills/lark-mail/references/lark-mail-triage.md +122 -0
  221. package/skills/lark-mail/references/lark-mail-watch.md +94 -0
  222. package/skills/lark-minutes/SKILL.md +139 -0
  223. package/skills/lark-minutes/references/lark-minutes-download.md +137 -0
  224. package/skills/lark-minutes/references/lark-minutes-search.md +206 -0
  225. package/skills/lark-minutes/references/lark-minutes-upload.md +104 -0
  226. package/skills/lark-okr/SKILL.md +133 -0
  227. package/skills/lark-okr/references/lark-okr-contentblock.md +359 -0
  228. package/skills/lark-okr/references/lark-okr-cycle-detail.md +84 -0
  229. package/skills/lark-okr/references/lark-okr-cycle-list.md +90 -0
  230. package/skills/lark-okr/references/lark-okr-entities.md +329 -0
  231. package/skills/lark-okr/references/lark-okr-image-upload.md +116 -0
  232. package/skills/lark-okr/references/lark-okr-progress-create.md +81 -0
  233. package/skills/lark-okr/references/lark-okr-progress-delete.md +47 -0
  234. package/skills/lark-okr/references/lark-okr-progress-get.md +62 -0
  235. package/skills/lark-okr/references/lark-okr-progress-list.md +80 -0
  236. package/skills/lark-okr/references/lark-okr-progress-update.md +81 -0
  237. package/skills/lark-openapi-explorer/SKILL.md +153 -0
  238. package/skills/lark-shared/SKILL.md +144 -0
  239. package/skills/lark-sheets/SKILL.md +343 -0
  240. package/skills/lark-sheets/references/lark-sheets-cell-data.md +197 -0
  241. package/skills/lark-sheets/references/lark-sheets-cell-images.md +59 -0
  242. package/skills/lark-sheets/references/lark-sheets-cell-style-and-merge.md +141 -0
  243. package/skills/lark-sheets/references/lark-sheets-dropdown.md +133 -0
  244. package/skills/lark-sheets/references/lark-sheets-filter-views.md +193 -0
  245. package/skills/lark-sheets/references/lark-sheets-float-images.md +125 -0
  246. package/skills/lark-sheets/references/lark-sheets-formula.md +88 -0
  247. package/skills/lark-sheets/references/lark-sheets-row-column-management.md +151 -0
  248. package/skills/lark-sheets/references/lark-sheets-sheet-management.md +164 -0
  249. package/skills/lark-sheets/references/lark-sheets-spreadsheet-management.md +140 -0
  250. package/skills/lark-skill-maker/SKILL.md +85 -0
  251. package/skills/lark-slides/SKILL.md +296 -0
  252. package/skills/lark-slides/assets/templates/administration--all_hands_meeting.xml +1999 -0
  253. package/skills/lark-slides/assets/templates/administration--annual_gala.xml +1160 -0
  254. package/skills/lark-slides/assets/templates/administration--company_intro.xml +1376 -0
  255. package/skills/lark-slides/assets/templates/administration--corporate_culture.xml +1765 -0
  256. package/skills/lark-slides/assets/templates/hr--employee_training.xml +912 -0
  257. package/skills/lark-slides/assets/templates/hr--employee_training_workshop.xml +1504 -0
  258. package/skills/lark-slides/assets/templates/hr--onboarding.xml +933 -0
  259. package/skills/lark-slides/assets/templates/marketing--brand_communication.xml +1367 -0
  260. package/skills/lark-slides/assets/templates/marketing--brand_logo_design.xml +1347 -0
  261. package/skills/lark-slides/assets/templates/marketing--brand_operations_plan.xml +1309 -0
  262. package/skills/lark-slides/assets/templates/marketing--business_plan.xml +1646 -0
  263. package/skills/lark-slides/assets/templates/marketing--marketing_plan.xml +198 -0
  264. package/skills/lark-slides/assets/templates/marketing--marketing_strategy.xml +1484 -0
  265. package/skills/lark-slides/assets/templates/marketing--product_whitepaper.xml +198 -0
  266. package/skills/lark-slides/assets/templates/marketing--roadshow_business_plan.xml +1506 -0
  267. package/skills/lark-slides/assets/templates/misc--book_sharing.xml +198 -0
  268. package/skills/lark-slides/assets/templates/misc--club_event_plan.xml +4885 -0
  269. package/skills/lark-slides/assets/templates/misc--student_career_plan.xml +1854 -0
  270. package/skills/lark-slides/assets/templates/office--dark_general.xml +3763 -0
  271. package/skills/lark-slides/assets/templates/office--dept_annual_report.xml +1192 -0
  272. package/skills/lark-slides/assets/templates/office--light_general.xml +3378 -0
  273. package/skills/lark-slides/assets/templates/office--project_kickoff.xml +3152 -0
  274. package/skills/lark-slides/assets/templates/office--quarterly_review.xml +1253 -0
  275. package/skills/lark-slides/assets/templates/office--work_report.xml +1099 -0
  276. package/skills/lark-slides/assets/templates/office--work_summary.xml +4420 -0
  277. package/skills/lark-slides/assets/templates/office--work_summary_report.xml +1523 -0
  278. package/skills/lark-slides/assets/templates/operations--brand_logo_design.xml +1347 -0
  279. package/skills/lark-slides/assets/templates/operations--brand_operations_plan.xml +1309 -0
  280. package/skills/lark-slides/assets/templates/operations--marketing_plan.xml +1469 -0
  281. package/skills/lark-slides/assets/templates/operations--product_promotion.xml +687 -0
  282. package/skills/lark-slides/assets/templates/personal--experience_sharing.xml +2242 -0
  283. package/skills/lark-slides/assets/templates/personal--personal_resume.xml +2047 -0
  284. package/skills/lark-slides/assets/templates/personal--promotion_defense.xml +1099 -0
  285. package/skills/lark-slides/assets/templates/personal--promotion_report.xml +1039 -0
  286. package/skills/lark-slides/assets/templates/personal--self_intro.xml +696 -0
  287. package/skills/lark-slides/assets/templates/personal--teaching_sharing.xml +3013 -0
  288. package/skills/lark-slides/assets/templates/product--business_case_analysis.xml +1341 -0
  289. package/skills/lark-slides/assets/templates/product--market_analysis.xml +898 -0
  290. package/skills/lark-slides/assets/templates/product--product_analysis.xml +1537 -0
  291. package/skills/lark-slides/assets/templates/product--product_intro.xml +2838 -0
  292. package/skills/lark-slides/assets/templates/product--product_promotion.xml +687 -0
  293. package/skills/lark-slides/assets/templates/product--product_promotion_2.xml +198 -0
  294. package/skills/lark-slides/references/asset-planning.md +124 -0
  295. package/skills/lark-slides/references/examples.md +261 -0
  296. package/skills/lark-slides/references/lark-slides-create.md +137 -0
  297. package/skills/lark-slides/references/lark-slides-edit-workflows.md +142 -0
  298. package/skills/lark-slides/references/lark-slides-media-upload.md +128 -0
  299. package/skills/lark-slides/references/lark-slides-replace-slide.md +239 -0
  300. package/skills/lark-slides/references/lark-slides-xml-presentation-slide-create.md +220 -0
  301. package/skills/lark-slides/references/lark-slides-xml-presentation-slide-delete.md +123 -0
  302. package/skills/lark-slides/references/lark-slides-xml-presentation-slide-get.md +110 -0
  303. package/skills/lark-slides/references/lark-slides-xml-presentation-slide-replace.md +186 -0
  304. package/skills/lark-slides/references/lark-slides-xml-presentations-get.md +98 -0
  305. package/skills/lark-slides/references/planning-layer.md +219 -0
  306. package/skills/lark-slides/references/slide-templates.md +201 -0
  307. package/skills/lark-slides/references/slides_demo.xml +226 -0
  308. package/skills/lark-slides/references/slides_xml_schema_definition.xml +3004 -0
  309. package/skills/lark-slides/references/template-catalog.md +463 -0
  310. package/skills/lark-slides/references/template-index.json +198 -0
  311. package/skills/lark-slides/references/troubleshooting.md +198 -0
  312. package/skills/lark-slides/references/validation-checklist.md +102 -0
  313. package/skills/lark-slides/references/visual-planning.md +250 -0
  314. package/skills/lark-slides/references/xml-format-guide.md +369 -0
  315. package/skills/lark-slides/references/xml-schema-quick-ref.md +215 -0
  316. package/skills/lark-slides/scripts/template_tool.py +970 -0
  317. package/skills/lark-slides/scripts/template_tool_test.py +177 -0
  318. package/skills/lark-slides/scripts/xml_text_overlap_lint.py +367 -0
  319. package/skills/lark-slides/scripts/xml_text_overlap_lint_test.py +263 -0
  320. package/skills/lark-task/SKILL.md +165 -0
  321. package/skills/lark-task/references/lark-task-assign.md +38 -0
  322. package/skills/lark-task/references/lark-task-comment.md +28 -0
  323. package/skills/lark-task/references/lark-task-complete.md +27 -0
  324. package/skills/lark-task/references/lark-task-create.md +57 -0
  325. package/skills/lark-task/references/lark-task-followers.md +35 -0
  326. package/skills/lark-task/references/lark-task-get-my-tasks.md +55 -0
  327. package/skills/lark-task/references/lark-task-get-related-tasks.md +53 -0
  328. package/skills/lark-task/references/lark-task-reminder.md +36 -0
  329. package/skills/lark-task/references/lark-task-reopen.md +27 -0
  330. package/skills/lark-task/references/lark-task-search.md +41 -0
  331. package/skills/lark-task/references/lark-task-set-ancestor.md +32 -0
  332. package/skills/lark-task/references/lark-task-subscribe-event.md +86 -0
  333. package/skills/lark-task/references/lark-task-tasklist-create.md +35 -0
  334. package/skills/lark-task/references/lark-task-tasklist-members.md +36 -0
  335. package/skills/lark-task/references/lark-task-tasklist-search.md +38 -0
  336. package/skills/lark-task/references/lark-task-tasklist-task-add.md +38 -0
  337. package/skills/lark-task/references/lark-task-update.md +37 -0
  338. package/skills/lark-task/references/lark-task-upload-attachment.md +59 -0
  339. package/skills/lark-vc/SKILL.md +168 -0
  340. package/skills/lark-vc/references/lark-vc-notes.md +126 -0
  341. package/skills/lark-vc/references/lark-vc-recording.md +153 -0
  342. package/skills/lark-vc/references/lark-vc-search.md +193 -0
  343. package/skills/lark-vc-agent/SKILL.md +121 -0
  344. package/skills/lark-vc-agent/references/lark-vc-agent-meeting-events.md +247 -0
  345. package/skills/lark-vc-agent/references/lark-vc-agent-meeting-join.md +133 -0
  346. package/skills/lark-vc-agent/references/lark-vc-agent-meeting-leave.md +111 -0
  347. package/skills/lark-whiteboard/SKILL.md +144 -0
  348. package/skills/lark-whiteboard/references/connectors.md +102 -0
  349. package/skills/lark-whiteboard/references/content.md +40 -0
  350. package/skills/lark-whiteboard/references/image.md +80 -0
  351. package/skills/lark-whiteboard/references/lark-whiteboard-query.md +49 -0
  352. package/skills/lark-whiteboard/references/lark-whiteboard-update.md +100 -0
  353. package/skills/lark-whiteboard/references/layout.md +374 -0
  354. package/skills/lark-whiteboard/references/schema.md +357 -0
  355. package/skills/lark-whiteboard/references/style.md +318 -0
  356. package/skills/lark-whiteboard/references/typography.md +73 -0
  357. package/skills/lark-whiteboard/routes/dsl.md +107 -0
  358. package/skills/lark-whiteboard/routes/mermaid.md +27 -0
  359. package/skills/lark-whiteboard/routes/svg.md +54 -0
  360. package/skills/lark-whiteboard/scenes/architecture.md +433 -0
  361. package/skills/lark-whiteboard/scenes/bar-chart.md +187 -0
  362. package/skills/lark-whiteboard/scenes/comparison.md +135 -0
  363. package/skills/lark-whiteboard/scenes/fishbone.md +238 -0
  364. package/skills/lark-whiteboard/scenes/flowchart.md +198 -0
  365. package/skills/lark-whiteboard/scenes/flywheel.md +195 -0
  366. package/skills/lark-whiteboard/scenes/funnel.md +198 -0
  367. package/skills/lark-whiteboard/scenes/line-chart.md +214 -0
  368. package/skills/lark-whiteboard/scenes/mermaid.md +130 -0
  369. package/skills/lark-whiteboard/scenes/milestone.md +139 -0
  370. package/skills/lark-whiteboard/scenes/organization.md +173 -0
  371. package/skills/lark-whiteboard/scenes/photo-showcase.md +198 -0
  372. package/skills/lark-whiteboard/scenes/pyramid.md +99 -0
  373. package/skills/lark-whiteboard/scenes/swimlane.md +371 -0
  374. package/skills/lark-whiteboard/scenes/treemap.md +198 -0
  375. package/skills/lark-wiki/SKILL.md +119 -0
  376. package/skills/lark-wiki/references/lark-wiki-delete-space.md +205 -0
  377. package/skills/lark-wiki/references/lark-wiki-member-add.md +66 -0
  378. package/skills/lark-wiki/references/lark-wiki-member-list.md +76 -0
  379. package/skills/lark-wiki/references/lark-wiki-member-remove.md +61 -0
  380. package/skills/lark-wiki/references/lark-wiki-move.md +183 -0
  381. package/skills/lark-wiki/references/lark-wiki-node-copy.md +72 -0
  382. package/skills/lark-wiki/references/lark-wiki-node-create.md +127 -0
  383. package/skills/lark-wiki/references/lark-wiki-node-delete.md +62 -0
  384. package/skills/lark-wiki/references/lark-wiki-node-get.md +56 -0
  385. package/skills/lark-wiki/references/lark-wiki-node-list.md +198 -0
  386. package/skills/lark-wiki/references/lark-wiki-space-create.md +46 -0
  387. package/skills/lark-wiki/references/lark-wiki-space-list.md +198 -0
  388. package/skills/lark-workflow-meeting-summary/SKILL.md +104 -0
  389. package/skills/lark-workflow-standup-report/SKILL.md +120 -0
  390. package/skills/mmx-cli/SKILL.md +440 -0
  391. package/src/bot.ts +109 -0
  392. package/src/cards.ts +105 -0
  393. package/src/config.ts +33 -0
  394. package/src/daemon.ts +217 -0
  395. package/src/extension.ts +132 -0
  396. package/src/poller.ts +135 -0
  397. package/src/renderer.ts +47 -0
  398. package/src/session-registry.ts +90 -0
  399. package/src/types.ts +29 -0
  400. package/tests/bot.test.ts +104 -0
  401. package/tests/cards.test.ts +48 -0
  402. package/tests/config.test.ts +59 -0
  403. package/tests/renderer.test.ts +74 -0
  404. package/tests/session-registry.test.ts +94 -0
  405. package/tests/types.test.ts +35 -0
  406. package/tsconfig.json +16 -0
  407. package/vitest.config.ts +7 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 yandy
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,111 @@
1
+ # pi-feishu-cli
2
+
3
+ 在飞书中与 Pi 对话的 [pi package](https://pi.dev/docs/latest/packages)。包含 26 个飞书 CLI skills 和一个飞书 IM 守护进程。
4
+
5
+ ## 安装
6
+
7
+ ```bash
8
+ pi install ./pi-feishu-cli
9
+ ```
10
+
11
+ ## 启动
12
+
13
+ **方式一:Pi 内命令**
14
+
15
+ ```
16
+ /feishu-im start 启动守护进程
17
+ /feishu-im status 查看状态
18
+ /feishu-im stop 停止守护进程
19
+ /feishu-im restart 重启守护进程
20
+ ```
21
+
22
+ **方式二:CLI flag**
23
+
24
+ ```bash
25
+ pi --feishu-im
26
+ ```
27
+
28
+ 首次启动会自动检查 `lark-cli` 是否安装和配置,如未完成会给出引导提示。
29
+
30
+ ## 前置依赖
31
+
32
+ - [lark-cli](https://github.com/larksuite/lark-cli) — 飞书 API 调用工具
33
+ - 飞书机器人应用凭证(通过 `lark-cli config init` 配置)
34
+
35
+ ## 配置
36
+
37
+ `~/.pi/agent/feishu-im/config.json`:
38
+
39
+ ```json
40
+ {
41
+ "strategy": "mention",
42
+ "model": "anthropic/claude-sonnet-4-20250514",
43
+ "pollInterval": 5
44
+ }
45
+ ```
46
+
47
+ | 字段 | 类型 | 默认值 | 说明 |
48
+ |------|------|--------|------|
49
+ | `strategy` | `"open"` \| `"mention"` | `"mention"` | 群聊策略:mention 仅回复 @机器人,open 回复全部 |
50
+ | `model` | `string` | 空 | 新会话默认模型,不设置则用 Pi 默认 |
51
+ | `pollInterval` | `number` | `5` | 长轮询间隔(秒) |
52
+
53
+ ## 架构
54
+
55
+ ```
56
+ pi TUI → extension(/feishu-im start)
57
+
58
+ spawn daemon
59
+
60
+ ┌──────────▼──────────┐
61
+ │ 守护进程 (Node.js) │
62
+ │ ┌───────────────┐ │
63
+ │ │ 长轮询事件 │ │
64
+ │ └───────┬───────┘ │
65
+ │ ▼ │
66
+ │ ┌───────────────┐ │
67
+ │ │ 消息路由 Bot │ │
68
+ │ │ 命令/对话分发 │ │
69
+ │ └───────┬───────┘ │
70
+ │ ▼ │
71
+ │ ┌───────────────┐ │
72
+ │ │ Pi SDK Agent │ │
73
+ │ │ 处理消息回复 │ │
74
+ │ └───────────────┘ │
75
+ └─────────────────────┘
76
+ ```
77
+
78
+ 守护进程独立于 Pi TUI 运行,关闭 Pi 后仍可继续对话。
79
+
80
+ ## 飞书内命令
81
+
82
+ | 命令 | 说明 |
83
+ |------|------|
84
+ | `/new [名称]` | 创建新会话 |
85
+ | `/sessions` | 查看会话列表(卡片) |
86
+ | `/switch <id>` | 切换会话 |
87
+ | `/rm <id>` | 删除会话 |
88
+ | `/model` | 切换模型(卡片) |
89
+
90
+ ## 数据目录
91
+
92
+ ```
93
+ ~/.pi/agent/
94
+ ├── feishu-im/
95
+ │ ├── config.json # 配置
96
+ │ ├── daemon.pid # PID
97
+ │ └── registry.json # 飞书↔Pi 会话映射
98
+ └── sessions/ # Pi session 文件
99
+ ```
100
+
101
+ ## Skills
102
+
103
+ 包含 26 个飞书 CLI skills,覆盖 IM、日历、文档、表格、审批、OKR 等飞书服务。通过 Pi 的技能系统自动加载,对话中按需调用。
104
+
105
+ ## 开发
106
+
107
+ ```bash
108
+ npm install
109
+ npx vitest run # 运行测试
110
+ npx vitest # 监听模式
111
+ ```
@@ -0,0 +1,29 @@
1
+ import { SessionRegistry } from "./session-registry.js";
2
+ import type { FeishuEvent } from "./poller.js";
3
+ import type { FeishuImConfig } from "./types.js";
4
+ export interface RouteResultCommand {
5
+ type: "command";
6
+ command: string;
7
+ args: string;
8
+ chatId: string;
9
+ threadId?: string;
10
+ }
11
+ export interface RouteResultMessage {
12
+ type: "message";
13
+ text: string;
14
+ chatId: string;
15
+ threadId?: string;
16
+ }
17
+ export interface RouteResultSkip {
18
+ type: "skip";
19
+ }
20
+ export type RouteResult = RouteResultCommand | RouteResultMessage | RouteResultSkip;
21
+ export declare class Bot {
22
+ private registry;
23
+ private strategy;
24
+ constructor(registry: SessionRegistry, strategy: FeishuImConfig["strategy"]);
25
+ route(event: FeishuEvent): RouteResult;
26
+ private isCommand;
27
+ private parseCommand;
28
+ private extractText;
29
+ }
@@ -0,0 +1,75 @@
1
+ const BOT_OPEN_ID = "__bot_open_id__";
2
+ export class Bot {
3
+ registry;
4
+ strategy;
5
+ constructor(registry, strategy) {
6
+ this.registry = registry;
7
+ this.strategy = strategy;
8
+ }
9
+ route(event) {
10
+ const msg = event.event?.message;
11
+ if (!msg)
12
+ return { type: "skip" };
13
+ const chatId = msg.chat_id;
14
+ const text = this.extractText(msg.content, msg.message_type);
15
+ if (!text)
16
+ return { type: "skip" };
17
+ const mentions = msg.mentions ?? [];
18
+ const hasMentions = mentions.length > 0;
19
+ const isMentioned = mentions.some((m) => m.key === BOT_OPEN_ID);
20
+ if (this.strategy === "mention" && hasMentions && !isMentioned) {
21
+ if (!this.isCommand(text))
22
+ return { type: "skip" };
23
+ }
24
+ const commandResult = this.parseCommand(text);
25
+ if (commandResult) {
26
+ return {
27
+ type: "command",
28
+ command: commandResult.command,
29
+ args: commandResult.args,
30
+ chatId,
31
+ threadId: msg.parent_id,
32
+ };
33
+ }
34
+ return {
35
+ type: "message",
36
+ text,
37
+ chatId,
38
+ threadId: msg.parent_id,
39
+ };
40
+ }
41
+ isCommand(text) {
42
+ return ["/new", "/sessions", "/switch", "/rm", "/model"].some((cmd) => text.trim().startsWith(cmd));
43
+ }
44
+ parseCommand(text) {
45
+ const trimmed = text.trim();
46
+ if (trimmed === "/sessions" || trimmed === "/model") {
47
+ return { command: trimmed.slice(1), args: "" };
48
+ }
49
+ if (trimmed.startsWith("/new ")) {
50
+ return { command: "new", args: trimmed.slice(5).trim() || "默认会话" };
51
+ }
52
+ if (trimmed === "/new") {
53
+ return { command: "new", args: "默认会话" };
54
+ }
55
+ if (trimmed.startsWith("/switch ")) {
56
+ return { command: "switch", args: trimmed.slice(8).trim() };
57
+ }
58
+ if (trimmed.startsWith("/rm ")) {
59
+ return { command: "rm", args: trimmed.slice(4).trim() };
60
+ }
61
+ return null;
62
+ }
63
+ extractText(content, msgType) {
64
+ if (msgType === "text") {
65
+ try {
66
+ const parsed = JSON.parse(content);
67
+ return parsed.text ?? "";
68
+ }
69
+ catch {
70
+ return content;
71
+ }
72
+ }
73
+ return "";
74
+ }
75
+ }
@@ -0,0 +1,6 @@
1
+ import type { SessionInfo } from "./types.js";
2
+ export declare function buildSessionListCard(chatId: string, sessions: SessionInfo[], activeId: string | null): string;
3
+ export declare function buildModelSelectCard(chatId: string, models: Array<{
4
+ id: string;
5
+ name: string;
6
+ }>, current: string): string;
@@ -0,0 +1,87 @@
1
+ export function buildSessionListCard(chatId, sessions, activeId) {
2
+ const header = {
3
+ title: { tag: "plain_text", content: "Pi 会话管理" },
4
+ template: "blue",
5
+ };
6
+ const elements = [];
7
+ if (sessions.length === 0) {
8
+ elements.push({
9
+ tag: "div",
10
+ text: { tag: "lark_md", content: "暂无会话" },
11
+ });
12
+ }
13
+ else {
14
+ for (const sess of sessions) {
15
+ const isActive = sess.id === activeId;
16
+ const prefix = isActive ? "▶ " : "";
17
+ elements.push({
18
+ tag: "div",
19
+ text: {
20
+ tag: "lark_md",
21
+ content: `${prefix}**${sess.name}** \n\`${sess.id}\``,
22
+ },
23
+ });
24
+ elements.push({ tag: "hr" });
25
+ }
26
+ elements.pop(); // remove last hr
27
+ }
28
+ elements.push({
29
+ tag: "action",
30
+ actions: [
31
+ {
32
+ tag: "button",
33
+ text: { tag: "plain_text", content: "➕ 新建会话" },
34
+ type: "primary",
35
+ value: JSON.stringify({ action: "new_session", chat_id: chatId }),
36
+ },
37
+ {
38
+ tag: "button",
39
+ text: { tag: "plain_text", content: "🔄 切换模型" },
40
+ value: JSON.stringify({ action: "model_select", chat_id: chatId }),
41
+ },
42
+ ],
43
+ });
44
+ return JSON.stringify({
45
+ msg_type: "interactive",
46
+ card: { header, elements },
47
+ });
48
+ }
49
+ export function buildModelSelectCard(chatId, models, current) {
50
+ const header = {
51
+ title: { tag: "plain_text", content: "选择模型" },
52
+ template: "blue",
53
+ };
54
+ const elements = [];
55
+ elements.push({
56
+ tag: "div",
57
+ text: {
58
+ tag: "lark_md",
59
+ content: `当前: **${models.find((m) => m.id === current)?.name ?? current}**`,
60
+ },
61
+ });
62
+ elements.push({ tag: "hr" });
63
+ for (const model of models) {
64
+ elements.push({
65
+ tag: "action",
66
+ actions: [
67
+ {
68
+ tag: "button",
69
+ text: {
70
+ tag: "plain_text",
71
+ content: model.id === current ? `▶ ${model.name}` : model.name,
72
+ },
73
+ type: model.id === current ? "primary" : "default",
74
+ value: JSON.stringify({
75
+ action: "select_model",
76
+ chat_id: chatId,
77
+ model_id: model.id,
78
+ }),
79
+ },
80
+ ],
81
+ });
82
+ }
83
+ return JSON.stringify({
84
+ msg_type: "interactive",
85
+ card: { header, elements },
86
+ });
87
+ }
@@ -0,0 +1,3 @@
1
+ import type { FeishuImConfig } from "./types.js";
2
+ export declare const DEFAULT_CONFIG: Required<Omit<FeishuImConfig, "model">>;
3
+ export declare function loadConfig(configDir: string): FeishuImConfig;
@@ -0,0 +1,28 @@
1
+ import { readFileSync, existsSync, mkdirSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ export const DEFAULT_CONFIG = {
4
+ strategy: "mention",
5
+ pollInterval: 5,
6
+ autoStart: false,
7
+ };
8
+ export function loadConfig(configDir) {
9
+ if (!existsSync(configDir)) {
10
+ mkdirSync(configDir, { recursive: true });
11
+ }
12
+ const configPath = join(configDir, "config.json");
13
+ if (!existsSync(configPath)) {
14
+ return { ...DEFAULT_CONFIG };
15
+ }
16
+ try {
17
+ const raw = JSON.parse(readFileSync(configPath, "utf-8"));
18
+ return {
19
+ strategy: raw.strategy ?? DEFAULT_CONFIG.strategy,
20
+ model: raw.model,
21
+ pollInterval: raw.pollInterval ?? DEFAULT_CONFIG.pollInterval,
22
+ autoStart: raw.autoStart ?? DEFAULT_CONFIG.autoStart,
23
+ };
24
+ }
25
+ catch {
26
+ return { ...DEFAULT_CONFIG };
27
+ }
28
+ }
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,151 @@
1
+ #!/usr/bin/env node
2
+ import { join } from "node:path";
3
+ import { homedir } from "node:os";
4
+ import { writeFileSync } from "node:fs";
5
+ import { createAgentSessionRuntime, createAgentSessionServices, createAgentSessionFromServices, getAgentDir, SessionManager, } from "@earendil-works/pi-coding-agent";
6
+ import { loadConfig } from "./config.js";
7
+ import { SessionRegistry } from "./session-registry.js";
8
+ import { Bot } from "./bot.js";
9
+ import { pollEvents, sendMessage, larkCliAvailable, larkCliConfigured } from "./poller.js";
10
+ import { buildSessionListCard, buildModelSelectCard } from "./cards.js";
11
+ const FEISHU_IM_DIR = join(homedir(), ".pi", "agent", "feishu-im");
12
+ const PID_FILE = join(FEISHU_IM_DIR, "daemon.pid");
13
+ function getAvailableModels() {
14
+ return [
15
+ { id: "anthropic/claude-opus-4-5", name: "Claude Opus 4.5" },
16
+ { id: "anthropic/claude-sonnet-4-20250514", name: "Claude Sonnet 4" },
17
+ { id: "anthropic/claude-haiku-3-5", name: "Claude Haiku 3.5" },
18
+ ];
19
+ }
20
+ async function handleCommand(registry, command, args, chatId, currentModel) {
21
+ switch (command) {
22
+ case "new": {
23
+ const session = registry.createSession(chatId, args || "未命名会话");
24
+ await sendMessage(JSON.stringify({ text: `已创建会话: **${session.name}** (\`${session.id}\`)` }), chatId);
25
+ return;
26
+ }
27
+ case "sessions": {
28
+ const chat = registry.getChatSessions(chatId);
29
+ if (!chat) {
30
+ await sendMessage(JSON.stringify({ text: "暂无会话" }), chatId);
31
+ return;
32
+ }
33
+ const card = buildSessionListCard(chatId, chat.sessions, chat.active);
34
+ await sendMessage(card, chatId, "interactive");
35
+ return;
36
+ }
37
+ case "switch": {
38
+ const switched = registry.switchSession(chatId, args);
39
+ if (switched) {
40
+ const session = registry
41
+ .getChatSessions(chatId)
42
+ ?.sessions.find((s) => s.id === args);
43
+ await sendMessage(JSON.stringify({ text: `已切换到: **${session?.name ?? args}**` }), chatId);
44
+ }
45
+ else {
46
+ await sendMessage(JSON.stringify({ text: `未找到会话: \`${args}\`` }), chatId);
47
+ }
48
+ return;
49
+ }
50
+ case "rm": {
51
+ const deleted = registry.deleteSession(chatId, args);
52
+ if (deleted) {
53
+ await sendMessage(JSON.stringify({ text: `已删除会话: \`${args}\`` }), chatId);
54
+ }
55
+ else {
56
+ await sendMessage(JSON.stringify({ text: `删除失败,未找到会话: \`${args}\`` }), chatId);
57
+ }
58
+ return;
59
+ }
60
+ case "model": {
61
+ const models = getAvailableModels();
62
+ const card = buildModelSelectCard(chatId, models, currentModel);
63
+ await sendMessage(card, chatId, "interactive");
64
+ return;
65
+ }
66
+ }
67
+ }
68
+ async function runDaemon() {
69
+ if (!(await larkCliAvailable())) {
70
+ console.error("lark-cli 未安装。运行: npm i -g lark-cli");
71
+ process.exit(1);
72
+ }
73
+ if (!(await larkCliConfigured())) {
74
+ console.error("lark-cli 未配置。运行: lark-cli config init");
75
+ process.exit(1);
76
+ }
77
+ const config = loadConfig(FEISHU_IM_DIR);
78
+ const registry = new SessionRegistry(FEISHU_IM_DIR);
79
+ const bot = new Bot(registry, config.strategy);
80
+ writeFileSync(PID_FILE, String(process.pid));
81
+ const cwd = process.cwd();
82
+ const agentDir = getAgentDir();
83
+ const runtime = await createAgentSessionRuntime(async ({ cwd, sessionManager, sessionStartEvent }) => {
84
+ const services = await createAgentSessionServices({ cwd });
85
+ return {
86
+ ...(await createAgentSessionFromServices({
87
+ services,
88
+ sessionManager,
89
+ sessionStartEvent,
90
+ })),
91
+ services,
92
+ diagnostics: services.diagnostics,
93
+ };
94
+ }, {
95
+ cwd,
96
+ agentDir,
97
+ sessionManager: SessionManager.create(cwd),
98
+ });
99
+ console.log("[feishu-im] Daemon started, PID:", process.pid);
100
+ console.log("[feishu-im] Strategy:", config.strategy);
101
+ const pollIntervalMs = config.pollInterval * 1000;
102
+ while (true) {
103
+ try {
104
+ const result = await pollEvents();
105
+ if (result.error) {
106
+ console.error("[feishu-im] Poll error:", result.error);
107
+ await new Promise((r) => setTimeout(r, pollIntervalMs));
108
+ continue;
109
+ }
110
+ for (const event of result.events) {
111
+ const route = bot.route(event);
112
+ if (route.type === "skip")
113
+ continue;
114
+ if (route.type === "command") {
115
+ await handleCommand(registry, route.command, route.args, route.chatId, config.model ?? "claude-sonnet");
116
+ continue;
117
+ }
118
+ const sessionInfo = registry.ensureSession(route.chatId);
119
+ const sessionPath = join(agentDir, "sessions", `${sessionInfo.id}.jsonl`);
120
+ try {
121
+ const sessionManager = SessionManager.open(sessionPath);
122
+ const { session: agentSession } = await createAgentSessionFromServices({
123
+ services: runtime.services,
124
+ sessionManager,
125
+ sessionStartEvent: undefined,
126
+ });
127
+ agentSession.subscribe((agentEvent) => {
128
+ if (agentEvent.type === "message_update" &&
129
+ agentEvent.assistantMessageEvent.type === "text_delta") {
130
+ // Streaming response handling — placeholder for future enhancement
131
+ }
132
+ });
133
+ await agentSession.prompt(route.text);
134
+ agentSession.dispose();
135
+ }
136
+ catch (err) {
137
+ console.error("[feishu-im] Agent error:", err instanceof Error ? err.message : String(err));
138
+ await sendMessage(JSON.stringify({ text: "处理消息时出错,请重试。" }), route.chatId);
139
+ }
140
+ }
141
+ }
142
+ catch (err) {
143
+ console.error("[feishu-im] Loop error:", err);
144
+ }
145
+ await new Promise((r) => setTimeout(r, pollIntervalMs));
146
+ }
147
+ }
148
+ runDaemon().catch((err) => {
149
+ console.error("[feishu-im] Fatal error:", err);
150
+ process.exit(1);
151
+ });
@@ -0,0 +1,2 @@
1
+ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
2
+ export default function (pi: ExtensionAPI): void;
@@ -0,0 +1,124 @@
1
+ import { spawn, execSync } from "node:child_process";
2
+ import { readFileSync, unlinkSync } from "node:fs";
3
+ import { join, dirname } from "node:path";
4
+ import { homedir } from "node:os";
5
+ import { fileURLToPath } from "node:url";
6
+ const FEISHU_IM_DIR = join(homedir(), ".pi", "agent", "feishu-im");
7
+ const PID_FILE = join(FEISHU_IM_DIR, "daemon.pid");
8
+ const __filename = fileURLToPath(import.meta.url);
9
+ const __dirname = dirname(__filename);
10
+ function isRunning() {
11
+ try {
12
+ const pid = parseInt(readFileSync(PID_FILE, "utf-8").trim());
13
+ try {
14
+ process.kill(pid, 0);
15
+ return true;
16
+ }
17
+ catch {
18
+ return false;
19
+ }
20
+ }
21
+ catch {
22
+ return false;
23
+ }
24
+ }
25
+ function getPid() {
26
+ try {
27
+ return parseInt(readFileSync(PID_FILE, "utf-8").trim());
28
+ }
29
+ catch {
30
+ return null;
31
+ }
32
+ }
33
+ async function handleStart(ctx) {
34
+ if (isRunning()) {
35
+ ctx.ui.notify(`飞书 IM 守护进程已在运行 (PID: ${getPid()})`, "info");
36
+ return;
37
+ }
38
+ try {
39
+ execSync("which lark-cli", { stdio: "ignore" });
40
+ }
41
+ catch {
42
+ ctx.ui.notify("lark-cli 未安装。请运行: npm i -g lark-cli", "error");
43
+ return;
44
+ }
45
+ try {
46
+ execSync("lark-cli config show", { stdio: "pipe", timeout: 5000 });
47
+ }
48
+ catch {
49
+ ctx.ui.notify("lark-cli 未配置。请运行: lark-cli config init", "error");
50
+ return;
51
+ }
52
+ const daemonPath = join(__dirname, "daemon.ts");
53
+ const child = spawn("node", ["--import", "jiti/register", daemonPath], {
54
+ detached: true,
55
+ stdio: "ignore",
56
+ env: { ...process.env, PI_FEISHU_IM: "1" },
57
+ });
58
+ child.unref();
59
+ await new Promise((r) => setTimeout(r, 2000));
60
+ if (isRunning()) {
61
+ ctx.ui.notify(`飞书 IM 守护进程已启动 (PID: ${getPid()})`, "info");
62
+ }
63
+ else {
64
+ ctx.ui.notify("飞书 IM 守护进程启动失败,请检查日志", "error");
65
+ }
66
+ }
67
+ function handleStop(ctx) {
68
+ const pid = getPid();
69
+ if (!pid || !isRunning()) {
70
+ ctx.ui.notify("飞书 IM 守护进程未在运行", "info");
71
+ return;
72
+ }
73
+ try {
74
+ process.kill(pid, "SIGTERM");
75
+ try {
76
+ unlinkSync(PID_FILE);
77
+ }
78
+ catch { }
79
+ ctx.ui.notify("飞书 IM 守护进程已停止", "info");
80
+ }
81
+ catch {
82
+ ctx.ui.notify("停止守护进程失败", "error");
83
+ }
84
+ }
85
+ function handleStatus(ctx) {
86
+ if (isRunning()) {
87
+ ctx.ui.notify(`飞书 IM 守护进程运行中 (PID: ${getPid()})`, "info");
88
+ }
89
+ else {
90
+ ctx.ui.notify("飞书 IM 守护进程未在运行", "info");
91
+ }
92
+ }
93
+ export default function (pi) {
94
+ pi.registerCommand("feishu-im", {
95
+ description: "管理飞书 IM 守护进程 (start|stop|status|restart)",
96
+ handler: async (args, ctx) => {
97
+ const sub = args?.trim() || "start";
98
+ switch (sub) {
99
+ case "start":
100
+ await handleStart(ctx);
101
+ break;
102
+ case "stop":
103
+ handleStop(ctx);
104
+ break;
105
+ case "status":
106
+ handleStatus(ctx);
107
+ break;
108
+ case "restart":
109
+ handleStop(ctx);
110
+ await new Promise((r) => setTimeout(r, 1000));
111
+ await handleStart(ctx);
112
+ break;
113
+ default:
114
+ ctx.ui.notify("用法: /feishu-im [start|stop|status|restart]", "error");
115
+ }
116
+ },
117
+ });
118
+ pi.registerFlag("feishu-im", {
119
+ description: "启动时自动启动飞书 IM 守护进程",
120
+ handler: async (ctx) => {
121
+ await handleStart(ctx);
122
+ },
123
+ });
124
+ }
@@ -0,0 +1,33 @@
1
+ export interface FeishuEvent {
2
+ type: string;
3
+ event?: {
4
+ message?: {
5
+ chat_id: string;
6
+ message_id: string;
7
+ parent_id?: string;
8
+ message_type: string;
9
+ content: string;
10
+ mentions?: Array<{
11
+ key: string;
12
+ name: string;
13
+ }>;
14
+ };
15
+ sender?: {
16
+ sender_id: {
17
+ open_id: string;
18
+ user_id?: string;
19
+ };
20
+ sender_type: string;
21
+ };
22
+ };
23
+ raw: unknown;
24
+ }
25
+ export interface PollResult {
26
+ events: FeishuEvent[];
27
+ error: string | null;
28
+ }
29
+ export declare function pollEvents(): Promise<PollResult>;
30
+ export declare function larkCliAvailable(): Promise<boolean>;
31
+ export declare function larkCliConfigured(): Promise<boolean>;
32
+ export declare function sendMessage(content: string, chatId: string, msgType?: "text" | "interactive"): Promise<boolean>;
33
+ export declare function downloadResource(messageId: string, fileKey: string, fileType: string, outputPath: string): Promise<boolean>;