aitable-workflow-cli 0.1.15 → 0.1.16-beta.1786022310508

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 (263) hide show
  1. package/package.json +3 -3
  2. package/templates/support-qa/lib/__tests__/declarative-matcher.test.ts +240 -0
  3. package/templates/support-qa/lib/__tests__/dingtalk-group-membership.test.ts +127 -0
  4. package/templates/support-qa/lib/__tests__/memory-events.test.ts +90 -0
  5. package/templates/support-qa/lib/action-dispatch.ts +1 -1
  6. package/templates/support-qa/lib/declarative-matcher.ts +398 -0
  7. package/templates/support-qa/lib/dingtalk-group-membership.ts +151 -0
  8. package/templates/support-qa/lib/guards.ts +18 -0
  9. package/templates/support-qa/lib/memory-events.ts +60 -41
  10. package/templates/support-qa/lib/preflight.ts +294 -0
  11. package/templates/support-qa/package.json +2 -4
  12. package/templates/support-qa/profiles/aitable/profile/fastpath/known-answers.yml +1 -1
  13. package/templates/support-qa/profiles/aitable/profile/troubleshoot/classifiers.yml +1 -1
  14. package/templates/support-qa/workflows/config-sync/recipes/config_sync.recipe.ts +10 -8
  15. package/templates/support-qa/workflows/daily-review/recipes/daily_review.recipe.ts +1 -1
  16. package/templates/support-qa/workflows/group-qa/recipes/answer.recipe.ts +2 -7
  17. package/templates/support-qa/workflows/group-qa/recipes/conversation_handler.recipe.ts +3 -3
  18. package/templates/support-qa/workflows/group-qa/recipes/fastpath.recipe.ts +5 -11
  19. package/templates/support-qa/workflows/group-qa/recipes/on-action.recipe.ts +4 -2
  20. package/templates/support-qa/workflows/group-qa/recipes/reply-to-group.recipe.ts +13 -7
  21. package/templates/support-qa/workflows/group-qa/recipes/troubleshoot.recipe.ts +12 -18
  22. package/templates/support-qa/workspaces/support/AGENTS.md +1 -1
  23. package/templates/aitable-handoff/.env.example +0 -17
  24. package/templates/aitable-handoff/aitable-workflow.config.yml +0 -64
  25. package/templates/aitable-handoff/coding-agents.config.json +0 -17
  26. package/templates/aitable-handoff/npmrc +0 -1
  27. package/templates/aitable-handoff/package.json +0 -16
  28. package/templates/aitable-handoff/roles/config-syncer.role.yml +0 -4
  29. package/templates/aitable-handoff/roles/daily-review.role.yml +0 -4
  30. package/templates/aitable-handoff/roles/faq-support.role.yml +0 -9
  31. package/templates/aitable-handoff/roles/faq-troubleshooter.role.yml +0 -17
  32. package/templates/aitable-handoff/roles/kb-editor.role.yml +0 -19
  33. package/templates/aitable-handoff/wiki/faq-support/01-/345/277/253/351/200/237/345/205/245/351/227/250/6/350/212/202/350/257/276/345/270/246/344/275/240/345/277/253/351/200/237/344/270/212/346/211/213AI/350/241/250/346/240/274.md +0 -43
  34. package/templates/aitable-handoff/wiki/faq-support/01-/345/277/253/351/200/237/345/205/245/351/227/250/AI/350/241/250/346/240/274/350/241/214/346/225/260/350/257/264/346/230/216.md +0 -85
  35. package/templates/aitable-handoff/wiki/faq-support/01-/345/277/253/351/200/237/345/205/245/351/227/250//344/275/277/347/224/250/345/277/253/346/215/267/351/224/256.md +0 -34
  36. package/templates/aitable-handoff/wiki/faq-support/01-/345/277/253/351/200/237/345/205/245/351/227/250//345/260/206Excel/346/226/207/344/273/266/345/257/274/345/205/245AI/350/241/250/346/240/274.md +0 -48
  37. package/templates/aitable-handoff/wiki/faq-support/01-/345/277/253/351/200/237/345/205/245/351/227/250//345/270/270/350/247/201/351/227/256/351/242/230.md +0 -88
  38. package/templates/aitable-handoff/wiki/faq-support/01-/345/277/253/351/200/237/345/205/245/351/227/250//346/250/241/346/235/277/344/270/255/345/277/203.md +0 -59
  39. package/templates/aitable-handoff/wiki/faq-support/01-/345/277/253/351/200/237/345/205/245/351/227/250//351/222/211/351/222/211AI/350/241/250/346/240/274/345/270/270/350/247/201/344/270/212/351/231/220.md +0 -181
  40. package/templates/aitable-handoff/wiki/faq-support/01-/345/277/253/351/200/237/345/205/245/351/227/250//351/222/211/351/222/211AI/350/241/250/346/240/274/345/277/253/351/200/237/344/270/212/346/211/213.md +0 -177
  41. package/templates/aitable-handoff/wiki/faq-support/02-/345/237/272/347/241/200/346/223/215/344/275/234/AI/350/241/250/346/240/274/347/232/204/345/257/274/345/207/272.md +0 -27
  42. package/templates/aitable-handoff/wiki/faq-support/02-/345/237/272/347/241/200/346/223/215/344/275/234//344/275/277/347/224/250/345/210/206/347/273/204.md +0 -67
  43. package/templates/aitable-handoff/wiki/faq-support/02-/345/237/272/347/241/200/346/223/215/344/275/234//344/275/277/347/224/250/345/241/253/350/211/262.md +0 -99
  44. package/templates/aitable-handoff/wiki/faq-support/02-/345/237/272/347/241/200/346/223/215/344/275/234//344/275/277/347/224/250/346/216/222/345/272/217.md +0 -66
  45. package/templates/aitable-handoff/wiki/faq-support/02-/345/237/272/347/241/200/346/223/215/344/275/234//344/275/277/347/224/250/347/255/233/351/200/211/345/222/214/347/255/233/351/200/211/346/235/241/344/273/266/347/273/204.md +0 -104
  46. package/templates/aitable-handoff/wiki/faq-support/02-/345/237/272/347/241/200/346/223/215/344/275/234//346/237/245/347/234/213/345/216/206/345/217/262/350/256/260/345/275/225.md +0 -79
  47. package/templates/aitable-handoff/wiki/faq-support/02-/345/237/272/347/241/200/346/223/215/344/275/234//347/224/250AI/350/241/250/346/240/274/344/270/200/350/241/250/344/270/200/345/212/251/347/220/206/345/217/221/346/266/210/346/201/257.md +0 -94
  48. package/templates/aitable-handoff/wiki/faq-support/02-/345/237/272/347/241/200/346/223/215/344/275/234//350/207/252/345/256/232/344/271/211/350/256/260/345/275/225/345/220/215/347/247/260.md +0 -35
  49. package/templates/aitable-handoff/wiki/faq-support/02-/345/237/272/347/241/200/346/223/215/344/275/234//350/207/252/345/256/232/344/271/211/350/256/260/345/275/225/350/257/246/346/203/205/351/241/265/345/222/214/345/241/253/345/206/231/351/241/265.md +0 -141
  50. package/templates/aitable-handoff/wiki/faq-support/02-/345/237/272/347/241/200/346/223/215/344/275/234//350/260/203/346/225/264/345/210/227/345/256/275.md +0 -42
  51. package/templates/aitable-handoff/wiki/faq-support/02-/345/237/272/347/241/200/346/223/215/344/275/234//350/260/203/346/225/264/350/241/214/351/253/230.md +0 -40
  52. package/templates/aitable-handoff/wiki/faq-support/03-/344/275/277/347/224/250/345/255/227/346/256/265//344/270/272/350/241/250/346/240/274/346/267/273/345/212/240/345/255/227/346/256/265.md +0 -188
  53. package/templates/aitable-handoff/wiki/faq-support/03-/344/275/277/347/224/250/345/255/227/346/256/265//345/215/225/351/200/211/345/244/232/351/200/211/345/255/227/346/256/265/345/220/214/346/255/245/345/205/266/344/273/226/350/241/250/351/200/211/351/241/271.md +0 -142
  54. package/templates/aitable-handoff/wiki/faq-support/03-/344/275/277/347/224/250/345/255/227/346/256/265//345/255/227/346/256/265/347/256/241/347/220/206.md +0 -44
  55. package/templates/aitable-handoff/wiki/faq-support/03-/344/275/277/347/224/250/345/255/227/346/256/265//345/255/227/346/256/265/347/261/273/345/236/213/345/210/227/350/241/250.md +0 -95
  56. package/templates/aitable-handoff/wiki/faq-support/03-/344/275/277/347/224/250/345/255/227/346/256/265//345/255/227/346/256/265/347/274/226/347/273/204.md +0 -138
  57. package/templates/aitable-handoff/wiki/faq-support/04-/344/275/277/347/224/250/350/241/250/345/215/225//350/241/250/345/215/225/345/221/250/346/234/237/345/210/206/350/241/250.md +0 -42
  58. package/templates/aitable-handoff/wiki/faq-support/04-/344/275/277/347/224/250/350/241/250/345/215/225//350/241/250/345/215/225/345/237/272/347/241/200/346/223/215/344/275/234.md +0 -344
  59. package/templates/aitable-handoff/wiki/faq-support/04-/344/275/277/347/224/250/350/241/250/345/215/225//350/241/250/345/215/225/346/230/216/347/273/206/350/241/250-/344/270/200/346/254/241/345/241/253/345/206/231/345/244/232/346/235/241/346/217/220/344/272/244.md +0 -174
  60. package/templates/aitable-handoff/wiki/faq-support/04-/344/275/277/347/224/250/350/241/250/345/215/225//350/241/250/345/215/225/351/242/204/345/241/253/351/273/230/350/256/244/345/200/274.md +0 -97
  61. package/templates/aitable-handoff/wiki/faq-support/05-/345/205/254/345/274/217/345/207/275/346/225/260//344/275/277/347/224/250AI/347/224/237/346/210/220/345/205/254/345/274/217.md +0 -26
  62. package/templates/aitable-handoff/wiki/faq-support/05-/345/205/254/345/274/217/345/207/275/346/225/260//344/275/277/347/224/250/345/205/254/345/274/217/345/207/275/346/225/260/345/270/270/350/247/201/351/227/256/351/242/230.md +0 -179
  63. package/templates/aitable-handoff/wiki/faq-support/05-/345/205/254/345/274/217/345/207/275/346/225/260//344/275/277/347/224/250/345/205/254/345/274/217/345/255/227/346/256/265.md +0 -81
  64. package/templates/aitable-handoff/wiki/faq-support/05-/345/205/254/345/274/217/345/207/275/346/225/260//344/275/277/347/224/250/345/207/275/346/225/260.md +0 -21
  65. package/templates/aitable-handoff/wiki/faq-support/05-/345/205/254/345/274/217/345/207/275/346/225/260//345/205/254/345/274/217/345/207/275/346/225/260/345/244/247/345/205/250.md +0 -433
  66. package/templates/aitable-handoff/wiki/faq-support/05-/345/205/254/345/274/217/345/207/275/346/225/260//345/205/254/345/274/217/346/224/257/346/214/201/346/230/276/347/244/272/346/240/274/345/274/217.md +0 -126
  67. package/templates/aitable-handoff/wiki/faq-support/05-/345/205/254/345/274/217/345/207/275/346/225/260//345/205/254/345/274/217/351/224/231/350/257/257/344/273/243/347/240/201/345/210/227/350/241/250.md +0 -30
  68. package/templates/aitable-handoff/wiki/faq-support/05-/345/205/254/345/274/217/345/207/275/346/225/260//345/207/275/346/225/260/345/256/236/350/267/265.md +0 -13
  69. package/templates/aitable-handoff/wiki/faq-support/06-/346/225/260/346/215/256/350/277/236/346/216/245/344/270/255/345/277/203//346/225/260/346/215/256/350/277/236/346/216/245/344/270/255/345/277/203.md +0 -169
  70. package/templates/aitable-handoff/wiki/faq-support/06-/346/225/260/346/215/256/350/277/236/346/216/245/344/270/255/345/277/203//347/273/204/347/273/207/345/206/205/345/205/261/344/272/253/346/225/260/346/215/256/346/272/220.md +0 -106
  71. package/templates/aitable-handoff/wiki/faq-support/06-/346/225/260/346/215/256/350/277/236/346/216/245/344/270/255/345/277/203//350/267/250AI/350/241/250/346/240/274/346/225/260/346/215/256/345/220/214/346/255/245.md +0 -176
  72. package/templates/aitable-handoff/wiki/faq-support/06-/346/225/260/346/215/256/350/277/236/346/216/245/344/270/255/345/277/203//351/222/211/351/222/211AI/345/220/254/350/256/260/346/225/260/346/215/256/345/220/214/346/255/245.md +0 -100
  73. package/templates/aitable-handoff/wiki/faq-support/06-/346/225/260/346/215/256/350/277/236/346/216/245/344/270/255/345/277/203//351/222/211/351/222/211OA/345/256/241/346/211/271/346/225/260/346/215/256/345/220/214/346/255/245.md +0 -194
  74. package/templates/aitable-handoff/wiki/faq-support/06-/346/225/260/346/215/256/350/277/236/346/216/245/344/270/255/345/277/203//351/222/211/351/222/211/345/276/205/345/212/236/346/225/260/346/215/256/345/220/214/346/255/245.md +0 -87
  75. package/templates/aitable-handoff/wiki/faq-support/06-/346/225/260/346/215/256/350/277/236/346/216/245/344/270/255/345/277/203//351/222/211/351/222/211/346/227/245/347/250/213/346/225/260/346/215/256/345/220/214/346/255/245.md +0 -92
  76. package/templates/aitable-handoff/wiki/faq-support/06-/346/225/260/346/215/256/350/277/236/346/216/245/344/270/255/345/277/203//351/222/211/351/222/211/350/200/203/345/213/244/346/211/223/345/215/241/346/225/260/346/215/256/345/220/214/346/255/245.md +0 -129
  77. package/templates/aitable-handoff/wiki/faq-support/06-/346/225/260/346/215/256/350/277/236/346/216/245/344/270/255/345/277/203//351/222/211/351/222/211/350/241/250/346/240/274/346/225/260/346/215/256/345/220/214/346/255/245.md +0 -229
  78. package/templates/aitable-handoff/wiki/faq-support/06-/346/225/260/346/215/256/350/277/236/346/216/245/344/270/255/345/277/203//351/222/211/351/222/211/351/200/232/350/256/257/345/275/225/346/225/260/346/215/256/345/220/214/346/255/245.md +0 -120
  79. package/templates/aitable-handoff/wiki/faq-support/07-/344/275/277/347/224/250/350/247/206/345/233/276//344/275/277/347/224/250AI/350/241/250/346/240/274/350/247/206/345/233/276.md +0 -219
  80. package/templates/aitable-handoff/wiki/faq-support/07-/344/275/277/347/224/250/350/247/206/345/233/276//345/210/206/344/272/253/350/247/206/345/233/276.md +0 -71
  81. package/templates/aitable-handoff/wiki/faq-support/07-/344/275/277/347/224/250/350/247/206/345/233/276//346/225/260/346/215/256/350/241/250/345/222/214/350/247/206/345/233/276/347/232/204/345/205/263/347/263/273.md +0 -48
  82. package/templates/aitable-handoff/wiki/faq-support/07-/344/275/277/347/224/250/350/247/206/345/233/276//346/227/245/345/216/206/350/247/206/345/233/276.md +0 -89
  83. package/templates/aitable-handoff/wiki/faq-support/07-/344/275/277/347/224/250/350/247/206/345/233/276//346/237/245/350/257/242/351/241/265/351/235/242.md +0 -116
  84. package/templates/aitable-handoff/wiki/faq-support/07-/344/275/277/347/224/250/350/247/206/345/233/276//347/224/230/347/211/271/345/233/276.md +0 -135
  85. package/templates/aitable-handoff/wiki/faq-support/07-/344/275/277/347/224/250/350/247/206/345/233/276//347/224/273/345/206/214/350/247/206/345/233/276.md +0 -28
  86. package/templates/aitable-handoff/wiki/faq-support/07-/344/275/277/347/224/250/350/247/206/345/233/276//347/234/213/346/235/277/350/247/206/345/233/276.md +0 -35
  87. package/templates/aitable-handoff/wiki/faq-support/07-/344/275/277/347/224/250/350/247/206/345/233/276//350/241/250/346/240/274/350/247/206/345/233/276.md +0 -116
  88. package/templates/aitable-handoff/wiki/faq-support/07-/344/275/277/347/224/250/350/247/206/345/233/276//351/200/217/350/247/206/350/241/250/350/247/206/345/233/276.md +0 -123
  89. package/templates/aitable-handoff/wiki/faq-support/08-/344/275/277/347/224/250/344/273/252/350/241/250/347/233/230/TOP_N/345/210/206/346/236/220.md +0 -78
  90. package/templates/aitable-handoff/wiki/faq-support/08-/344/275/277/347/224/250/344/273/252/350/241/250/347/233/230//344/273/252/350/241/250/347/233/230/344/270/255/346/267/273/345/212/240/345/244/232/344/270/252/346/225/260/346/215/256/346/272/220.md +0 -129
  91. package/templates/aitable-handoff/wiki/faq-support/08-/344/275/277/347/224/250/344/273/252/350/241/250/347/233/230//344/273/252/350/241/250/347/233/230/345/215/225/345/233/276/350/241/250/345/222/214AI/350/247/243/350/257/273/345/206/205/345/256/271/345/210/206/344/272/253.md +0 -104
  92. package/templates/aitable-handoff/wiki/faq-support/08-/344/275/277/347/224/250/344/273/252/350/241/250/347/233/230//344/273/252/350/241/250/347/233/230/345/270/270/350/247/201/351/227/256/351/242/230.md +0 -31
  93. package/templates/aitable-handoff/wiki/faq-support/08-/344/275/277/347/224/250/344/273/252/350/241/250/347/233/230//344/273/252/350/241/250/347/233/230/346/231/272/350/203/275/346/200/273/347/273/223/345/210/206/346/236/220.md +0 -57
  94. package/templates/aitable-handoff/wiki/faq-support/08-/344/275/277/347/224/250/344/273/252/350/241/250/347/233/230//344/273/252/350/241/250/347/233/230/347/273/204/344/273/266.md +0 -47
  95. package/templates/aitable-handoff/wiki/faq-support/08-/344/275/277/347/224/250/344/273/252/350/241/250/347/233/230//344/275/277/347/224/250AI/350/241/250/346/240/274/344/273/252/350/241/250/347/233/230.md +0 -226
  96. package/templates/aitable-handoff/wiki/faq-support/08-/344/275/277/347/224/250/344/273/252/350/241/250/347/233/230//344/275/277/347/224/250/350/207/252/345/212/250/345/214/226/346/265/201/347/250/213/345/217/221/351/200/201/344/273/252/350/241/250/347/233/230.md +0 -49
  97. package/templates/aitable-handoff/wiki/faq-support/08-/344/275/277/347/224/250/344/273/252/350/241/250/347/233/230//345/210/206/344/272/253/344/273/252/350/241/250/347/233/230.md +0 -74
  98. package/templates/aitable-handoff/wiki/faq-support/08-/344/275/277/347/224/250/344/273/252/350/241/250/347/233/230//345/234/250/344/273/252/350/241/250/347/233/230/344/270/255/347/255/233/351/200/211/346/225/260/346/215/256.md +0 -65
  99. package/templates/aitable-handoff/wiki/faq-support/08-/344/275/277/347/224/250/344/273/252/350/241/250/347/233/230//350/207/252/345/256/232/344/271/211/344/273/252/350/241/250/347/233/230/344/270/255/345/277/203.md +0 -93
  100. package/templates/aitable-handoff/wiki/faq-support/08-/344/275/277/347/224/250/344/273/252/350/241/250/347/233/230//350/267/237/351/232/217/350/256/277/351/227/256/350/200/205/346/235/203/351/231/220/347/273/237/350/256/241.md +0 -48
  101. package/templates/aitable-handoff/wiki/faq-support/09-/345/272/224/347/224/250/346/250/241/345/274/217//345/205/250/346/226/260/345/272/224/347/224/250/346/250/241/345/274/217.md +0 -155
  102. package/templates/aitable-handoff/wiki/faq-support/09-/345/272/224/347/224/250/346/250/241/345/274/217//345/210/227/350/241/250/347/273/204/344/273/266.md +0 -228
  103. package/templates/aitable-handoff/wiki/faq-support/09-/345/272/224/347/224/250/346/250/241/345/274/217//345/233/276/347/211/207.md +0 -93
  104. package/templates/aitable-handoff/wiki/faq-support/09-/345/272/224/347/224/250/346/250/241/345/274/217//346/214/211/351/222/256.md +0 -86
  105. package/templates/aitable-handoff/wiki/faq-support/09-/345/272/224/347/224/250/346/250/241/345/274/217//346/240/207/347/255/276/351/241/265.md +0 -97
  106. package/templates/aitable-handoff/wiki/faq-support/09-/345/272/224/347/224/250/346/250/241/345/274/217//350/247/206/345/233/276/347/273/204/344/273/266.md +0 -125
  107. package/templates/aitable-handoff/wiki/faq-support/09-/345/272/224/347/224/250/346/250/241/345/274/217//350/277/207/346/273/244/345/231/250.md +0 -110
  108. package/templates/aitable-handoff/wiki/faq-support/09-/345/272/224/347/224/250/346/250/241/345/274/217//351/200/217/350/247/206/350/241/250/347/273/204/344/273/266.md +0 -142
  109. package/templates/aitable-handoff/wiki/faq-support/10-/350/207/252/345/212/250/345/214/226/345/267/245/344/275/234/346/265/201/Webhook/345/217/202/346/225/260/347/232/204/350/257/246/347/273/206/350/257/264/346/230/216.md +0 -76
  110. package/templates/aitable-handoff/wiki/faq-support/10-/350/207/252/345/212/250/345/214/226/345/267/245/344/275/234/346/265/201//344/270/200/350/241/250/344/270/200/345/217/267Agent/346/224/257/346/214/201/347/276/244/346/224/266/351/233/206.md +0 -150
  111. package/templates/aitable-handoff/wiki/faq-support/10-/350/207/252/345/212/250/345/214/226/345/267/245/344/275/234/346/265/201//344/275/277/347/224/250webhook/350/247/246/345/217/221/350/207/252/345/212/250/345/214/226.md +0 -163
  112. package/templates/aitable-handoff/wiki/faq-support/10-/350/207/252/345/212/250/345/214/226/345/267/245/344/275/234/346/265/201//344/275/277/347/224/250/344/270/215/345/220/214/350/272/253/344/273/275/345/217/221/351/200/201/351/222/211/351/222/211/346/266/210/346/201/257.md +0 -60
  113. package/templates/aitable-handoff/wiki/faq-support/10-/350/207/252/345/212/250/345/214/226/345/267/245/344/275/234/346/265/201//344/275/277/347/224/250/350/207/252/345/212/250/345/214/226/345/267/245/344/275/234/346/265/201.md +0 -219
  114. package/templates/aitable-handoff/wiki/faq-support/10-/350/207/252/345/212/250/345/214/226/345/267/245/344/275/234/346/265/201//344/275/277/347/224/250/350/207/252/345/212/250/345/214/226/345/276/252/347/216/257/350/212/202/347/202/271.md +0 -63
  115. package/templates/aitable-handoff/wiki/faq-support/10-/350/207/252/345/212/250/345/214/226/345/267/245/344/275/234/346/265/201//345/234/250/346/265/201/347/250/213/344/270/255/344/275/277/347/224/250AI/351/227/256/347/255/224.md +0 -69
  116. package/templates/aitable-handoff/wiki/faq-support/10-/350/207/252/345/212/250/345/214/226/345/267/245/344/275/234/346/265/201//345/234/250/346/266/210/346/201/257/345/215/241/347/211/207/344/270/212/346/267/273/345/212/240/346/214/211/351/222/256.md +0 -93
  117. package/templates/aitable-handoff/wiki/faq-support/10-/350/207/252/345/212/250/345/214/226/345/267/245/344/275/234/346/265/201//346/265/201/347/250/213/345/217/230/351/207/217/350/247/243/351/207/212/344/270/216/345/270/270/350/247/201/346/212/245/351/224/231.md +0 -158
  118. package/templates/aitable-handoff/wiki/faq-support/10-/350/207/252/345/212/250/345/214/226/345/267/245/344/275/234/346/265/201//346/265/201/347/250/213/350/247/246/345/217/221/346/235/241/344/273/266/344/270/216/346/211/247/350/241/214/345/212/250/344/275/234/344/270/200/350/247/210.md +0 -310
  119. package/templates/aitable-handoff/wiki/faq-support/10-/350/207/252/345/212/250/345/214/226/345/267/245/344/275/234/346/265/201//347/224/250AI/350/241/250/346/240/274/344/270/200/350/241/250/344/270/200/345/212/251/347/220/206/345/217/221/346/266/210/346/201/257-/350/207/252/345/212/250/345/214/226.md +0 -129
  120. package/templates/aitable-handoff/wiki/faq-support/10-/350/207/252/345/212/250/345/214/226/345/267/245/344/275/234/346/265/201//347/224/250/346/237/245/346/211/276/350/256/260/345/275/225/345/217/221/351/200/201/347/273/204/345/220/210/345/255/227/346/256/265/351/200/232/347/237/245.md +0 -66
  121. package/templates/aitable-handoff/wiki/faq-support/10-/350/207/252/345/212/250/345/214/226/345/267/245/344/275/234/346/265/201//350/207/252/345/212/250/345/214/226/345/210/233/345/273/272/351/222/211/351/222/211/345/276/205/345/212/236/346/210/226/346/227/245/347/250/213.md +0 -84
  122. package/templates/aitable-handoff/wiki/faq-support/10-/350/207/252/345/212/250/345/214/226/345/267/245/344/275/234/346/265/201//350/207/252/345/212/250/345/214/226/345/217/221/350/265/267AI/347/224/265/350/257/235/345/244/226/345/221/274.md +0 -322
  123. package/templates/aitable-handoff/wiki/faq-support/10-/350/207/252/345/212/250/345/214/226/345/267/245/344/275/234/346/265/201//350/207/252/345/212/250/345/214/226/345/217/221/350/265/267OA/345/256/241/346/211/271.md +0 -93
  124. package/templates/aitable-handoff/wiki/faq-support/10-/350/207/252/345/212/250/345/214/226/345/267/245/344/275/234/346/265/201//350/207/252/345/212/250/345/214/226/345/217/221/351/200/201HTTP/350/257/267/346/261/202.md +0 -168
  125. package/templates/aitable-handoff/wiki/faq-support/10-/350/207/252/345/212/250/345/214/226/345/267/245/344/275/234/346/265/201//350/207/252/345/212/250/345/214/226/345/270/270/350/247/201/351/227/256/351/242/230.md +0 -83
  126. package/templates/aitable-handoff/wiki/faq-support/10-/350/207/252/345/212/250/345/214/226/345/267/245/344/275/234/346/265/201//350/207/252/345/212/250/345/214/226/346/211/271/351/207/217/345/217/221/351/202/256/344/273/266.md +0 -79
  127. package/templates/aitable-handoff/wiki/faq-support/10-/350/207/252/345/212/250/345/214/226/345/267/245/344/275/234/346/265/201//350/207/252/345/212/250/345/214/226/346/224/257/346/214/201/346/217/222/345/205/245/345/223/252/344/272/233/345/217/230/351/207/217/345/206/205/345/256/271.md +0 -80
  128. package/templates/aitable-handoff/wiki/faq-support/10-/350/207/252/345/212/250/345/214/226/345/267/245/344/275/234/346/265/201//350/207/252/345/212/250/345/214/226/346/233/264/345/244/232/346/211/247/350/241/214/345/212/250/344/275/234/344/275/277/347/224/250/346/214/207/345/215/227.md +0 -21
  129. package/templates/aitable-handoff/wiki/faq-support/10-/350/207/252/345/212/250/345/214/226/345/267/245/344/275/234/346/265/201//350/260/203/347/224/250/344/270/211/346/226/271/345/267/245/344/275/234/346/265/201/345/272/224/347/224/250.md +0 -161
  130. package/templates/aitable-handoff/wiki/faq-support/11-AI/350/241/250/346/240/274/345/212/251/347/220/206/AI/350/241/250/346/240/274/344/270/207/350/203/275/350/264/264/344/274/230/345/205/210/344/275/277/347/224/250/347/224/263/350/257/267.md +0 -67
  131. package/templates/aitable-handoff/wiki/faq-support/11-AI/350/241/250/346/240/274/345/212/251/347/220/206/AI/350/241/250/346/240/274/344/270/207/350/203/275/350/264/264/344/275/277/347/224/250/350/257/264/346/230/216.md +0 -63
  132. package/templates/aitable-handoff/wiki/faq-support/11-AI/350/241/250/346/240/274/345/212/251/347/220/206/AI/350/241/250/346/240/274/345/212/251/347/220/206.md +0 -107
  133. package/templates/aitable-handoff/wiki/faq-support/12-/351/253/230/347/272/247/346/235/203/351/231/220//344/275/277/347/224/250AI/350/241/250/346/240/274/351/253/230/347/272/247/346/235/203/351/231/220.md +0 -194
  134. package/templates/aitable-handoff/wiki/faq-support/12-/351/253/230/347/272/247/346/235/203/351/231/220//350/241/214/345/210/227/346/235/203/351/231/220/350/256/276/347/275/256/345/217/212/351/253/230/347/272/247/346/235/203/351/231/220/345/257/271/350/241/250/345/215/225/345/205/254/345/274/217/347/232/204/345/275/261/345/223/215.md +0 -32
  135. package/templates/aitable-handoff/wiki/faq-support/12-/351/253/230/347/272/247/346/235/203/351/231/220//351/242/204/350/247/210/351/253/230/347/272/247/346/235/203/351/231/220/347/273/223/346/236/234.md +0 -43
  136. package/templates/aitable-handoff/wiki/faq-support/12-/351/253/230/347/272/247/346/235/203/351/231/220//351/253/230/347/272/247/346/235/203/351/231/220/345/270/270/350/247/201/351/227/256/351/242/230.md +0 -47
  137. package/templates/aitable-handoff/wiki/faq-support/12-/351/253/230/347/272/247/346/235/203/351/231/220//351/253/230/347/272/247/346/235/203/351/231/220/347/232/204/351/273/230/350/256/244/350/247/222/350/211/262.md +0 -36
  138. package/templates/aitable-handoff/wiki/faq-support/13-/346/217/222/344/273/266/344/270/255/345/277/203/AI/350/241/250/346/240/274/344/270/211/346/226/271/346/217/222/344/273/266/344/275/277/347/224/250/346/216/210/346/235/203.md +0 -19
  139. package/templates/aitable-handoff/wiki/faq-support/13-/346/217/222/344/273/266/344/270/255/345/277/203/AI/350/241/250/346/240/274/346/217/222/344/273/266-/350/204/232/346/234/254/346/217/222/344/273/266.md +0 -42
  140. package/templates/aitable-handoff/wiki/faq-support/13-/346/217/222/344/273/266/344/270/255/345/277/203/AI/350/241/250/346/240/274/346/217/222/344/273/266-/350/207/252/345/256/232/344/271/211/346/217/222/344/273/266.md +0 -51
  141. package/templates/aitable-handoff/wiki/faq-support/13-/346/217/222/344/273/266/344/270/255/345/277/203/AI/350/241/250/346/240/274/346/217/222/344/273/266/344/270/255/345/277/203-/344/275/277/347/224/250/346/214/207/345/215/227.md +0 -97
  142. package/templates/aitable-handoff/wiki/faq-support/14-/347/256/241/347/220/206/345/220/216/345/217/260//344/275/277/347/224/250/346/225/260/346/215/256/350/257/264/346/230/216.md +0 -82
  143. package/templates/aitable-handoff/wiki/faq-support/14-/347/256/241/347/220/206/345/220/216/345/217/260//346/235/203/347/233/212/346/225/260/346/215/256/350/257/264/346/230/216.md +0 -111
  144. package/templates/aitable-handoff/wiki/faq-support/15-/345/234/272/346/231/257/345/256/236/350/267/265/AI/350/241/250/346/240/274/350/257/257/345/210/240/346/201/242/345/244/215/346/214/207/345/215/227.md +0 -37
  145. package/templates/aitable-handoff/wiki/faq-support/15-/345/234/272/346/231/257/345/256/236/350/267/265//345/234/250/350/241/250/346/240/274/344/270/255/346/240/207/350/256/260/351/207/215/345/244/215/345/206/205/345/256/271.md +0 -43
  146. package/templates/aitable-handoff/wiki/faq-support/15-/345/234/272/346/231/257/345/256/236/350/267/265//347/233/264/346/222/255/345/205/254/345/274/200/347/263/273/345/210/227/350/257/276.md +0 -21
  147. package/templates/aitable-handoff/wiki/faq-support/16-/344/273/230/350/264/271/346/235/203/347/233/212//351/222/211/351/222/211AI/350/241/250/346/240/274/344/273/230/350/264/271/346/235/203/347/233/212.md +0 -144
  148. package/templates/aitable-handoff/wiki/faq-support/16-/344/273/230/350/264/271/346/235/203/347/233/212//351/222/211/351/222/211AI/350/241/250/346/240/274/346/220/255/345/273/272/346/234/215/345/212/241.md +0 -95
  149. package/templates/aitable-handoff/wiki/faq-support/17-/345/205/254/345/221/212/AI/350/241/250/346/240/274-/346/216/222/347/211/210/346/211/223/345/215/260/345/215/207/347/272/247/350/257/264/346/230/216.md +0 -40
  150. package/templates/aitable-handoff/wiki/faq-support/17-/345/205/254/345/221/212/AI/350/241/250/346/240/274-/347/211/210/346/234/254/345/215/207/347/272/247/351/200/232/347/237/245.md +0 -21
  151. package/templates/aitable-handoff/wiki/faq-support/17-/345/205/254/345/221/212//350/267/250AI/350/241/250/346/240/274/346/225/260/346/215/256/345/220/214/346/255/245/350/260/203/346/225/264/350/257/264/346/230/216.md +0 -55
  152. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI /350/241/250/346/240/274/346/217/222/344/273/266 - /344/274/201/344/270/232/345/206/205/346/217/222/344/273/266/345/217/221/345/270/203/346/214/207/345/215/227.md" +0 -159
  153. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274 AI /345/255/227/346/256/265 /345/274/200/345/217/221/346/214/207/345/215/227/AI/350/241/250/346/240/274 AI /345/255/227/346/256/265/345/274/200/345/217/221/346/214/207/345/215/227/357/274/210FaaS/347/211/210/357/274/211.md" +0 -1362
  154. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274 AI /345/255/227/346/256/265 /345/274/200/345/217/221/346/214/207/345/215/227/AI/350/241/250/346/240/274 AI /345/255/227/346/256/265/345/274/200/345/217/221/346/214/207/345/215/227/357/274/210/345/205/254/345/274/217/347/211/210/357/274/211.md" +0 -556
  155. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274 AI /345/255/227/346/256/265 /345/274/200/345/217/221/346/214/207/345/215/227.md" +0 -15
  156. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/255/227/346/256/265/346/250/241/347/211/210 /344/275/277/347/224/250/346/214/207/345/215/227/AI /350/241/250/346/240/274 AI /345/255/227/346/256/265/345/270/270/350/247/201/346/212/245/351/224/231/350/257/264/346/230/216.md" +0 -649
  157. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/255/227/346/256/265/346/250/241/347/211/210 /344/275/277/347/224/250/346/214/207/345/215/227/Dify/346/231/272/350/203/275/344/275/223.md" +0 -55
  158. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/255/227/346/256/265/346/250/241/347/211/210 /344/275/277/347/224/250/346/214/207/345/215/227/GPTPro /345/255/227/346/256/265/346/215/267/345/276/204 /345/257/206/351/222/245/350/216/267/345/217/226/346/214/207/345/215/227.md" +0 -23
  159. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/255/227/346/256/265/346/250/241/347/211/210 /344/275/277/347/224/250/346/214/207/345/215/227/OpenClaw /345/260/217/351/276/231/350/231/276/345/212/251/346/211/213/351/205/215/347/275/256/346/225/231/347/250/213.md" +0 -27
  160. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/255/227/346/256/265/346/250/241/347/211/210 /344/275/277/347/224/250/346/214/207/345/215/227//345/233/275/345/206/205/345/244/226/345/277/253/351/200/222/347/211/251/346/265/201/344/277/241/346/201/257/346/237/245/350/257/242/344/275/277/347/224/250/346/214/207/345/215/227.md" +0 -907
  161. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/255/227/346/256/265/346/250/241/347/211/210 /344/275/277/347/224/250/346/214/207/345/215/227//345/277/253/351/200/222/347/211/251/346/265/201/346/237/245/350/257/242/345/212/251/346/211/213/344/275/277/347/224/250/346/214/207/345/215/227.md" +0 -1
  162. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/AI/350/241/250/346/240/274JSAPI /347/261/273/345/236/213/346/217/217/350/277/260.xlsx +0 -0
  163. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Base /346/250/241/345/235/227.md" +0 -391
  164. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227/AttachmentField /351/231/204/344/273/266/345/255/227/346/256/265.md" +0 -200
  165. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227/AutoNumberField /350/207/252/345/212/250/347/274/226/345/217/267/345/255/227/346/256/265.md" +0 -75
  166. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227/BarcodeField /346/235/241/347/240/201/345/255/227/346/256/265.md" +0 -95
  167. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227/BidirectionalLinkField /345/217/214/345/220/221/345/205/263/350/201/224/345/255/227/346/256/265.md" +0 -294
  168. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227/CheckboxField /345/244/215/351/200/211/346/241/206/345/255/227/346/256/265.md" +0 -95
  169. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227/CreatedTimeField /345/210/233/345/273/272/346/227/266/351/227/264/345/255/227/346/256/265.md" +0 -134
  170. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227/CurrencyField /350/264/247/345/270/201/345/255/227/346/256/265.md" +0 -260
  171. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227/DateField /346/227/245/346/234/237/345/255/227/346/256/265.md" +0 -183
  172. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227/DepartmentField /351/203/250/351/227/250/345/255/227/346/256/265.md" +0 -111
  173. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227/EmailField /351/202/256/347/256/261/345/255/227/346/256/265.md" +0 -99
  174. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227/FilterUpField /346/237/245/346/211/276/345/274/225/347/224/250/345/255/227/346/256/265.md" +0 -73
  175. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227/FormulaField /345/205/254/345/274/217/345/255/227/346/256/265.md" +0 -109
  176. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227/GeoLocationField /345/234/260/347/220/206/344/275/215/347/275/256/345/255/227/346/256/265.md" +0 -33
  177. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227/GroupField /347/276/244/347/273/204/345/255/227/346/256/265.md" +0 -111
  178. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227/LastModifiedTimeField /346/234/200/345/220/216/346/233/264/346/226/260/346/227/266/351/227/264/345/255/227/346/256/265.md" +0 -134
  179. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227/LookupField /345/205/263/350/201/224/345/274/225/347/224/250/345/255/227/346/256/265.md" +0 -71
  180. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227/MultiSelectField /345/244/232/351/200/211/345/255/227/346/256/265.md" +0 -349
  181. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227/NumberField /346/225/260/345/255/227/345/255/227/346/256/265.md" +0 -175
  182. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227/PrimaryField /344/270/273/351/224/256/346/226/207/346/241/243/345/255/227/346/256/265.md" +0 -91
  183. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227/ProgressField /350/277/233/345/272/246/345/255/227/346/256/265.md" +0 -324
  184. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227/RatingField /350/257/204/345/210/206/345/255/227/346/256/265.md" +0 -320
  185. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227/RichTextField /345/257/214/346/226/207/346/234/254/345/255/227/346/256/265.md" +0 -45
  186. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227/SingleSelectField /345/215/225/351/200/211/345/255/227/346/256/265.md" +0 -336
  187. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227/TelephoneField /347/224/265/350/257/235/345/255/227/346/256/265.md" +0 -99
  188. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227/TextField /346/226/207/346/234/254/345/255/227/346/256/265.md" +0 -93
  189. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227/UnidirectionalLinkFields /345/215/225/345/220/221/345/205/263/350/201/224/345/255/227/346/256/265.md" +0 -295
  190. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227/UrlField /351/223/276/346/216/245/345/255/227/346/256/265.md" +0 -163
  191. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227/UserField /344/272/272/345/221/230/345/255/227/346/256/265.md" +0 -266
  192. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Field /346/250/241/345/235/227.md" +0 -379
  193. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Record /346/250/241/345/235/227.md" +0 -277
  194. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/Sheet /346/250/241/345/235/227.md" +0 -1013
  195. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/UI /346/250/241/345/235/227.md" +0 -472
  196. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/View /346/250/241/345/235/227/GridView /350/241/250/346/240/274/350/247/206/345/233/276.md" +0 -835
  197. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243/View /346/250/241/345/235/227.md" +0 -203
  198. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243//345/255/227/346/256/265/346/225/260/346/215/256/347/273/223/346/236/204.md +0 -65
  199. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/345/257/271/350/261/241/346/250/241/345/236/213API/345/217/202/350/200/203/346/226/207/346/241/243//350/257/273/345/206/231AI /350/241/250/346/240/274/346/250/241/345/236/213.md" +0 -29
  200. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/346/225/260/346/215/256/346/272/220 /345/274/200/345/217/221/346/214/207/345/215/227.md" +0 -607
  201. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/350/204/232/346/234/254/346/217/222/344/273/266 /345/274/200/345/217/221/346/214/207/345/215/227/Base /346/250/241/345/235/227.md" +0 -391
  202. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/350/204/232/346/234/254/346/217/222/344/273/266 /345/274/200/345/217/221/346/214/207/345/215/227/Field /346/250/241/345/235/227.md" +0 -379
  203. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/350/204/232/346/234/254/346/217/222/344/273/266 /345/274/200/345/217/221/346/214/207/345/215/227/Input/346/250/241/345/235/227.md" +0 -331
  204. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/350/204/232/346/234/254/346/217/222/344/273/266 /345/274/200/345/217/221/346/214/207/345/215/227/Output/346/250/241/345/235/227.md" +0 -197
  205. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/350/204/232/346/234/254/346/217/222/344/273/266 /345/274/200/345/217/221/346/214/207/345/215/227/Record /346/250/241/345/235/227.md" +0 -277
  206. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/350/204/232/346/234/254/346/217/222/344/273/266 /345/274/200/345/217/221/346/214/207/345/215/227/Sheet /346/250/241/345/235/227.md" +0 -1013
  207. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/350/204/232/346/234/254/346/217/222/344/273/266 /345/274/200/345/217/221/346/214/207/345/215/227/UI /346/250/241/345/235/227.md" +0 -472
  208. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/350/204/232/346/234/254/346/217/222/344/273/266 /345/274/200/345/217/221/346/214/207/345/215/227/View /346/250/241/345/235/227.md" +0 -203
  209. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/350/204/232/346/234/254/346/217/222/344/273/266 /345/274/200/345/217/221/346/214/207/345/215/227//345/255/227/346/256/265/346/225/260/346/215/256/347/273/223/346/236/204.md" +0 -65
  210. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/350/204/232/346/234/254/346/217/222/344/273/266 /345/274/200/345/217/221/346/214/207/345/215/227.md" +0 -142
  211. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/350/276/271/346/240/217/346/217/222/344/273/266 /345/274/200/345/217/221/346/214/207/345/215/227/Base /346/250/241/345/235/227.md" +0 -391
  212. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/350/276/271/346/240/217/346/217/222/344/273/266 /345/274/200/345/217/221/346/214/207/345/215/227/Event/344/272/213/344/273/266/346/250/241/345/235/227.md" +0 -182
  213. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/350/276/271/346/240/217/346/217/222/344/273/266 /345/274/200/345/217/221/346/214/207/345/215/227/Field /346/250/241/345/235/227.md" +0 -379
  214. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/350/276/271/346/240/217/346/217/222/344/273/266 /345/274/200/345/217/221/346/214/207/345/215/227/Record /346/250/241/345/235/227.md" +0 -277
  215. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/350/276/271/346/240/217/346/217/222/344/273/266 /345/274/200/345/217/221/346/214/207/345/215/227/Sheet /346/250/241/345/235/227.md" +0 -1013
  216. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/350/276/271/346/240/217/346/217/222/344/273/266 /345/274/200/345/217/221/346/214/207/345/215/227/UI /346/250/241/345/235/227.md" +0 -472
  217. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/350/276/271/346/240/217/346/217/222/344/273/266 /345/274/200/345/217/221/346/214/207/345/215/227/View /346/250/241/345/235/227.md" +0 -203
  218. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/350/276/271/346/240/217/346/217/222/344/273/266 /345/274/200/345/217/221/346/214/207/345/215/227//345/205/266/344/273/226/346/216/245/345/217/243.md" +0 -146
  219. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/350/276/271/346/240/217/346/217/222/344/273/266 /345/274/200/345/217/221/346/214/207/345/215/227//345/255/227/346/256/265/346/225/260/346/215/256/347/273/223/346/236/204.md" +0 -65
  220. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/350/276/271/346/240/217/346/217/222/344/273/266 /345/274/200/345/217/221/346/214/207/345/215/227//346/240/270/345/277/203/347/237/245/350/257/206.md" +0 -54
  221. package/templates/aitable-handoff/wiki/faq-support/18-/345/274/200/345/217/221/350/200/205/346/214/207/345/215/227/AI/350/241/250/346/240/274/350/276/271/346/240/217/346/217/222/344/273/266 /345/274/200/345/217/221/346/214/207/345/215/227.md" +0 -192
  222. package/templates/aitable-handoff/wiki/faq-support//351/222/211/351/222/211AI/350/241/250/346/240/274FAQ.md +0 -611
  223. package/templates/aitable-handoff/workflows/admin-kb-update/recipes/kb-refine.recipe.ts +0 -131
  224. package/templates/aitable-handoff/workflows/admin-kb-update/recipes/kb_sync_handler.recipe.ts +0 -130
  225. package/templates/aitable-handoff/workflows/admin-kb-update/workflow.yml +0 -125
  226. package/templates/aitable-handoff/workflows/config-sync/recipes/config_sync.recipe.ts +0 -448
  227. package/templates/aitable-handoff/workflows/config-sync/recipes/config_sync_handler.recipe.ts +0 -16
  228. package/templates/aitable-handoff/workflows/config-sync/workflow.yml +0 -73
  229. package/templates/aitable-handoff/workflows/daily-review/recipes/daily_review.recipe.ts +0 -529
  230. package/templates/aitable-handoff/workflows/daily-review/recipes/daily_review_handler.recipe.ts +0 -26
  231. package/templates/aitable-handoff/workflows/daily-review/recipes/memory-events.ts +0 -56
  232. package/templates/aitable-handoff/workflows/daily-review/workflow.yml +0 -92
  233. package/templates/aitable-handoff/workflows/group-qa/error-replies.json +0 -53
  234. package/templates/aitable-handoff/workflows/group-qa/recipes/answer.recipe.ts +0 -197
  235. package/templates/aitable-handoff/workflows/group-qa/recipes/conversation_handler.recipe.ts +0 -294
  236. package/templates/aitable-handoff/workflows/group-qa/recipes/issue-classifier.ts +0 -120
  237. package/templates/aitable-handoff/workflows/group-qa/recipes/known-error-match.recipe.ts +0 -75
  238. package/templates/aitable-handoff/workflows/group-qa/recipes/memory-events.ts +0 -55
  239. package/templates/aitable-handoff/workflows/group-qa/recipes/reply-to-group.recipe.ts +0 -132
  240. package/templates/aitable-handoff/workflows/group-qa/recipes/troubleshoot-issue.recipe.ts +0 -195
  241. package/templates/aitable-handoff/workflows/group-qa/workflow.yml +0 -210
  242. package/templates/aitable-handoff/workspaces/daily-review/AGENTS.md +0 -189
  243. package/templates/aitable-handoff/workspaces/faq-support/AGENTS.md +0 -448
  244. package/templates/aitable-handoff/workspaces/faq-support/contacts.json +0 -14
  245. package/templates/aitable-handoff/workspaces/faq-support/owner-map.json +0 -18
  246. package/templates/aitable-handoff/workspaces/faq-support/skills/bug-triage/SKILL.md +0 -130
  247. package/templates/aitable-handoff/workspaces/faq-troubleshooter/AGENTS.md +0 -53
  248. package/templates/aitable-handoff/workspaces/faq-troubleshooter/skills/troubleshooting/SKILL.md +0 -58
  249. package/templates/aitable-handoff/workspaces/faq-troubleshooter/skills/troubleshooting/aitable-import-troubleshooter/SKILL.md +0 -485
  250. package/templates/aitable-handoff/workspaces/faq-troubleshooter/skills/troubleshooting/aitable-openapi-troubleshooter/SKILL.md +0 -183
  251. package/templates/aitable-handoff/workspaces/faq-troubleshooter/skills/troubleshooting/import-openapi-e2e-troubleshooter/SKILL.md +0 -459
  252. package/templates/aitable-handoff/workspaces/faq-troubleshooter/skills/troubleshooting/notable-datasource-troubleshooter/SKILL.md +0 -1286
  253. package/templates/aitable-handoff/workspaces/faq-troubleshooter/skills/troubleshooting/notable-field-troubleshooter/SKILL.md +0 -673
  254. package/templates/aitable-handoff/workspaces/faq-troubleshooter/skills/troubleshooting/spreadsheet-datasync-troubleshooter/SKILL.md +0 -322
  255. package/templates/aitable-handoff/workspaces/kb-editor/AGENTS.md +0 -32
  256. package/templates/support-qa/lib/assemble-cli.ts +0 -30
  257. package/templates/support-qa/lib/assemble.ts +0 -279
  258. package/templates/support-qa/lib/echo-guard.ts +0 -50
  259. package/templates/support-qa/lib/fastpath.ts +0 -227
  260. package/templates/support-qa/lib/owner-mention.ts +0 -140
  261. package/templates/support-qa/lib/profile-guard.ts +0 -55
  262. package/templates/support-qa/lib/send-failure-guard.ts +0 -59
  263. package/templates/support-qa/lib/troubleshoot.ts +0 -236
@@ -1,448 +0,0 @@
1
- import { execFile } from "node:child_process";
2
- import { promisify } from "node:util";
3
- import { z } from "zod";
4
- import { normalizeByType, tableRefConfigSchema, globalVarRefPath, type RecipeDefinition, type RecipeContext, type RecipeResult } from "aitable-workflow-core";
5
-
6
- const execFileAsync = promisify(execFile);
7
-
8
- /** 从配置取 globalVar key:接受 "${globalVar.x}" 引用(解析出 x)或裸 key;空则回退默认。 */
9
- function varKey(raw: unknown, fallback: string): string {
10
- const s = String(raw ?? "").trim();
11
- return globalVarRefPath(s) ?? (s || fallback);
12
- }
13
-
14
- type Cells = Record<string, unknown>;
15
- type Rec = { recordId: string; cells: Cells };
16
- export type GroupConfig = {
17
- groupId: string;
18
- groupName?: string;
19
- inbound?: string;
20
- outbound?: string;
21
- credRef?: string;
22
- botNick?: string;
23
- troubleshootingEnabled: boolean;
24
- };
25
- export type AdminConfig = { userId: string; nick: string; openDingTalkId: string };
26
- type FetchResult<T> = { ok: true; data: T } | { ok: false; error: string };
27
-
28
- // 管理员 contact 解析的并发上限:避免 N 较大时同时拉起过多 dws 子进程。
29
- const CONTACT_CONCURRENCY = 5;
30
-
31
- async function dwsJson(args: string[], timeoutMs = 30_000): Promise<{ records: Rec[] }> {
32
- const { stdout } = await execFileAsync("dws", args, { encoding: "utf-8", timeout: timeoutMs, maxBuffer: 5 * 1024 * 1024 });
33
- const parsed = JSON.parse(stdout.trim()) as unknown;
34
- return { records: extractRecords(parsed) };
35
- }
36
-
37
- /** dws record query/list 返回 `{ data: { records: [...] } }`,需 unwrap */
38
- function extractRecords(raw: unknown): Rec[] {
39
- if (!raw || typeof raw !== "object") return [];
40
- const rec = raw as Record<string, unknown>;
41
- const payload = (rec.data ?? rec) as Record<string, unknown> | undefined;
42
- if (!payload || typeof payload !== "object") return [];
43
- const records = payload.records;
44
- return Array.isArray(records) ? (records as Rec[]) : [];
45
- }
46
-
47
- async function dwsRaw(args: string[], timeoutMs = 15_000): Promise<unknown> {
48
- const { stdout } = await execFileAsync("dws", args, { encoding: "utf-8", timeout: timeoutMs, maxBuffer: 5 * 1024 * 1024 });
49
- return JSON.parse(stdout.trim());
50
- }
51
-
52
- /** 有界并发地映射:最多 limit 个任务同时进行,返回与输入等长的结果数组。 */
53
- async function mapWithConcurrency<T, R>(items: T[], limit: number, fn: (item: T) => Promise<R>): Promise<R[]> {
54
- const results = new Array<R>(items.length);
55
- let cursor = 0;
56
- const workers = Array.from({ length: Math.min(limit, items.length) }, async () => {
57
- while (cursor < items.length) {
58
- const index = cursor++;
59
- results[index] = await fn(items[index]);
60
- }
61
- });
62
- await Promise.all(workers);
63
- return results;
64
- }
65
-
66
- function cellText(v: unknown, fieldType?: string): string {
67
- const normalized = normalizeByType(v, fieldType);
68
- if (typeof normalized === "string") return normalized.trim();
69
- if (typeof normalized === "number") return String(normalized);
70
- return "";
71
- }
72
-
73
- /** 群配置开关:仅明确的真值开启;缺失、空值或未知格式一律关闭。 */
74
- export function cellBoolean(v: unknown): boolean {
75
- if (typeof v === "boolean") return v;
76
- if (typeof v === "number") return v === 1;
77
- if (typeof v === "string") {
78
- return ["true", "1", "yes", "on", "是", "开启", "启用", "已勾选"].includes(v.trim().toLowerCase());
79
- }
80
- if (Array.isArray(v)) return v.some(cellBoolean);
81
- const record = asRecord(v);
82
- if (!record) return false;
83
- if ("value" in record) return cellBoolean(record.value);
84
- if ("name" in record) return cellBoolean(record.name);
85
- return false;
86
- }
87
-
88
- function asRecord(value: unknown): Record<string, unknown> | null {
89
- return value !== null && typeof value === "object" && !Array.isArray(value)
90
- ? value as Record<string, unknown>
91
- : null;
92
- }
93
-
94
- /** 将快照标准化,避免 DWS 返回顺序或 JSON 格式变化造成伪更新。 */
95
- export function normalizeGroupConfigs(raw: unknown): GroupConfig[] {
96
- if (!Array.isArray(raw)) return [];
97
- return raw.flatMap((value): GroupConfig[] => {
98
- const record = asRecord(value);
99
- const groupId = cellText(record?.groupId);
100
- if (!groupId) return [];
101
- const groupName = cellText(record?.groupName);
102
- const inbound = cellText(record?.inbound);
103
- const outbound = cellText(record?.outbound);
104
- const credRef = cellText(record?.credRef);
105
- const botNick = cellText(record?.botNick);
106
- const troubleshootingEnabled = cellBoolean(record?.troubleshootingEnabled);
107
-
108
- const normalized: GroupConfig = { groupId, troubleshootingEnabled };
109
- if (groupName) normalized.groupName = groupName;
110
- if (inbound) normalized.inbound = inbound;
111
- if (outbound) normalized.outbound = outbound;
112
- if (credRef) normalized.credRef = credRef;
113
- if (botNick) normalized.botNick = botNick;
114
- return [normalized];
115
- }).sort((left, right) => (
116
- left.groupId.localeCompare(right.groupId)
117
- || JSON.stringify(left).localeCompare(JSON.stringify(right))
118
- ));
119
- }
120
-
121
- export function normalizeAdminConfigs(raw: unknown): AdminConfig[] {
122
- if (!Array.isArray(raw)) return [];
123
- return raw.flatMap((value): AdminConfig[] => {
124
- const record = asRecord(value);
125
- const userId = cellText(record?.userId);
126
- const nick = cellText(record?.nick);
127
- const openDingTalkId = cellText(record?.openDingTalkId);
128
- return userId && nick && openDingTalkId ? [{ userId, nick, openDingTalkId }] : [];
129
- }).sort((left, right) => (
130
- left.userId.localeCompare(right.userId)
131
- || JSON.stringify(left).localeCompare(JSON.stringify(right))
132
- ));
133
- }
134
-
135
- /** 空快照门禁的计数游标(按目标 globalVar 派生,避免多份快照互相干扰)。 */
136
- export function emptyStreakKey(key: string): string {
137
- return `${key}__empty_streak`;
138
- }
139
-
140
- /**
141
- * 空快照发布门禁:远端读到空且旧值非空时,不立刻清空,先累计"连续读到空"轮数,
142
- * 达到 rounds 轮才认定为真实清空。防的是"读成功但结果为空"这类抖动(表查询瞬时
143
- * 返回 0 条、字段解析不到 userId 等)被当成"远端已清空",把管理员/群名单误清 ——
144
- * 管理员被清会让真人同事消息退化成普通用户提问;pull 名单被清会让机器人整群失聪。
145
- * 旧值本来就是空,或本轮非空时,直接放行并复位计数。
146
- */
147
- export function gateEmptySnapshot(
148
- ctx: RecipeContext,
149
- key: string,
150
- nextCount: number,
151
- rounds: number,
152
- ): { allow: boolean; streak: number; rounds: number } {
153
- const required = Math.max(1, Math.trunc(rounds) || 1);
154
- const streakKey = emptyStreakKey(key);
155
- const rawStreak = Math.trunc(Number(ctx.getGlobalVar(streakKey) ?? 0));
156
- const prevStreak = Number.isFinite(rawStreak) && rawStreak > 0 ? rawStreak : 0;
157
- const currentValue = ctx.getGlobalVar(key);
158
- const currentCount = Array.isArray(currentValue) ? currentValue.length : 0;
159
-
160
- if (nextCount > 0 || currentCount === 0) {
161
- if (prevStreak !== 0) ctx.setGlobalVar(streakKey, 0);
162
- return { allow: true, streak: 0, rounds: required };
163
- }
164
-
165
- const streak = prevStreak + 1;
166
- ctx.setGlobalVar(streakKey, streak >= required ? 0 : streak);
167
- return { allow: streak >= required, streak, rounds: required };
168
- }
169
-
170
- /** 快照计数留痕文案:暂缓清空时显式带上门禁轮次,便于 trace 上直接看出"被拦下"而非"真为 0"。 */
171
- function snapshotCountLabel(result: FetchResult<unknown[]>, gate?: { allow: boolean; streak: number; rounds: number }): string {
172
- if (!result.ok) return "读取失败";
173
- if (gate && !gate.allow) return `0(暂缓清空 ${gate.streak}/${gate.rounds})`;
174
- return String(result.data.length);
175
- }
176
-
177
- /** 内容变化时发布到 globalVar;返回是否实际更新(用于留痕判定)。 */
178
- export function publishIfChanged<T>(
179
- ctx: RecipeContext,
180
- key: string,
181
- nextRaw: unknown,
182
- normalize: (raw: unknown) => T[],
183
- ): boolean {
184
- const next = normalize(nextRaw);
185
- const current = normalize(ctx.getGlobalVar(key) ?? []);
186
- if (JSON.stringify(current) === JSON.stringify(next)) return false;
187
- ctx.setGlobalVar(key, next);
188
- return true;
189
- }
190
-
191
-
192
-
193
- /** 从 dws field get 结果中提取字段名→字段ID 映射(兼容数组或 { data: { fields: [...] } } 嵌套) */
194
- interface FieldMeta { fieldId: string; type: string; }
195
- function extractFieldMap(raw: unknown): Map<string, FieldMeta> {
196
- let arr: unknown[] = [];
197
- if (Array.isArray(raw)) arr = raw;
198
- else if (raw && typeof raw === "object") {
199
- const rec = raw as Record<string, unknown>;
200
- if (Array.isArray(rec.fields)) arr = rec.fields;
201
- else if (Array.isArray(rec.result)) arr = rec.result;
202
- else if (rec.data && typeof rec.data === "object") {
203
- const data = rec.data as Record<string, unknown>;
204
- if (Array.isArray(data.fields)) arr = data.fields;
205
- else if (Array.isArray(data.result)) arr = data.result;
206
- }
207
- }
208
- const map = new Map<string, FieldMeta>();
209
- for (const field of arr) {
210
- if (!field || typeof field !== "object") continue;
211
- const rec = field as Record<string, unknown>;
212
- const id = typeof rec.fieldId === "string" ? rec.fieldId : typeof rec.id === "string" ? rec.id : null;
213
- const name = typeof rec.fieldName === "string" ? rec.fieldName : typeof rec.name === "string" ? rec.name : null;
214
- const type = typeof rec.type === "string" ? rec.type : "text";
215
- if (id && name) map.set(name, { fieldId: id, type });
216
- }
217
- return map;
218
- }
219
-
220
- async function fetchFieldMap(baseId: string, tableId: string): Promise<Map<string, FieldMeta>> {
221
- const raw = await dwsRaw(["aitable", "field", "get", "--base-id", baseId, "--table-id", tableId, "--format", "json"]);
222
- return extractFieldMap(raw);
223
- }
224
-
225
- /** 从 fieldMap 解析字段 ID(查不到则回退原值) */
226
- function resolveFieldKey(nameOrId: string, fieldMap: Map<string, FieldMeta>): string {
227
- return fieldMap.get(nameOrId)?.fieldId ?? nameOrId;
228
- }
229
- /** 从 fieldMap 获取字段类型(查不到则 undefined,走 normalizeByType 默认) */
230
- function fieldType(nameOrId: string, fieldMap: Map<string, FieldMeta>): string | undefined {
231
- return fieldMap.get(nameOrId)?.type;
232
- }
233
-
234
- const recipe: RecipeDefinition = {
235
- meta: {
236
- id: "config_sync",
237
- name: "拉取并固化群/管理员配置",
238
- role: "config-syncer",
239
- description: "dws 拉群配置表 + 管理员表 + contact 解析 → 发布到 globalVar(group_configs/group_pull_list/admins)",
240
- version: "1.0.0",
241
- requiresAgent: false,
242
- timeoutMs: 120_000,
243
- config: z.object({
244
- group_table: tableRefConfigSchema({
245
- label: "群配置表",
246
- description: "群配置表(读取群ID、群名称、入站方式、出站方式、凭据引用、机器人昵称、是否排查问题)",
247
- access: "read",
248
- ownership: "owned",
249
- autoCreate: true,
250
- defaultBase: "workflow.tracker.base_id",
251
- setupSchema: {
252
- fields: [
253
- { name: "群ID", type: "text" },
254
- { name: "群名称", type: "text" },
255
- // 入站/出站双轴正交:
256
- // 入站方式=dws(个人号轮询,进 pull 名单)/stream(企业机器人 WebSocket,@机器人触发);
257
- // 出站方式=session(会话内 @提问者,依赖 stream 登记的 sessionWebhook)/webhook(命名 webhook 降级)。
258
- // 用单选杜绝手填写错;具体用哪套 webhook 凭证由「凭据引用」在 messaging.robots/webhooks 命名空间内指定。
259
- // 象限约束:出站=session 依赖入站=stream(sessionWebhook 只由 stream 登记);dws+session 物理不可能,运行期降级 webhook。
260
- { name: "入站方式", type: "singleSelect", options: ["dws", "stream"] },
261
- { name: "出站方式", type: "singleSelect", options: ["session", "webhook"] },
262
- { name: "凭据引用", type: "text" },
263
- { name: "机器人昵称", type: "text" },
264
- { name: "是否排查问题", type: "checkbox" },
265
- ],
266
- },
267
- }),
268
- admin_table: tableRefConfigSchema({
269
- label: "管理员配置表",
270
- description: "管理员配置表(读取管理员名单)",
271
- access: "read",
272
- ownership: "owned",
273
- autoCreate: true,
274
- defaultBase: "workflow.tracker.base_id",
275
- setupSchema: {
276
- fields: [
277
- { name: "管理员", type: "user" },
278
- ],
279
- },
280
- }),
281
- group_var: z.string().default("${globalVar.group_configs}").describe("发布群配置的目标 globalVar"),
282
- pull_list_var: z.string().default("${globalVar.group_pull_list}").describe("发布 dws 轮询群列表的目标 globalVar"),
283
- stream_var: z.string().default("${globalVar.stream_robot_refs}").describe("发布 stream 入站机器人 credRef 名单的目标 globalVar"),
284
- admin_var: z.string().default("${globalVar.admins}").describe("发布管理员名单的目标 globalVar"),
285
- empty_confirm_rounds: z.coerce.number().int().min(1).default(2)
286
- .describe("空快照发布门禁轮数:远端读到空且旧值非空时,需连续读到空达到该轮数才真正清空;未达轮数保留旧值并留痕(防读空抖动误清群/管理员名单)。设 1 即恢复旧的即时清空行为"),
287
- }),
288
- },
289
-
290
- async execute(ctx: RecipeContext): Promise<RecipeResult> {
291
- const { config, log } = ctx;
292
- const gt = config.group_table as { baseId: string; tableId: string };
293
- const at = config.admin_table as { baseId: string; tableId: string };
294
- const groupVar = varKey(config.group_var, "group_configs");
295
- const pullListVar = varKey(config.pull_list_var, "group_pull_list");
296
- const streamVar = varKey(config.stream_var, "stream_robot_refs");
297
- const adminVar = varKey(config.admin_var, "admins");
298
- const emptyConfirmRounds = Math.max(1, Math.trunc(Number(config.empty_confirm_rounds ?? 2)) || 1);
299
-
300
- // 表自建后字段名固定,通过 field get 解析为字段ID再读取 cells
301
- const GROUP_FIELDS = {
302
- groupId: "群ID",
303
- groupName: "群名称",
304
- inbound: "入站方式",
305
- outbound: "出站方式",
306
- credRef: "凭据引用",
307
- botNick: "机器人昵称",
308
- troubleshootingEnabled: "是否排查问题",
309
- };
310
- const ADMIN_FIELDS = { user: "管理员" };
311
-
312
- // 1) 群配置
313
- let groupResult: FetchResult<GroupConfig[]>;
314
- try {
315
- const groupFieldMap = await fetchFieldMap(gt.baseId, gt.tableId);
316
- const groupIdKey = resolveFieldKey(GROUP_FIELDS.groupId, groupFieldMap);
317
- const groupNameKey = resolveFieldKey(GROUP_FIELDS.groupName, groupFieldMap);
318
- const inboundKey = resolveFieldKey(GROUP_FIELDS.inbound, groupFieldMap);
319
- const outboundKey = resolveFieldKey(GROUP_FIELDS.outbound, groupFieldMap);
320
- const credRefKey = resolveFieldKey(GROUP_FIELDS.credRef, groupFieldMap);
321
- const botNickKey = resolveFieldKey(GROUP_FIELDS.botNick, groupFieldMap);
322
- const troubleshootingEnabledKey = resolveFieldKey(GROUP_FIELDS.troubleshootingEnabled, groupFieldMap);
323
- const inboundType = fieldType(GROUP_FIELDS.inbound, groupFieldMap);
324
- const outboundType = fieldType(GROUP_FIELDS.outbound, groupFieldMap);
325
- const { records } = await dwsJson(["aitable", "record", "query", "--base-id", gt.baseId, "--table-id", gt.tableId, "--all", "--format", "json"]);
326
- const groups = normalizeGroupConfigs(records.map((r) => ({
327
- groupId: cellText(r.cells[groupIdKey], fieldType(GROUP_FIELDS.groupId, groupFieldMap)),
328
- groupName: cellText(r.cells[groupNameKey], fieldType(GROUP_FIELDS.groupName, groupFieldMap)) || undefined,
329
- inbound: cellText(r.cells[inboundKey], inboundType) || undefined,
330
- outbound: cellText(r.cells[outboundKey], outboundType) || undefined,
331
- credRef: cellText(r.cells[credRefKey], fieldType(GROUP_FIELDS.credRef, groupFieldMap)) || undefined,
332
- botNick: cellText(r.cells[botNickKey], fieldType(GROUP_FIELDS.botNick, groupFieldMap)) || undefined,
333
- troubleshootingEnabled: cellBoolean(r.cells[troubleshootingEnabledKey]),
334
- })));
335
- groupResult = { ok: true, data: groups };
336
- } catch (e) {
337
- const error = e instanceof Error ? e.message : String(e);
338
- log(`群配置拉取失败,保留旧值: ${error}`);
339
- groupResult = { ok: false, error };
340
- }
341
-
342
- // 2) 管理员 userId → nick/openId(contact 链式)。每个 userId 内部 get→search 需串行,
343
- // 但不同 userId 之间用有界并发处理,避免 N 较大时串行阻塞过久。
344
- let adminResult: FetchResult<AdminConfig[]>;
345
- try {
346
- const adminFieldMap = await fetchFieldMap(at.baseId, at.tableId);
347
- const userKey = resolveFieldKey(ADMIN_FIELDS.user, adminFieldMap);
348
- const { records } = await dwsJson(["aitable", "record", "list", "--base-id", at.baseId, "--table-id", at.tableId, "--all", "--format", "json"]);
349
- const userIds = [...new Set(records.flatMap((r) => Array.isArray(r.cells[userKey]) ? (r.cells[userKey] as { userId?: string }[]).map((u) => u?.userId ?? "").filter(Boolean) : []))];
350
- const resolutionErrors: string[] = [];
351
- const resolved = await mapWithConcurrency(userIds, CONTACT_CONCURRENCY, async (uid) => {
352
- try {
353
- const got = await dwsRaw(["contact", "user", "get", "--ids", uid, "--format", "json"]) as { result?: { orgEmployeeModel?: { orgUserName?: string } }[] };
354
- const name = got?.result?.[0]?.orgEmployeeModel?.orgUserName;
355
- if (!name) throw new Error("未查询到组织内姓名");
356
- const searched = await dwsRaw(["contact", "user", "search", "--query", name, "--format", "json"]) as { result?: { userId?: string; nick?: string; openDingTalkId?: string }[] };
357
- const match = (searched?.result ?? []).find((u) => u.userId === uid);
358
- if (match?.openDingTalkId && match?.nick) return { userId: uid, nick: match.nick, openDingTalkId: match.openDingTalkId };
359
- throw new Error("未查询到匹配的 openDingTalkId/nick");
360
- } catch (e) {
361
- const error = `${uid}: ${e instanceof Error ? e.message : String(e)}`;
362
- resolutionErrors.push(error);
363
- log(`contact 解析失败 ${error}`);
364
- return null;
365
- }
366
- });
367
- if (resolutionErrors.length > 0) {
368
- throw new Error(`${resolutionErrors.length} 名管理员解析失败: ${resolutionErrors.sort().join("; ")}`);
369
- }
370
- const admins = normalizeAdminConfigs(resolved.filter((a): a is AdminConfig => a !== null));
371
- adminResult = { ok: true, data: admins };
372
- } catch (e) {
373
- const error = e instanceof Error ? e.message : String(e);
374
- log(`管理员拉取失败,保留旧值: ${error}`);
375
- adminResult = { ok: false, error };
376
- }
377
-
378
- // 3) 仅发布变化的成功快照到 globalVar。失败保留旧值;"成功但为空"需经 empty_confirm_rounds
379
- // 门禁连续确认后才真正清空(单次读空视为抖动,保留旧值并留痕)。
380
- const changed: string[] = [];
381
- const failures: string[] = [];
382
- const withheld: string[] = [];
383
- let groupGate: { allow: boolean; streak: number; rounds: number } | undefined;
384
- let adminGate: { allow: boolean; streak: number; rounds: number } | undefined;
385
- if (groupResult.ok) {
386
- groupGate = gateEmptySnapshot(ctx, groupVar, groupResult.data.length, emptyConfirmRounds);
387
- if (!groupGate.allow) {
388
- // 群配置是 pull/stream 名单的唯一来源,暂缓时三份派生快照必须一起不动,
389
- // 否则会出现"群配置保旧、pull 名单被清空"的半清空态(机器人静默失聪)。
390
- withheld.push(`群配置(读到空 ${groupGate.streak}/${groupGate.rounds} 轮,暂缓清空)`);
391
- log(`群配置读到空但旧值非空,暂缓清空(第 ${groupGate.streak}/${groupGate.rounds} 轮):群配置/pull 名单/stream 名单一并保留旧值`);
392
- } else {
393
- // 象限校验:出站=session 依赖入站=stream(sessionWebhook 只由 stream 登记),dws+session 物理不可能,告警(运行期降级 webhook)。
394
- for (const g of groupResult.data) {
395
- if (g.outbound === "session" && g.inbound !== "stream") {
396
- log(`群配置象限告警 ${g.groupName ?? g.groupId}: 出站=session 依赖入站=stream,当前入站=${g.inbound ?? "空"},运行期将降级 webhook`);
397
- }
398
- }
399
- if (publishIfChanged(ctx, groupVar, groupResult.data, normalizeGroupConfigs)) changed.push("群配置");
400
- // 派生 pull 名单:只把入站=dws 的群写入(dws 轮询源监听),入站=stream 群走机器人 WebSocket 不入名单。
401
- const pullIds = groupResult.data.filter((g) => g.inbound === "dws").map((g) => g.groupId);
402
- if (publishIfChanged(ctx, pullListVar, pullIds, (v) => Array.isArray(v) ? v as string[] : [])) changed.push("pull 名单");
403
- // 派生 stream 机器人名单:只把入站=stream 且有 credRef 的群的 credRef 去重写入(stream 源据此维护连接池)。
404
- const streamRefs = [...new Set(
405
- groupResult.data.filter((g) => g.inbound === "stream" && g.credRef).map((g) => g.credRef!),
406
- )];
407
- if (publishIfChanged(ctx, streamVar, streamRefs, (v) => Array.isArray(v) ? v as string[] : [])) changed.push("stream 名单");
408
- }
409
- } else {
410
- failures.push(`群配置: ${groupResult.error}`);
411
- }
412
- if (adminResult.ok) {
413
- adminGate = gateEmptySnapshot(ctx, adminVar, adminResult.data.length, emptyConfirmRounds);
414
- if (!adminGate.allow) {
415
- withheld.push(`管理员配置(读到空 ${adminGate.streak}/${adminGate.rounds} 轮,暂缓清空)`);
416
- log(`管理员名单读到空但旧值非空,暂缓清空(第 ${adminGate.streak}/${adminGate.rounds} 轮):保留旧名单,避免真人同事发言被误判为用户提问`);
417
- } else if (publishIfChanged(ctx, adminVar, adminResult.data, normalizeAdminConfigs)) {
418
- changed.push("管理员配置");
419
- }
420
- } else {
421
- failures.push(`管理员配置: ${adminResult.error}`);
422
- }
423
-
424
- const shouldTrack = changed.length > 0 || failures.length > 0 || withheld.length > 0;
425
- const syncResult = [
426
- changed.length > 0 ? `已更新 ${changed.join("、")}` : "",
427
- withheld.length > 0 ? `暂缓清空: ${withheld.join(";")}` : "",
428
- failures.length > 0 ? `同步异常: ${failures.join(";")}` : "",
429
- ].filter(Boolean).join(";") || "无变化";
430
- const groupCount = snapshotCountLabel(groupResult, groupGate);
431
- const adminCount = snapshotCountLabel(adminResult, adminGate);
432
- log(`配置同步完成:${syncResult};群 ${groupCount}、管理员 ${adminCount}${shouldTrack ? "" : "(不留痕)"}`);
433
- return {
434
- status: "success",
435
- output: { sync_result: syncResult, group_count: groupCount, admin_count: adminCount },
436
- // 两份成功快照均无变化 → on_demand 模式下不建行;失败/暂缓清空仍留痕,便于发现同步异常。
437
- ...(shouldTrack ? {} : { tracker: false }),
438
- logs: [
439
- `群 ${groupCount}`,
440
- `管理员 ${adminCount}`,
441
- ...(changed.length > 0 ? [`变更: ${changed.join("、")}`] : []),
442
- ...withheld.map((item) => `暂缓: ${item}`),
443
- ...failures.map((failure) => `失败: ${failure}`),
444
- ],
445
- };
446
- },
447
- };
448
- export default recipe;
@@ -1,16 +0,0 @@
1
- import type { EventHandlerRecipeDefinition, HandlerInitContext, HandlerInstance } from "aitable-workflow-core";
2
-
3
- const recipe: EventHandlerRecipeDefinition = {
4
- meta: { id: "config_sync_handler", name: "配置同步触发器", description: "cron tick → 建一条配置同步工单" },
5
- create(ctx: HandlerInitContext): HandlerInstance {
6
- return {
7
- onEvent(event) {
8
- const firedAt = String(event.payload?.firedAt ?? new Date().toISOString());
9
- ctx.log(`配置同步触发 @ ${firedAt}`);
10
- ctx.pushEvent({ action: "create_record", fields: { "标题": `配置同步 ${firedAt}` } });
11
- },
12
- stop() {},
13
- };
14
- },
15
- };
16
- export default recipe;
@@ -1,73 +0,0 @@
1
- meta:
2
- name: "群/管理员配置同步"
3
- version: "1.0.0"
4
- domain: config_sync
5
- description: "定时从固定 AI 表格拉取群配置与管理员,发布到 globalVar(group_configs/admins,供 group-qa 活读);不发群"
6
-
7
- notification:
8
- channel: "none"
9
-
10
- tracker:
11
- label: "群与管理员配置同步留痕表"
12
- base_id: "" # 与其它工作流同 base;table_id 留空 setup 自动建表回写
13
- table_id: ""
14
- states:
15
- initial: "待处理"
16
- active: [ "处理中" ]
17
- terminal: [ "已完成", "已关闭" ]
18
- blocked: "已阻塞"
19
- fields:
20
- state: "状态"
21
- title: "标题"
22
- current_step: "当前步骤"
23
- event_log: "事件日志"
24
- field_definitions:
25
- - name: 同步结果
26
- type: text
27
- - name: 群数量
28
- type: text
29
- - name: 管理员数量
30
- type: text
31
- views:
32
- - id: default_grid
33
- type: Grid
34
- name: 表格
35
- field_order: [ 标题, 同步结果, 群数量, 管理员数量, 状态, 当前步骤, 事件日志 ]
36
- description: 配置同步留痕
37
-
38
- event_sources:
39
- - name: 定时同步
40
- type: cron_scheduler
41
- handler: config_sync_handler
42
- record_policy: on_demand # 无变更的 tick 不建行(见 config_sync recipe 的 tracker:false)
43
- config:
44
- interval_ms: 300000 # 5 分钟
45
- fire_immediately: true
46
- event_type: config_sync_tick
47
-
48
- steps:
49
- - id: config_sync
50
- name: "拉取并固化群/管理员配置"
51
- recipe: config_sync
52
- auto: true
53
- config:
54
- group_table:
55
- baseId: ""
56
- tableId: ""
57
- admin_table:
58
- baseId: ""
59
- tableId: ""
60
- group_var: "${globalVar.group_configs}"
61
- pull_list_var: "${globalVar.group_pull_list}"
62
- admin_var: "${globalVar.admins}"
63
- input_mapping: {}
64
- output_mapping:
65
- sync_result: "同步结果"
66
- group_count: "群数量"
67
- admin_count: "管理员数量"
68
-
69
- edges:
70
- - from: __start__
71
- to: config_sync
72
- - from: config_sync
73
- to: __end__