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.
- package/package.json +3 -3
- package/templates/support-qa/lib/__tests__/declarative-matcher.test.ts +240 -0
- package/templates/support-qa/lib/__tests__/dingtalk-group-membership.test.ts +127 -0
- package/templates/support-qa/lib/__tests__/memory-events.test.ts +90 -0
- package/templates/support-qa/lib/action-dispatch.ts +1 -1
- package/templates/support-qa/lib/declarative-matcher.ts +398 -0
- package/templates/support-qa/lib/dingtalk-group-membership.ts +151 -0
- package/templates/support-qa/lib/guards.ts +18 -0
- package/templates/support-qa/lib/memory-events.ts +60 -41
- package/templates/support-qa/lib/preflight.ts +294 -0
- package/templates/support-qa/package.json +2 -4
- package/templates/support-qa/profiles/aitable/profile/fastpath/known-answers.yml +1 -1
- package/templates/support-qa/profiles/aitable/profile/troubleshoot/classifiers.yml +1 -1
- package/templates/support-qa/workflows/config-sync/recipes/config_sync.recipe.ts +10 -8
- package/templates/support-qa/workflows/daily-review/recipes/daily_review.recipe.ts +1 -1
- package/templates/support-qa/workflows/group-qa/recipes/answer.recipe.ts +2 -7
- package/templates/support-qa/workflows/group-qa/recipes/conversation_handler.recipe.ts +3 -3
- package/templates/support-qa/workflows/group-qa/recipes/fastpath.recipe.ts +5 -11
- package/templates/support-qa/workflows/group-qa/recipes/on-action.recipe.ts +4 -2
- package/templates/support-qa/workflows/group-qa/recipes/reply-to-group.recipe.ts +13 -7
- package/templates/support-qa/workflows/group-qa/recipes/troubleshoot.recipe.ts +12 -18
- package/templates/support-qa/workspaces/support/AGENTS.md +1 -1
- package/templates/aitable-handoff/.env.example +0 -17
- package/templates/aitable-handoff/aitable-workflow.config.yml +0 -64
- package/templates/aitable-handoff/coding-agents.config.json +0 -17
- package/templates/aitable-handoff/npmrc +0 -1
- package/templates/aitable-handoff/package.json +0 -16
- package/templates/aitable-handoff/roles/config-syncer.role.yml +0 -4
- package/templates/aitable-handoff/roles/daily-review.role.yml +0 -4
- package/templates/aitable-handoff/roles/faq-support.role.yml +0 -9
- package/templates/aitable-handoff/roles/faq-troubleshooter.role.yml +0 -17
- package/templates/aitable-handoff/roles/kb-editor.role.yml +0 -19
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- package/templates/aitable-handoff/wiki/faq-support//351/222/211/351/222/211AI/350/241/250/346/240/274FAQ.md +0 -611
- package/templates/aitable-handoff/workflows/admin-kb-update/recipes/kb-refine.recipe.ts +0 -131
- package/templates/aitable-handoff/workflows/admin-kb-update/recipes/kb_sync_handler.recipe.ts +0 -130
- package/templates/aitable-handoff/workflows/admin-kb-update/workflow.yml +0 -125
- package/templates/aitable-handoff/workflows/config-sync/recipes/config_sync.recipe.ts +0 -448
- package/templates/aitable-handoff/workflows/config-sync/recipes/config_sync_handler.recipe.ts +0 -16
- package/templates/aitable-handoff/workflows/config-sync/workflow.yml +0 -73
- package/templates/aitable-handoff/workflows/daily-review/recipes/daily_review.recipe.ts +0 -529
- package/templates/aitable-handoff/workflows/daily-review/recipes/daily_review_handler.recipe.ts +0 -26
- package/templates/aitable-handoff/workflows/daily-review/recipes/memory-events.ts +0 -56
- package/templates/aitable-handoff/workflows/daily-review/workflow.yml +0 -92
- package/templates/aitable-handoff/workflows/group-qa/error-replies.json +0 -53
- package/templates/aitable-handoff/workflows/group-qa/recipes/answer.recipe.ts +0 -197
- package/templates/aitable-handoff/workflows/group-qa/recipes/conversation_handler.recipe.ts +0 -294
- package/templates/aitable-handoff/workflows/group-qa/recipes/issue-classifier.ts +0 -120
- package/templates/aitable-handoff/workflows/group-qa/recipes/known-error-match.recipe.ts +0 -75
- package/templates/aitable-handoff/workflows/group-qa/recipes/memory-events.ts +0 -55
- package/templates/aitable-handoff/workflows/group-qa/recipes/reply-to-group.recipe.ts +0 -132
- package/templates/aitable-handoff/workflows/group-qa/recipes/troubleshoot-issue.recipe.ts +0 -195
- package/templates/aitable-handoff/workflows/group-qa/workflow.yml +0 -210
- package/templates/aitable-handoff/workspaces/daily-review/AGENTS.md +0 -189
- package/templates/aitable-handoff/workspaces/faq-support/AGENTS.md +0 -448
- package/templates/aitable-handoff/workspaces/faq-support/contacts.json +0 -14
- package/templates/aitable-handoff/workspaces/faq-support/owner-map.json +0 -18
- package/templates/aitable-handoff/workspaces/faq-support/skills/bug-triage/SKILL.md +0 -130
- package/templates/aitable-handoff/workspaces/faq-troubleshooter/AGENTS.md +0 -53
- package/templates/aitable-handoff/workspaces/faq-troubleshooter/skills/troubleshooting/SKILL.md +0 -58
- package/templates/aitable-handoff/workspaces/faq-troubleshooter/skills/troubleshooting/aitable-import-troubleshooter/SKILL.md +0 -485
- package/templates/aitable-handoff/workspaces/faq-troubleshooter/skills/troubleshooting/aitable-openapi-troubleshooter/SKILL.md +0 -183
- package/templates/aitable-handoff/workspaces/faq-troubleshooter/skills/troubleshooting/import-openapi-e2e-troubleshooter/SKILL.md +0 -459
- package/templates/aitable-handoff/workspaces/faq-troubleshooter/skills/troubleshooting/notable-datasource-troubleshooter/SKILL.md +0 -1286
- package/templates/aitable-handoff/workspaces/faq-troubleshooter/skills/troubleshooting/notable-field-troubleshooter/SKILL.md +0 -673
- package/templates/aitable-handoff/workspaces/faq-troubleshooter/skills/troubleshooting/spreadsheet-datasync-troubleshooter/SKILL.md +0 -322
- package/templates/aitable-handoff/workspaces/kb-editor/AGENTS.md +0 -32
- package/templates/support-qa/lib/assemble-cli.ts +0 -30
- package/templates/support-qa/lib/assemble.ts +0 -279
- package/templates/support-qa/lib/echo-guard.ts +0 -50
- package/templates/support-qa/lib/fastpath.ts +0 -227
- package/templates/support-qa/lib/owner-mention.ts +0 -140
- package/templates/support-qa/lib/profile-guard.ts +0 -55
- package/templates/support-qa/lib/send-failure-guard.ts +0 -59
- 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
|
-
}
|