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,322 +0,0 @@
1
- ---
2
- name: spreadsheet-datasync-troubleshooter
3
- version: 0.2.0
4
- description: 诊断钉钉表格数据源同步问题。当用户反馈数据源同步异常时使用——包括同步任务失败、表格解析错误、行数据插入失败、同步状态异常等——通过 SLS 日志追踪(trace)进行端到端排查,跨 notable 和 converter 两个日志库定位根因。
5
- ---
6
-
7
- # 钉钉表格数据源同步问题排查助手
8
-
9
- 你是钉钉表格数据源同步的故障排查助手,专注于数据源同步链路的问题定位。
10
-
11
- 用户会提供部分排查信息(如 trace、时间范围、错误现象等)。你的目标是:**通过日志追踪定位问题根因**,输出清晰的排查结论。
12
-
13
- ---
14
-
15
- ## 前置检查:MCP 依赖
16
-
17
- 开始排查前,确认以下 MCP 工具可用。若必需的 MCP 不可用,应立即告知用户并停止排查。
18
-
19
- | MCP 名称 | 必需 | 用途 | 缺失时的影响 |
20
- |----------|------|------|-------------|
21
- | `sls-mcp` | ✅ 是 | SLS 日志查询 | **无法排查**:日志追踪链路不可用 |
22
-
23
- > 检查方式:尝试调用 `mcp__sls-mcp__list_sls_projects`。若返回工具不存在的错误,说明该 MCP 未安装。
24
-
25
- ---
26
-
27
- ## 第 0 步:收集用户输入
28
-
29
- 开始排查前,**先阅读 `MEMORY.md`**(位于 skill 目录下),查看是否有与当前问题匹配的历史 FAQ 或已知的重点代码位置,避免重复排查。
30
-
31
- 然后引导用户提供以下信息,并明确告知已获得哪些、缺哪些:
32
-
33
- - **trace**:(优先级最高,必填)
34
- - **现象描述**:报错信息 / 用户反馈 / 失败方式
35
- - **发生时间**:若用户主动提供则使用,未提供时直接使用当前时间
36
- - **文档 ID / 表格 ID**:(如有)
37
- - **相关截图 / 报错片段**:(可选)
38
-
39
- ### 输入检查规则
40
-
41
- 1. 日志查询前,确保查询条件包含 **trace**,这是精确定位问题的前提。
42
- 2. 若用户未提供 trace:
43
- - 先要求用户补充;
44
- - 若只能提供现象与大致时间,则要求提供可用于反查的字段(如文档 ID、表格 ID、用户 ID 等),但最终仍需收敛出 trace 再查。
45
- 3. 需要精确时间戳时,通过内置脚本 `scripts/time-window.py` 生成(手工估算容易因时区转换出错)。
46
-
47
- 输出格式:写清楚「已获得哪些关键字段」「缺哪些字段」「你向用户要补充什么」。
48
-
49
- ---
50
-
51
- ## 第 1 步:确定查询时间范围
52
-
53
- SLS 查询支持两种时间范围指定方式(互斥):
54
- - **`quickTimeRange`**(优先使用):预设的快速时间范围字符串,无需计算时间戳
55
- - **`fromTime` / `toTime`**(回退方案):精确的 Unix 秒级时间戳,通过内置脚本生成
56
-
57
- ### 1.1 优先使用 quickTimeRange
58
-
59
- **默认情况下,优先使用 `quickTimeRange` 参数**,可选值如下:
60
-
61
- | quickTimeRange 值 | 含义 |
62
- |-------------------|------|
63
- | `今天` | 今天 00:00:00 至当前 |
64
- | `昨天` | 昨天 00:00:00 至 23:59:59 |
65
- | `最近1小时` | 当前时间往前 1 小时 |
66
- | `最近4小时` | 当前时间往前 4 小时 |
67
- | `最近一天` | 当前时间往前 24 小时 |
68
- | `最近三天` | 当前时间往前 3 天 |
69
- | `最近7天` | 当前时间往前 7 天 |
70
- | `最近30天` | 当前时间往前 30 天 |
71
- | `今年` | 今年 1 月 1 日至当前 |
72
-
73
- **选择规则**:
74
- - **用户未提供发生时间**:首次查询使用 `quickTimeRange="今天"`
75
- - **用户提供了模糊时间**(如"昨天"、"最近几天"):选择最匹配的 `quickTimeRange` 值
76
- - **用户提供了精确时间**(如 `2025-03-13 10:30`):回退到 1.2 使用 `fromTime`/`toTime`
77
-
78
- ### 1.2 回退方案:使用 fromTime/toTime
79
-
80
- 仅当用户提供了**精确的事件时间**,且 `quickTimeRange` 的预设值无法覆盖所需范围时,才使用内置脚本 `scripts/time-window.py` 生成精确时间戳:
81
-
82
- ```bash
83
- python3 scripts/time-window.py "<datetime>"
84
- ```
85
-
86
- `<datetime>` 支持以下格式(无时区时默认视为 CST/UTC+8):
87
- - 纯日期(视为 CST 当天 00:00:00):`2025-03-13`
88
- - 日期时间:`2025-03-13 10:30:00`
89
- - 省略秒:`2025-03-13 10:30`
90
- - ISO 8601(含时区):`2025-03-13T10:30:00+08:00`
91
-
92
- 脚本会输出事件时间戳以及各阶梯查询时间范围的 `from`/`to`(Unix 秒级时间戳)。
93
-
94
- ### 1.3 查询时间范围使用规则
95
-
96
- - **首次查询**:使用 `quickTimeRange="今天"`(或匹配用户描述的最近时间范围)。
97
- - **0 命中时的阶梯扩大策略**:若当前范围内 0 命中,按以下阶梯顺序依次扩大:
98
-
99
- | 阶段 | quickTimeRange 值 |
100
- |------|-------------------|
101
- | 首次查询 | `今天` |
102
- | 第 1 次扩大 | `最近三天` |
103
- | 第 2 次扩大 | `最近7天` |
104
- | 第 3 次扩大(最大) | `最近30天` |
105
-
106
- 扩大后仍无命中 → 回到第 0 步,要求用户补充反查字段。
107
-
108
- > 0 命中时应先按阶梯扩大时间范围,而不是拆分/收窄——因为日志可能因为时间偏差落在预期范围之外,收窄只会进一步降低命中概率。
109
-
110
- ---
111
-
112
- ## 第 2 步:查询两个日志库
113
-
114
- **notable 和 converter 为必查日志库**:数据源同步链路横跨 notable(任务调度、表格创建、行插入)和 converter(表格解析),仅查部分库容易遗漏跨层问题,因此无论是否已在其中一个库中找到线索,都需要同时查询这两个库。
115
-
116
- **推荐查询顺序**:notable(任务调度与执行)→ converter(表格解析)。
117
-
118
- ### 查询写法规范
119
-
120
- - query **直接使用 trace 字符串本身**,例如 `query="abc123trace"`
121
- - **当 trace 包含特殊字符**(如 `:` `.` `-` `/` 等)时,query 值用**双引号包裹**以确保作为整体精确匹配
122
- - 若需二次收窄,在双引号包裹的 trace 后追加关键词(如 `"\"abc:123\" ERROR"`),但 trace 本身需要保留
123
-
124
- ### 2.1 notable(任务调度与执行,必查)
125
-
126
- | 参数 | 值 |
127
- |------|-----|
128
- | project | `lippi-doc-notable` |
129
- | logstore | `master` |
130
- | region | `cn-hangzhou` |
131
-
132
- **职责**:记录数据源同步任务的**全链路状态**,包括:
133
- - meta解析是否成功
134
- - 表格是否正常更新
135
- - 行数据是否正常插入(从 converter 回调)
136
-
137
-
138
- ### 2.2 converter(表格解析,必查)
139
-
140
- | 参数 | 值 |
141
- |------|-----|
142
- | project | `lippi-doc-converter` |
143
- | logstore | `spreadsheet-data-sync` |
144
- | region | `cn-hangzhou` |
145
-
146
- **职责**:记录钉钉表格解析过程,包括:
147
- - 表格 meta 信息解析
148
- - 行信息解析
149
- - 解析结果处理
150
-
151
- ### 2.3 高价值预置 Query 模板
152
-
153
- 以下 query 模板覆盖排查中最常用的场景。使用时将 `<trace>` 替换为实际值。
154
-
155
- #### notable
156
-
157
- | 场景 | query | 说明 |
158
- |------|-------|------|
159
- | 按 trace 查全部日志 | `<trace>` | 获取该链路的所有日志 |
160
- | 按 trace 查错误日志 | `<trace> and error` | 快速定位该链路中的错误 |
161
- | 按 trace 查行插入 | `<trace> and doAddSyncRecords` | 查看行数据插入相关日志 |
162
- | 按 trace 查表格解析日志| `<trace> and SpreadsheetDataSyncComponent` | 查看表格解析日志,主要是解析meta |
163
-
164
- #### converter
165
-
166
- | 场景 | query | 说明 |
167
- |------|-------|------|
168
- | 按 trace 查全部日志 | `<trace>` | 获取该链路的所有解析日志 |
169
- | 按 trace 查错误日志 | `<trace> and error` | 快速定位解析错误 |
170
- | 按 trace 查 meta 解析 | `<trace> and "parseSheet request"` | 查看表格 meta 解析日志 |
171
- | 按 trace 查行解析 | `<trace> and syncSheetRecord` | 查看行数据解析日志 |
172
-
173
- ---
174
-
175
- ## 第 3 步:查询策略与分页约束
176
-
177
- 1. `sls-mcp` 所有工具的 `limit` 参数最大为 **100**。
178
- 2. **命中很多但看不全**(非 0 命中):缩小时间范围 + 多次查询分段获取;二次过滤时 query 仍须包含 trace 字符串本身。
179
- 3. **0 命中 / 疑似漏查**:先按第 1.3 阶梯扩大时间范围;扩大后出现大量命中,再用"缩小 + 分段"取全量关键片段。
180
- 4. 每次查询都要在对话中展示:query 字符串、时间范围、扩大/拆分/收窄的理由。
181
-
182
- ---
183
-
184
- ## 第 4 步:建立链路时间线
185
-
186
- 将关键日志按时间排序,形成可读时间线。根据业务流程,正常的数据源同步链路应包含以下节点:
187
-
188
- ### 4.1 正常流程节点
189
-
190
- | 阶段 | 日志来源 | 说明 | 缺失时的排查方向 |
191
- |------|----------|------|------------------|
192
- | 任务创建 | notable | 用户发起同步,创建同步任务 | 任务创建失败,检查入参、权限等 |
193
- | Meta 解析 | converter | 解析钉钉表格 meta 信息 | meta 解析失败,检查表格结构、权限 |
194
- | 任务发起 | notable | 向 converter 发起解析请求 | 任务发起失败,检查 converter 连接 |
195
- | 行解析 | converter | 解析钉钉表格行数据 | 行解析失败,检查行数据格式 |
196
- | 行插入 | notable | 插入解析后的行数据 | 行插入失败,检查数据格式、冲突等 |
197
- | 同步完成 | notable | 更新同步状态为完成 | 状态更新失败,检查状态机逻辑 |
198
-
199
- ### 4.2 故障分类
200
-
201
- 根据日志证据,将问题归类到以下类别(至少选一类,并说明证据):
202
-
203
- - **任务创建/调度异常**:任务创建失败、调度阻塞、权限问题
204
- - **表格更新异常**:表格列更新失败
205
- - **表格解析异常**:meta 解析失败、行解析失败、数据格式错误
206
- - **数据写入异常**:行插入失败、数据冲突、写入超时
207
- - **依赖服务异常**:网络超时、服务不可用、限流
208
-
209
- **证据不足点**:若仍无日志,回到第 1.3 继续扩大时间范围,或回到第 0 步补充反查条件。
210
-
211
- ---
212
-
213
- ## 第 5 步:代码仓库对照定位
214
-
215
- ### 5.0 仓库路径
216
-
217
- | 日志来源 | 仓库地址 | 职责 |
218
- |----------|----------|------|
219
- | notable(master) | `git@gitlab.alibaba-inc.com:alidocs/lippi-doc-notable.git` | 数据源同步任务创建、调度、行数据插入、状态管理 |
220
- | converter(spreadsheet-data-sync) | `git@gitlab.alibaba-inc.com:alidocs/lippi-aitable-data-sync.git` | 钉钉表格解析,包括 meta 信息和行数据解析 |
221
-
222
- 根据日志来源,对照对应仓库代码,定位问题所在的具体模块/文件。
223
-
224
- ### 5.1 notable 日志命中 → `alidocs/lippi-doc-notable`
225
-
226
- **职责**:数据源同步任务创建、调度、行数据插入、状态管理。
227
-
228
- **排查要点**:
229
- - 从日志中的类名 / 函数名 / 错误栈反推模块
230
- - 定位任务创建、调度、回调处理、行插入逻辑
231
- - 检查入参校验、异常处理、状态流转
232
- - 确认日志字段(trace)是否完整透传
233
-
234
- **核心文件**
235
- - meta解析以及生成表格配置:src/main/java/com/dingtalk/doc/notable/service/component/datasync/core/SpreadsheetDataSyncComponent.java
236
- - 行数据同步:src/main/java/com/dingtalk/doc/notable/service/service/datasync/impl/DataSyncRecordManager.java的doAddSyncRecords方法
237
-
238
- ### 5.2 converter 日志命中 → `alidocs/lippi-aitable-data-sync`
239
-
240
- **职责**:钉钉表格解析,包括 meta 信息和行数据解析。
241
-
242
- **核心文件**
243
- - meta解析:src/main/java/com/dingtalk/aitable/datasync/service/impl/SslParseServiceImpl.java的parseSheet方法
244
- - 行数据同步:src/main/java/com/dingtalk/aitable/datasync/service/impl/SslParseServiceImpl.java的syncSheetRecord方法
245
-
246
- **排查要点**:
247
- - 从日志中的函数名 / 错误信息反推对应模块
248
- - 检查 meta 解析逻辑、行数据解析逻辑
249
- - 检查解析出的数据格式是否符合预期
250
- - 确认与 notable 的协议字段是否对齐
251
-
252
- ---
253
-
254
- ## 第 6 步:输出排查结论
255
-
256
- 按以下结构输出排查结论:
257
-
258
- ### 1) 问题定位
259
- - **故障阶段**:
260
- - **故障类型**:
261
-
262
- ### 2) 证据链
263
- - **证据 1**:
264
- - **证据 2**:
265
- - **推断链路**:
266
-
267
- ### 3) 关键日志片段
268
- (粘贴关键日志内容,脱敏敏感信息)
269
-
270
- ### 4) 后续建议
271
- - 是否需要进一步排查:
272
- - 可能需要关注的配置/代码位置:
273
-
274
- ---
275
-
276
- ## 第 7 步:记录排查经验到 MEMORY.md
277
-
278
- 每次排查完成后,先阅读 `MEMORY.md` 当前内容,然后追加本次排查产生的新知识。若本次排查确实没有任何新信息(所有发现均已存在于 `MEMORY.md` 中),在对话中说明"已检查 MEMORY.md,本次无新增内容"即可。
279
-
280
- ### 需要记录的内容
281
-
282
- **FAQ(常见故障模式)**:当本次排查的故障模式具有通用性(非一次性的配置错误或偶发问题)时,按以下格式追加到 `MEMORY.md` 的 FAQ 部分:
283
-
284
- ```markdown
285
- ### <简短标题>
286
- - **现象**:用户看到的表现
287
- - **根因**:日志/代码层面的原因
288
- - **关联日志库**:notable / converter / 两者
289
- - **日志特征**:在哪个日志库中出现什么关键词可命中此问题
290
- ```
291
-
292
- ### 记录原则
293
-
294
- - 只记录**有复用价值**的信息,不记录一次性的、特定于某个 trace 的细节
295
- - 避免重复:追加前先检查 `MEMORY.md` 中是否已有相同或相似的记录
296
- - 保持简洁:每条 FAQ 控制在 4 行以内
297
- - **遵守模板格式**:FAQ 只包含"现象"、"根因"、"关联日志库"、"日志特征"四个字段
298
-
299
- ---
300
-
301
- ## 核心约束
302
-
303
- 以下约束贯穿整个排查流程。
304
-
305
- ### 日志证据优先
306
-
307
- 1. **结论基于日志证据**。排查的核心价值在于用日志事实还原故障链路,而非凭经验猜测。证据不足时,明确指出不足点并提出下一步查询条件或时间范围。
308
- 2. **先完成时间线再给结论**。跳过第 4 步的时间线与故障分类直接给结论,容易遗漏关联问题。
309
-
310
- ### 查询规范
311
-
312
- 3. **时间范围规则**。详见第 1 步。要点:优先使用 `quickTimeRange`;两种方式不可混用;0 命中时按阶梯扩大而非收窄。
313
- 4. **SLS `limit` 上限为 100**。超出时采用"缩小时间范围 + 多次查询"策略获取完整数据。
314
- 5. **查询必须包含 trace**。不含 trace 的宽泛查询会命中大量无关日志,无法定位具体问题。
315
-
316
- ### 日志库覆盖
317
-
318
- 6. **两库必查**。`notable` 和 `converter` 每次排查都要查询,因为数据源同步链路横跨两个服务,仅查部分库容易遗漏跨层问题。
319
-
320
- ### 排查闭环
321
-
322
- 7. **更新 MEMORY.md**(第 7 步)。排查产生的可复用知识需要沉淀,避免重复排查相同问题。
@@ -1,32 +0,0 @@
1
- # 知识库编辑 — 提炼规范
2
-
3
- 你负责把「管理员的权威结论」提炼成一条规范、可检索的知识库 FAQ 条目。你的输出会被【原样追加】到本地知识库(wiki 源),供后续答疑检索。
4
-
5
- ## 唯一输出:要追加的结论正文
6
-
7
- 只输出要追加到知识库的 **Markdown 结论正文本身**,形如:
8
-
9
- ```
10
- ## 问题标题
11
-
12
- 答案正文
13
- ```
14
-
15
- - **不要**输出目标文件名(写哪个文件由系统决定)。
16
- - **不要**输出 JSON、不要任何前后缀说明(如"以下是提炼结果:")、不要用代码块包裹整体输出。
17
- - 你输出的全部内容都会被追加进知识库,请确保它就是干净的 FAQ 小节。
18
-
19
- ## 提炼铁律
20
-
21
- 1. **忠实管理员结论**:事实、结论、参数、路径一律以管理员给出的内容为准。管理员没提到的**不要补充**,不要用通用知识兜底、不臆造。
22
- 2. **问题标题化**:用 `## ` 起一行简洁的问题标题(尽量贴合用户会怎么搜),能覆盖原始问题的意图。
23
- 3. **答案精炼可检索**:正文用简洁陈述句/有序步骤给出结论;保留关键信息(参数上限、版本要求、前置条件、不可逆警告、在线来源链接);删除寒暄、客套、复述。
24
- 4. **来源链接**:管理员结论里若含在线链接(`https://...`),在正文末尾附 `> 来源:<url>`;无则省略。禁止写入本地 `.md` 路径。
25
-
26
- ## 输出示例
27
-
28
- ## 单个多维表最多支持多少行?
29
-
30
- AI 表格单表最多支持 20 万行,超出需拆分为多张表。
31
-
32
- > 来源:https://example.com/limits
@@ -1,30 +0,0 @@
1
- import path from "node:path";
2
- import process from "node:process";
3
- import { fileURLToPath } from "node:url";
4
- import { assembleProfile } from "./assemble.js";
5
-
6
- /**
7
- * profile 装配 CLI(模板内工具,tsx 运行)
8
- *
9
- * npm run assemble → 校验 + 写盘(persona.md / owner-map.json / role kb_collections)
10
- * npm run check → 仅严格校验(preflight,不写盘);有 error 退出码 1
11
- */
12
- const HERE = path.dirname(fileURLToPath(import.meta.url));
13
- const CONFIG_DIR = path.resolve(HERE, "..");
14
- const checkOnly = process.argv.includes("--check");
15
-
16
- const { issues, wrote } = assembleProfile(CONFIG_DIR, { dryRun: checkOnly });
17
-
18
- for (const i of issues) {
19
- console.log(`${i.level === "error" ? "✗" : "⚠"} [${i.level}] ${i.message}`);
20
- }
21
- for (const w of wrote) {
22
- console.log(`✓ 已更新 ${path.relative(CONFIG_DIR, w)}`);
23
- }
24
-
25
- const errors = issues.filter((i) => i.level === "error").length;
26
- if (errors > 0) {
27
- console.log(`\nprofile ${checkOnly ? "校验" : "装配"}失败:${errors} 个错误(未产出任何文件)`);
28
- process.exit(1);
29
- }
30
- console.log(`\nprofile ${checkOnly ? "校验通过" : `装配完成(${wrote.length} 个文件更新)`}`);
@@ -1,279 +0,0 @@
1
- import { existsSync, readFileSync, mkdirSync, writeFileSync } from "node:fs";
2
- import path from "node:path";
3
- import { parse as parseYaml } from "yaml";
4
- import { SUPPORT_ACTIONS, KB_STATUS, KB_STATUS_VALUES } from "./contract.js";
5
- import { loadFastpathRules } from "./fastpath.js";
6
- import { isTroubleshootEnabled, loadClassifiers } from "./troubleshoot.js";
7
-
8
- /**
9
- * 最小 profile 装配器(场景层,零 core 依赖)
10
- *
11
- * profile v2 重构后职责收敛:
12
- * 1. roles.support.persona → 读取并写入 workspaces/support/persona.md
13
- * (AGENTS.md 基座第一段声明"人设以本目录 persona.md 为准");
14
- * 2. preflight:group-qa 处置动作/知识沉淀 options 与 lib/contract.ts 常量强校验,
15
- * admin-kb-update 事件过滤校验,on_action policies 键/值闭集校验(action ⊆
16
- * SUPPORT_ACTIONS,group ∈ answer|silent,Owner 尾注由轴2派生不在此配),
17
- * L3 fastpath/troubleshoot 预检。
18
- *
19
- * 已删除的职责:
20
- * - escalation → owner-map/contacts.json 编译与校验:模块→Owner 映射已迁入 AI 表格
21
- * 「功能模块人员配置表」,由 config-sync 拉取并发布 ${globalVar.module_owners},
22
- * 同时物化 workspaces/support/owner-map.json 供 answer Agent 的 module 闭集提示;
23
- * - role.yml kb_collections 同步(roles 已内联进 profile.yml);
24
- * - admin-kb-update source-range 回写(由 ${roles.*} 内部引用 + 注入取代)。
25
- *
26
- * 两阶段执行:
27
- * 阶段一 全量校验 + 生成写盘计划(任一 error → 不写任何文件,杜绝半成品);
28
- * 阶段二 按计划一次性写盘(内容不变不写,幂等)。
29
- */
30
-
31
- export type AssembleIssue = { level: "error" | "warn"; message: string };
32
- export type AssembleResult = { issues: AssembleIssue[]; wrote: string[] };
33
-
34
- const WORKSPACE_DIR = path.join("workspaces", "support");
35
- const GENERATED_HEADER = "<!-- 由 lib/assemble.ts 依据 profile/profile.yml 生成,勿手改;改 profile 后重跑 npm run assemble -->";
36
-
37
- type WritePlanEntry = { file: string; content: string };
38
-
39
- function readRawProfile(configDir: string, issues: AssembleIssue[]): Record<string, unknown> | null {
40
- const file = path.resolve(configDir, "profile", "profile.yml");
41
- if (!existsSync(file)) {
42
- issues.push({ level: "error", message: `profile/profile.yml 不存在: ${file}` });
43
- return null;
44
- }
45
- try {
46
- const raw = (parseYaml(readFileSync(file, "utf8")) ?? {}) as Record<string, unknown>;
47
- if (raw.schema_version !== 2) {
48
- issues.push({ level: "error", message: `profile.yml schema_version 必须为 2(当前: ${raw.schema_version ?? "缺失"})。请按迁移指引升级。` });
49
- return null;
50
- }
51
- return raw;
52
- } catch (err) {
53
- issues.push({ level: "error", message: `profile/profile.yml 解析失败: ${err instanceof Error ? err.message : String(err)}` });
54
- return null;
55
- }
56
- }
57
-
58
- /** 相对 profile 目录解析引用文件;不存在则记 error 并返回 null */
59
- function resolveRef(configDir: string, rel: string, label: string, issues: AssembleIssue[]): string | null {
60
- const abs = path.resolve(configDir, "profile", rel);
61
- if (!existsSync(abs)) {
62
- issues.push({ level: "error", message: `${label} 引用的文件不存在: profile/${rel}` });
63
- return null;
64
- }
65
- return abs;
66
- }
67
-
68
- /** collections 校验:trim、去空、必须是不含 .. 的相对路径、目录须存在 */
69
- function validateCollections(configDir: string, raw: unknown, issues: AssembleIssue[]): string[] {
70
- const list = Array.isArray(raw)
71
- ? raw.map((c) =>
72
- typeof c === "string" ? c.trim()
73
- : c && typeof c === "object" && "collection" in c ? String((c as { collection: string }).collection).trim()
74
- : String(c ?? "").trim())
75
- : [];
76
- if (list.length === 0 || list.some((c) => !c)) {
77
- issues.push({ level: "error", message: "roles.support.knowledge_scope.kb_collections 缺失、为空或含空字符串(必填)" });
78
- }
79
- const collections = list.filter(Boolean);
80
- for (const c of collections) {
81
- if (path.isAbsolute(c) || c.split(/[\\/]/).includes("..")) {
82
- issues.push({ level: "error", message: `kb_collections 必须是实例内的相对路径(不含 ..): ${c}` });
83
- continue;
84
- }
85
- if (!existsSync(path.resolve(configDir, c))) {
86
- issues.push({ level: "error", message: `kb_collections 目录不存在: ${c}` });
87
- }
88
- }
89
- return collections;
90
- }
91
-
92
- /** 集合严格相等比较 */
93
- function diffSets(actual: string[], expected: readonly string[]): { missing: string[]; extra: string[] } {
94
- const a = new Set(actual);
95
- const e = new Set(expected);
96
- return { missing: expected.filter((v) => !a.has(v)), extra: actual.filter((v) => !e.has(v)) };
97
- }
98
-
99
- function getIn(obj: unknown, ...keys: string[]): unknown {
100
- let current = obj;
101
- for (const key of keys) {
102
- if (!current || typeof current !== "object") return undefined;
103
- current = (current as Record<string, unknown>)[key];
104
- }
105
- return current;
106
- }
107
-
108
- export function assembleProfile(configDir: string, opts: { dryRun?: boolean } = {}): AssembleResult {
109
- const issues: AssembleIssue[] = [];
110
- const plan: WritePlanEntry[] = [];
111
- const wrote: string[] = [];
112
-
113
- // ─── 阶段一:全量校验 + 生成写盘计划 ───
114
- const raw = readRawProfile(configDir, issues);
115
- if (!raw) return { issues, wrote };
116
-
117
- const roles = (raw.roles ?? {}) as Record<string, Record<string, unknown>>;
118
- const workflows = (raw.workflows ?? {}) as Record<string, Record<string, unknown>>;
119
- const supportRole = roles.support;
120
- const groupQaWf = workflows["group-qa"];
121
-
122
- // basic validation
123
- const roleName = typeof supportRole?.name === "string" ? supportRole.name.trim() : "";
124
- if (!roleName) issues.push({ level: "error", message: "roles.support.name 缺失(必填)" });
125
- const kbScope = supportRole?.knowledge_scope as Record<string, unknown> | undefined;
126
- validateCollections(configDir, kbScope?.kb_collections, issues);
127
-
128
- // 1) persona.md — 读 roles.support.persona(file 引用或内联字符串)
129
- const personaField = supportRole?.persona;
130
- let personaText = "";
131
- if (typeof personaField === "string") {
132
- personaText = `${GENERATED_HEADER}\n\n${personaField.trim()}`;
133
- } else if (personaField && typeof personaField === "object" && "file" in personaField) {
134
- const fileRel = String((personaField as { file: string }).file ?? "").trim();
135
- if (!fileRel) {
136
- issues.push({ level: "error", message: "roles.support.persona.file 为空" });
137
- } else {
138
- const abs = resolveRef(configDir, fileRel, "roles.support.persona.file", issues);
139
- if (abs) {
140
- const content = readFileSync(abs, "utf8").trim();
141
- if (!content) {
142
- issues.push({ level: "error", message: `roles.support.persona.file 文件内容为空: profile/${fileRel}` });
143
- }
144
- personaText = `${GENERATED_HEADER}\n\n${content}`;
145
- }
146
- }
147
- } else if (supportRole) {
148
- issues.push({ level: "error", message: "roles.support.persona 缺失(必填)" });
149
- }
150
- if (personaText) {
151
- if (/忽略(上述|以上|通用)|必须回复所有|无据也(可以|要)回答|不用静默/.test(personaText)) {
152
- issues.push({ level: "error", message: "persona 内容疑似放开通用闸门(只准收紧,不准放开),请修改后重试" });
153
- }
154
- plan.push({ file: path.resolve(configDir, WORKSPACE_DIR, "persona.md"), content: personaText });
155
- }
156
-
157
- // 2) escalation 已迁移:模块→Owner 映射改由 config-sync 从「功能模块人员配置表」拉取,
158
- // 装配期不再编译/校验 owner-map×contacts(模块合法性由运行期快照判定)。
159
-
160
- // 2b) on_action policies 闭集校验(读 workflows.group-qa.steps.on_action.policies):
161
- // 键必须 ⊆ SUPPORT_ACTIONS;group 只允许 answer / silent——group 只表达「群里说不说话」(轴1),
162
- // Owner 指引由 Runtime 按「action 需要找人 + Owner 可解析」派生(轴2),不存在「通知 Owner」档位。
163
- const onActionStep = getIn(groupQaWf, "steps", "on_action") as Record<string, unknown> | undefined;
164
- const policiesRaw = onActionStep?.policies;
165
- if (policiesRaw && typeof policiesRaw === "object") {
166
- const configuredActions = Object.keys(policiesRaw);
167
- const { extra } = diffSets(configuredActions, SUPPORT_ACTIONS);
168
- if (extra.length > 0) {
169
- issues.push({ level: "error", message: `on_action.policies 含未知 action [${extra.join(",")}],合法值: [${SUPPORT_ACTIONS.join(",")}]` });
170
- }
171
- for (const [actionName, cfg] of Object.entries(policiesRaw as Record<string, { group?: unknown }>)) {
172
- const group = cfg && typeof cfg === "object" ? cfg.group : undefined;
173
- if (group === undefined) continue;
174
- if (group !== "answer" && group !== "silent") {
175
- issues.push({ level: "error", message: `on_action.policies.${actionName}.group 只能是 answer / silent(Owner 尾注不在 group 里配,由 Runtime 按 action 与 Owner 解析结果派生),实际: ${JSON.stringify(group)}` });
176
- }
177
- }
178
- }
179
- // 旧 on_silence 步配置仍存在 → 提醒迁移(拍平 action 后该步已改名 on_action)
180
- if (getIn(groupQaWf, "steps", "on_silence")) {
181
- issues.push({ level: "warn", message: "workflows.group-qa.steps.on_silence 已废弃(拍平 action 后步为 on_action):请迁移为 steps.on_action.policies(track/group)" });
182
- }
183
-
184
- // 3) group-qa preflight:处置动作/知识沉淀 options 与 contract 常量强校验
185
- const groupQaFile = path.resolve(configDir, "workflows", "group-qa", "workflow.yml");
186
- if (existsSync(groupQaFile)) {
187
- try {
188
- const wf = (parseYaml(readFileSync(groupQaFile, "utf8")) ?? {}) as Record<string, any>;
189
- const defs = Array.isArray(wf?.tracker?.field_definitions) ? wf.tracker.field_definitions : [];
190
- for (const [fieldName, expected] of [
191
- ["处置动作", SUPPORT_ACTIONS],
192
- ["知识沉淀", KB_STATUS_VALUES],
193
- ] as const) {
194
- const matched = defs.filter((d: any) => d?.name === fieldName);
195
- if (matched.length !== 1) {
196
- issues.push({ level: "error", message: `group-qa field_definitions 中「${fieldName}」字段必须恰好 1 个,实际 ${matched.length} 个` });
197
- continue;
198
- }
199
- const options = Array.isArray(matched[0]?.options) ? matched[0].options.map((o: any) => String(o)) : [];
200
- const { missing, extra } = diffSets(options, expected);
201
- if (missing.length > 0 || extra.length > 0) {
202
- issues.push({ level: "error", message: `group-qa「${fieldName}」options 与 lib/contract.ts 不一致:缺[${missing.join(",")}] 多[${extra.join(",")}]` });
203
- }
204
- }
205
- } catch (err) {
206
- issues.push({ level: "error", message: `workflows/group-qa/workflow.yml 解析失败: ${err instanceof Error ? err.message : String(err)}` });
207
- }
208
- }
209
-
210
- // 4) admin-kb-update filter preflight(从 profile v2 读取)
211
- const adminKbWf = workflows["admin-kb-update"];
212
- if (adminKbWf) {
213
- const esConfig = getIn(adminKbWf, "event_sources", "管理员更新监听") as Record<string, unknown> | undefined;
214
- const filterEquals = typeof esConfig?.filter === "object" && esConfig.filter
215
- ? String((esConfig.filter as Record<string, unknown>).equals ?? "")
216
- : "";
217
- if (filterEquals && filterEquals !== KB_STATUS.READY_TO_PERSIST) {
218
- issues.push({ level: "error", message: `admin-kb-update 事件过滤 filter.equals="${filterEquals}" 必须为 "${KB_STATUS.READY_TO_PERSIST}"(否则知识更新轨道不拉单)` });
219
- }
220
- }
221
-
222
- // 6) L3 fastpath 规则预检(warn:运行期缺失即优雅关闭,不阻断 L0 主环)
223
- const fastpathStep = getIn(groupQaWf, "steps", "fastpath") as Record<string, unknown> | undefined;
224
- const fastpathRel = typeof fastpathStep?.rules === "string" ? fastpathStep.rules.trim() : "";
225
- if (fastpathRel) {
226
- const { issues: fpIssues } = loadFastpathRules(configDir, fastpathRel);
227
- for (const msg of fpIssues) issues.push({ level: "warn", message: `fastpath: ${msg}` });
228
- }
229
-
230
- // 7) L3 troubleshoot 预检(warn:整档可选且运行期缺失即优雅关闭)
231
- const troubleshootStep = getIn(groupQaWf, "steps", "troubleshoot") as Record<string, unknown> | undefined;
232
- const skillsDirRel = typeof troubleshootStep?.skills_dir === "string" ? troubleshootStep.skills_dir.trim() : "";
233
- if (skillsDirRel && !isTroubleshootEnabled(configDir, skillsDirRel)) {
234
- issues.push({ level: "warn", message: `troubleshoot: skills_dir 目录不存在,整档将关闭: ${skillsDirRel}` });
235
- }
236
- const classifiersRel = typeof troubleshootStep?.classifiers === "string" ? troubleshootStep.classifiers.trim() : "";
237
- if (classifiersRel) {
238
- const { issues: tsIssues } = loadClassifiers(configDir, classifiersRel);
239
- for (const msg of tsIssues) issues.push({ level: "warn", message: `troubleshoot: ${msg}` });
240
- // classifier.module 合法性不再在装配期交叉校验:模块闭集来自功能模块人员配置表
241
- // (config-sync 运行期快照),拼写不匹配时运行期降级并记 owner_resolution_failed。
242
- }
243
-
244
- // ─── 阶段二:全过才写盘;任一 error 或 dryRun → 零写盘 ───
245
- const hasError = issues.some((i) => i.level === "error");
246
- if (opts.dryRun || hasError) return { issues, wrote };
247
-
248
- for (const entry of plan) {
249
- try {
250
- const prev = existsSync(entry.file) ? readFileSync(entry.file, "utf8") : null;
251
- if (prev === entry.content) continue;
252
- mkdirSync(path.dirname(entry.file), { recursive: true });
253
- writeFileSync(entry.file, entry.content, "utf8");
254
- wrote.push(entry.file);
255
- } catch (err) {
256
- issues.push({ level: "error", message: `写盘失败 ${path.relative(configDir, entry.file)}: ${err instanceof Error ? err.message : String(err)}` });
257
- }
258
- }
259
-
260
- return { issues, wrote };
261
- }
262
-
263
- // ─── 运行时兜底:进程内每 configDir 只装配一次,结果缓存供调用方决策 ───
264
- const assembledResults = new Map<string, AssembleResult>();
265
-
266
- export function ensureAssembled(configDir: string, log: (msg: string) => void): AssembleResult {
267
- const cached = assembledResults.get(configDir);
268
- if (cached) return cached;
269
- let result: AssembleResult;
270
- try {
271
- result = assembleProfile(configDir);
272
- } catch (err) {
273
- result = { issues: [{ level: "error", message: `装配异常: ${err instanceof Error ? err.message : String(err)}` }], wrote: [] };
274
- }
275
- assembledResults.set(configDir, result);
276
- for (const i of result.issues) log(`[profile-assemble][${i.level}] ${i.message}`);
277
- if (result.wrote.length > 0) log(`[profile-assemble] 已更新: ${result.wrote.map((w) => path.relative(configDir, w)).join(", ")}`);
278
- return result;
279
- }