[{"data":1,"prerenderedAt":7867},["ShallowReactive",2],{"published-article-paths":3,"search-navigation":348,"\u002Fzh\u002Farticle\u002Fself-hosting-buzz-as-the-workspace-where-ai-agents-become-colleagues":421,"\u002Fzh\u002Farticle\u002Fself-hosting-buzz-as-the-workspace-where-ai-agents-become-colleagues-surround":2717},[4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62,64,66,68,70,72,74,76,78,80,82,84,86,88,90,92,94,96,98,100,102,104,106,108,110,112,114,116,118,120,122,124,126,128,130,132,134,136,138,140,142,144,146,148,150,152,154,156,158,160,162,164,166,168,170,172,174,176,178,180,182,184,186,188,190,192,194,196,198,200,202,204,206,208,210,212,214,216,218,220,222,224,226,228,230,232,234,236,238,240,242,244,246,248,250,252,254,256,258,260,262,264,266,268,270,272,274,276,278,280,282,284,286,288,290,292,294,296,298,300,302,304,306,308,310,312,314,316,318,320,322,324,326,328,330,332,334,336,338,340,342,344,346],{"path":5},"\u002Fde\u002Farticle\u002Fai-agent-skills-what-they-are-how-to-create-them",{"path":7},"\u002Fde\u002Farticle\u002Fbringing-buzz-to-deepseek-harness",{"path":9},"\u002Fde\u002Farticle\u002Fcentralised-the-skills-for-agents",{"path":11},"\u002Fde\u002Farticle\u002Fexposing-hermes-agent-to-private-network-using-cloudflare-warp",{"path":13},"\u002Fde\u002Farticle\u002Fhow-ai-agent-skills-replace-nuxt-app-scaffolding-scripts",{"path":15},"\u002Fde\u002Farticle\u002Fhow-to-setup-hermes-on-remote-server",{"path":17},"\u002Fde\u002Farticle\u002Fself-hosted-travel-planner-trek",{"path":19},"\u002Fde\u002Farticle\u002Fself-hosting-buzz-as-the-workspace-where-ai-agents-become-colleagues",{"path":21},"\u002Fde\u002Farticle\u002Fsetup-antigravity-2",{"path":23},"\u002Fde\u002Farticle\u002Fsetup-netsuite-mcp-on-chatgpt-claude",{"path":25},"\u002Fde\u002Farticle\u002Fswitch-between-multiple-cloudflare-warp-orgs-on-mac",{"path":27},"\u002Fde\u002Farticle\u002Fsync-obsidian-across-devices",{"path":29},"\u002Fde\u002Farticle\u002Ftesting-claude-fable-5-in-financial-analysis",{"path":31},"\u002Fde\u002Farticle\u002Fuse-browser-and-scheduler-in-antigravity-2",{"path":33},"\u002Fde\u002Farticle\u002Fuse-cloudflare-as-ai-memory",{"path":35},"\u002Fde\u002Farticle\u002Fwhat-can-we-do-with-antigravity-2",{"path":37},"\u002Fen\u002Farticle\u002Fai-agent-skills-what-they-are-how-to-create-them",{"path":39},"\u002Fen\u002Farticle\u002Fbringing-buzz-to-deepseek-harness",{"path":41},"\u002Fen\u002Farticle\u002Fcentralised-the-skills-for-agents",{"path":43},"\u002Fen\u002Farticle\u002Fexposing-hermes-agent-to-private-network-using-cloudflare-warp",{"path":45},"\u002Fen\u002Farticle\u002Fhow-ai-agent-skills-replace-nuxt-app-scaffolding-scripts",{"path":47},"\u002Fen\u002Farticle\u002Fhow-to-secure-nodewarden-at-cloudflare",{"path":49},"\u002Fen\u002Farticle\u002Fhow-to-setup-hermes-on-remote-server",{"path":51},"\u002Fen\u002Farticle\u002Fself-hosted-travel-planner-trek",{"path":53},"\u002Fen\u002Farticle\u002Fself-hosting-buzz-as-the-workspace-where-ai-agents-become-colleagues",{"path":55},"\u002Fen\u002Farticle\u002Fself-hosting-nodewarden-at-cloudflare",{"path":57},"\u002Fen\u002Farticle\u002Fsetup-antigravity-2",{"path":59},"\u002Fen\u002Farticle\u002Fsetup-netsuite-mcp-on-chatgpt-claude",{"path":61},"\u002Fen\u002Farticle\u002Fswitch-between-multiple-cloudflare-warp-orgs-on-mac",{"path":63},"\u002Fen\u002Farticle\u002Fsync-obsidian-across-devices",{"path":65},"\u002Fen\u002Farticle\u002Ftesting-claude-fable-5-in-financial-analysis",{"path":67},"\u002Fen\u002Farticle\u002Fuse-browser-and-scheduler-in-antigravity-2",{"path":69},"\u002Fen\u002Farticle\u002Fuse-cloudflare-as-ai-memory",{"path":71},"\u002Fen\u002Farticle\u002Fwhat-can-we-do-with-antigravity-2",{"path":73},"\u002Fes\u002Farticle\u002Fai-agent-skills-what-they-are-how-to-create-them",{"path":75},"\u002Fes\u002Farticle\u002Fbringing-buzz-to-deepseek-harness",{"path":77},"\u002Fes\u002Farticle\u002Fcentralised-the-skills-for-agents",{"path":79},"\u002Fes\u002Farticle\u002Fexposing-hermes-agent-to-private-network-using-cloudflare-warp",{"path":81},"\u002Fes\u002Farticle\u002Fhow-ai-agent-skills-replace-nuxt-app-scaffolding-scripts",{"path":83},"\u002Fes\u002Farticle\u002Fhow-to-secure-nodewarden-at-cloudflare",{"path":85},"\u002Fes\u002Farticle\u002Fhow-to-setup-hermes-on-remote-server",{"path":87},"\u002Fes\u002Farticle\u002Fself-hosted-travel-planner-trek",{"path":89},"\u002Fes\u002Farticle\u002Fself-hosting-buzz-as-the-workspace-where-ai-agents-become-colleagues",{"path":91},"\u002Fes\u002Farticle\u002Fself-hosting-nodewarden-at-cloudflare",{"path":93},"\u002Fes\u002Farticle\u002Fsetup-antigravity-2",{"path":95},"\u002Fes\u002Farticle\u002Fsetup-netsuite-mcp-on-chatgpt-claude",{"path":97},"\u002Fes\u002Farticle\u002Fswitch-between-multiple-cloudflare-warp-orgs-on-mac",{"path":99},"\u002Fes\u002Farticle\u002Fsync-obsidian-across-devices",{"path":101},"\u002Fes\u002Farticle\u002Ftesting-claude-fable-5-in-financial-analysis",{"path":103},"\u002Fes\u002Farticle\u002Fuse-browser-and-scheduler-in-antigravity-2",{"path":105},"\u002Fes\u002Farticle\u002Fuse-cloudflare-as-ai-memory",{"path":107},"\u002Fes\u002Farticle\u002Fwhat-can-we-do-with-antigravity-2",{"path":109},"\u002Ffr\u002Farticle\u002Fai-agent-skills-what-they-are-how-to-create-them",{"path":111},"\u002Ffr\u002Farticle\u002Fbringing-buzz-to-deepseek-harness",{"path":113},"\u002Ffr\u002Farticle\u002Fcentralised-the-skills-for-agents",{"path":115},"\u002Ffr\u002Farticle\u002Fexposing-hermes-agent-to-private-network-using-cloudflare-warp",{"path":117},"\u002Ffr\u002Farticle\u002Fhow-ai-agent-skills-replace-nuxt-app-scaffolding-scripts",{"path":119},"\u002Ffr\u002Farticle\u002Fhow-to-secure-nodewarden-at-cloudflare",{"path":121},"\u002Ffr\u002Farticle\u002Fhow-to-setup-hermes-on-remote-server",{"path":123},"\u002Ffr\u002Farticle\u002Fself-hosted-travel-planner-trek",{"path":125},"\u002Ffr\u002Farticle\u002Fself-hosting-buzz-as-the-workspace-where-ai-agents-become-colleagues",{"path":127},"\u002Ffr\u002Farticle\u002Fself-hosting-nodewarden-at-cloudflare",{"path":129},"\u002Ffr\u002Farticle\u002Fsetup-antigravity-2",{"path":131},"\u002Ffr\u002Farticle\u002Fsetup-netsuite-mcp-on-chatgpt-claude",{"path":133},"\u002Ffr\u002Farticle\u002Fswitch-between-multiple-cloudflare-warp-orgs-on-mac",{"path":135},"\u002Ffr\u002Farticle\u002Fsync-obsidian-across-devices",{"path":137},"\u002Ffr\u002Farticle\u002Ftesting-claude-fable-5-in-financial-analysis",{"path":139},"\u002Ffr\u002Farticle\u002Fuse-browser-and-scheduler-in-antigravity-2",{"path":141},"\u002Ffr\u002Farticle\u002Fuse-cloudflare-as-ai-memory",{"path":143},"\u002Ffr\u002Farticle\u002Fwhat-can-we-do-with-antigravity-2",{"path":145},"\u002Fid\u002Farticle\u002Fai-agent-skills-what-they-are-how-to-create-them",{"path":147},"\u002Fid\u002Farticle\u002Fbringing-buzz-to-deepseek-harness",{"path":149},"\u002Fid\u002Farticle\u002Fcentralised-the-skills-for-agents",{"path":151},"\u002Fid\u002Farticle\u002Fexposing-hermes-agent-to-private-network-using-cloudflare-warp",{"path":153},"\u002Fid\u002Farticle\u002Fhow-ai-agent-skills-replace-nuxt-app-scaffolding-scripts",{"path":155},"\u002Fid\u002Farticle\u002Fhow-to-secure-nodewarden-at-cloudflare",{"path":157},"\u002Fid\u002Farticle\u002Fhow-to-setup-hermes-on-remote-server",{"path":159},"\u002Fid\u002Farticle\u002Fself-hosted-travel-planner-trek",{"path":161},"\u002Fid\u002Farticle\u002Fself-hosting-buzz-as-the-workspace-where-ai-agents-become-colleagues",{"path":163},"\u002Fid\u002Farticle\u002Fself-hosting-nodewarden-at-cloudflare",{"path":165},"\u002Fid\u002Farticle\u002Fsetup-antigravity-2",{"path":167},"\u002Fid\u002Farticle\u002Fsetup-netsuite-mcp-on-chatgpt-claude",{"path":169},"\u002Fid\u002Farticle\u002Fswitch-between-multiple-cloudflare-warp-orgs-on-mac",{"path":171},"\u002Fid\u002Farticle\u002Fsync-obsidian-across-devices",{"path":173},"\u002Fid\u002Farticle\u002Ftesting-claude-fable-5-in-financial-analysis",{"path":175},"\u002Fid\u002Farticle\u002Fuse-browser-and-scheduler-in-antigravity-2",{"path":177},"\u002Fid\u002Farticle\u002Fuse-cloudflare-as-ai-memory",{"path":179},"\u002Fid\u002Farticle\u002Fwhat-can-we-do-with-antigravity-2",{"path":181},"\u002Fja\u002Farticle\u002Fai-agent-skills-what-they-are-how-to-create-them",{"path":183},"\u002Fja\u002Farticle\u002Fbringing-buzz-to-deepseek-harness",{"path":185},"\u002Fja\u002Farticle\u002Fcentralised-the-skills-for-agents",{"path":187},"\u002Fja\u002Farticle\u002Fexposing-hermes-agent-to-private-network-using-cloudflare-warp",{"path":189},"\u002Fja\u002Farticle\u002Fhow-ai-agent-skills-replace-nuxt-app-scaffolding-scripts",{"path":191},"\u002Fja\u002Farticle\u002Fhow-to-setup-hermes-on-remote-server",{"path":193},"\u002Fja\u002Farticle\u002Fself-hosted-travel-planner-trek",{"path":195},"\u002Fja\u002Farticle\u002Fself-hosting-buzz-as-the-workspace-where-ai-agents-become-colleagues",{"path":197},"\u002Fja\u002Farticle\u002Fsetup-antigravity-2",{"path":199},"\u002Fja\u002Farticle\u002Fsetup-netsuite-mcp-on-chatgpt-claude",{"path":201},"\u002Fja\u002Farticle\u002Fswitch-between-multiple-cloudflare-warp-orgs-on-mac",{"path":203},"\u002Fja\u002Farticle\u002Fsync-obsidian-across-devices",{"path":205},"\u002Fja\u002Farticle\u002Ftesting-claude-fable-5-in-financial-analysis",{"path":207},"\u002Fja\u002Farticle\u002Fuse-browser-and-scheduler-in-antigravity-2",{"path":209},"\u002Fja\u002Farticle\u002Fuse-cloudflare-as-ai-memory",{"path":211},"\u002Fja\u002Farticle\u002Fwhat-can-we-do-with-antigravity-2",{"path":213},"\u002Fpt\u002Farticle\u002Fai-agent-skills-what-they-are-how-to-create-them",{"path":215},"\u002Fpt\u002Farticle\u002Fbringing-buzz-to-deepseek-harness",{"path":217},"\u002Fpt\u002Farticle\u002Fcentralised-the-skills-for-agents",{"path":219},"\u002Fpt\u002Farticle\u002Fexposing-hermes-agent-to-private-network-using-cloudflare-warp",{"path":221},"\u002Fpt\u002Farticle\u002Fhow-ai-agent-skills-replace-nuxt-app-scaffolding-scripts",{"path":223},"\u002Fpt\u002Farticle\u002Fhow-to-secure-nodewarden-at-cloudflare",{"path":225},"\u002Fpt\u002Farticle\u002Fhow-to-setup-hermes-on-remote-server",{"path":227},"\u002Fpt\u002Farticle\u002Fself-hosted-travel-planner-trek",{"path":229},"\u002Fpt\u002Farticle\u002Fself-hosting-buzz-as-the-workspace-where-ai-agents-become-colleagues",{"path":231},"\u002Fpt\u002Farticle\u002Fself-hosting-nodewarden-at-cloudflare",{"path":233},"\u002Fpt\u002Farticle\u002Fsetup-antigravity-2",{"path":235},"\u002Fpt\u002Farticle\u002Fsetup-netsuite-mcp-on-chatgpt-claude",{"path":237},"\u002Fpt\u002Farticle\u002Fswitch-between-multiple-cloudflare-warp-orgs-on-mac",{"path":239},"\u002Fpt\u002Farticle\u002Fsync-obsidian-across-devices",{"path":241},"\u002Fpt\u002Farticle\u002Ftesting-claude-fable-5-in-financial-analysis",{"path":243},"\u002Fpt\u002Farticle\u002Fuse-browser-and-scheduler-in-antigravity-2",{"path":245},"\u002Fpt\u002Farticle\u002Fuse-cloudflare-as-ai-memory",{"path":247},"\u002Fpt\u002Farticle\u002Fwhat-can-we-do-with-antigravity-2",{"path":249},"\u002Ftw\u002Farticle\u002Fai-agent-skills-what-they-are-how-to-create-them",{"path":251},"\u002Ftw\u002Farticle\u002Fbringing-buzz-to-deepseek-harness",{"path":253},"\u002Ftw\u002Farticle\u002Fcentralised-the-skills-for-agents",{"path":255},"\u002Ftw\u002Farticle\u002Fexposing-hermes-agent-to-private-network-using-cloudflare-warp",{"path":257},"\u002Ftw\u002Farticle\u002Fhow-ai-agent-skills-replace-nuxt-app-scaffolding-scripts",{"path":259},"\u002Ftw\u002Farticle\u002Fhow-to-setup-hermes-on-remote-server",{"path":261},"\u002Ftw\u002Farticle\u002Fself-hosted-travel-planner-trek",{"path":263},"\u002Ftw\u002Farticle\u002Fself-hosting-buzz-as-the-workspace-where-ai-agents-become-colleagues",{"path":265},"\u002Ftw\u002Farticle\u002Fsetup-antigravity-2",{"path":267},"\u002Ftw\u002Farticle\u002Fsetup-netsuite-mcp-on-chatgpt-claude",{"path":269},"\u002Ftw\u002Farticle\u002Fswitch-between-multiple-cloudflare-warp-orgs-on-mac",{"path":271},"\u002Ftw\u002Farticle\u002Fsync-obsidian-across-devices",{"path":273},"\u002Ftw\u002Farticle\u002Ftesting-claude-fable-5-in-financial-analysis",{"path":275},"\u002Ftw\u002Farticle\u002Fuse-browser-and-scheduler-in-antigravity-2",{"path":277},"\u002Ftw\u002Farticle\u002Fuse-cloudflare-as-ai-memory",{"path":279},"\u002Ftw\u002Farticle\u002Fwhat-can-we-do-with-antigravity-2",{"path":281},"\u002Fvi\u002Farticle\u002Fai-agent-skills-what-they-are-how-to-create-them",{"path":283},"\u002Fvi\u002Farticle\u002Fbringing-buzz-to-deepseek-harness",{"path":285},"\u002Fvi\u002Farticle\u002Fcentralised-the-skills-for-agents",{"path":287},"\u002Fvi\u002Farticle\u002Fexposing-hermes-agent-to-private-network-using-cloudflare-warp",{"path":289},"\u002Fvi\u002Farticle\u002Fhow-ai-agent-skills-replace-nuxt-app-scaffolding-scripts",{"path":291},"\u002Fvi\u002Farticle\u002Fhow-to-secure-nodewarden-at-cloudflare",{"path":293},"\u002Fvi\u002Farticle\u002Fhow-to-setup-hermes-on-remote-server",{"path":295},"\u002Fvi\u002Farticle\u002Fself-hosted-travel-planner-trek",{"path":297},"\u002Fvi\u002Farticle\u002Fself-hosting-buzz-as-the-workspace-where-ai-agents-become-colleagues",{"path":299},"\u002Fvi\u002Farticle\u002Fself-hosting-nodewarden-at-cloudflare",{"path":301},"\u002Fvi\u002Farticle\u002Fsetup-antigravity-2",{"path":303},"\u002Fvi\u002Farticle\u002Fsetup-netsuite-mcp-on-chatgpt-claude",{"path":305},"\u002Fvi\u002Farticle\u002Fswitch-between-multiple-cloudflare-warp-orgs-on-mac",{"path":307},"\u002Fvi\u002Farticle\u002Fsync-obsidian-across-devices",{"path":309},"\u002Fvi\u002Farticle\u002Ftesting-claude-fable-5-in-financial-analysis",{"path":311},"\u002Fvi\u002Farticle\u002Fuse-browser-and-scheduler-in-antigravity-2",{"path":313},"\u002Fvi\u002Farticle\u002Fuse-cloudflare-as-ai-memory",{"path":315},"\u002Fvi\u002Farticle\u002Fwhat-can-we-do-with-antigravity-2",{"path":317},"\u002Fzh\u002Farticle\u002Fai-agent-skills-what-they-are-how-to-create-them",{"path":319},"\u002Fzh\u002Farticle\u002Fbringing-buzz-to-deepseek-harness",{"path":321},"\u002Fzh\u002Farticle\u002Fcentralised-the-skills-for-agents",{"path":323},"\u002Fzh\u002Farticle\u002Fexposing-hermes-agent-to-private-network-using-cloudflare-warp",{"path":325},"\u002Fzh\u002Farticle\u002Fhow-ai-agent-skills-replace-nuxt-app-scaffolding-scripts",{"path":327},"\u002Fzh\u002Farticle\u002Fhow-to-setup-hermes-on-remote-server",{"path":329},"\u002Fzh\u002Farticle\u002Fself-hosted-travel-planner-trek",{"path":331},"\u002Fzh\u002Farticle\u002Fself-hosting-buzz-as-the-workspace-where-ai-agents-become-colleagues",{"path":333},"\u002Fzh\u002Farticle\u002Fsetup-antigravity-2",{"path":335},"\u002Fzh\u002Farticle\u002Fsetup-netsuite-mcp-on-chatgpt-claude",{"path":337},"\u002Fzh\u002Farticle\u002Fswitch-between-multiple-cloudflare-warp-orgs-on-mac",{"path":339},"\u002Fzh\u002Farticle\u002Fsync-obsidian-across-devices",{"path":341},"\u002Fzh\u002Farticle\u002Ftesting-claude-fable-5-in-financial-analysis",{"path":343},"\u002Fzh\u002Farticle\u002Fuse-browser-and-scheduler-in-antigravity-2",{"path":345},"\u002Fzh\u002Farticle\u002Fuse-cloudflare-as-ai-memory",{"path":347},"\u002Fzh\u002Farticle\u002Fwhat-can-we-do-with-antigravity-2",[349,353,357,361,365,369,373,377,381,385,389,393,397,401,405,409,413,417],{"title":350,"path":351,"stem":352},"AI Agent Skills: What They Are & How to Create Them","\u002Farticle\u002Fai-agent-skills-what-they-are-how-to-create-them","en\u002Farticle\u002Fai-agent-skills-what-they-are-how-to-create-them",{"title":354,"path":355,"stem":356},"Bringing Buzz to DeepSeek Harness: Taught to Speak Nostr","\u002Farticle\u002Fbringing-buzz-to-deepseek-harness","en\u002Farticle\u002Fbringing-buzz-to-deepseek-harness",{"title":358,"path":359,"stem":360},"Solving AI Agent Skills Fragmentation with npx skills","\u002Farticle\u002Fcentralised-the-skills-for-agents","en\u002Farticle\u002Fcentralised-the-skills-for-agents",{"title":362,"path":363,"stem":364},"How to Expose Hermes Agent Privately with Cloudflare WARP","\u002Farticle\u002Fexposing-hermes-agent-to-private-network-using-cloudflare-warp","en\u002Farticle\u002Fexposing-hermes-agent-to-private-network-using-cloudflare-warp",{"title":366,"path":367,"stem":368},"How AI Agent Skills Replace Nuxt App Scaffolding Scripts","\u002Farticle\u002Fhow-ai-agent-skills-replace-nuxt-app-scaffolding-scripts","en\u002Farticle\u002Fhow-ai-agent-skills-replace-nuxt-app-scaffolding-scripts",{"title":370,"path":371,"stem":372},"Stop Exposing Your Vault: Secure NodeWarden with Cloudflare","\u002Farticle\u002Fhow-to-secure-nodewarden-at-cloudflare","en\u002Farticle\u002Fhow-to-secure-nodewarden-at-cloudflare",{"title":374,"path":375,"stem":376},"How to Deploy Hermes Agent on a Linux VPS","\u002Farticle\u002Fhow-to-setup-hermes-on-remote-server","en\u002Farticle\u002Fhow-to-setup-hermes-on-remote-server",{"title":378,"path":379,"stem":380},"Self-Host Your Travel Itineraries with TREK and Docker","\u002Farticle\u002Fself-hosted-travel-planner-trek","en\u002Farticle\u002Fself-hosted-travel-planner-trek",{"title":382,"path":383,"stem":384},"Self-Host Block's Buzz: Shared AI Agent Workspace","\u002Farticle\u002Fself-hosting-buzz-as-the-workspace-where-ai-agents-become-colleagues","en\u002Farticle\u002Fself-hosting-buzz-as-the-workspace-where-ai-agents-become-colleagues",{"title":386,"path":387,"stem":388},"How to Self-Host a BitWarden Compatible Server Nodewarden","\u002Farticle\u002Fself-hosting-nodewarden-at-cloudflare","en\u002Farticle\u002Fself-hosting-nodewarden-at-cloudflare",{"title":390,"path":391,"stem":392},"Google Antigravity 2 Hands-On: Setup & First Impressions","\u002Farticle\u002Fsetup-antigravity-2","en\u002Farticle\u002Fsetup-antigravity-2",{"title":394,"path":395,"stem":396},"NetSuite AI Connector Guide: MCP Setup & Use Cases","\u002Farticle\u002Fsetup-netsuite-mcp-on-chatgpt-claude","en\u002Farticle\u002Fsetup-netsuite-mcp-on-chatgpt-claude",{"title":398,"path":399,"stem":400},"Switch Between Multiple Cloudflare WARP Orgs on Mac","\u002Farticle\u002Fswitch-between-multiple-cloudflare-warp-orgs-on-mac","en\u002Farticle\u002Fswitch-between-multiple-cloudflare-warp-orgs-on-mac",{"title":402,"path":403,"stem":404},"How to Sync Obsidian Vaults Across Devices Securely","\u002Farticle\u002Fsync-obsidian-across-devices","en\u002Farticle\u002Fsync-obsidian-across-devices",{"title":406,"path":407,"stem":408},"Testing Claude Fable 5: A Financial Analysis Review","\u002Farticle\u002Ftesting-claude-fable-5-in-financial-analysis","en\u002Farticle\u002Ftesting-claude-fable-5-in-financial-analysis",{"title":410,"path":411,"stem":412},"Guide to Browser and Scheduler in Antigravity 2","\u002Farticle\u002Fuse-browser-and-scheduler-in-antigravity-2","en\u002Farticle\u002Fuse-browser-and-scheduler-in-antigravity-2",{"title":414,"path":415,"stem":416},"Build a Persistent AI Memory System on Cloudflare","\u002Farticle\u002Fuse-cloudflare-as-ai-memory","en\u002Farticle\u002Fuse-cloudflare-as-ai-memory",{"title":418,"path":419,"stem":420},"Antigravity 2 in Action: AI Agents, Skills, and MCP","\u002Farticle\u002Fwhat-can-we-do-with-antigravity-2","en\u002Farticle\u002Fwhat-can-we-do-with-antigravity-2",{"id":422,"title":423,"author":424,"body":425,"category":2673,"date":2676,"description":2677,"extension":2678,"image":2679,"imageAlt":2680,"isPublished":772,"meta":2681,"minRead":861,"navigation":772,"path":331,"seo":2707,"stem":2709,"tags":2710,"updatedAt":2715,"__hash__":2716},"article\u002Fzh\u002Farticle\u002Fself-hosting-buzz-as-the-workspace-where-ai-agents-become-colleagues.md","自建 Block 旗下 Buzz 协作平台：轻松构建人类与 AI 智能体高效协同工作的全新共享工作空间","",{"type":426,"value":427,"toc":2643},"minimark",[428,432,439,446,451,454,494,498,504,542,546,551,565,573,581,585,590,606,612,663,702,706,715,721,725,728,968,972,1018,1025,1032,1040,1093,1099,1129,1133,1137,1156,1186,1199,1241,1249,1534,1538,1584,1589,1596,1601,1605,1629,1632,1638,1644,1648,1657,1663,1666,1672,1679,1708,1715,1721,1724,1730,1734,1737,1740,1743,1749,1752,1758,1764,1770,1775,1779,1790,1797,1803,1806,1812,1815,1822,1828,1835,1839,1847,1911,1920,1975,1978,2050,2056,2072,2078,2082,2128,2134,2137,2143,2146,2152,2156,2173,2189,2195,2293,2296,2302,2313,2362,2368,2374,2387,2403,2406,2412,2416,2423,2445,2455,2553,2563,2569,2576,2582,2585,2591,2594,2600,2603,2606,2609,2639],[429,430,431],"p",{},"在与多个 AI 智能体（AI Agent）协同工作时，最让人头疼的障碍莫过于“上下文断片化（Context Fragmentation）”。由于对话分散在不同的工具中，您最终不得不扮演起一个“肉肉路由器”的角色——频繁地从 Claude Code 中复制对话并粘贴到 Gemini CLI，然后再从 Gemini CLI 复制并粘贴 to Hermes Agent 中。而当您身边还有人类团队成员一起协作时，这种繁琐的摩擦感更是成倍增长。",[429,433,434],{},[435,436],"img",{"alt":437,"src":438},"Buzz 协作工作空间的用户界面，显示聊天频道和活跃的 AI 智能体","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf-Hosting%20Buzz%20As%20The%20Workspace%20Where%20AI%20Agents%20Become%20Colleagues\u002Fbuzz-workspace-interface.webp",[429,440,441,445],{},[442,443,444],"strong",{},"Buzz"," 是一款开源的协同工作空间，它将人类团队和 AI 智能体凝聚在一个统一的环境中。在这里，人类同事与 AI 智能体能够共享相同的任务和项目历史，并实现天衣无缝的工作交接。",[447,448,450],"h2",{"id":449},"什么是-block-旗下的-buzz人机协同的-ai-智能体共享空间","什么是 Block 旗下的 Buzz？人机协同的 AI 智能体共享空间",[429,452,453],{},"Buzz 是 Block 公司（由推特创始人杰克·多西创立）推出的开源协作工作空间，它让团队成员和 AI 智能体能够在相同的频道与项目中并肩工作。它具有以下几个核心亮点：",[455,456,457,464,470,476,482,488],"ul",{},[458,459,460,463],"li",{},[442,461,462],{},"共享上下文："," 频道是团队成员与智能体开展协作的核心阵地。所有的对话记录和项目历史都完整保留在频道中。",[458,465,466,469],{},[442,467,468],{},"智能体间通信："," 智能体之间能够跨机器直接进行交流。一个 AI 智能体可以 @ 另一个智能体，从而完成工作的转交或代码的交叉审查。",[458,471,472,475],{},[442,473,474],{},"提及驱动激活："," AI 智能体仅在被 @ 提及时才会激活，平时则保持静默。被提及时，智能体将读取频道中的相关上下文并开始工作。",[458,477,478,481],{},[442,479,480],{},"统一身份系统："," 团队成员与 AI 智能体使用同一套身份系统，并通过加密私钥\u002F公钥进行安全认证。",[458,483,484,487],{},[442,485,486],{},"委派命令："," 您可以向人类同事授予指挥您的智能体的权限，让整个团队都能轻松指派和调用彼此的数字助手。",[458,489,490,493],{},[442,491,492],{},"自托管服务器："," 因为您是该服务器的托管者，所以您的数据完全由您掌控。您可以自由决定谁能加入，并定义专属的运行规则。",[447,495,497],{"id":496},"基于-nostr-的加密级-buzz-架构解析","基于 Nostr 的加密级 Buzz 架构解析",[429,499,500],{},[435,501],{"alt":502,"src":503},"基于 Nostr 协议的 Buzz 协作空间加密级架构拓扑图","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf-Hosting%20Buzz%20As%20The%20Workspace%20Where%20AI%20Agents%20Become%20Colleagues\u002Fbuzz-nostr-cryptographic-architecture.webp",[455,505,506,512,518,524,530,536],{},[458,507,508,511],{},[442,509,510],{},"Nostr 中继器充当服务器："," 消息、工作流、代码仓库以及其他事件都经过加密签名和验证，并存储在 Nostr 中继服务器（Relay）上。Nostr 协议原生支持通过 WebSockets 和 REST API 进行通信。",[458,513,514,517],{},[442,515,516],{},"统一加密身份："," 人类和智能体都使用各自的加密密钥进行认证。此身份完全保留在客户端，绝不会存储在服务器上。",[458,519,520,523],{},[442,521,522],{},"一等公民级智能体："," 每个智能体都拥有独立的身份、频道成员资格和审计跟踪（Audit Trail）。智能体使用智能体通信协议（ACP）连接到工作空间。",[458,525,526,529],{},[442,527,528],{},"去中心化 Git 仓库："," 代码库存储在兼容 S3 的对象存储中，而任务、拉取请求（PR）和代码审查则在 Nostr 事件日志中进行追踪。因此，Buzz 的 Git 仓库实际上是托管在 Nostr 中继器上，而非 GitHub。",[458,531,532,535],{},[442,533,534],{},"Buzz 客户端属于 Nostr 客户端："," Buzz 应用与 Nostr 中继器是分离的；它是一个桌面或移动端客户端，负责连接到中继器的 URL 节点。",[458,537,538,541],{},[442,539,540],{},"基础技术栈："," 由 PostgreSQL 数据库处理事件存储与全文检索，Redis 负责管理发布\u002F订阅（Pub\u002FSub）消息队列，而兼容 S3 的 MinIO 用于存储媒体文件。",[447,543,545],{"id":544},"如何在-linux-vps-上部署自托管的-block-旗下-buzz","如何在 Linux VPS 上部署自托管的 Block 旗下 Buzz",[547,548,550],"h3",{"id":549},"_0-prerequisites","0. Prerequisites",[455,552,553,556,559,562],{},[458,554,555],{},"一台 Linux VPS",[458,557,558],{},"域名已指向您的服务器 IP 地址",[458,560,561],{},"Docker 以及 Docker Compose 插件",[458,563,564],{},"Cloudflare 账户（免费服务计划）",[429,566,567,568,572],{},"在本指南中，我们将把 Nostr 中继器部署在 Ubuntu VPS 上，并通过 ",[569,570,571],"a",{"href":363},"教程：使用 Cloudflare WARP 安全地将 Hermes Agent 暴露至私有网络"," 保护其安全。整个基础技术栈包含 Docker Compose 中的四个服务：中继器（relay）、PostgreSQL、Redis 和 MinIO，并使用 Caddy 来提供 HTTPS 支持。",[574,575],"article-card",{"description":576,"image":577,"image-alt":578,"label":579,"min-read":580,"title":571,"to":363},"了解如何利用 Cloudflare WARP 和 Zero Trust（零信任）在不开放入站防火墙端口的情况下，安全地在全球范围内暴露和访问您的 Hermes Agent。","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FExposing%20Hermes%20Agent%20to%20Private%20Network%20Using%20Cloudflare%20WARP\u002FZH-Exposing-Hermes-Agent-to-Private-Network-Using-Cloudflare-WARP.webp","使用 Cloudflare Zero Trust 和 WARP 隧道安全地将 Hermes Agent 暴露到私有网络","相关指南","8",[547,582,584],{"id":583},"_1-cloudflare-dns-与-api-令牌","1. Cloudflare DNS 与 API 令牌",[586,587,589],"h4",{"id":588},"创建-cloudflare-api-令牌token","创建 Cloudflare API 令牌（Token）",[591,592,593,600],"ol",{},[458,594,595,596,599],{},"点击右上角的个人头像，并在下拉菜单中选择 ",[442,597,598],{},"Profile","。",[458,601,602,603,599],{},"点击 ",[442,604,605],{},"API Tokens",[429,607,608],{},[435,609],{"alt":610,"src":611},"Cloudflare 用户个人资料页面，显示 API 令牌创建菜单","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf-Hosting%20Buzz%20As%20The%20Workspace%20Where%20AI%20Agents%20Become%20Colleagues\u002Fcloudflare-profile-api-tokens.webp",[591,613,615,621,627,648,653,657,660],{"start":614},3,[458,616,602,617,620],{},[442,618,619],{},"Create Token"," 按钮。",[458,622,623,624,599],{},"选择使用模板 ",[442,625,626],{},"Edit zone DNS",[458,628,629,630],{},"配置模版如下：\n",[455,631,632,638],{},[458,633,634,637],{},[442,635,636],{},"Permissions",": Zone — DNS — Edit",[458,639,640,643,644],{},[442,641,642],{},"Zone Resources",": Include — Specific zone — ",[645,646,647],"code",{},"example.com",[458,649,602,650,599],{},[442,651,652],{},"Continue to summary",[458,654,602,655,599],{},[442,656,619],{},[458,658,659],{},"拷贝生成的 API 令牌，因为页面关闭后它将不再显示。",[458,661,662],{},"在终端中验证生成的令牌，确保其能正常工作：",[664,665,669],"pre",{"className":666,"code":667,"language":668,"meta":424,"style":424},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","curl \"https:\u002F\u002Fapi.cloudflare.com\u002Fclient\u002Fv4\u002Fuser\u002Ftokens\u002Fverify\" -H \"Authorization: Bearer YOUR_TOKEN_HERE\"\n","bash",[645,670,671],{"__ignoreMap":424},[672,673,676,680,684,688,691,694,696,699],"span",{"class":674,"line":675},"line",1,[672,677,679],{"class":678},"sBMFI","curl",[672,681,683],{"class":682},"sMK4o"," \"",[672,685,687],{"class":686},"sfazB","https:\u002F\u002Fapi.cloudflare.com\u002Fclient\u002Fv4\u002Fuser\u002Ftokens\u002Fverify",[672,689,690],{"class":682},"\"",[672,692,693],{"class":686}," -H",[672,695,683],{"class":682},[672,697,698],{"class":686},"Authorization: Bearer YOUR_TOKEN_HERE",[672,700,701],{"class":682},"\"\n",[586,703,705],{"id":704},"dns-解析记录","DNS 解析记录",[455,707,708],{},[458,709,710,711,714],{},"创建一条 A 记录，并将代理状态设置为 ",[442,712,713],{},"仅限 DNS","（DNS only）。",[429,716,717],{},[435,718],{"alt":719,"src":720},"在 Cloudflare 控制台中配置 Buzz 域名的 DNS A 记录，并将代理状态设置为仅限 DNS","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf-Hosting%20Buzz%20As%20The%20Workspace%20Where%20AI%20Agents%20Become%20Colleagues\u002Fcloudflare-dns-a-record-configuration.webp",[547,722,724],{"id":723},"_2-在-ubuntu-上安装-docker","2. 在 Ubuntu 上安装 Docker",[429,726,727],{},"运行以下命令在 Ubuntu 上安装 Docker：",[664,729,731],{"className":666,"code":730,"language":668,"meta":424,"style":424},"# Add Docker's official GPG key and set up the Docker repository\ncurl -fsSL https:\u002F\u002Fdownload.docker.com\u002Flinux\u002Fubuntu\u002Fgpg | sudo gpg --dearmor -o \u002Fusr\u002Fshare\u002Fkeyrings\u002Fdocker-archive-keyring.gpg\n\n# Add the official Docker repository\necho \"deb [arch=amd64 signed-by=\u002Fusr\u002Fshare\u002Fkeyrings\u002Fdocker-archive-keyring.gpg] https:\u002F\u002Fdownload.docker.com\u002Flinux\u002Fubuntu $(lsb_release -cs) stable\" | sudo tee \u002Fetc\u002Fapt\u002Fsources.list.d\u002Fdocker.list > \u002Fdev\u002Fnull\n\n# Update package list\nsudo apt update\n\n# Install Docker Engine, Docker Community Edition, and containerd runtime\nsudo apt install docker-ce docker-ce-cli containerd.io -y\n\n# Start automatically when the system boots\nsudo systemctl enable docker\n\n# Verify docker is installed\ndocker --version\n\nsudo apt install -y docker-compose-plugin\n\n# Verify the compose plugin is installed\ndocker compose version\n\n",[645,732,733,739,768,774,780,825,830,836,848,853,859,881,886,892,906,911,917,926,931,946,951,957],{"__ignoreMap":424},[672,734,735],{"class":674,"line":675},[672,736,738],{"class":737},"sHwdD","# Add Docker's official GPG key and set up the Docker repository\n",[672,740,742,744,747,750,753,756,759,762,765],{"class":674,"line":741},2,[672,743,679],{"class":678},[672,745,746],{"class":686}," -fsSL",[672,748,749],{"class":686}," https:\u002F\u002Fdownload.docker.com\u002Flinux\u002Fubuntu\u002Fgpg",[672,751,752],{"class":682}," |",[672,754,755],{"class":678}," sudo",[672,757,758],{"class":686}," gpg",[672,760,761],{"class":686}," --dearmor",[672,763,764],{"class":686}," -o",[672,766,767],{"class":686}," \u002Fusr\u002Fshare\u002Fkeyrings\u002Fdocker-archive-keyring.gpg\n",[672,769,770],{"class":674,"line":614},[672,771,773],{"emptyLinePlaceholder":772},true,"\n",[672,775,777],{"class":674,"line":776},4,[672,778,779],{"class":737},"# Add the official Docker repository\n",[672,781,783,787,789,792,795,798,801,804,807,809,811,813,816,819,822],{"class":674,"line":782},5,[672,784,786],{"class":785},"s2Zo4","echo",[672,788,683],{"class":682},[672,790,791],{"class":686},"deb [arch=amd64 signed-by=\u002Fusr\u002Fshare\u002Fkeyrings\u002Fdocker-archive-keyring.gpg] https:\u002F\u002Fdownload.docker.com\u002Flinux\u002Fubuntu ",[672,793,794],{"class":682},"$(",[672,796,797],{"class":678},"lsb_release",[672,799,800],{"class":686}," -cs",[672,802,803],{"class":682},")",[672,805,806],{"class":686}," stable",[672,808,690],{"class":682},[672,810,752],{"class":682},[672,812,755],{"class":678},[672,814,815],{"class":686}," tee",[672,817,818],{"class":686}," \u002Fetc\u002Fapt\u002Fsources.list.d\u002Fdocker.list",[672,820,821],{"class":682}," >",[672,823,824],{"class":686}," \u002Fdev\u002Fnull\n",[672,826,828],{"class":674,"line":827},6,[672,829,773],{"emptyLinePlaceholder":772},[672,831,833],{"class":674,"line":832},7,[672,834,835],{"class":737},"# Update package list\n",[672,837,839,842,845],{"class":674,"line":838},8,[672,840,841],{"class":678},"sudo",[672,843,844],{"class":686}," apt",[672,846,847],{"class":686}," update\n",[672,849,851],{"class":674,"line":850},9,[672,852,773],{"emptyLinePlaceholder":772},[672,854,856],{"class":674,"line":855},10,[672,857,858],{"class":737},"# Install Docker Engine, Docker Community Edition, and containerd runtime\n",[672,860,862,864,866,869,872,875,878],{"class":674,"line":861},11,[672,863,841],{"class":678},[672,865,844],{"class":686},[672,867,868],{"class":686}," install",[672,870,871],{"class":686}," docker-ce",[672,873,874],{"class":686}," docker-ce-cli",[672,876,877],{"class":686}," containerd.io",[672,879,880],{"class":686}," -y\n",[672,882,884],{"class":674,"line":883},12,[672,885,773],{"emptyLinePlaceholder":772},[672,887,889],{"class":674,"line":888},13,[672,890,891],{"class":737},"# Start automatically when the system boots\n",[672,893,895,897,900,903],{"class":674,"line":894},14,[672,896,841],{"class":678},[672,898,899],{"class":686}," systemctl",[672,901,902],{"class":686}," enable",[672,904,905],{"class":686}," docker\n",[672,907,909],{"class":674,"line":908},15,[672,910,773],{"emptyLinePlaceholder":772},[672,912,914],{"class":674,"line":913},16,[672,915,916],{"class":737},"# Verify docker is installed\n",[672,918,920,923],{"class":674,"line":919},17,[672,921,922],{"class":678},"docker",[672,924,925],{"class":686}," --version\n",[672,927,929],{"class":674,"line":928},18,[672,930,773],{"emptyLinePlaceholder":772},[672,932,934,936,938,940,943],{"class":674,"line":933},19,[672,935,841],{"class":678},[672,937,844],{"class":686},[672,939,868],{"class":686},[672,941,942],{"class":686}," -y",[672,944,945],{"class":686}," docker-compose-plugin\n",[672,947,949],{"class":674,"line":948},20,[672,950,773],{"emptyLinePlaceholder":772},[672,952,954],{"class":674,"line":953},21,[672,955,956],{"class":737},"# Verify the compose plugin is installed\n",[672,958,960,962,965],{"class":674,"line":959},22,[672,961,922],{"class":678},[672,963,964],{"class":686}," compose",[672,966,967],{"class":686}," version\n",[547,969,971],{"id":970},"_3-克隆仓库并进行配置","3. 克隆仓库并进行配置",[664,973,975],{"className":666,"code":974,"language":668,"meta":424,"style":424},"git clone https:\u002F\u002Fgithub.com\u002Fblock\u002Fbuzz.git\n\ncd buzz\u002Fdeploy\u002Fcompose\ncp .env.example .env\nnano .env\n",[645,976,977,988,992,1000,1011],{"__ignoreMap":424},[672,978,979,982,985],{"class":674,"line":675},[672,980,981],{"class":678},"git",[672,983,984],{"class":686}," clone",[672,986,987],{"class":686}," https:\u002F\u002Fgithub.com\u002Fblock\u002Fbuzz.git\n",[672,989,990],{"class":674,"line":741},[672,991,773],{"emptyLinePlaceholder":772},[672,993,994,997],{"class":674,"line":614},[672,995,996],{"class":785},"cd",[672,998,999],{"class":686}," buzz\u002Fdeploy\u002Fcompose\n",[672,1001,1002,1005,1008],{"class":674,"line":776},[672,1003,1004],{"class":678},"cp",[672,1006,1007],{"class":686}," .env.example",[672,1009,1010],{"class":686}," .env\n",[672,1012,1013,1016],{"class":674,"line":782},[672,1014,1015],{"class":678},"nano",[672,1017,1010],{"class":686},[429,1019,1020,1021,1024],{},"编辑 ",[645,1022,1023],{},".env"," 文件：",[455,1026,1027],{},[458,1028,1029],{},[442,1030,1031],{},"域名配置:",[664,1033,1038],{"className":1034,"code":1036,"language":1037},[1035],"language-text","BUZZ_DOMAIN=buzz.pafor.me\nRELAY_URL=wss:\u002F\u002Fbuzz.pafor.me\nBUZZ_PAIRING_RELAY_URL=wss:\u002F\u002Fbuzz.pafor.me\u002Fpair\nBUZZ_MEDIA_BASE_URL=https:\u002F\u002Fbuzz.pafor.me\u002Fmedia\nBUZZ_MEDIA_SERVER_DOMAIN=buzz.pafor.me\nBUZZ_CORS_ORIGINS=https:\u002F\u002Fbuzz.pafor.me\n","text",[645,1039,1036],{"__ignoreMap":424},[455,1041,1042,1052],{},[458,1043,1044,1047,1048,1051],{},[442,1045,1046],{},"所有者公钥:"," ",[645,1049,1050],{},"RELAY_OWNER_PUBKEY"," 字段需要填入您的 64 位 16 进制公钥。请先在桌面客户端生成一个身份（选择 'Create a new identity key' → 复制以 npub 格式开头的公开 ID），然后将其转换为 16 进制格式。",[458,1053,1054,1057],{},[442,1055,1056],{},"密钥安全（Secrets）:",[455,1058,1059,1071,1086],{},[458,1060,1061,1062,1066,1067,1070],{},"使用该 ",[569,1063,1065],{"href":1064},"\u002Fzh\u002Ftools\u002Fsecret-key-hex","在线工具"," 或运行命令 ",[645,1068,1069],{},"openssl rand -hex 32","（运行 7 次）来生成高强度的随机密钥。",[458,1072,1073,1074,1077,1078,1081,1082,1085],{},"将所有的 ",[645,1075,1076],{},"CHANGE_ME"," 占位符替换掉：包括 ",[645,1079,1080],{},"BUZZ_RELAY_PRIVATE_KEY","、",[645,1083,1084],{},"BUZZ_GIT_HOOK_HMAC_SECRET","、Postgres\u002FRedis\u002FTypesense 的密码以及 S3 的 Access\u002FSecret Key。",[458,1087,1088,1089,1092],{},"未替换的占位符是导致容器陷入无限重启循环的最常见原因；请通过命令 ",[645,1090,1091],{},"grep CHANGE_ME .env"," 来核对并排除隐患。",[664,1094,1097],{"className":1095,"code":1096,"language":1037},[1035],"    BUZZ_RELAY_PRIVATE_KEY=CHANGE_ME_64_HEX_PRIVATE_KEY\n    BUZZ_GIT_HOOK_HMAC_SECRET=CHANGE_ME_RANDOM_64_HEX\n    POSTGRES_PASSWORD=CHANGE_ME_RANDOM_PASSWORD\n    REDIS_PASSWORD=CHANGE_ME_RANDOM_PASSWORD\n    TYPESENSE_API_KEY=CHANGE_ME_RANDOM_API_KEY\n    BUZZ_S3_ACCESS_KEY=CHANGE_ME_RANDOM_ACCESS_KEY\n    BUZZ_S3_SECRET_KEY=CHANGE_ME_RANDOM_SECRET_KEY\n",[645,1098,1096],{"__ignoreMap":424},[455,1100,1101],{},[458,1102,1103,1106],{},[442,1104,1105],{},"其他配置项:",[455,1107,1108,1115],{},[458,1109,1110,1111,1114],{},"将环境变量 ",[645,1112,1113],{},"CLOUDFLARE_API_TOKEN"," 添加到您的配置中，并赋予先前生成的 API 令牌值。Caddy 将用其自动申请证书。",[458,1116,1117,1118,1120,1121,1124,1125,1128],{},"Buzz 的默认配置非常开放，任何知道您中继器地址的人都可以验证并加入。为了安全起见，请务必配置 ",[645,1119,1050],{},"，并将 ",[645,1122,1123],{},"BUZZ_REQUIRE_RELAY_MEMBERSHIP=true"," 和 ",[645,1126,1127],{},"BUZZ_REQUIRE_AUTH_TOKEN=true"," 设为启用状态。",[547,1130,1132],{"id":1131},"_4-使用-caddy-开启-https-访问","4. 使用 Caddy 开启 HTTPS 访问",[586,1134,1136],{"id":1135},"构建集成-cloudflare-dns-模块的自定义-caddy-镜像","构建集成 Cloudflare DNS 模块的自定义 Caddy 镜像",[455,1138,1139,1150,1153],{},[458,1140,1141,1142,1145,1146,1149],{},"我们在 Caddy 中配置基于 Cloudflare 的 DNS-01 挑战（Challenge）。DNS-01 验证的原理是让 Caddy 插件向您的",[442,1143,1144],{},"公网 DNS"," 写入一条 TXT 挑战记录 ",[645,1147,1148],{},"_acme-challenge.buzz.pafor.me","；",[458,1151,1152],{},"随后 Let's Encrypt 从公共互联网上查询该记录，以确权您的域名。这意味着您的域名必须是 Cloudflare 账户中的公网解析区域，而不能只是 Zero Trust \u002F WARP 局域网 DNS 内的私有域名。如果您的域名只在私网下分发解析而没有公网节点，DNS-01 将会失败，需要改用其他验证方式。",[458,1154,1155],{},"将以下配置加入到 Caddyfile 中：",[664,1157,1161],{"className":1158,"code":1159,"language":1160,"meta":424,"style":424},"language-yml shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{\n  acme_dns cloudflare {env.CLOUDFLARE_API_TOKEN}\n}\n","yml",[645,1162,1163,1168,1182],{"__ignoreMap":424},[672,1164,1165],{"class":674,"line":675},[672,1166,1167],{"class":682},"{\n",[672,1169,1170,1173,1176,1179],{"class":674,"line":741},[672,1171,1172],{"class":686},"  acme_dns cloudflare",[672,1174,1175],{"class":682}," {",[672,1177,1178],{"class":686},"env.CLOUDFLARE_API_TOKEN",[672,1180,1181],{"class":682},"}\n",[672,1183,1184],{"class":674,"line":614},[672,1185,1181],{"class":682},[455,1187,1188],{},[458,1189,1190,1191,1194,1195,1198],{},"创建一个 ",[645,1192,1193],{},"Dockerfile.caddy","，其内容如下，这是 ",[645,1196,1197],{},"compose.caddy.yml"," 运行所必需的：",[664,1200,1202],{"className":1158,"code":1201,"language":1160,"meta":424,"style":424},"FROM caddy:2-builder AS builder\n\nRUN xcaddy build \\\n    --with github.com\u002Fcaddy-dns\u002Fcloudflare\n\nFROM caddy:2-alpine\n\nCOPY --from=builder \u002Fusr\u002Fbin\u002Fcaddy \u002Fusr\u002Fbin\u002Fcaddy\n",[645,1203,1204,1209,1213,1218,1223,1227,1232,1236],{"__ignoreMap":424},[672,1205,1206],{"class":674,"line":675},[672,1207,1208],{"class":686},"FROM caddy:2-builder AS builder\n",[672,1210,1211],{"class":674,"line":741},[672,1212,773],{"emptyLinePlaceholder":772},[672,1214,1215],{"class":674,"line":614},[672,1216,1217],{"class":686},"RUN xcaddy build \\\n",[672,1219,1220],{"class":674,"line":776},[672,1221,1222],{"class":686},"    --with github.com\u002Fcaddy-dns\u002Fcloudflare\n",[672,1224,1225],{"class":674,"line":782},[672,1226,773],{"emptyLinePlaceholder":772},[672,1228,1229],{"class":674,"line":827},[672,1230,1231],{"class":686},"FROM caddy:2-alpine\n",[672,1233,1234],{"class":674,"line":832},[672,1235,773],{"emptyLinePlaceholder":772},[672,1237,1238],{"class":674,"line":838},[672,1239,1240],{"class":686},"COPY --from=builder \u002Fusr\u002Fbin\u002Fcaddy \u002Fusr\u002Fbin\u002Fcaddy\n",[455,1242,1243],{},[458,1244,1245,1246,1248],{},"修改 ",[645,1247,1197],{},"，以使用我们刚生成的带有 Cloudflare 插件的 Caddy 镜像，并传入 API 令牌参数：",[664,1250,1252],{"className":1158,"code":1251,"language":1160,"meta":424,"style":424},"services:\n  relay:\n    ports: !reset []\n\n  caddy:\n    build:\n      context: .\n      dockerfile: Dockerfile.caddy\n    image: buzz-caddy:cloudflare\n    depends_on:\n      relay:\n        condition: service_healthy\n    environment:\n      BUZZ_DOMAIN: ${BUZZ_DOMAIN:?set BUZZ_DOMAIN}\n      CLOUDFLARE_API_TOKEN: ${CLOUDFLARE_API_TOKEN:?set CLOUDFLARE_API_TOKEN}\n    ports:\n      - \"${CADDY_HTTP_PORT:-80}:80\"\n      - \"${CADDY_HTTPS_PORT:-443}:443\"\n    volumes:\n      - .\u002FCaddyfile:\u002Fetc\u002Fcaddy\u002FCaddyfile:ro\n      - buzz-caddy-data:\u002Fdata\n      - buzz-caddy-config:\u002Fconfig\n    restart: unless-stopped\n    networks:\n      - buzz-net\n\nvolumes:\n  buzz-caddy-data:\n    labels:\n      com.buzz.volume: caddy-data\n  buzz-caddy-config:\n    labels:\n      com.buzz.volume: caddy-config\n",[645,1253,1254,1263,1270,1285,1289,1296,1303,1314,1324,1334,1341,1348,1358,1365,1375,1385,1391,1403,1414,1421,1428,1435,1442,1453,1461,1469,1474,1482,1490,1498,1509,1517,1524],{"__ignoreMap":424},[672,1255,1256,1260],{"class":674,"line":675},[672,1257,1259],{"class":1258},"swJcz","services",[672,1261,1262],{"class":682},":\n",[672,1264,1265,1268],{"class":674,"line":741},[672,1266,1267],{"class":1258},"  relay",[672,1269,1262],{"class":682},[672,1271,1272,1275,1278,1282],{"class":674,"line":614},[672,1273,1274],{"class":1258},"    ports",[672,1276,1277],{"class":682},":",[672,1279,1281],{"class":1280},"spNyl"," !reset",[672,1283,1284],{"class":682}," []\n",[672,1286,1287],{"class":674,"line":776},[672,1288,773],{"emptyLinePlaceholder":772},[672,1290,1291,1294],{"class":674,"line":782},[672,1292,1293],{"class":1258},"  caddy",[672,1295,1262],{"class":682},[672,1297,1298,1301],{"class":674,"line":827},[672,1299,1300],{"class":1258},"    build",[672,1302,1262],{"class":682},[672,1304,1305,1308,1310],{"class":674,"line":832},[672,1306,1307],{"class":1258},"      context",[672,1309,1277],{"class":682},[672,1311,1313],{"class":1312},"sbssI"," .\n",[672,1315,1316,1319,1321],{"class":674,"line":838},[672,1317,1318],{"class":1258},"      dockerfile",[672,1320,1277],{"class":682},[672,1322,1323],{"class":686}," Dockerfile.caddy\n",[672,1325,1326,1329,1331],{"class":674,"line":850},[672,1327,1328],{"class":1258},"    image",[672,1330,1277],{"class":682},[672,1332,1333],{"class":686}," buzz-caddy:cloudflare\n",[672,1335,1336,1339],{"class":674,"line":855},[672,1337,1338],{"class":1258},"    depends_on",[672,1340,1262],{"class":682},[672,1342,1343,1346],{"class":674,"line":861},[672,1344,1345],{"class":1258},"      relay",[672,1347,1262],{"class":682},[672,1349,1350,1353,1355],{"class":674,"line":883},[672,1351,1352],{"class":1258},"        condition",[672,1354,1277],{"class":682},[672,1356,1357],{"class":686}," service_healthy\n",[672,1359,1360,1363],{"class":674,"line":888},[672,1361,1362],{"class":1258},"    environment",[672,1364,1262],{"class":682},[672,1366,1367,1370,1372],{"class":674,"line":894},[672,1368,1369],{"class":1258},"      BUZZ_DOMAIN",[672,1371,1277],{"class":682},[672,1373,1374],{"class":686}," ${BUZZ_DOMAIN:?set BUZZ_DOMAIN}\n",[672,1376,1377,1380,1382],{"class":674,"line":908},[672,1378,1379],{"class":1258},"      CLOUDFLARE_API_TOKEN",[672,1381,1277],{"class":682},[672,1383,1384],{"class":686}," ${CLOUDFLARE_API_TOKEN:?set CLOUDFLARE_API_TOKEN}\n",[672,1386,1387,1389],{"class":674,"line":913},[672,1388,1274],{"class":1258},[672,1390,1262],{"class":682},[672,1392,1393,1396,1398,1401],{"class":674,"line":919},[672,1394,1395],{"class":682},"      -",[672,1397,683],{"class":682},[672,1399,1400],{"class":686},"${CADDY_HTTP_PORT:-80}:80",[672,1402,701],{"class":682},[672,1404,1405,1407,1409,1412],{"class":674,"line":928},[672,1406,1395],{"class":682},[672,1408,683],{"class":682},[672,1410,1411],{"class":686},"${CADDY_HTTPS_PORT:-443}:443",[672,1413,701],{"class":682},[672,1415,1416,1419],{"class":674,"line":933},[672,1417,1418],{"class":1258},"    volumes",[672,1420,1262],{"class":682},[672,1422,1423,1425],{"class":674,"line":948},[672,1424,1395],{"class":682},[672,1426,1427],{"class":686}," .\u002FCaddyfile:\u002Fetc\u002Fcaddy\u002FCaddyfile:ro\n",[672,1429,1430,1432],{"class":674,"line":953},[672,1431,1395],{"class":682},[672,1433,1434],{"class":686}," buzz-caddy-data:\u002Fdata\n",[672,1436,1437,1439],{"class":674,"line":959},[672,1438,1395],{"class":682},[672,1440,1441],{"class":686}," buzz-caddy-config:\u002Fconfig\n",[672,1443,1445,1448,1450],{"class":674,"line":1444},23,[672,1446,1447],{"class":1258},"    restart",[672,1449,1277],{"class":682},[672,1451,1452],{"class":686}," unless-stopped\n",[672,1454,1456,1459],{"class":674,"line":1455},24,[672,1457,1458],{"class":1258},"    networks",[672,1460,1262],{"class":682},[672,1462,1464,1466],{"class":674,"line":1463},25,[672,1465,1395],{"class":682},[672,1467,1468],{"class":686}," buzz-net\n",[672,1470,1472],{"class":674,"line":1471},26,[672,1473,773],{"emptyLinePlaceholder":772},[672,1475,1477,1480],{"class":674,"line":1476},27,[672,1478,1479],{"class":1258},"volumes",[672,1481,1262],{"class":682},[672,1483,1485,1488],{"class":674,"line":1484},28,[672,1486,1487],{"class":1258},"  buzz-caddy-data",[672,1489,1262],{"class":682},[672,1491,1493,1496],{"class":674,"line":1492},29,[672,1494,1495],{"class":1258},"    labels",[672,1497,1262],{"class":682},[672,1499,1501,1504,1506],{"class":674,"line":1500},30,[672,1502,1503],{"class":1258},"      com.buzz.volume",[672,1505,1277],{"class":682},[672,1507,1508],{"class":686}," caddy-data\n",[672,1510,1512,1515],{"class":674,"line":1511},31,[672,1513,1514],{"class":1258},"  buzz-caddy-config",[672,1516,1262],{"class":682},[672,1518,1520,1522],{"class":674,"line":1519},32,[672,1521,1495],{"class":1258},[672,1523,1262],{"class":682},[672,1525,1527,1529,1531],{"class":674,"line":1526},33,[672,1528,1503],{"class":1258},[672,1530,1277],{"class":682},[672,1532,1533],{"class":686}," caddy-config\n",[586,1535,1537],{"id":1536},"启动-docker-容器组合","启动 Docker 容器组合",[664,1539,1541],{"className":666,"code":1540,"language":668,"meta":424,"style":424},"docker compose -f compose.yml -f compose.caddy.yml up -d\n\n#Check the Docker status\ndocker compose ps\n",[645,1542,1543,1566,1570,1575],{"__ignoreMap":424},[672,1544,1545,1547,1549,1552,1555,1557,1560,1563],{"class":674,"line":675},[672,1546,922],{"class":678},[672,1548,964],{"class":686},[672,1550,1551],{"class":686}," -f",[672,1553,1554],{"class":686}," compose.yml",[672,1556,1551],{"class":686},[672,1558,1559],{"class":686}," compose.caddy.yml",[672,1561,1562],{"class":686}," up",[672,1564,1565],{"class":686}," -d\n",[672,1567,1568],{"class":674,"line":741},[672,1569,773],{"emptyLinePlaceholder":772},[672,1571,1572],{"class":674,"line":614},[672,1573,1574],{"class":737},"#Check the Docker status\n",[672,1576,1577,1579,1581],{"class":674,"line":776},[672,1578,922],{"class":678},[672,1580,964],{"class":686},[672,1582,1583],{"class":686}," ps\n",[435,1585],{"src":1586,"alt":1587,"style":1588},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf-Hosting%20Buzz%20As%20The%20Workspace%20Where%20AI%20Agents%20Become%20Colleagues\u002Fdocker-compose-ps-status-terminal.webp","终端窗口显示通过 docker compose ps 运行的 Buzz 服务容器状态","max-width: 700px; width: 100%; height: auto;",[429,1590,1591,1592,1595],{},"打开您的网页浏览器并访问 ",[645,1593,1594],{},"http:\u002F\u002Fbuzz.pafor.me","，验证中继服务是否已顺利跑起来。",[435,1597],{"src":1598,"alt":1599,"style":1600},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf-Hosting%20Buzz%20As%20The%20Workspace%20Where%20AI%20Agents%20Become%20Colleagues\u002Fbuzz-relay-running-browser-verification.webp","浏览器验证页面，显示自托管 Block's Buzz 中继服务器的成功运行响应","max-width: 500px; width: 100%; height: auto;",[547,1602,1604],{"id":1603},"步骤-5建立起首日备份机制","步骤 5：建立起首日备份机制",[664,1606,1608],{"className":666,"code":1607,"language":668,"meta":424,"style":424},"mkdir -p \u002Fbuzz_backups\ncrontab -e\n",[645,1609,1610,1621],{"__ignoreMap":424},[672,1611,1612,1615,1618],{"class":674,"line":675},[672,1613,1614],{"class":678},"mkdir",[672,1616,1617],{"class":686}," -p",[672,1619,1620],{"class":686}," \u002Fbuzz_backups\n",[672,1622,1623,1626],{"class":674,"line":741},[672,1624,1625],{"class":678},"crontab",[672,1627,1628],{"class":686}," -e\n",[429,1630,1631],{},"添加一个每日凌晨自动执行的数据库快照定时任务（Cron Job）：",[664,1633,1636],{"className":1634,"code":1635,"language":1037},[1035],"0 3 * * * cd \u002Fhome\u002F\u003Cuser>\u002Fbuzz\u002Fdeploy\u002Fcompose && docker compose exec -T postgres pg_dump -U buzz buzz > \u002Fbuzz_backups\u002Fbuzz-$(date +\\%Y\\%m\\%d).sql\n",[645,1637,1635],{"__ignoreMap":424},[429,1639,1640,1641,1643],{},"注意：请将 ",[645,1642,1080],{}," 视为永久不可失配的密钥。由于中继器中的事件都与此密钥绑定，如果未来变更了私钥，旧事件将无法通过验证；即便您恢复了数据库备份，在新私钥下它也不会被 Nostr 网络视为同一个中继服务。",[447,1645,1647],{"id":1646},"配置-buzz-桌面客户端与-nostr-加密身份","配置 Buzz 桌面客户端与 Nostr 加密身份",[429,1649,1650,1651,1656],{},"从 ",[569,1652,1653],{"href":1653,"rel":1654},"https:\u002F\u002Fgithub.com\u002Fblock\u002Fbuzz\u002Freleases",[1655],"nofollow"," 下载最新版 Buzz 桌面客户端并运行。依次完善个人资料，直到您来到 “Join or create a community” 界面。",[429,1658,1659],{},[435,1660],{"alt":1661,"src":1662},"Buzz 桌面客户端初始设置界面，用于加入或创建社区","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf-Hosting%20Buzz%20As%20The%20Workspace%20Where%20AI%20Agents%20Become%20Colleagues\u002Fbuzz-desktop-client-setup-community.webp",[429,1664,1665],{},"点击 “Join a community” 并拷贝您的公钥（Public Key）。",[429,1667,1668],{},[435,1669],{"alt":1670,"src":1671},"Buzz 客户端界面显示加入社区前的公钥数字身份","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf-Hosting%20Buzz%20As%20The%20Workspace%20Where%20AI%20Agents%20Become%20Colleagues\u002Fbuzz-desktop-client-join-community-public-key.webp",[429,1673,1674,1675,1678],{},"在 ",[442,1676,1677],{},"VPS 上","运行以下命令行工具，将您自己添加为该平台的首位会员：",[664,1680,1682],{"className":666,"code":1681,"language":668,"meta":424,"style":424},"docker compose exec relay buzz-admin add-member --pubkey npub1yourkeyhere\n",[645,1683,1684],{"__ignoreMap":424},[672,1685,1686,1688,1690,1693,1696,1699,1702,1705],{"class":674,"line":675},[672,1687,922],{"class":678},[672,1689,964],{"class":686},[672,1691,1692],{"class":686}," exec",[672,1694,1695],{"class":686}," relay",[672,1697,1698],{"class":686}," buzz-admin",[672,1700,1701],{"class":686}," add-member",[672,1703,1704],{"class":686}," --pubkey",[672,1706,1707],{"class":686}," npub1yourkeyhere\n",[429,1709,1710,1711,1714],{},"在客户端中填入 ",[645,1712,1713],{},"wss:\u002F\u002Fbuzz.pafor.me"," 作为社区接入 URL，然后点击 “Next”。",[429,1716,1717],{},[435,1718],{"alt":1719,"src":1720},"在 Buzz 桌面客户端中输入自托管社区中继服务器的 URL 地址","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf-Hosting%20Buzz%20As%20The%20Workspace%20Where%20AI%20Agents%20Become%20Colleagues\u002Fbuzz-desktop-client-input-community-url.webp",[429,1722,1723],{},"起一个帅气的昵称，然后点击 “Next” 按钮。",[429,1725,1726],{},[435,1727],{"alt":1728,"src":1729},"Buzz 客户端个人资料配置界面，用于输入用户昵称","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf-Hosting%20Buzz%20As%20The%20Workspace%20Where%20AI%20Agents%20Become%20Colleagues\u002Fbuzz-desktop-client-profile-name-input.webp",[547,1731,1733],{"id":1732},"协作频道与-ai-智能体","协作频道与 AI 智能体",[429,1735,1736],{},"频道是围绕特定任务或项目划分的群组。为您手头的每个任务或工程建立独立的频道，并将团队成员与所需的 AI 智能体拉入其中。",[429,1738,1739],{},"频道内的所有消息、代码与文档都会被自动分享，免去了逐一向新成员同步前因后果的烦恼。任何人都可以通过“@”来点名激活特定的 AI 智能体，智能体收到召唤后会读取相关历史消息并立刻着手处理。更妙的是，不同的 AI 智能体之间也能互相 @ 指派任务。",[429,1741,1742],{},"让我们试着给预置的智能体发一条私信（DM）",[429,1744,1745],{},[435,1746],{"alt":1747,"src":1748},"在 Buzz 协同桌面客户端中给 AI 智能体发送私信（DM）","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf-Hosting%20Buzz%20As%20The%20Workspace%20Where%20AI%20Agents%20Become%20Colleagues\u002Fbuzz-desktop-client-dm-agent.webp",[429,1750,1751],{},"创建一个新频道并拉几个 AI 智能体进来吧",[429,1753,1754],{},[435,1755],{"alt":1756,"src":1757},"在 Buzz 桌面客户端中创建新的任务或项目协作频道","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf-Hosting%20Buzz%20As%20The%20Workspace%20Where%20AI%20Agents%20Become%20Colleagues\u002Fbuzz-desktop-client-create-channel-dialog.webp",[429,1759,1760],{},[435,1761],{"alt":1762,"src":1763},"将团队成员和 AI 智能体添加至新创建的协作频道中","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf-Hosting%20Buzz%20As%20The%20Workspace%20Where%20AI%20Agents%20Become%20Colleagues\u002Fbuzz-desktop-client-add-agents-to-channel.webp",[429,1765,1766],{},[435,1767],{"alt":1768,"src":1769},"活跃协作频道视图，展示合并后的聊天历史和项目任务","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf-Hosting%20Buzz%20As%20The%20Workspace%20Where%20AI%20Agents%20Become%20Colleagues\u002Fbuzz-desktop-client-channel-view.webp",[435,1771],{"src":1772,"alt":1773,"style":1774},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf-Hosting%20Buzz%20As%20The%20Workspace%20Where%20AI%20Agents%20Become%20Colleagues\u002Fbuzz-desktop-client-channel-active-agents.webp","已集成到协同项目频道中的活跃 AI 智能体列表细节视图","max-width: 367px; width: 100%; height: auto;",[547,1776,1778],{"id":1777},"激活智能体运行时agent-runtimes","激活智能体运行时（Agent Runtimes）",[429,1780,1781,1782,1785,1786,1789],{},"平台自带的运行时预设依赖于“自动探测”来查找特定系统目录（例如 ",[645,1783,1784],{},"~\u002F.local\u002Fbin","）下的执行程序（如 ",[645,1787,1788],{},"hermes-acp","）。如果您的智能体软件安装在非标准路径下，Buzz 将无法正确识别。",[429,1791,1792,1793,1796],{},"以 Kimi Code 为例，它的智能体 ID 为 kimi，Buzz 默认会在 ",[645,1794,1795],{},"~\u002F.local\u002Fbin\u002Fkimi"," 寻找它。通过创建一个软链接（Symbolic Link）即可轻松搞定：",[664,1798,1801],{"className":1799,"code":1800,"language":1037},[1035],"ln -s kimi-cli \u002FUsers\u002F\u003Cuser>\u002F.local\u002Fbin\u002Fkimi\n",[645,1802,1800],{"__ignoreMap":424},[429,1804,1805],{},"此时，Kimi Code 就会显示在“Agent runtimes”列表中。",[429,1807,1808],{},[435,1809],{"alt":1810,"src":1811},"Buzz 客户端设置界面，显示已配置的 AI 智能体运行时列表（包括 Kimi）","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf-Hosting%20Buzz%20As%20The%20Workspace%20Where%20AI%20Agents%20Become%20Colleagues\u002Fbuzz-settings-agent-runtimes-list.webp",[547,1813,1814],{"id":1814},"项目与代码仓库管理",[429,1816,1817,1818,1821],{},"请先在 Settings → Experiments 菜单中激活“",[442,1819,1820],{},"Projects","”实验性功能：",[429,1823,1824],{},[435,1825],{"alt":1826,"src":1827},"在 Buzz 客户端设置的 Experiments 标签页中激活实验性 Projects 功能","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf-Hosting%20Buzz%20As%20The%20Workspace%20Where%20AI%20Agents%20Become%20Colleagues\u002Fbuzz-settings-experiments-projects.webp",[429,1829,1830,1831,1834],{},"目前，一个项目（Project）必须使用 ",[645,1832,1833],{},"buzz-cli"," 命令行工具来创建（虽然在后续版本中会加入 UI 直接创建的支持）。",[586,1836,1838],{"id":1837},"在-vps-上安装并部署-buzz-cli","在 VPS 上安装并部署 buzz-cli",[429,1840,1674,1841,1843,1844,1846],{},[442,1842,1677],{},"依次执行以下命令，编译并安装好 ",[645,1845,1833],{}," 客户端：",[664,1848,1850],{"className":666,"code":1849,"language":668,"meta":424,"style":424},"sudo apt install cargo\ncd ~\u002Fbuzz\ncargo install --path crates\u002Fbuzz-cli\necho 'export PATH=\"$HOME\u002F.cargo\u002Fbin:$PATH\"' >> ~\u002F.bashrc && source ~\u002F.bashrc\n",[645,1851,1852,1863,1870,1883],{"__ignoreMap":424},[672,1853,1854,1856,1858,1860],{"class":674,"line":675},[672,1855,841],{"class":678},[672,1857,844],{"class":686},[672,1859,868],{"class":686},[672,1861,1862],{"class":686}," cargo\n",[672,1864,1865,1867],{"class":674,"line":741},[672,1866,996],{"class":785},[672,1868,1869],{"class":686}," ~\u002Fbuzz\n",[672,1871,1872,1875,1877,1880],{"class":674,"line":614},[672,1873,1874],{"class":678},"cargo",[672,1876,868],{"class":686},[672,1878,1879],{"class":686}," --path",[672,1881,1882],{"class":686}," crates\u002Fbuzz-cli\n",[672,1884,1885,1887,1890,1893,1896,1899,1902,1905,1908],{"class":674,"line":776},[672,1886,786],{"class":785},[672,1888,1889],{"class":682}," '",[672,1891,1892],{"class":686},"export PATH=\"$HOME\u002F.cargo\u002Fbin:$PATH\"",[672,1894,1895],{"class":682},"'",[672,1897,1898],{"class":682}," >>",[672,1900,1901],{"class":686}," ~\u002F.bashrc",[672,1903,1904],{"class":682}," &&",[672,1906,1907],{"class":785}," source",[672,1909,1910],{"class":686}," ~\u002F.bashrc\n",[429,1912,1913,1914,1916,1917,1919],{},"使用在线工具或通过 ",[645,1915,1833],{}," 生成一对 Nostr 加密公私钥。这组密钥将代表该 ",[645,1918,1833],{}," 工具在 Nostr 网络中的数字身份。",[664,1921,1923],{"className":666,"code":1922,"language":668,"meta":424,"style":424},"docker run --rm --entrypoint \u002Fusr\u002Flocal\u002Fbin\u002Fbuzz-admin ghcr.io\u002Fblock\u002Fbuzz:main generate-key\n\n# Use the generated Public Key\ndocker compose exec relay buzz-admin add-member --pubkey generated_Public_key\n",[645,1924,1925,1947,1951,1956],{"__ignoreMap":424},[672,1926,1927,1929,1932,1935,1938,1941,1944],{"class":674,"line":675},[672,1928,922],{"class":678},[672,1930,1931],{"class":686}," run",[672,1933,1934],{"class":686}," --rm",[672,1936,1937],{"class":686}," --entrypoint",[672,1939,1940],{"class":686}," \u002Fusr\u002Flocal\u002Fbin\u002Fbuzz-admin",[672,1942,1943],{"class":686}," ghcr.io\u002Fblock\u002Fbuzz:main",[672,1945,1946],{"class":686}," generate-key\n",[672,1948,1949],{"class":674,"line":741},[672,1950,773],{"emptyLinePlaceholder":772},[672,1952,1953],{"class":674,"line":614},[672,1954,1955],{"class":737},"# Use the generated Public Key\n",[672,1957,1958,1960,1962,1964,1966,1968,1970,1972],{"class":674,"line":776},[672,1959,922],{"class":678},[672,1961,964],{"class":686},[672,1963,1692],{"class":686},[672,1965,1695],{"class":686},[672,1967,1698],{"class":686},[672,1969,1701],{"class":686},[672,1971,1704],{"class":686},[672,1973,1974],{"class":686}," generated_Public_key\n",[429,1976,1977],{},"配置您的 CLI 环境变量：",[664,1979,1981],{"className":666,"code":1980,"language":668,"meta":424,"style":424},"# Copy the Secret key as the BUZZ_PRIVATE_KEY\necho 'export BUZZ_PRIVATE_KEY=\"nsec1...\"'  >> \u002Fhome\u002F\u003Cuser>\u002F.bashrc\n\necho 'export BUZZ_RELAY_URL=\"wss:\u002F\u002Fbuzz.pafor.me\"'  >> \u002Fhome\u002F\u003Cuser>\u002F.bashrc\n",[645,1982,1983,1988,2021,2025],{"__ignoreMap":424},[672,1984,1985],{"class":674,"line":675},[672,1986,1987],{"class":737},"# Copy the Secret key as the BUZZ_PRIVATE_KEY\n",[672,1989,1990,1992,1994,1997,1999,2002,2005,2008,2011,2015,2018],{"class":674,"line":741},[672,1991,786],{"class":785},[672,1993,1889],{"class":682},[672,1995,1996],{"class":686},"export BUZZ_PRIVATE_KEY=\"nsec1...\"",[672,1998,1895],{"class":682},[672,2000,2001],{"class":682},"  >>",[672,2003,2004],{"class":686}," \u002Fhome\u002F",[672,2006,2007],{"class":682},"\u003C",[672,2009,2010],{"class":686},"use",[672,2012,2014],{"class":2013},"sTEyZ","r",[672,2016,2017],{"class":682},">",[672,2019,2020],{"class":686},"\u002F.bashrc\n",[672,2022,2023],{"class":674,"line":614},[672,2024,773],{"emptyLinePlaceholder":772},[672,2026,2027,2029,2031,2034,2036,2038,2040,2042,2044,2046,2048],{"class":674,"line":776},[672,2028,786],{"class":785},[672,2030,1889],{"class":682},[672,2032,2033],{"class":686},"export BUZZ_RELAY_URL=\"wss:\u002F\u002Fbuzz.pafor.me\"",[672,2035,1895],{"class":682},[672,2037,2001],{"class":682},[672,2039,2004],{"class":686},[672,2041,2007],{"class":682},[672,2043,2010],{"class":686},[672,2045,2014],{"class":2013},[672,2047,2017],{"class":682},[672,2049,2020],{"class":686},[429,2051,2052,2053,2055],{},"运行以下命令来测试 ",[645,2054,1833],{}," 是否已经与您的中继器配对畅通：",[664,2057,2059],{"className":666,"code":2058,"language":668,"meta":424,"style":424},"buzz channels list\n",[645,2060,2061],{"__ignoreMap":424},[672,2062,2063,2066,2069],{"class":674,"line":675},[672,2064,2065],{"class":678},"buzz",[672,2067,2068],{"class":686}," channels",[672,2070,2071],{"class":686}," list\n",[429,2073,2074],{},[435,2075],{"alt":2076,"src":2077},"终端命令行运行验证，通过列出活跃频道来检查 buzz-cli 配置是否正确","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf-Hosting%20Buzz%20As%20The%20Workspace%20Where%20AI%20Agents%20Become%20Colleagues\u002Fbuzz-cli-channels-list-terminal.webp",[586,2079,2081],{"id":2080},"使用-buzz-cli-创建全新的项目","使用 buzz-cli 创建全新的项目",[664,2083,2085],{"className":666,"code":2084,"language":668,"meta":424,"style":424},"# --channel refers to the UUID of the channel\nbuzz repos create --id TestKOA --name 'Display Name' --channel \"bd92b3d1-8fac-441c-a9ac-2b2f3aac5c5b\"\n",[645,2086,2087,2092],{"__ignoreMap":424},[672,2088,2089],{"class":674,"line":675},[672,2090,2091],{"class":737},"# --channel refers to the UUID of the channel\n",[672,2093,2094,2096,2099,2102,2105,2108,2111,2113,2116,2118,2121,2123,2126],{"class":674,"line":741},[672,2095,2065],{"class":678},[672,2097,2098],{"class":686}," repos",[672,2100,2101],{"class":686}," create",[672,2103,2104],{"class":686}," --id",[672,2106,2107],{"class":686}," TestKOA",[672,2109,2110],{"class":686}," --name",[672,2112,1889],{"class":682},[672,2114,2115],{"class":686},"Display Name",[672,2117,1895],{"class":682},[672,2119,2120],{"class":686}," --channel",[672,2122,683],{"class":682},[672,2124,2125],{"class":686},"bd92b3d1-8fac-441c-a9ac-2b2f3aac5c5b",[672,2127,701],{"class":682},[429,2129,2130,2131,2133],{},"项目的所有权极为严格，只有创建者才有权将其删除。由于该“Display Name”项目是由 ",[645,2132,1833],{}," 发起创建的，而目前的命令行版本尚未内置删除指令，因此该项目无法通过常规方式清空。",[429,2135,2136],{},"再次点开您的桌面客户端，验证该项目是否已显示在工作区中。",[429,2138,2139],{},[435,2140],{"alt":2141,"src":2142},"Buzz 桌面客户端项目视图页面，确认项目已成功创建","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf-Hosting%20Buzz%20As%20The%20Workspace%20Where%20AI%20Agents%20Become%20Colleagues\u002Fbuzz-desktop-client-project-view.webp",[429,2144,2145],{},"一旦项目列表在界面中开启，后续您便可以直接通过右上角的 “+” 按钮随心所欲地添加更多子项目了。",[429,2147,2148],{},[435,2149],{"alt":2150,"src":2151},"在 Buzz 桌面客户端中点击右上角加号按钮来添加新项目","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf-Hosting%20Buzz%20As%20The%20Workspace%20Where%20AI%20Agents%20Become%20Colleagues\u002Fbuzz-desktop-client-add-project-button.webp",[586,2153,2155],{"id":2154},"拉入现有的-git-代码仓库","拉入现有的 Git 代码仓库",[429,2157,2158,2159,2162,2163,2166,2167,2172],{},"在您的本地开发机器上安装 ",[645,2160,2161],{},"git-credential-nostr"," 凭证辅助工具。这需要您的系统已安装 ",[442,2164,2165],{},"Git 2.46+"," 版本并配有 Rust 构建环境。详情可参考此项目的 ",[569,2168,2171],{"href":2169,"rel":2170},"https:\u002F\u002Fgithub.com\u002Fblock\u002Fbuzz\u002Ftree\u002Fmain\u002Fcrates\u002Fgit-credential-nostr",[1655],"Readme"," 描述：",[664,2174,2176],{"className":666,"code":2175,"language":668,"meta":424,"style":424},"cargo install --path crates\u002Fgit-credential-nostr\n",[645,2177,2178],{"__ignoreMap":424},[672,2179,2180,2182,2184,2186],{"class":674,"line":675},[672,2181,1874],{"class":678},[672,2183,868],{"class":686},[672,2185,1879],{"class":686},[672,2187,2188],{"class":686}," crates\u002Fgit-credential-nostr\n",[429,2190,2191,2192,2194],{},"对 ",[645,2193,2161],{}," 进行配置，使其获得 Buzz 中继器的授权权限：",[664,2196,2198],{"className":666,"code":2197,"language":668,"meta":424,"style":424},"# 1. Register the helper and enable per-path credentials.\ngit config --global credential.helper nostr\ngit config --global credential.useHttpPath true\n\n# 2. Store your nsec in a key file (must be 0600). Replace \"nsec1...\" with your private key\nmkdir -p ~\u002F.nostr\necho \"nsec1...\" > ~\u002F.nostr\u002Fkey && chmod 600 ~\u002F.nostr\u002Fkey\ngit config --global nostr.keyfile ~\u002F.nostr\u002Fkey\n",[645,2199,2200,2205,2221,2235,2239,2244,2253,2280],{"__ignoreMap":424},[672,2201,2202],{"class":674,"line":675},[672,2203,2204],{"class":737},"# 1. Register the helper and enable per-path credentials.\n",[672,2206,2207,2209,2212,2215,2218],{"class":674,"line":741},[672,2208,981],{"class":678},[672,2210,2211],{"class":686}," config",[672,2213,2214],{"class":686}," --global",[672,2216,2217],{"class":686}," credential.helper",[672,2219,2220],{"class":686}," nostr\n",[672,2222,2223,2225,2227,2229,2232],{"class":674,"line":614},[672,2224,981],{"class":678},[672,2226,2211],{"class":686},[672,2228,2214],{"class":686},[672,2230,2231],{"class":686}," credential.useHttpPath",[672,2233,2234],{"class":682}," true\n",[672,2236,2237],{"class":674,"line":776},[672,2238,773],{"emptyLinePlaceholder":772},[672,2240,2241],{"class":674,"line":782},[672,2242,2243],{"class":737},"# 2. Store your nsec in a key file (must be 0600). Replace \"nsec1...\" with your private key\n",[672,2245,2246,2248,2250],{"class":674,"line":827},[672,2247,1614],{"class":678},[672,2249,1617],{"class":686},[672,2251,2252],{"class":686}," ~\u002F.nostr\n",[672,2254,2255,2257,2259,2262,2264,2266,2269,2271,2274,2277],{"class":674,"line":832},[672,2256,786],{"class":785},[672,2258,683],{"class":682},[672,2260,2261],{"class":686},"nsec1...",[672,2263,690],{"class":682},[672,2265,821],{"class":682},[672,2267,2268],{"class":686}," ~\u002F.nostr\u002Fkey",[672,2270,1904],{"class":682},[672,2272,2273],{"class":678}," chmod",[672,2275,2276],{"class":1312}," 600",[672,2278,2279],{"class":686}," ~\u002F.nostr\u002Fkey\n",[672,2281,2282,2284,2286,2288,2291],{"class":674,"line":838},[672,2283,981],{"class":678},[672,2285,2211],{"class":686},[672,2287,2214],{"class":686},[672,2289,2290],{"class":686}," nostr.keyfile",[672,2292,2279],{"class":686},[429,2294,2295],{},"在 Buzz 中继上开辟出该 Git 库的存储节点：",[664,2297,2300],{"className":2298,"code":2299,"language":1037},[1035],"buzz repos create --id koa-email-routing --name \"KOA Email Routing\" --clone \"https:\u002F\u002Fbuzz.pafor.me\u002Fgit\u002F\u003Cpub_key>\u002Fkoa-email-routing\" --nostr-relay \"wss:\u002F\u002Fbuzz.pafor.me\"\n",[645,2301,2299],{"__ignoreMap":424},[429,2303,2304,2305,2308,2309,2312],{},"在第一次执行 ",[645,2306,2307],{},"git push"," 时，您可能会被拦截并报错 ",[645,2310,2311],{},"remote: missing Authorization header","。这是由于 Git 写入控制（ACL）是由频道成员资格决定的，您必须先将该仓库 ID 与一个具体的 Buzz 频道进行绑定，从而授权合规写入：",[664,2314,2316],{"className":666,"code":2315,"language":668,"meta":424,"style":424},"buzz repos bind --id koa-email-routing --channel \u003CCHANNEL_UUID>\n\n# push the code again\ngit push\n",[645,2317,2318,2346,2350,2355],{"__ignoreMap":424},[672,2319,2320,2322,2324,2327,2329,2332,2334,2337,2340,2343],{"class":674,"line":675},[672,2321,2065],{"class":678},[672,2323,2098],{"class":686},[672,2325,2326],{"class":686}," bind",[672,2328,2104],{"class":686},[672,2330,2331],{"class":686}," koa-email-routing",[672,2333,2120],{"class":686},[672,2335,2336],{"class":682}," \u003C",[672,2338,2339],{"class":686},"CHANNEL_UUI",[672,2341,2342],{"class":2013},"D",[672,2344,2345],{"class":682},">\n",[672,2347,2348],{"class":674,"line":741},[672,2349,773],{"emptyLinePlaceholder":772},[672,2351,2352],{"class":674,"line":614},[672,2353,2354],{"class":737},"# push the code again\n",[672,2356,2357,2359],{"class":674,"line":776},[672,2358,981],{"class":678},[672,2360,2361],{"class":686}," push\n",[429,2363,2364,2365,2367],{},"在某些情况下，在 Buzz 桌面版中查阅项目进度时会遇到类似下方的 Git 模块拉取失败提示。这是由于该桌面应用要求系统必须搭载 ",[442,2366,2165],{}," 版本，而应用直接启动时可能默认寻址到了系统中的旧版 Git 引擎：",[429,2369,2370],{},[435,2371],{"alt":2372,"src":2373},"Buzz 客户端展示由于本地 Git 版本低于 2.46 导致的 Git 库加载失败报错界面","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf-Hosting%20Buzz%20As%20The%20Workspace%20Where%20AI%20Agents%20Become%20Colleagues\u002Fbuzz-desktop-client-git-version-error.webp",[429,2375,2376,2377,2380,2381,2386],{},"请在您的 shell 配置文件中通过执行 ",[645,2378,2379],{},"launchctl setenv PATH \"\u002Fopt\u002Fhomebrew\u002Fbin:\u002Fusr\u002Flocal\u002Fbin:\u002Fusr\u002Fbin:\u002Fbin:\u002Fusr\u002Fsbin:\u002Fsbin\""," 声明新版 Git 所在的 PATH，并直接在终端中拉起 Buzz 应用。对此可参考该 ",[569,2382,2385],{"href":2383,"rel":2384},"https:\u002F\u002Fgithub.com\u002Fblock\u002Fbuzz\u002Fissues\u002F5348",[1655],"Issue"," 的详细排查记录。",[664,2388,2390],{"className":666,"code":2389,"language":668,"meta":424,"style":424},"open -a Buzz\n",[645,2391,2392],{"__ignoreMap":424},[672,2393,2394,2397,2400],{"class":674,"line":675},[672,2395,2396],{"class":678},"open",[672,2398,2399],{"class":686}," -a",[672,2401,2402],{"class":686}," Buzz\n",[429,2404,2405],{},"重新进入客户端中的 Projects 标签页，您会惊喜地发现代码库的所有提交与详情已经完美加载出来了。",[429,2407,2408],{},[435,2409],{"alt":2410,"src":2411},"代码库提交详情成功加载后的 Buzz 桌面客户端项目面板","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf-Hosting%20Buzz%20As%20The%20Workspace%20Where%20AI%20Agents%20Become%20Colleagues\u002Fbuzz-desktop-client-repository-details-loaded.webp",[447,2413,2415],{"id":2414},"利用二维码将-ai-助手同步至手机端-buzz-app","利用二维码将 AI 助手同步至手机端 Buzz App",[429,2417,2418,2419,2422],{},"Buzz 手机端的“扫码配对”只认 HTTPS 协议，且 VPS 上的中继服务默认并不会在后台运行 ",[645,2420,2421],{},"buzz-pair-relay"," 组件。",[664,2424,2426],{"className":666,"code":2425,"language":668,"meta":424,"style":424},"cd ~\u002Fbuzz\ncargo install --path crates\u002Fbuzz-pair-relay\n",[645,2427,2428,2434],{"__ignoreMap":424},[672,2429,2430,2432],{"class":674,"line":675},[672,2431,996],{"class":785},[672,2433,1869],{"class":686},[672,2435,2436,2438,2440,2442],{"class":674,"line":741},[672,2437,1874],{"class":678},[672,2439,868],{"class":686},[672,2441,1879],{"class":686},[672,2443,2444],{"class":686}," crates\u002Fbuzz-pair-relay\n",[429,2446,2447,2448,2451,2452,2454],{},"将以下配置注入到您的 ",[645,2449,2450],{},"compose.yml"," 文件中，声明并启动 ",[645,2453,2421],{}," 容器进程：",[664,2456,2458],{"className":1158,"code":2457,"language":1160,"meta":424,"style":424},"  pair:\n    image: ${BUZZ_IMAGE:-ghcr.io\u002Fblock\u002Fbuzz:main}\n    entrypoint: [\"\u002Fusr\u002Flocal\u002Fbin\u002Fbuzz-pair-relay\"]\n    environment:\n      BUZZ_PAIR_RELAY_BIND_ADDR: 0.0.0.0:5000\n    ports:\n      - \"${BUZZ_PAIR_RELAY_PORT:-5000}:5000\"\n    restart: unless-stopped\n    networks:\n      [buzz-net]\n",[645,2459,2460,2467,2476,2496,2502,2512,2518,2529,2537,2543],{"__ignoreMap":424},[672,2461,2462,2465],{"class":674,"line":675},[672,2463,2464],{"class":1258},"  pair",[672,2466,1262],{"class":682},[672,2468,2469,2471,2473],{"class":674,"line":741},[672,2470,1328],{"class":1258},[672,2472,1277],{"class":682},[672,2474,2475],{"class":686}," ${BUZZ_IMAGE:-ghcr.io\u002Fblock\u002Fbuzz:main}\n",[672,2477,2478,2481,2483,2486,2488,2491,2493],{"class":674,"line":614},[672,2479,2480],{"class":1258},"    entrypoint",[672,2482,1277],{"class":682},[672,2484,2485],{"class":682}," [",[672,2487,690],{"class":682},[672,2489,2490],{"class":686},"\u002Fusr\u002Flocal\u002Fbin\u002Fbuzz-pair-relay",[672,2492,690],{"class":682},[672,2494,2495],{"class":682},"]\n",[672,2497,2498,2500],{"class":674,"line":776},[672,2499,1362],{"class":1258},[672,2501,1262],{"class":682},[672,2503,2504,2507,2509],{"class":674,"line":782},[672,2505,2506],{"class":1258},"      BUZZ_PAIR_RELAY_BIND_ADDR",[672,2508,1277],{"class":682},[672,2510,2511],{"class":686}," 0.0.0.0:5000\n",[672,2513,2514,2516],{"class":674,"line":827},[672,2515,1274],{"class":1258},[672,2517,1262],{"class":682},[672,2519,2520,2522,2524,2527],{"class":674,"line":832},[672,2521,1395],{"class":682},[672,2523,683],{"class":682},[672,2525,2526],{"class":686},"${BUZZ_PAIR_RELAY_PORT:-5000}:5000",[672,2528,701],{"class":682},[672,2530,2531,2533,2535],{"class":674,"line":838},[672,2532,1447],{"class":1258},[672,2534,1277],{"class":682},[672,2536,1452],{"class":686},[672,2538,2539,2541],{"class":674,"line":850},[672,2540,1458],{"class":1258},[672,2542,1262],{"class":682},[672,2544,2545,2548,2551],{"class":674,"line":855},[672,2546,2547],{"class":682},"      [",[672,2549,2550],{"class":686},"buzz-net",[672,2552,2495],{"class":682},[429,2554,2555,2556,2558,2559,2562],{},"在您的 ",[645,2557,1023],{}," 中声明 ",[645,2560,2561],{},"BUZZ_PAIRING_RELAY_URL"," 及其专用的运行端口号：",[664,2564,2567],{"className":2565,"code":2566,"language":1037},[1035],"BUZZ_PAIRING_RELAY_URL=wss:\u002F\u002Fbuzz.pafor.me\u002Fpair\nBUZZ_PAIR_RELAY_PORT=5000\n",[645,2568,2566],{"__ignoreMap":424},[429,2570,2571,2572,2575],{},"点击桌面端应用中的 Settings, 进入 “",[442,2573,2574],{},"Mobile","” 配对项：",[429,2577,2578],{},[435,2579],{"alt":2580,"src":2581},"Buzz 桌面客户端设置中展示的 Mobile 移动端配对配置标签页","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf-Hosting%20Buzz%20As%20The%20Workspace%20Where%20AI%20Agents%20Become%20Colleagues\u002Fbuzz-settings-mobile-tab.webp",[429,2583,2584],{},"点击 “Start pairing” —— 界面会生成专属的绑定二维码；打开手机端 App 扫一扫，接着在桌面端点击 “Code Match” 确认无误，双端便立即完成信任绑定。",[429,2586,2587],{},[435,2588],{"alt":2589,"src":2590},"在桌面客户端中生成安全的配对二维码，用于同步 Buzz 手机端 App","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf-Hosting%20Buzz%20As%20The%20Workspace%20Where%20AI%20Agents%20Become%20Colleagues\u002Fbuzz-desktop-client-pairing-qr-code.webp",[429,2592,2593],{},"注意：手机端应用中的智能体之所以能随叫随到，是基于您的桌面端应用在后台持续维系运行。只有保障桌面机处于在线状态，手机端派发的智能体指令才能被顺利分发与执行。",[429,2595,2596],{},[435,2597],{"alt":2598,"src":2599},"在手机端 Buzz App 中成功加载同步后的活跃 AI 智能体列表","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf-Hosting%20Buzz%20As%20The%20Workspace%20Where%20AI%20Agents%20Become%20Colleagues\u002Fbuzz-mobile-app-active-agents.webp",[447,2601,2602],{"id":2602},"结语",[429,2604,2605],{},"不可否认，作为一个还处于发展初期的技术方案，Buzz 在面对大规模生产环境时依然稍显稚嫩，伴随着一些偶发的系统 Bug 与界面交互上的限制。但对于小型团队或单兵作战的独立开发者而言，这无疑是一场令人血脉偾张的前沿探索。它为我们揭开了一幅波澜壮阔的人机无缝协奏画卷，让我们提前触碰到了“AI 智能体成为工作伙伴”的未来工作模式。",[447,2607,2608],{"id":2608},"参考资源",[455,2610,2611,2618,2625,2632],{},[458,2612,2613],{},[569,2614,2617],{"href":2615,"rel":2616},"https:\u002F\u002Fgithub.com\u002Fblock\u002Fbuzz",[1655],"Buzz releases",[458,2619,2620],{},[569,2621,2624],{"href":2622,"rel":2623},"https:\u002F\u002Fblock.xyz\u002Finside\u002Fintroducing-buzz-where-humans-and-agents-work-together",[1655],"Introducing Buzz",[458,2626,2627],{},[569,2628,2631],{"href":2629,"rel":2630},"https:\u002F\u002Fwww.hostinger.com\u002Ftutorials\u002Fwhat-is-buzz",[1655],"What is buzz",[458,2633,2634],{},[569,2635,2638],{"href":2636,"rel":2637},"https:\u002F\u002Fmiget.com\u002Fblog\u002Fhow-to-self-host-buzz",[1655],"How to self-host Buzz (Miget)",[2640,2641,2642],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}",{"title":424,"searchDepth":741,"depth":614,"links":2644},[2645,2646,2647,2661,2670,2671,2672],{"id":449,"depth":741,"text":450},{"id":496,"depth":741,"text":497},{"id":544,"depth":741,"text":545,"children":2648},[2649,2650,2654,2655,2656,2660],{"id":549,"depth":614,"text":550},{"id":583,"depth":614,"text":584,"children":2651},[2652,2653],{"id":588,"depth":776,"text":589},{"id":704,"depth":776,"text":705},{"id":723,"depth":614,"text":724},{"id":970,"depth":614,"text":971},{"id":1131,"depth":614,"text":1132,"children":2657},[2658,2659],{"id":1135,"depth":776,"text":1136},{"id":1536,"depth":776,"text":1537},{"id":1603,"depth":614,"text":1604},{"id":1646,"depth":741,"text":1647,"children":2662},[2663,2664,2665],{"id":1732,"depth":614,"text":1733},{"id":1777,"depth":614,"text":1778},{"id":1814,"depth":614,"text":1814,"children":2666},[2667,2668,2669],{"id":1837,"depth":776,"text":1838},{"id":2080,"depth":776,"text":2081},{"id":2154,"depth":776,"text":2155},{"id":2414,"depth":741,"text":2415},{"id":2602,"depth":741,"text":2602},{"id":2608,"depth":741,"text":2608},[2674,2675,2065],"collaboration","ai-agents","2026-09-08","本教程将手把手带您在 Ubuntu VPS 上部署自托管的 Block 旗下 Nostr 中继服务 Buzz，并配置 Cloudflare DNS 安全网络。我们将帮助您搭建起一个安全性的共享工作空间，让您的团队成员与多个 AI 智能体（如 Claude、Kimi）能够基于加密身份进行高效沟通、共享项目上下文并实现无缝协作。","md","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf-Hosting%20Buzz%20As%20The%20Workspace%20Where%20AI%20Agents%20Become%20Colleagues\u002FZH-Self-Hosting-Buzz-As-The-Workspace-Where-AI-Agents-Become-Colleagues.webp","一张高颜值的 16:9 科技质感卡片，具有深蓝色和橙色色调，插图展示如何在 Ubuntu VPS 上部署自托管的 Block 旗下 Buzz 协作中继服务器，其中包含一个带有居中文字的毛玻璃微动质感面板。",{"schemaOrg":2682,"robots":2704,"sitemap":2705},[2683,2685],{"@type":2684,"headline":423,"description":2677,"image":2679},"TechArticle",{"@type":2686,"name":423,"description":2677,"image":2679,"step":2687},"HowTo",[2688,2692,2695,2698,2701],{"@type":2689,"name":2690,"text":2691},"HowToStep","阶段 1：Cloudflare 设置","创建 Cloudflare API 令牌并配置 DNS 解析设置。",{"@type":2689,"name":2693,"text":2694},"阶段 2：安装 Docker","在 Ubuntu VPS 上设置并安装 Docker 容器引擎。",{"@type":2689,"name":2696,"text":2697},"阶段 3：克隆与配置","克隆仓库代码并配置 docker-compose 环境变量。",{"@type":2689,"name":2699,"text":2700},"阶段 4：集成 Caddy","编译带有 Cloudflare DNS 挑战模块的的自定义 Caddy 镜像。",{"@type":2689,"name":2702,"text":2703},"阶段 5：自动备份","配置 cron 定时任务以实现 PostgreSQL 数据库的自动备份。","index, follow",{"lastmod":2706},"2026-09-03",{"title":2708,"description":2677,"ogTitle":423,"ogDescription":2677,"twitterTitle":423,"twitterDescription":2677},"如何在 Ubuntu VPS 上自建 Block 旗下的 Buzz 协作中继服务器","zh\u002Farticle\u002Fself-hosting-buzz-as-the-workspace-where-ai-agents-become-colleagues",[2711,2712,444,2713,2714],"Nostr","Docker","Caddy","Cloudflare",null,"Plt5qPXpCpnSq9t6cSV6VM3z9k3i2BkoxxI46S98hdM",{"surround":2718,"related":6044},[2719,4627],{"id":2720,"title":2721,"author":2715,"body":2722,"category":4609,"date":4611,"description":4612,"extension":2678,"image":4613,"imageAlt":4614,"isPublished":772,"meta":4615,"minRead":959,"navigation":772,"path":329,"seo":4622,"stem":4623,"tags":4624,"updatedAt":2706,"__hash__":4626},"article\u002Fzh\u002Farticle\u002Fself-hosted-travel-planner-trek.md","使用Docker与TREK自托管您的个性化智能旅行日程：一站式深度规划并轻松管理预订、财务和行李清单",{"type":426,"value":2723,"toc":4568},[2724,2727,2730,2733,2737,2741,2883,2886,2892,2911,2914,2917,3021,3032,3035,3040,3043,3054,3058,3062,3065,3068,3108,3112,3115,3148,3151,3191,3194,3199,3210,3214,3221,3225,3228,3320,3324,3327,3331,3338,3342,3345,3363,3374,3378,3381,3392,3396,3400,3411,3415,3419,3422,3426,3430,3433,3438,3441,3446,3452,3456,3460,3463,3467,3479,3484,3490,3495,3499,3502,3507,3512,3515,3522,3526,3529,3532,3542,3548,3553,3560,3565,3569,3575,3580,3583,3588,3592,3598,3602,3607,3611,3614,3617,3622,3627,3632,3636,3643,3648,3653,3658,3663,3667,3673,3678,3684,3688,3691,3695,3701,3706,3711,3717,3722,3727,3732,3746,3750,3755,3776,3781,3784,3788,3791,3796,3799,3847,3851,3858,3864,3869,3875,3880,3886,3891,3897,3900,3905,3912,3917,3923,3927,3934,3939,3942,3946,3950,3956,3960,3963,3970,3974,3981,3985,3997,4002,4006,4010,4020,4030,4035,4042,4047,4054,4058,4061,4227,4230,4234,4237,4242,4245,4251,4255,4262,4266,4269,4274,4281,4286,4290,4301,4372,4388,4391,4396,4400,4404,4415,4492,4506,4509,4513,4517,4520,4523,4526,4529,4538,4542,4565],[429,2725,2726],{},"在规划旅行时，最繁琐的部分莫过于那些零散的数据：机票预订PDF、酒店确认信、旅伴之间的聊天记录、想去的景点清单等，都散落在不同的角落。而当需要汇总总花销、拆分账单时，又得在海量的出行记录中不停翻找，极为耗费精力。",[429,2728,2729],{},"TREK是一款可以自托管的开源旅行规划系统，能够将您的行程、预订、财务预算和行李清单一站式整合到同一个平台中。其内置的MCP（Model Context Protocol）服务器还允许AI智能体（如Claude Desktop）直接操作您的出行数据。",[429,2731,2732],{},"本教程将带您一步步完成从系统部署到完整管理一次真实旅行的全过程。",[547,2734,2736],{"id":2735},"_1-如何使用docker部署trek旅行规划器","1. 如何使用Docker部署TREK旅行规划器",[586,2738,2740],{"id":2739},"在ubuntu-vps上安装docker","在Ubuntu VPS上安装Docker",[664,2742,2744],{"className":666,"code":2743,"language":668,"meta":424,"style":424},"# Add Docker's official GPG key and set up the Docker repository\ncurl -fsSL https:\u002F\u002Fdownload.docker.com\u002Flinux\u002Fubuntu\u002Fgpg | sudo gpg --dearmor -o \u002Fusr\u002Fshare\u002Fkeyrings\u002Fdocker-archive-keyring.gpg\n\n# Add the official Docker repository\necho \"deb [arch=amd64 signed-by=\u002Fusr\u002Fshare\u002Fkeyrings\u002Fdocker-archive-keyring.gpg] https:\u002F\u002Fdownload.docker.com\u002Flinux\u002Fubuntu $(lsb_release -cs) stable\" | sudo tee \u002Fetc\u002Fapt\u002Fsources.list.d\u002Fdocker.list > \u002Fdev\u002Fnull\n\n# Update package list\nsudo apt update\n\n# Install Docker Engine, Docker Community Edition, and containerd runtime\nsudo apt install docker-ce docker-ce-cli containerd.io -y\n\n# Verify docker is installed\ndocker --version\n\n# Starts automatically when your system boots\nsudo systemctl enable docker\n",[645,2745,2746,2750,2770,2774,2778,2810,2814,2818,2826,2830,2834,2850,2854,2858,2864,2868,2873],{"__ignoreMap":424},[672,2747,2748],{"class":674,"line":675},[672,2749,738],{"class":737},[672,2751,2752,2754,2756,2758,2760,2762,2764,2766,2768],{"class":674,"line":741},[672,2753,679],{"class":678},[672,2755,746],{"class":686},[672,2757,749],{"class":686},[672,2759,752],{"class":682},[672,2761,755],{"class":678},[672,2763,758],{"class":686},[672,2765,761],{"class":686},[672,2767,764],{"class":686},[672,2769,767],{"class":686},[672,2771,2772],{"class":674,"line":614},[672,2773,773],{"emptyLinePlaceholder":772},[672,2775,2776],{"class":674,"line":776},[672,2777,779],{"class":737},[672,2779,2780,2782,2784,2786,2788,2790,2792,2794,2796,2798,2800,2802,2804,2806,2808],{"class":674,"line":782},[672,2781,786],{"class":785},[672,2783,683],{"class":682},[672,2785,791],{"class":686},[672,2787,794],{"class":682},[672,2789,797],{"class":678},[672,2791,800],{"class":686},[672,2793,803],{"class":682},[672,2795,806],{"class":686},[672,2797,690],{"class":682},[672,2799,752],{"class":682},[672,2801,755],{"class":678},[672,2803,815],{"class":686},[672,2805,818],{"class":686},[672,2807,821],{"class":682},[672,2809,824],{"class":686},[672,2811,2812],{"class":674,"line":827},[672,2813,773],{"emptyLinePlaceholder":772},[672,2815,2816],{"class":674,"line":832},[672,2817,835],{"class":737},[672,2819,2820,2822,2824],{"class":674,"line":838},[672,2821,841],{"class":678},[672,2823,844],{"class":686},[672,2825,847],{"class":686},[672,2827,2828],{"class":674,"line":850},[672,2829,773],{"emptyLinePlaceholder":772},[672,2831,2832],{"class":674,"line":855},[672,2833,858],{"class":737},[672,2835,2836,2838,2840,2842,2844,2846,2848],{"class":674,"line":861},[672,2837,841],{"class":678},[672,2839,844],{"class":686},[672,2841,868],{"class":686},[672,2843,871],{"class":686},[672,2845,874],{"class":686},[672,2847,877],{"class":686},[672,2849,880],{"class":686},[672,2851,2852],{"class":674,"line":883},[672,2853,773],{"emptyLinePlaceholder":772},[672,2855,2856],{"class":674,"line":888},[672,2857,916],{"class":737},[672,2859,2860,2862],{"class":674,"line":894},[672,2861,922],{"class":678},[672,2863,925],{"class":686},[672,2865,2866],{"class":674,"line":908},[672,2867,773],{"emptyLinePlaceholder":772},[672,2869,2870],{"class":674,"line":913},[672,2871,2872],{"class":737},"# Starts automatically when your system boots\n",[672,2874,2875,2877,2879,2881],{"class":674,"line":919},[672,2876,841],{"class":678},[672,2878,899],{"class":686},[672,2880,902],{"class":686},[672,2882,905],{"class":686},[586,2884,2885],{"id":2885},"生成加密密钥",[429,2887,2888,2889,2891],{},"TREK使用一个专门的密钥来加密敏感数据。您可以使用以下命令或这个",[569,2890,1065],{"href":1064},"来生成加密密钥：",[664,2893,2895],{"className":666,"code":2894,"language":668,"meta":424,"style":424},"openssl rand -hex 32\n",[645,2896,2897],{"__ignoreMap":424},[672,2898,2899,2902,2905,2908],{"class":674,"line":675},[672,2900,2901],{"class":678},"openssl",[672,2903,2904],{"class":686}," rand",[672,2906,2907],{"class":686}," -hex",[672,2909,2910],{"class":1312}," 32\n",[429,2912,2913],{},"请务必将其妥善保存在安全的地方。如果遗失该密钥，您将无法访问已加密的数据。",[586,2915,2916],{"id":2916},"启动容器",[664,2918,2920],{"className":666,"code":2919,"language":668,"meta":424,"style":424},"docker run -d \\\n  --name trek \\\n  -p 3000:3000 \\\n  -e ENCRYPTION_KEY=\"\u003Cgenerated_key>\" \\\n  -e APP_URL=\"https:\u002F\u002Ftrek.pafor.me\" \\\n  -v .\u002Fdata:\u002Fapp\u002Fdata \\\n  -v .\u002Fuploads:\u002Fapp\u002Fuploads \\\n  --restart unless-stopped \\\n  mauriceboe\u002Ftrek:latest\n",[645,2921,2922,2934,2944,2954,2971,2987,2997,3006,3016],{"__ignoreMap":424},[672,2923,2924,2926,2928,2931],{"class":674,"line":675},[672,2925,922],{"class":678},[672,2927,1931],{"class":686},[672,2929,2930],{"class":686}," -d",[672,2932,2933],{"class":2013}," \\\n",[672,2935,2936,2939,2942],{"class":674,"line":741},[672,2937,2938],{"class":686},"  --name",[672,2940,2941],{"class":686}," trek",[672,2943,2933],{"class":2013},[672,2945,2946,2949,2952],{"class":674,"line":614},[672,2947,2948],{"class":686},"  -p",[672,2950,2951],{"class":686}," 3000:3000",[672,2953,2933],{"class":2013},[672,2955,2956,2959,2962,2964,2967,2969],{"class":674,"line":776},[672,2957,2958],{"class":686},"  -e",[672,2960,2961],{"class":686}," ENCRYPTION_KEY=",[672,2963,690],{"class":682},[672,2965,2966],{"class":686},"\u003Cgenerated_key>",[672,2968,690],{"class":682},[672,2970,2933],{"class":2013},[672,2972,2973,2975,2978,2980,2983,2985],{"class":674,"line":782},[672,2974,2958],{"class":686},[672,2976,2977],{"class":686}," APP_URL=",[672,2979,690],{"class":682},[672,2981,2982],{"class":686},"https:\u002F\u002Ftrek.pafor.me",[672,2984,690],{"class":682},[672,2986,2933],{"class":2013},[672,2988,2989,2992,2995],{"class":674,"line":827},[672,2990,2991],{"class":686},"  -v",[672,2993,2994],{"class":686}," .\u002Fdata:\u002Fapp\u002Fdata",[672,2996,2933],{"class":2013},[672,2998,2999,3001,3004],{"class":674,"line":832},[672,3000,2991],{"class":686},[672,3002,3003],{"class":686}," .\u002Fuploads:\u002Fapp\u002Fuploads",[672,3005,2933],{"class":2013},[672,3007,3008,3011,3014],{"class":674,"line":838},[672,3009,3010],{"class":686},"  --restart",[672,3012,3013],{"class":686}," unless-stopped",[672,3015,2933],{"class":2013},[672,3017,3018],{"class":674,"line":850},[672,3019,3020],{"class":686},"  mauriceboe\u002Ftrek:latest\n",[455,3022,3023],{},[458,3024,3025,3031],{},[442,3026,3027,3028],{},"必须正确设置 ",[645,3029,3030],{},"APP_URL"," —— 因为MCP服务器的OAuth授权发现流程完全依赖于它。请在一开始就将其设置为您最终的公开HTTPS地址。",[429,3033,3034],{},"首次运行需要一些时间来拉取镜像：",[435,3036],{"src":3037,"alt":3038,"style":3039},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-docker-pull-image.webp","TREK 的 Docker 拉取和运行日志","max-width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[429,3041,3042],{},"验证容器是否成功运行：",[664,3044,3046],{"className":666,"code":3045,"language":668,"meta":424,"style":424},"docker ps\n",[645,3047,3048],{"__ignoreMap":424},[672,3049,3050,3052],{"class":674,"line":675},[672,3051,922],{"class":678},[672,3053,1583],{"class":686},[435,3055],{"src":3056,"alt":3057,"style":3039},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-docker-ps-status.webp","通过 docker ps 验证运行中的容器状态",[547,3059,3061],{"id":3060},"_2-使用caddy反向代理配置域名路由与ssl证书","2. 使用Caddy反向代理配置域名路由与SSL证书",[429,3063,3064],{},"通行密钥（Passkeys）功能和MCP所需的OAuth授权都强制要求HTTPS加密。我们的域名托管在提供免费SSL证书和DDoS保护的Cloudflare上。",[429,3066,3067],{},"我们将Caddy配置为安全的反向代理服务器，用来指向容器的3000端口。Caddyfile配置示例如下：",[664,3069,3073],{"className":3070,"code":3071,"language":3072,"meta":424,"style":424},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{$TREK_DOMAIN} {\n  encode zstd gzip\n  reverse_proxy host.docker.internal:3000\n}\n","json",[645,3074,3075,3089,3094,3104],{"__ignoreMap":424},[672,3076,3077,3080,3083,3086],{"class":674,"line":675},[672,3078,3079],{"class":682},"{",[672,3081,3082],{"class":2013},"$TREK_DOMAIN",[672,3084,3085],{"class":682},"}",[672,3087,3088],{"class":682}," {\n",[672,3090,3091],{"class":674,"line":741},[672,3092,3093],{"class":2013},"  encode zstd gzip\n",[672,3095,3096,3099,3101],{"class":674,"line":614},[672,3097,3098],{"class":2013},"  reverse_proxy host.docker.internal",[672,3100,1277],{"class":682},[672,3102,3103],{"class":1312},"3000\n",[672,3105,3106],{"class":674,"line":776},[672,3107,1181],{"class":682},[547,3109,3111],{"id":3110},"_3-初始配置与安全的管理员设置","3. 初始配置与安全的管理员设置",[429,3113,3114],{},"创建管理员账户有两种方式：",[455,3116,3117,3129],{},[458,3118,3119,3128],{},[442,3120,3121,3122,1124,3125],{},"在环境配置中直接设置 ",[645,3123,3124],{},"ADMIN_EMAIL",[645,3126,3127],{},"ADMIN_PASSWORD"," 变量，系统将直接使用该凭证。",[458,3130,3131,3132,3135,3136,3139,3140,3143,3144,3147],{},"TREK会自动生成一个邮箱 ",[645,3133,3134],{},"admin@trek.local","、用户名 ",[645,3137,3138],{},"admin","，以及一个",[442,3141,3142],{},"随机生成的密码，并打印到容器日志中","。运行 ",[645,3145,3146],{},"docker logs trek"," 即可获取。",[429,3149,3150],{},"如果您在日志中找不到密码，可以通过以下命令进行手动重置：",[664,3152,3154],{"className":666,"code":3153,"language":668,"meta":424,"style":424},"docker exec -it -e RESET_ADMIN_EMAIL=admin@trek.local -e RESET_ADMIN_PASSWORD='YourNewPassword' trek node server\u002Freset-admin.js\n",[645,3155,3156],{"__ignoreMap":424},[672,3157,3158,3160,3162,3165,3168,3171,3173,3176,3178,3181,3183,3185,3188],{"class":674,"line":675},[672,3159,922],{"class":678},[672,3161,1692],{"class":686},[672,3163,3164],{"class":686}," -it",[672,3166,3167],{"class":686}," -e",[672,3169,3170],{"class":686}," RESET_ADMIN_EMAIL=admin@trek.local",[672,3172,3167],{"class":686},[672,3174,3175],{"class":686}," RESET_ADMIN_PASSWORD=",[672,3177,1895],{"class":682},[672,3179,3180],{"class":686},"YourNewPassword",[672,3182,1895],{"class":682},[672,3184,2941],{"class":686},[672,3186,3187],{"class":686}," node",[672,3189,3190],{"class":686}," server\u002Freset-admin.js\n",[429,3192,3193],{},"在首次登录时，系统会提示您修改初始密码。",[435,3195],{"src":3196,"alt":3197,"style":3198},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-initial-login-password-prompt.webp","初始登录和管理员密码重置提示","max-width: 215px; width:100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[429,3200,602,3201,3204,3205],{},[442,3202,3203],{},"Admin（管理员）"," 选项卡并更新您的电子邮箱：",[435,3206],{"src":3207,"alt":3208,"style":3209},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-admin-email-update-panel.webp","在 TREK 管理员设置中配置自定义电子邮件","max-width: 700px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[586,3211,3213],{"id":3212},"_31-备份策略","3.1 备份策略",[429,3215,3216,3217],{},"在管理员后台，可以非常方便地配置带有保留策略的自动备份方案：\n",[435,3218],{"src":3219,"alt":3220,"style":3039},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-admin-backup-retention-policy.webp","配置自动备份计划和保留规则",[586,3222,3224],{"id":3223},"_32-将上传的文件存储到cloudflare-r2","3.2 将上传的文件存储到Cloudflare R2",[429,3226,3227],{},"将上传的文件、照片和备份数据保存在Cloudflare R2中，能够让您的VPS磁盘保持干净和轻量。TREK全面支持S3兼容的存储后端，而Cloudflare R2正是这一需求的完美解决方案。",[591,3229,3230,3237,3249,3260,3271,3283,3294,3309],{},[458,3231,3232,3233,3236],{},"新建一个名为 ",[645,3234,3235],{},"trek"," 的R2存储桶。",[458,3238,1674,3239,3242,3243,3244],{},[442,3240,3241],{},"Account Details（账户详情）"," 区域，找到您的账户ID：","\n  ",[435,3245],{"src":3246,"alt":3247,"style":3248},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Fcloudflare-r2-account-details-id.webp","在控制台中定位 Cloudflare 帐户 ID","max-width: 325px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[458,3250,602,3251,3254,3243,3255],{},[442,3252,3253],{},"Manage API Tokens（管理API令牌）","：",[435,3256],{"src":3257,"alt":3258,"style":3259},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Fcloudflare-r2-manage-api-tokens-button.webp","Cloudflare 控制台中的管理 API 令牌界面","max-width: 282px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[458,3261,602,3262,3265,3243,3266],{},[442,3263,3264],{},"Create Account API token（创建账户API令牌）","，并授予针对该桶的读写权限：",[435,3267],{"src":3268,"alt":3269,"style":3270},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Fcloudflare-r2-create-token-permissions.webp","创建具有读写权限的 R2 访问令牌","max-width: 360px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[458,3272,3273,3274,3277,3243,3278],{},"在管理员面板中，点击 ",[442,3275,3276],{},"Storage（存储）"," 配置页：",[435,3279],{"src":3280,"alt":3281,"style":3282},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-administration-storage-menu.webp","导航到 TREK 控制面板中的存储设置","max-width: 539px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[458,3284,602,3285,3288,3243,3289],{},[442,3286,3287],{},"Add Backend（添加后端）"," 按钮，填入您的Endpoint（终结点）、Bucket（存储桶名称）和API凭证：",[435,3290],{"src":3291,"alt":3292,"style":3293},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-add-storage-backend-credentials.webp","配置 S3 兼容的 Cloudflare R2 存储后端","max-width: 445px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[458,3295,602,3296,3299,3300,3303,3243,3304],{},[442,3297,3298],{},"Apply（应用）","，然后点击 ",[442,3301,3302],{},"Test（测试）"," 链接。当看到“Connection OK”字样时，说明连接测试成功：",[435,3305],{"src":3306,"alt":3307,"style":3308},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-test-storage-backend-connection-ok.webp","存储后端连接测试成功，显示 Connection OK","max-width: 677px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[458,3310,3311,3312,3254,3243,3315],{},"将所有存储类别切换为Cloudflare R2并点击 ",[442,3313,3314],{},"Save changes（保存修改）",[435,3316],{"src":3317,"alt":3318,"style":3319},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-switch-storage-categories-r2.webp","将所有 file 存储分类路由到 Cloudflare R2","max-width: 653px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[586,3321,3323],{"id":3322},"_33-通行密钥passkey登录","3.3 通行密钥（Passkey）登录",[429,3325,3326],{},"TREK支持通行密钥、双重身份验证（2FA）以及基于OIDC的单点登录。如果想开启通行密钥，请在设置中输入您的域名和Allowed Origins（允许的源），然后保存即可：",[435,3328],{"src":3329,"alt":3330,"style":3039},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-passkey-allowed-origins-settings.webp","注册用于安全金钥（Passkey）身份验证的允许源",[429,3332,3333,3334,3337],{},"如果没有正确配置 ",[442,3335,3336],{},"Allowed Origins","，通行密钥注册将会失败。",[586,3339,3341],{"id":3340},"_34-google-maps-api密钥","3.4 Google Maps API密钥",[429,3343,3344],{},"配置Google Maps密钥可以让您的地点检索功能变得更丰富，自动补充评分、营业时间和地点实景图。如果您不配置密钥，TREK会默认降级使用免费的OpenStreetMap（只是不显示评分和实景照片）。",[429,3346,3347,3348,3353,3354,3357,3358],{},"访问此",[569,3349,3352],{"href":3350,"rel":3351},"https:\u002F\u002Fmapsplatform.google.com\u002Fmaps-demo-key\u002F",[1655],"链接","并点击 ",[442,3355,3356],{},"Get demo key"," 即可申请一个测试密钥：                                                  ",[435,3359],{"src":3360,"alt":3361,"style":3362},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Fgoogle-maps-get-demo-api-key.webp","申请 Google Maps Platform API 密钥","max-width: 176px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[429,3364,3365,3366,3369,3370],{},"将获取到的API Key粘贴到设置中，然后点击 ",[442,3367,3368],{},"Test"," 验证连接是否通畅：\n",[435,3371],{"src":3372,"alt":3373,"style":3039},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-google-maps-key-test-connection.webp","在设置中验证 Google Maps API 密钥的连通性",[586,3375,3377],{"id":3376},"_35-ai集成","3.5 AI集成",[429,3379,3380],{},"内置的AI解析引擎主要用于处理您的预订确认邮件和PDF，将它们自动转换为结构化的预订数据。",[429,3382,3383,3384,3387,3388,3391],{},"点击左侧菜单中的 ",[442,3385,3386],{},"Addons（附加组件）"," 并启用 ",[442,3389,3390],{},"AI Parsing","。选择“OpenAI”（或其它兼容的AI提供商）并填写相应的凭证信息：",[435,3393],{"src":3394,"alt":3395,"style":3039},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-addons-enable-ai-parsing-openai.webp","启用带有 OpenAI 集成的 AI 解析插件",[586,3397,3399],{"id":3398},"_36-mcp访问权限","3.6 MCP访问权限",[429,3401,3402,3403,3406,3407,3410],{},"同样在 ",[442,3404,3405],{},"Addons"," 选项中，开启 ",[442,3408,3409],{},"MCP"," 协议：",[435,3412],{"src":3413,"alt":3414,"style":3039},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-addons-enable-mcp.webp","启用 Model Context Protocol MCP 服务器插件",[586,3416,3418],{"id":3417},"_37-插件推荐","3.7 插件推荐",[429,3420,3421],{},"以下几款官方插件非常推荐您顺手激活：",[435,3423],{"src":3424,"alt":3425,"style":3039},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-recommended-addons-plugins-activation.webp","活跃的推荐插件和扩展列表",[586,3427,3429],{"id":3428},"_38-创建您的日常使用账户","3.8 创建您的日常使用账户",[429,3431,3432],{},"在平时规划旅行时，建议使用普通用户账户，而非管理员账户。让我们在后台创建一个日常账户并登录：",[435,3434],{"src":3435,"alt":3436,"style":3437},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-create-regular-user-form.webp","在 TREK 面板中创建普通用户账户","max-width: 420px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[429,3439,3440],{},"登录后，建议立刻绑定通行密钥或设置2FA来强化该账户的安全级别：",[435,3442],{"src":3443,"alt":3444,"style":3445},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-user-security-passkey-2fa-setup.webp","使用安全金钥（Passkey）和双重认证配置用户安全设置","max-width: 381px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[429,3447,602,3448,3451],{},[442,3449,3450],{},"+ Add a passkey","，输入当前密码，然后按照浏览器提示完成安全确认：",[435,3453],{"src":3454,"alt":3455,"style":3039},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-add-passkey-confirm-password.webp","确认密码以注册新的硬件安全金钥",[547,3457,3459],{"id":3458},"_4-测试您的部署导入历史出行数据","4. 测试您的部署：导入历史出行数据",[429,3461,3462],{},"快速上手并熟悉TREK系统的一个极佳方式是，将您过去走过的旅行足迹录入其中。",[586,3464,3466],{"id":3465},"_41-创建旅行计划","4.1 创建旅行计划",[429,3468,602,3469,3472,3473,1124,3476,3254],{},[442,3470,3471],{},"+ New Trip（新建旅行）","，并根据那次历史旅行的真实起止时间设定 ",[442,3474,3475],{},"Start Date",[442,3477,3478],{},"End Date",[435,3480],{"src":3481,"alt":3482,"style":3483},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-create-new-trip-details.webp","创建具有自定义日期范围的新旅行","max-width: 334px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[429,3485,3486,3487,3254],{},"上传一张好看的封面图（可以直接将图片拖入或从剪贴板粘贴），接着点击 ",[442,3488,3489],{},"Create New Trip",[435,3491],{"src":3492,"alt":3493,"style":3494},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-trip-cover-image-upload.webp","配置高质量的旅行封面图片","max-width: 608px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[586,3496,3498],{"id":3497},"_42-导入预订信息","4.2 导入预订信息",[429,3500,3501],{},"将您当时留存的机票、火车票和其它交通工具预订确认文件直接拖放到上传区域：",[435,3503],{"src":3504,"alt":3505,"style":3506},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-import-travel-booking-files.webp","用于导入旅行 PDF 和预订文件的拖拽区域","max-width: 570px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[435,3508],{"src":3509,"alt":3510,"style":3511},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-import-booking-pdf-processing-status.webp","已上传预订的处理窗口，显示提取状态","max-width: 377px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[429,3513,3514],{},"由于我们已经启用了AI解析引擎，预订确认PDF文件会被自动分析，提取出结构化的预订日程。",[429,3516,3517,3518,3521],{},"检查解析结果无误后，点击 ",[442,3519,3520],{},"Add"," 将其正式写入预订数据中：",[435,3523],{"src":3524,"alt":3525,"style":3039},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-review-parsed-booking-details.webp","审查由 AI 提取的结构化预订细节",[429,3527,3528],{},"如果有些预订确认仅保存在邮件中，您可以将其导出为PDF格式并上传，同样可以走这套提取流程。",[429,3530,3531],{},"在系统中，已导入的预订信息会以极具现代感的方式呈现：",[429,3533,3534,3538],{},[435,3535],{"src":3536,"alt":3537,"style":3039},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-trip-bookings-timeline-view.webp","旅行预订的完整时间线展示",[435,3539],{"src":3540,"alt":3541,"style":3039},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-booking-confirmation-details.webp","已确认交通预订的详细视图",[429,3543,1674,3544,3547],{},[442,3545,3546],{},"Plan（日程规划）"," 页面中，所有的酒店和住宿点都会在地图上被优雅地标注出来：",[435,3549],{"src":3550,"alt":3551,"style":3552},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-plan-accommodations-map-display.webp","标有所有酒店住宿的交互式地图","max-width: 546px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[429,3554,3555,3556,3559],{},"点击上方的 ",[442,3557,3558],{},"Atlas（旅行足迹）","，您将能从清单和世界地图上直观地看到所有已拜访的国家：",[435,3561],{"src":3562,"alt":3563,"style":3564},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-atlas-countries-visited-summary.webp","个人 Atlas 追踪器中的旅行历史概述","max-width: 407px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[586,3566,3568],{"id":3567},"_43-添加旅行同伴","4.3 添加旅行同伴",[429,3570,602,3571,3574],{},[442,3572,3573],{},"Share（分享）"," 按钮：",[435,3576],{"src":3577,"alt":3578,"style":3579},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-trip-share-options-button.webp","在 TREK 中打开旅行分享对话框","max-width: 224px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[429,3581,3582],{},"在弹出的对话框底部，可以直接添加旅行同伴为Guest（嘉宾）：",[435,3584],{"src":3585,"alt":3586,"style":3587},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-trip-add-companions-guests.webp","添加自定义旅行同伴和随行客人","max-width: 635px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[586,3589,3591],{"id":3590},"_44-记录旅行费用","4.4 记录旅行费用",[429,3593,602,3594,3597],{},[442,3595,3596],{},"Add expense（添加开销）","，来记录那些无法通过PDF预订单自动解析的杂项支出，例如境外险、当地公共交通费、临时SIM卡等：",[435,3599],{"src":3600,"alt":3601,"style":3039},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-add-custom-expense-form.webp","在支出表单中输入详细的花费数据",[435,3603],{"src":3604,"alt":3605,"style":3606},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-expenses-list-billing-split.webp","分摊账单明细和费用追踪账本","max-width: 526px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[586,3608,3610],{"id":3609},"_45-拆分旅行阶段","4.5 拆分旅行阶段",[429,3612,3613],{},"该功能需要提前在后台激活“Trip Segment”插件。",[429,3615,3616],{},"对于那些超长周期的旅程，将其拆分为不同的阶段能让脉络更清晰，每个阶段都可以有自己独立的预订项目、待办事项和成本账单：",[435,3618],{"src":3619,"alt":3620,"style":3621},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-trip-segments-overview-display.webp","将复杂的行程拆分为旅行段","max-width: 465px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[435,3623],{"src":3624,"alt":3625,"style":3626},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-trip-segment-itinerary-details.webp","显示地点和计划的活跃旅行段","max-width: 596px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[435,3628],{"src":3629,"alt":3630,"style":3631},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-trip-segments-interactive-map.webp","在时间线上绘制不同的旅行航段","max-width: 605px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[586,3633,3635],{"id":3634},"_46-创建journal日志并查看旅行足迹atlas","4.6 创建Journal（日志）并查看旅行足迹（Atlas）",[429,3637,3638,3639,3642],{},"您还可以将几次旅行串联成一个 ",[442,3640,3641],{},"Journey（旅程）","，并图文并茂地撰写游记故事，方便分享给您的朋友们：",[435,3644],{"src":3645,"alt":3646,"style":3647},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-create-new-journey-group.webp","将多次旅行合并为一个可视化的旅程","max-width: 441px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[435,3649],{"src":3650,"alt":3651,"style":3652},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-journey-timeline-story-writing.webp","在旅程面板中撰写可视化故事","max-width: 443px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[435,3654],{"src":3655,"alt":3656,"style":3657},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-journey-gallery-media-grid.webp","旅程内部的媒体收集和画廊网格","max-width: 440px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[435,3659],{"src":3660,"alt":3661,"style":3662},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-journey-public-share-link.webp","为协同旅程生成公开分享链接","max-width: 532px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[547,3664,3666],{"id":3665},"_5-设计自定义行程与行李清单","5. 设计自定义行程与行李清单",[429,3668,602,3669,3672],{},[442,3670,3671],{},"+ New Trip","，输入旅行的专属名称并指定起止日期：",[435,3674],{"src":3675,"alt":3676,"style":3677},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-planning-new-trip-setup.webp","创建未定日期旅行的初始提示对话框","max-width: 432px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[429,3679,3680,3683],{},[442,3681,3682],{},"如果具体的出行时间还没有敲定，可以将日期项留空。"," 此时系统会显示一个“天数配置（最高支持365天）”字段，您可以先设计每日的游玩内容，等后续买好机票后再一键锚定日期。",[586,3685,3687],{"id":3686},"_51-添加地点景点","5.1 添加地点\u002F景点",[429,3689,3690],{},"这是旅行规划中最耗时的一步，但TREK提供了四种极具效率的方式来帮助您添加地点：",[435,3692],{"src":3693,"alt":3694,"style":3039},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-add-places-methods-overview.webp","向行程添加新地点的多种途径",[429,3696,3697,3700],{},[442,3698,3699],{},"1. 直接在地图上右键点击："," 会在该坐标处直接创建新地点，其标准地址会被系统自动逆地理编码解析出来：",[435,3702],{"src":3703,"alt":3704,"style":3705},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-right-click-map-location.webp","在地图界面右键点击以精确定位","max-width: 632px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[435,3707],{"src":3708,"alt":3709,"style":3710},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-right-click-reverse-geocode-address.webp","所选地图坐标的自动逆地理编码","max-width: 628px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[429,3712,3713,3716],{},[442,3714,3715],{},"2. 点击 + Add Place\u002FActivity："," 在搜索框中直接通过关键字进行检索",[435,3718],{"src":3719,"alt":3720,"style":3721},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-search-place-by-name-input.webp","使用文本输入搜索真实地点","max-width: 642px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[435,3723],{"src":3724,"alt":3725,"style":3726},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-select-place-search-results-list.webp","显示带有地址标注的地点搜索结果列表","max-width: 594px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[435,3728],{"src":3729,"alt":3730,"style":3731},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-place-details-rich-info-card.webp","包含评论和评分的完整地点信息卡","max-width: 568px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[429,3733,3734,3737,3738,3741,3742,3745],{},[442,3735,3736],{},"3. 直接粘贴谷歌地图分享链接："," （如 ",[645,3739,3740],{},"maps.app.goo.gl\u002F…"," 或 ",[645,3743,3744],{},"maps.google.com\u002F…","）粘贴到检索栏中。TREK会自动抓取该地点的名称、地址和经纬度：",[435,3747],{"src":3748,"alt":3749,"style":3308},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-paste-google-maps-share-link.webp","直接从粘贴的 Google 地图分享链接解析地点",[435,3751],{"src":3752,"alt":3753,"style":3754},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-google-maps-parsed-location.webp","成功从地图 URL 中提取坐标","max-width: 543px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[429,3756,3757,3760,3761,3764,3765,3741,3768,3771,3772,3775],{},[442,3758,3759],{},"4. 批量导入数据："," 这是最轻松的方案。如果您在Google Maps中维护着自己的“想去清单”，可以将其导出为 ",[645,3762,3763],{},".gpx"," 文件（",[645,3766,3767],{},".kml",[645,3769,3770],{},".kmz"," 格式亦支持），然后点击右侧面板的 ",[442,3773,3774],{},"Import file","，一键拉取所有数据：",[435,3777],{"src":3778,"alt":3779,"style":3780},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-bulk-import-places-gpx-file.webp","使用 GPX 或 KML 文件批量导入地点","max-width: 389px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[429,3782,3783],{},"推荐您可以先把所有感兴趣的项目都添加进来。至于如何将它们科学地归入到每一天的日程中，后续可以直接在面板里拖拽处理。",[586,3785,3787],{"id":3786},"_52-每日日程与备注","5.2 每日日程与备注",[429,3789,3790],{},"Day Plan（每日计划）的核心逻辑是将所有的目的地按每日访问顺序进行排序。整个界面是一个可以折叠、支持任意拖放的模块：",[435,3792],{"src":3793,"alt":3794,"style":3795},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-day-plan-drag-drop-ordering.webp","使用拖放操作自定义每日路线顺序","max-width: 496px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[429,3797,3798],{},"这些细节机制设计得极其精妙实用：",[455,3800,3801,3811,3821,3831],{},[458,3802,3803,3806,3807],{},[442,3804,3805],{},"中间移动方式","：点击每日日程左上角的公共汽车图标，可以设定各节点之间的过渡交通方式（如地铁、自驾、甚至是直达航班）：\n",[435,3808],{"src":3809,"alt":3810,"style":3039},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-day-plan-commuting-transport-button.webp","登记日行程各段之间的通勤交通方式",[458,3812,3813,3816,3817],{},[442,3814,3815],{},"每日备忘","：点击左下角的便签图标可以附加各种定制化提醒（例如：“今天需要提早出发”、“美术馆门票需提前预约”）：\n",[435,3818],{"src":3819,"alt":3820,"style":3039},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-day-plan-icon-tagged-notes-button.webp","为天行程添加显眼的、带有图标的自定义备注",[458,3822,3823,3826,3827],{},[442,3824,3825],{},"指定时间段","：从右侧拖拽地点并给它分配一个开始时间。设置了时间的地点会自动在地图上生成推荐的行进路线：\n",[435,3828],{"src":3829,"alt":3830,"style":3039},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-day-plan-timed-places-routing.webp","带时间点的地点之间自动计算的交通路线",[458,3832,3833,3834,3837,3838,3841,3842,599],{},"关于智能路线优化（",[442,3835,3836],{},"Route optimisation","）以及气候（",[442,3839,3840],{},"Weather","），您可以查阅 ",[569,3843,3846],{"href":3844,"rel":3845},"https:\u002F\u002Fgithub.com\u002Fliketrek\u002FTREK\u002Fwiki\u002FDay-Plans-and-Notes",[1655],"Day Plans and Notes的Wiki文档",[586,3848,3850],{"id":3849},"_53-收藏夹可重复使用的地点清单","5.3 收藏夹：可重复使用的地点清单",[429,3852,3853,3854,3857],{},"Collections（收藏夹）允许用户在具体的旅行项目之外，保存并分类管理自己精心收集的宝藏地点。您可以将其打包分享给朋友。这些地点在加入旅行时是采用",[442,3855,3856],{},"复制","的方式，因此在旅行日程中对其进行的任何个性化标注，都不会破坏您收藏夹里的原始干净数据。",[429,3859,3860,3861,3254],{},"点击顶部菜单栏中的 ",[442,3862,3863],{},"Collections",[435,3865],{"src":3866,"alt":3867,"style":3868},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-collections-dashboard-view.webp","访问保存地点的自定义用户收藏夹","max-width: 495px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[429,3870,602,3871,3874],{},[442,3872,3873],{},"+ New list"," 建立新的分类列表：",[435,3876],{"src":3877,"alt":3878,"style":3879},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-collections-create-new-list.webp","在收藏夹中创建自定义列表","max-width: 269px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[429,3881,602,3882,3885],{},[442,3883,3884],{},"+ Add a place"," 并填入该地点的详细情况：",[435,3887],{"src":3888,"alt":3889,"style":3890},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-collections-add-place-manually-form.webp","手动输入表单以填充自定义收藏列表","max-width: 271px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[429,3892,3893,3896],{},[442,3894,3895],{},"注意："," 收藏夹内的搜索组件偶尔可能会因网络原因失效，如果发生该情况，您可以通过手动输入来创建。",[429,3898,3899],{},"当地点带有准确的GPS坐标时，它们会精美地展示在地图中：",[435,3901],{"src":3902,"alt":3903,"style":3904},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-collections-map-places-display.webp","在交互式地图上可视化自定义收藏中的地点","max-width: 592px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[429,3906,3907,3908,3911],{},"如需批量组织这些地标，可以点击 ",[442,3909,3910],{},"checkbox（勾选框）"," 图标：",[435,3913],{"src":3914,"alt":3915,"style":3916},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-collections-select-places-tickbox.webp","批量标记已保存地点的选择模式","max-width: 662px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[429,3918,3919,3920,3254],{},"多选目标后，点击 ",[442,3921,3922],{},"Assign label（分配标签）",[435,3924],{"src":3925,"alt":3926,"style":3754},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-collections-group-assign-label.webp","为选定的收藏地点分配描述性标签",[429,3928,3929,3930,3933],{},"在分配之前，先点击 ",[442,3931,3932],{},"Manage labels（管理标签）"," 来新建一些醒目的彩色分组标签：",[435,3935],{"src":3936,"alt":3937,"style":3938},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-collections-manage-custom-labels.webp","创建和管理自定义标签","max-width: 411px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[429,3940,3941],{},"点击一个具体标签，接着选择一键绑定：",[435,3943],{"src":3944,"alt":3945,"style":3564},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-collections-confirm-label-selection.webp","应用自定义标签到成组的地点",[586,3947,3949],{"id":3948},"_54-费用与预算","5.4 费用与预算",[429,3951,1674,3952,3955],{},[442,3953,3954],{},"Costs（财务管理）"," 页面中，我们可以录入其它的预备预算和旅途支出。",[435,3957],{"src":3958,"alt":3959,"style":3795},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-costs-budget-overall-expenses-list.webp","完整的支出表格和余额结算账本",[429,3961,3962],{},"在结伴出行时，您可以在此页记录每个人的垫付账单，并选定分摊规则。",[429,3964,3965,3966,3969],{},"系统的结算后台采用了一种贪心匹配算法，计算并生成",[442,3967,3968],{},"最简化的转账精算方案","，帮大家用最少的转账次数轻松对齐账目。",[547,3971,3973],{"id":3972},"_6-利用model-context-protocolmcp实现ai驱动的旅行规划","6. 利用Model Context Protocol（MCP）实现AI驱动的旅行规划",[429,3975,3976,3977,3980],{},"TREK内置了 ",[442,3978,3979],{},"MCP（模型上下文协议）服务器","。这意味着，AI智能体可以直接“读写”您的行程规划数据。它提供了超过150个精细的原子工具和30个核心数据源，全方位覆盖行程、地点、账目、行李、预订和多人协作。",[586,3982,3984],{"id":3983},"_61-cloudflare-zero-trust网络配置","6.1 Cloudflare Zero Trust网络配置",[429,3986,3987,3988,3991,3992,599],{},"由于我们的自托管服务运行在 ",[569,3989,3990],{"href":363},"Cloudflare Zero Trust"," 内网环境下，我们需要在“Split Tunnels（分流隧道）”配置中，将该服务的域名加入到 Inclusion List（包含\u002F直连白名单）中。否则在进行 OAuth 登录授权发现时，接口调用会被网络策略阻断。具体的配置排障可以参考这个 GitHub 讨论贴：",[569,3993,3996],{"href":3994,"rel":3995},"https:\u002F\u002Fgithub.com\u002Fliketrek\u002FTREK\u002Fissues\u002F1463",[1655],"GitHub Issue",[574,3998],{"description":3999,"image":577,"image-alt":4000,"label":579,"min-read":4001,"title":571,"to":363},"本文深入探讨如何使用 Cloudflare WARP 与 Zero Trust 技术，在完全不需要开启任何防火墙入站端口的情况下，安全地将您的 Hermes Agent 暴露到私有网络中，从而实现全球范围内的安全访问。这为您构建专属私有远程 AI 基础设施打下坚实基础。","通过 Cloudflare Zero Trust 和 WARP 隧道安全地将 Hermes Agent 暴露至私有网络","5",[435,4003],{"src":4004,"alt":4005,"style":3039},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Fcloudflare-zero-trust-split-tunnels-domain.webp","向 Cloudflare Warp 分流隧道（Split Tunnels）添加自定义域名",[586,4007,4009],{"id":4008},"_62-claude-desktop客户端配置","6.2 Claude Desktop客户端配置",[429,4011,602,4012,4015,4016],{},[442,4013,4014],{},"+ New Client"," 创设一个新的 AI 客户端接口：\n",[435,4017],{"src":4018,"alt":4019,"style":3039},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-register-new-mcp-client.webp","在设置中注册新的自定义客户端令牌",[429,4021,4022,4023,4026,4027,3254],{},"选择 ",[442,4024,4025],{},"Claude Desktop"," 选项卡，然后点击 ",[442,4028,4029],{},"Register Client（注册客户端）",[435,4031],{"src":4032,"alt":4033,"style":4034},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-mcp-claude-desktop-client-credentials.webp","生成 Claude Desktop 客户端凭据","max-width: 354px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[429,4036,4037,4038,4041],{},"系统此时会展示唯一的 Client ID 和 Client Secret，请妥善保存。接着点击 ",[442,4039,4040],{},"Client Configuration（客户端配置）"," 调出我们需要在本地写入的 JSON 代码片段：",[435,4043],{"src":4044,"alt":4045,"style":4046},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-mcp-client-configuration-block.webp","获取预格式化的 MCP 服务器配置块","max-width: 508px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[429,4048,4049,4050,4053],{},"在 Claude Desktop 软件中，点击 ",[442,4051,4052],{},"Edit Config"," 会在代码编辑器中打开您本地的 MCP server 配置文件：",[435,4055],{"src":4056,"alt":4057,"style":3039},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Fclaude-desktop-mcp-config-json.webp","编辑 Claude Desktop 的本地 MCP 配置文件 json",[429,4059,4060],{},"将 TREK 的 MCP 代码块粘贴进去，并把占位符部分替换为上一步生成的客户端凭证：",[664,4062,4064],{"className":3070,"code":4063,"language":3072,"meta":424,"style":424},"  \"mcpServers\": {\n    \"trek\": {\n      \"command\": \"npx\",\n      \"args\": [\n        \"mcp-remote\",\n        \"https:\u002F\u002Ftrek.pafor.me\u002Fmcp\",\n        \"--static-oauth-client-info\",\n        \"{\\\"client_id\\\": \\\"\u003Cyour_client_id>\\\", \\\"client_secret\\\": \\\"\u003Cyour_client_secret>\\\"}\"\n      ]\n    }\n  },\n",[645,4065,4066,4081,4094,4116,4130,4142,4153,4164,4210,4215,4220],{"__ignoreMap":424},[672,4067,4068,4071,4074,4076,4079],{"class":674,"line":675},[672,4069,4070],{"class":682},"  \"",[672,4072,4073],{"class":686},"mcpServers",[672,4075,690],{"class":682},[672,4077,4078],{"class":2013},": ",[672,4080,1167],{"class":682},[672,4082,4083,4086,4088,4090,4092],{"class":674,"line":741},[672,4084,4085],{"class":682},"    \"",[672,4087,3235],{"class":1280},[672,4089,690],{"class":682},[672,4091,1277],{"class":682},[672,4093,3088],{"class":682},[672,4095,4096,4099,4102,4104,4106,4108,4111,4113],{"class":674,"line":614},[672,4097,4098],{"class":682},"      \"",[672,4100,4101],{"class":678},"command",[672,4103,690],{"class":682},[672,4105,1277],{"class":682},[672,4107,683],{"class":682},[672,4109,4110],{"class":686},"npx",[672,4112,690],{"class":682},[672,4114,4115],{"class":682},",\n",[672,4117,4118,4120,4123,4125,4127],{"class":674,"line":776},[672,4119,4098],{"class":682},[672,4121,4122],{"class":678},"args",[672,4124,690],{"class":682},[672,4126,1277],{"class":682},[672,4128,4129],{"class":682}," [\n",[672,4131,4132,4135,4138,4140],{"class":674,"line":782},[672,4133,4134],{"class":682},"        \"",[672,4136,4137],{"class":686},"mcp-remote",[672,4139,690],{"class":682},[672,4141,4115],{"class":682},[672,4143,4144,4146,4149,4151],{"class":674,"line":827},[672,4145,4134],{"class":682},[672,4147,4148],{"class":686},"https:\u002F\u002Ftrek.pafor.me\u002Fmcp",[672,4150,690],{"class":682},[672,4152,4115],{"class":682},[672,4154,4155,4157,4160,4162],{"class":674,"line":832},[672,4156,4134],{"class":682},[672,4158,4159],{"class":686},"--static-oauth-client-info",[672,4161,690],{"class":682},[672,4163,4115],{"class":682},[672,4165,4166,4168,4170,4173,4176,4178,4180,4182,4185,4187,4190,4192,4195,4197,4199,4201,4204,4206,4208],{"class":674,"line":838},[672,4167,4134],{"class":682},[672,4169,3079],{"class":686},[672,4171,4172],{"class":2013},"\\\"",[672,4174,4175],{"class":686},"client_id",[672,4177,4172],{"class":2013},[672,4179,4078],{"class":686},[672,4181,4172],{"class":2013},[672,4183,4184],{"class":686},"\u003Cyour_client_id>",[672,4186,4172],{"class":2013},[672,4188,4189],{"class":686},", ",[672,4191,4172],{"class":2013},[672,4193,4194],{"class":686},"client_secret",[672,4196,4172],{"class":2013},[672,4198,4078],{"class":686},[672,4200,4172],{"class":2013},[672,4202,4203],{"class":686},"\u003Cyour_client_secret>",[672,4205,4172],{"class":2013},[672,4207,3085],{"class":686},[672,4209,701],{"class":682},[672,4211,4212],{"class":674,"line":850},[672,4213,4214],{"class":682},"      ]\n",[672,4216,4217],{"class":674,"line":855},[672,4218,4219],{"class":682},"    }\n",[672,4221,4222,4225],{"class":674,"line":861},[672,4223,4224],{"class":682},"  }",[672,4226,4115],{"class":2013},[429,4228,4229],{},"重新启动 Claude Desktop 客户端。此时在 Local MCP servers（本地MCP服务）列表中就会看到 TREK 已经成功连接：",[435,4231],{"src":4232,"alt":4233,"style":3039},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Fclaude-desktop-mcp-trek-server-connected.webp","在 Claude 界面中验证活跃的 TREK 连接状态",[429,4235,4236],{},"现在，您可以直接用日常口语来下达规划指令了：",[435,4238],{"src":4239,"alt":4240,"style":4241},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Fclaude-desktop-mcp-natural-language-prompt.webp","使用自然语言提示 Claude 操作旅行数据","max-width: 550px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[429,4243,4244],{},"例如，我们用纯中文录入一笔非标准化的日常开支：",[664,4246,4249],{"className":4247,"code":4248,"language":1037,"meta":424},[1035],"For the West Europe trip, the Grab from KLIA1 to the hotel cost RM115.90 on 26\u002F4\u002F2025. Please add it as an expense without split to the trip.\n",[645,4250,4248],{"__ignoreMap":424},[435,4252],{"src":4253,"alt":4254,"style":3039},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Fclaude-desktop-mcp-add-expense-response.webp","Claude 调用工具自动记录一笔支出",[429,4256,4257,4258,4261],{},"回到后台，刷新 ",[442,4259,4260],{},"Costs"," 面板。我们可以看到这笔打车费用已经被精确地记录下来，且因为命令中并未提及“由谁付款”，系统体贴地将付款人项归纳为了“No one paid yet（尚未有人支付）”：",[435,4263],{"src":4264,"alt":4265,"style":3209},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-costs-page-mcp-parsed-expense.webp","在费用视图中确认最新由 AI 解析的支出",[429,4267,4268],{},"管理行李清单的方式也完全一致：",[435,4270],{"src":4271,"alt":4272,"style":4273},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Fclaude-desktop-mcp-add-packing-items.webp","Claude 使用自然语言提示添加打包清单物品","max-width: 631px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[429,4275,4276,4277,4280],{},"再次刷新 ",[442,4278,4279],{},"Packing List"," 页面，指定的这三样出行装备已经被整齐地加入到了清单之中：",[435,4282],{"src":4283,"alt":4284,"style":4285},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-packing-list-mcp-parsed-items.webp","在打包清单页面中确认最新解析的打包物品","max-width: 312px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[586,4287,4289],{"id":4288},"_63-gemini-cli动态注册","6.3 Gemini CLI（动态注册）",[429,4291,4292,4293,4296,4297,4300],{},"Gemini CLI 对 ",[442,4294,4295],{},"Dynamic Registration（动态注册机制）"," 提供了极佳的支持，这使得您完全无需在系统后台手动预注册任何客户端凭证。直接将以下代码追加到您本地的 ",[645,4298,4299],{},".gemini\u002Fsettings.json"," 文件中：",[664,4302,4304],{"className":3070,"code":4303,"language":3072,"meta":424,"style":424},"    \"trek\": {\n      \"httpUrl\": \"https:\u002F\u002Ftrek.pafor.me\u002Fmcp\",\n      \"oauth\": {\n        \"enabled\": true\n      }\n    }\n",[645,4305,4306,4318,4337,4350,4363,4368],{"__ignoreMap":424},[672,4307,4308,4310,4312,4314,4316],{"class":674,"line":675},[672,4309,4085],{"class":682},[672,4311,3235],{"class":686},[672,4313,690],{"class":682},[672,4315,4078],{"class":2013},[672,4317,1167],{"class":682},[672,4319,4320,4322,4325,4327,4329,4331,4333,4335],{"class":674,"line":741},[672,4321,4098],{"class":682},[672,4323,4324],{"class":1280},"httpUrl",[672,4326,690],{"class":682},[672,4328,1277],{"class":682},[672,4330,683],{"class":682},[672,4332,4148],{"class":686},[672,4334,690],{"class":682},[672,4336,4115],{"class":682},[672,4338,4339,4341,4344,4346,4348],{"class":674,"line":614},[672,4340,4098],{"class":682},[672,4342,4343],{"class":1280},"oauth",[672,4345,690],{"class":682},[672,4347,1277],{"class":682},[672,4349,3088],{"class":682},[672,4351,4352,4354,4357,4359,4361],{"class":674,"line":776},[672,4353,4134],{"class":682},[672,4355,4356],{"class":678},"enabled",[672,4358,690],{"class":682},[672,4360,1277],{"class":682},[672,4362,2234],{"class":682},[672,4364,4365],{"class":674,"line":782},[672,4366,4367],{"class":682},"      }\n",[672,4369,4370],{"class":674,"line":827},[672,4371,4219],{"class":682},[429,4373,4374,4375,4378,4379,4382,4383],{},"在终端运行 ",[645,4376,4377],{},"gemini"," 命令，并在随后拉起的网页授权页面中点击 ",[442,4380,4381],{},"Approve（批准）"," 即可：\n",[435,4384],{"src":4385,"alt":4386,"style":4387},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Fmcp-client-oauth-authorization-prompt.webp","批准针对 TREK MCP 服务器的 OAuth 访问授权","max-width: 488px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[429,4389,4390],{},"现在便可以通过极简的命令行终端向 AI 提问了：",[435,4392],{"src":4393,"alt":4394,"style":4395},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Fgemini-cli-mcp-prompt-itinerary.webp","使用 Gemini CLI 提示获取旅行行程","max-width: 415px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[435,4397],{"src":4398,"alt":4399,"style":3657},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Fgemini-cli-mcp-display-itinerary.webp","Gemini CLI 成功展示结构化的旅行信息",[586,4401,4403],{"id":4402},"_64-kimi-cli动态注册","6.4 Kimi CLI（动态注册）",[429,4405,4406,4407,4410,4411,4414],{},"原理基本相同。请在本地 ",[645,4408,4409],{},"\u002FUsers\u002F\u003C您的用户名>\u002F.kimi\u002F"," 目录下找到 ",[645,4412,4413],{},"mcp.json"," 并写入以下连接配置：",[664,4416,4418],{"className":3070,"code":4417,"language":3072,"meta":424,"style":424},"    \"trek\": {\n      \"type\": \"http\",\n      \"url\": \"https:\u002F\u002Ftrek.pafor.me\u002Fmcp\",\n      \"auth\": \"oauth\"\n    }\n",[645,4419,4420,4432,4452,4471,4488],{"__ignoreMap":424},[672,4421,4422,4424,4426,4428,4430],{"class":674,"line":675},[672,4423,4085],{"class":682},[672,4425,3235],{"class":686},[672,4427,690],{"class":682},[672,4429,4078],{"class":2013},[672,4431,1167],{"class":682},[672,4433,4434,4436,4439,4441,4443,4445,4448,4450],{"class":674,"line":741},[672,4435,4098],{"class":682},[672,4437,4438],{"class":1280},"type",[672,4440,690],{"class":682},[672,4442,1277],{"class":682},[672,4444,683],{"class":682},[672,4446,4447],{"class":686},"http",[672,4449,690],{"class":682},[672,4451,4115],{"class":682},[672,4453,4454,4456,4459,4461,4463,4465,4467,4469],{"class":674,"line":614},[672,4455,4098],{"class":682},[672,4457,4458],{"class":1280},"url",[672,4460,690],{"class":682},[672,4462,1277],{"class":682},[672,4464,683],{"class":682},[672,4466,4148],{"class":686},[672,4468,690],{"class":682},[672,4470,4115],{"class":682},[672,4472,4473,4475,4478,4480,4482,4484,4486],{"class":674,"line":776},[672,4474,4098],{"class":682},[672,4476,4477],{"class":1280},"auth",[672,4479,690],{"class":682},[672,4481,1277],{"class":682},[672,4483,683],{"class":682},[672,4485,4343],{"class":686},[672,4487,701],{"class":682},[672,4489,4490],{"class":674,"line":782},[672,4491,4219],{"class":682},[429,4493,4494,4495,4498,4499,4502,4503],{},"在终端执行 ",[645,4496,4497],{},"kimi mcp auth trek"," 并在网页上点击 ",[442,4500,4501],{},"Approve"," 完成快速授权：\n",[435,4504],{"src":4385,"alt":4386,"style":4505},"max-width: 453px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[429,4507,4508],{},"完成授权后，您将能够在命令行直接调用所有关联的微服务工具：",[435,4510],{"src":4511,"alt":4512,"style":3039},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Fkimi-cli-mcp-authorized-tools-list.webp","授权成功后 Kimi CLI 显示的可用工具列表",[547,4514,4516],{"id":4515},"_7-移动端使用体验","7. 移动端使用体验",[429,4518,4519],{},"在手机和移动设备上，TREK是以 PWA（渐进式Web应用）的形式呈现的。其内置的 Service Worker 能够将地图网格瓦片和日程 API 数据离线缓存，确保在野外或没有网络信号的极佳状态下，您依然能够流畅查看已制定的全部行程。不过，离线状态下的推送通知响应速度相较原生应用会有微小的延迟。",[547,4521,4522],{"id":4522},"写在最后",[429,4524,4525],{},"通过 MCP 将 AI 智能体接入您的日常旅行规划，可以帮您省去那些因手动键入繁多的航班和酒店确认单而产生的大量枯燥劳动。不仅如此，AI 还能根据您指定的具体出行节点和所处季节，智能推荐周边的特色景点。仅仅通过几句随意的对话，AI 就能轻松打通从前期灵感检索、行程路线设计，再到后期预算拆分和行李打包的完整全链路。",[429,4527,4528],{},"不过在目前的版本中，依然存在一些微小的体验瑕疵。例如：通过 PDF 智能解析导入订单时，账单货币会默认对齐到旅行项目的主货币，而不是当时实际刷卡结算的付款货币。此外，在 Collections 收藏夹中新建清单列表时，如果在列表尚未保存时就给它配置封面，该封面可能在保存后失效（您需要在列表正式建立后，点击“编辑”来重新添加并保存，即可解决）。",[429,4530,4531,4532,4537],{},"此外，因为它需要您拥有一定的 VPS 运维基础来亲自运行这套程序，对一般用户确实存在一些上手门槛。TREK 更适合那些重度旅行爱好者、数字游民以及对于自身出行数据隐私和排版有着高水准要求的极客用户。我们由衷地建议您在下定决心搭建自托管服务之前，可以先在 ",[569,4533,4536],{"href":4534,"rel":4535},"https:\u002F\u002Fdemo.liketrek.com\u002F",[1655],"demo.liketrek.com"," 上完整试用一下官方提供的公测 DEMO，看它是否切中您的日常痛点。",[547,4539,4541],{"id":4540},"参考资料","参考资料:",[455,4543,4544,4551,4558],{},[458,4545,4546],{},[569,4547,4550],{"href":4548,"rel":4549},"https:\u002F\u002Fgithub.com\u002Fliketrek\u002FTREK\u002Fwiki\u002FQuick-Start",[1655],"TREK Quick Start",[458,4552,4553],{},[569,4554,4557],{"href":4555,"rel":4556},"https:\u002F\u002Fgithub.com\u002Fliketrek\u002FTREK\u002Fwiki\u002FTroubleshooting",[1655],"TREK Troubleshooting",[458,4559,4560],{},[569,4561,4564],{"href":4562,"rel":4563},"https:\u002F\u002Fgithub.com\u002Fliketrek\u002FTREK\u002Fwiki\u002FMCP-Scopes",[1655],"TREK MCP Scopes",[2640,4566,4567],{},"html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}",{"title":424,"searchDepth":741,"depth":614,"links":4569},[4570,4575,4576,4586,4594,4600,4606,4607,4608],{"id":2735,"depth":614,"text":2736,"children":4571},[4572,4573,4574],{"id":2739,"depth":776,"text":2740},{"id":2885,"depth":776,"text":2885},{"id":2916,"depth":776,"text":2916},{"id":3060,"depth":614,"text":3061},{"id":3110,"depth":614,"text":3111,"children":4577},[4578,4579,4580,4581,4582,4583,4584,4585],{"id":3212,"depth":776,"text":3213},{"id":3223,"depth":776,"text":3224},{"id":3322,"depth":776,"text":3323},{"id":3340,"depth":776,"text":3341},{"id":3376,"depth":776,"text":3377},{"id":3398,"depth":776,"text":3399},{"id":3417,"depth":776,"text":3418},{"id":3428,"depth":776,"text":3429},{"id":3458,"depth":614,"text":3459,"children":4587},[4588,4589,4590,4591,4592,4593],{"id":3465,"depth":776,"text":3466},{"id":3497,"depth":776,"text":3498},{"id":3567,"depth":776,"text":3568},{"id":3590,"depth":776,"text":3591},{"id":3609,"depth":776,"text":3610},{"id":3634,"depth":776,"text":3635},{"id":3665,"depth":614,"text":3666,"children":4595},[4596,4597,4598,4599],{"id":3686,"depth":776,"text":3687},{"id":3786,"depth":776,"text":3787},{"id":3849,"depth":776,"text":3850},{"id":3948,"depth":776,"text":3949},{"id":3972,"depth":614,"text":3973,"children":4601},[4602,4603,4604,4605],{"id":3983,"depth":776,"text":3984},{"id":4008,"depth":776,"text":4009},{"id":4288,"depth":776,"text":4289},{"id":4402,"depth":776,"text":4403},{"id":4515,"depth":614,"text":4516},{"id":4522,"depth":614,"text":4522},{"id":4540,"depth":614,"text":4541},[4610,2675],"travel","2026-09-01","本文详细介绍如何使用Docker部署开源旅行规划系统TREK。我们将带您配置Caddy反向代理和Cloudflare R2对象存储，实现数据的安全备份与图片的高效加载。此外，还将演示如何利用MCP（模型上下文协议）连接Claude等AI智能体，通过自然语言对话一键生成您的专属旅行日程，开启完美旅程。","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002FZH-Self-hosted-travel-planner-TREK.webp","在一张温和的羊皮纸背景上，高质量极简风格的TREK自托管旅行规划器仪表盘3D插图。",{"schemaOrg":4616,"robots":2704,"sitemap":4621},[4617,4618],{"@type":2686,"headline":2721,"description":4612},{"@type":4619,"headline":4620,"description":4612},"Article","如何自托管AI旅行规划器TREK：基于Docker、Caddy与Cloudflare R2的终极部署教程",{"lastmod":4611},{"title":4620,"description":4612,"ogTitle":2721,"ogDescription":4612,"twitterTitle":2721,"twitterDescription":4612},"zh\u002Farticle\u002Fself-hosted-travel-planner-trek",[2712,4625,2713,2714,3409],"TREK","YpXK5B3vw79VCnu8AAPsKrl-TJGMOOkDVTMlz2Tw_9Y",{"id":4628,"title":4629,"author":424,"body":4630,"category":6023,"date":6025,"description":6026,"extension":2678,"image":6027,"imageAlt":6028,"isPublished":772,"meta":6029,"minRead":838,"navigation":772,"path":339,"seo":6035,"stem":6037,"tags":6038,"updatedAt":2715,"__hash__":6043},"article\u002Fzh\u002Farticle\u002Fsync-obsidian-across-devices.md","如何在多台设备之间安全地同步 Obsidian 本地知识库",{"type":426,"value":4631,"toc":6001},[4632,4635,4640,4649,4658,4675,4680,4686,4690,4695,4709,4725,4728,4732,4735,4741,4746,4750,4754,4805,4811,4841,4845,4852,4859,4866,4918,4921,4936,4942,4954,4958,4962,4968,4973,4984,5005,5010,5022,5027,5032,5037,5052,5055,5059,5062,5067,5071,5076,5090,5094,5108,5119,5123,5128,5131,5138,5171,5175,5181,5309,5343,5349,5369,5380,5385,5389,5404,5476,5480,5485,5520,5649,5656,5662,5669,5675,5678,5684,5691,5706,5717,5724,5730,5741,5872,5878,5883,5886,5891,5894,5898,5904,5909,5915,5926,5936,5940,5952,5958,5965,5971,5975,5998],[429,4633,4634],{},"Obsidian 是一款本地优先的知识管理应用。每一个笔记在设备上都是一个本地 Markdown 文件，并完全处于您的掌控之中。然而，我们通常希望在笔记本电脑、手机和其他设备上共享同一个本地知识库，或者希望在某些时候能够通过网页浏览器远程访问它。",[435,4636],{"src":4637,"alt":4638,"style":4639},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fobsidian-multi-device-sync-illustration.webp","跨多设备同步的 Obsidian 本地知识库的插图","max-width: 667px; width: 100%; height: auto;",[429,4641,4642,4643,4648],{},"市面上有很多针对 Obsidian 的同步方案，但在冲突处理、加密和数据自主权方面，它们或多或少都做出了一些妥协。",[569,4644,4647],{"href":4645,"rel":4646},"https:\u002F\u002Fgithub.com\u002Fhjinco\u002Fsynch",[1655],"Synch"," 是一款开源应用，它可以在自建服务器上实现具备端到端加密和冲突解决机制的 Obsidian 知识库同步。",[429,4650,4651,4652,4657],{},"虽然 Obsidian 的本地优先方案在绝大多数情况下都能完美工作，但在某些场景下，我们可能仍需要通过网页浏览器远程访问并编辑笔记。",[569,4653,4656],{"href":4654,"rel":4655},"https:\u002F\u002Fgithub.com\u002FNystik-gh\u002Fignis",[1655],"Ignis"," 是一款开源应用，它能够在网页浏览器中以接近原生的体验运行 Obsidian，让您能够直接读取和编辑知识库。",[429,4659,4660,4661,4664,4665,1124,4667,4669,4670,4674],{},"在本文中，我们将在一台 ",[442,4662,4663],{},"VPS","（虚拟专用服务器）上部署 ",[442,4666,4647],{},[442,4668,4656],{},"，并将它们安全地托管在 ",[442,4671,4672],{},[569,4673,3990],{"href":363}," 私有网络中，而无需将它们直接暴露在公网上。",[435,4676],{"src":4677,"alt":4678,"style":4679},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fobsidian-sync-cloudflare-zero-trust-architecture.webp","使用 Cloudflare Zero Trust 安全网络同步 Obsidian 的架构图","max-width: 671px; width: 100%; height: auto;",[574,4681],{"description":4682,"image":4683,"image-alt":4684,"label":579,"min-read":580,"title":4685,"to":363},"学习如何使用 Cloudflare WARP 和 Zero Trust 安全地在全球范围内暴露和访问您的 Hermes Agent，而无需在防火墙上开启任何入站端口。","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FExposing%20Hermes%20Agent%20to%20Private%20Network%20Using%20Cloudflare%20WARP\u002FEN-Exposing-Hermes-Agent-to-Private-Network-Using-Cloudflare-WARP.webp","使用 Cloudflare Zero Trust 和 WARP 隧道安全地将 Hermes Agent 暴露到私有网络中","如何使用 Cloudflare WARP 私密地公开暴露 Hermes Agent",[447,4687,4689],{"id":4688},"使用-synch-安全同步-obsidian-知识库","使用 Synch 安全同步 Obsidian 知识库",[429,4691,4692,4694],{},[442,4693,4647],{}," 提供以下特性：",[455,4696,4697,4700,4703,4706],{},[458,4698,4699],{},"检测到更改时立即实时同步您的知识库",[458,4701,4702],{},"并在上传前对知识库数据进行端到端加密",[458,4704,4705],{},"支持从历史版本记录中进行恢复",[458,4707,4708],{},"内置自动冲突解决机制",[429,4710,4711,4713,4714,4717,4718,4721,4722,4724],{},[442,4712,4647],{}," 会在您的本地设备上生成一个随机的 32 字节",[442,4715,4716],{},"知识库密钥","（Vault Key），该密钥专门用于加密您的知识库数据。当您创建远程知识库时，您需要设置一个",[442,4719,4720],{},"知识库密码","。该密码用于保护您的",[442,4723,4716],{},"，以便能够将密钥安全地存储在服务器上，并在其他设备上进行解密。",[429,4726,4727],{},"笔记的冲突解决是在客户端设备上完成的，而不是在服务器端。如果两台设备同时编辑同一个笔记，服务器会保留最先到达的版本，并通知另一台设备其本地版本已过时。随后，该设备会自动将服务器上的最新版本与其本地更改进行合并，然后再将合并后的最终笔记上传。",[547,4729,4731],{"id":4730},"在您的-vps-上部署-synch","在您的 VPS 上部署 Synch",[586,4733,4734],{"id":4734},"创建域名解析",[429,4736,4737,4738,4740],{},"在 Cloudflare 中创建一条 A 记录，并将其代理状态设置为",[442,4739,713],{},"（绕过 Cloudflare CDN）。",[435,4742],{"src":4743,"alt":4744,"style":4745},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fcloudflare-dns-a-record-synch-server.webp","在 Cloudflare 中为 Synch 同步服务器配置 DNS A 记录","max-width: 538px; width: 100%; height: auto;",[586,4747,4749],{"id":4748},"在-ubuntu-上使用-docker-安装-synch","在 Ubuntu 上使用 Docker 安装 Synch",[4751,4752,4753],"h5",{"id":4753},"克隆仓库",[664,4755,4757],{"className":666,"code":4756,"language":668,"meta":424,"style":424},"git clone https:\u002F\u002Fgithub.com\u002Fhjinco\u002Fsynch.git       \n        \n# Navigate to the API folder\ncd synch\u002Fapps\u002Fapi\n        \n# Copy the example environment file:\ncp .env.example .env\n",[645,4758,4759,4771,4776,4781,4788,4792,4797],{"__ignoreMap":424},[672,4760,4761,4763,4765,4768],{"class":674,"line":675},[672,4762,981],{"class":678},[672,4764,984],{"class":686},[672,4766,4767],{"class":686}," https:\u002F\u002Fgithub.com\u002Fhjinco\u002Fsynch.git",[672,4769,4770],{"class":2013},"       \n",[672,4772,4773],{"class":674,"line":741},[672,4774,4775],{"class":2013},"        \n",[672,4777,4778],{"class":674,"line":614},[672,4779,4780],{"class":737},"# Navigate to the API folder\n",[672,4782,4783,4785],{"class":674,"line":776},[672,4784,996],{"class":785},[672,4786,4787],{"class":686}," synch\u002Fapps\u002Fapi\n",[672,4789,4790],{"class":674,"line":782},[672,4791,4775],{"class":2013},[672,4793,4794],{"class":674,"line":827},[672,4795,4796],{"class":737},"# Copy the example environment file:\n",[672,4798,4799,4801,4803],{"class":674,"line":832},[672,4800,1004],{"class":678},[672,4802,1007],{"class":686},[672,4804,1010],{"class":686},[4751,4806,1020,4808,4810],{"id":4807},"编辑-env-环境变量",[645,4809,1023],{}," 环境变量",[455,4812,4813,4819,4835],{},[458,4814,4815,4818],{},[645,4816,4817],{},"PUBLIC_URL=synch.pafor.me","：输入您的 Synch 服务器公网域名（即在上一步中创建的域名）。",[458,4820,4821,1124,4824,4827,4828,4831,4832,4834],{},[645,4822,4823],{},"BETTER_AUTH_SECRET",[645,4825,4826],{},"SYNC_TOKEN_SECRET","：请使用此 ",[569,4829,4830],{"href":1064},"在线秘钥生成工具"," 或在终端中运行两次 ",[645,4833,1069],{}," 来生成高强度的随机秘钥。",[458,4836,4837,4840],{},[645,4838,4839],{},"AUTH_ALLOWED_EMAILS","：允许注册并创建账户的邮箱地址列表（用英文逗号分隔）。",[4751,4842,4844],{"id":4843},"将域名添加至-caddyfile","将域名添加至 Caddyfile",[429,4846,4847,4848,599],{},"有关如何将 Cloudflare DNS 模块集成到 Caddy 中并使用 Docker 容器启动的详细配置方法，请参阅我们的 ",[569,4849,4851],{"href":4850},"\u002Farticle\u002Fself-hosting-buzz-as-the-workspace-where-ai-agents-become-colleagues#_4-enable-https-with-caddy","自建 Buzz 协作平台文章",[574,4853],{"description":4854,"image":4855,"image-alt":4856,"label":4857,"min-read":4858,"title":423,"to":4850},"学习如何在 Docker 容器中配置 Caddy 反向代理，并利用 Cloudflare DNS Challenge 自动申请和管理 SSL\u002FTLS 证书。","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf-Hosting%20Buzz%20As%20The%20Workspace%20Where%20AI%20Agents%20Become%20Colleagues\u002FEN-Self-Hosting-Buzz-As-The-Workspace-Where-AI-Agents-Become-Colleagues.webp","在自建工作区中配置带有 Cloudflare DNS API 令牌的 Caddy，实现 SSL\u002FTLS 证书的自动申请与管理","自建指南","12",[429,4860,4861,4862,4865],{},"在您的 Caddyfile 中添加 ",[645,4863,4864],{},"SYNCH_DOMAIN"," 配置，并将其反向代理指向 8787 端口（Synch 容器内部运行的端口）：",[664,4867,4869],{"className":3070,"code":4868,"language":3072,"meta":424,"style":424},"{\n  acme_dns cloudflare {env.CLOUDFLARE_API_TOKEN}\n}\n\n{$SYNCH_DOMAIN} {\n  encode zstd gzip\n  reverse_proxy host.docker.internal:8787\n}\n",[645,4870,4871,4875,4882,4886,4890,4901,4905,4914],{"__ignoreMap":424},[672,4872,4873],{"class":674,"line":675},[672,4874,1167],{"class":682},[672,4876,4877,4880],{"class":674,"line":741},[672,4878,4879],{"class":2013},"  acme_dns cloudflare {env.CLOUDFLARE_API_TOKEN",[672,4881,1181],{"class":682},[672,4883,4884],{"class":674,"line":614},[672,4885,1181],{"class":2013},[672,4887,4888],{"class":674,"line":776},[672,4889,773],{"emptyLinePlaceholder":772},[672,4891,4892,4894,4897,4899],{"class":674,"line":782},[672,4893,3079],{"class":682},[672,4895,4896],{"class":2013},"$SYNCH_DOMAIN",[672,4898,3085],{"class":682},[672,4900,3088],{"class":682},[672,4902,4903],{"class":674,"line":827},[672,4904,3093],{"class":2013},[672,4906,4907,4909,4911],{"class":674,"line":832},[672,4908,3098],{"class":2013},[672,4910,1277],{"class":682},[672,4912,4913],{"class":1312},"8787\n",[672,4915,4916],{"class":674,"line":838},[672,4917,1181],{"class":682},[429,4919,4920],{},"启动容器：",[664,4922,4924],{"className":666,"code":4923,"language":668,"meta":424,"style":424},"docker compose up -d\n",[645,4925,4926],{"__ignoreMap":424},[672,4927,4928,4930,4932,4934],{"class":674,"line":675},[672,4929,922],{"class":678},[672,4931,964],{"class":686},[672,4933,1562],{"class":686},[672,4935,1565],{"class":686},[429,4937,4938,4939,4941],{},"运行以下 ",[645,4940,679],{}," 命令以验证服务的可用性：",[664,4943,4945],{"className":666,"code":4944,"language":668,"meta":424,"style":424},"curl https:\u002F\u002Fsynch.pafor.me\u002Fhealth\n",[645,4946,4947],{"__ignoreMap":424},[672,4948,4949,4951],{"class":674,"line":675},[672,4950,679],{"class":678},[672,4952,4953],{"class":686}," https:\u002F\u002Fsynch.pafor.me\u002Fhealth\n",[547,4955,4957],{"id":4956},"将-obsidian-客户端连接至您的-synch-服务器","将 Obsidian 客户端连接至您的 Synch 服务器",[586,4959,4961],{"id":4960},"在-obsidian-中安装-synch-插件","在 Obsidian 中安装 Synch 插件",[429,4963,4964,4965,3574],{},"打开 Obsidian 的“设置”（Settings），导航至“第三方插件”（Community plugins），然后点击 ",[442,4966,4967],{},"“浏览”（Browse）",[435,4969],{"src":4970,"alt":4971,"style":4972},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fobsidian-community-plugins-browse.webp","在 Obsidian 设置中浏览第三方社区插件","max-width: 523px; width: 100%; height: auto;",[429,4974,4975,4976,4979,4980],{},"搜索并安装 ",[442,4977,4978],{},"'Synchrun'"," 插件：\n",[435,4981],{"src":4982,"alt":4983,"style":4745},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fobsidian-install-synchrun-plugin.webp","在 Obsidian 中安装 Synchrun 同步插件",[429,4985,4986,4987,4989,4990,4993,4994,4997,4998,5001,5002,599],{},"安装完成后，打开 ",[442,4988,4978],{}," 插件设置，并启用 ",[442,4991,4992],{},"“使用自建服务器”（Use a self-hosted server）","。随后，在 ",[442,4995,4996],{},"“服务器 URL”（Server URL）"," 字段中输入 ",[645,4999,5000],{},"https:\u002F\u002Fsynch.pafor.me","，并点击 ",[442,5003,5004],{},"“保存”（Save）",[435,5006],{"src":5007,"alt":5008,"style":5009},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fobsidian-synchrun-plugin-settings-self-hosted.webp","在 Synchrun 插件设置中配置您的自建服务器 URL","max-width: 525px; width: 100%; height: auto;",[429,5011,602,5012,5015,5016,5018,5019,5021],{},[442,5013,5014],{},"“在当前设备上登录”（Sign in on this device）"," 按钮。接着，使用您在 ",[645,5017,1023],{}," 中 ",[645,5020,4839],{}," 列表中指定的邮箱地址进行注册，注册成功后您将看到以下授权页面：",[435,5023],{"src":5024,"alt":5025,"style":5026},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fsynchrun-account-authorization-page.webp","Synchrun 插件的账户授权登录页面","max-width: 494px; width: 100%; height: auto;",[429,5028,602,5029,3574],{},[442,5030,5031],{},"“允许 Obsidian 登录”（Allow Obsidian sign-in）",[435,5033],{"src":5034,"alt":5035,"style":5036},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fsynchrun-allow-obsidian-signin.webp","允许 Obsidian 通过 Synch 登录","max-width: 498px; width: 100%; height: auto;",[429,5038,602,5039,5042,5043,5046,5047],{},[442,5040,5041],{},"“返回 Obsidian”（Return to Obsidian）"," 按钮，随后点击 ",[442,5044,5045],{},"“创建知识库”（Create vault）","：\n",[435,5048],{"src":5049,"alt":5050,"style":5051},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fobsidian-synchrun-create-remote-vault.webp","在 Synchrun 中创建新的远程同步知识库","max-width: 496px; width: 100%; height: auto;",[429,5053,5054],{},"输入您自定义的知识库名称与高强度密码来创建远程知识库。",[435,5056],{"src":5057,"alt":5058,"style":1600},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fobsidian-synchrun-vault-password-setup.webp","为 Obsidian 远程知识库设置高强度安全密码",[429,5060,5061],{},"同步过程将立即开始，根据您的知识库文件大小，这可能会需要一些时间。同步完成后，界面将显示您所使用的总存储空间。",[435,5063],{"src":5064,"alt":5065,"style":5066},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fobsidian-synchrun-sync-completed-storage.webp","Synchrun 同步完成并显示所使用的总存储空间","max-width: 508px; width: 100%; height: auto;",[447,5068,5070],{"id":5069},"使用-ignis-实现基于浏览器的-obsidian-访问","使用 Ignis 实现基于浏览器的 Obsidian 访问",[429,5072,5073,5075],{},[442,5074,4656],{}," 通过将 Obsidian 的 Electron API 替换为 Web API，使得 Obsidian 的 JavaScript 代码能够直接在标准网页浏览器中运行。您所有的 Markdown 笔记和附件都将直接存储在托管服务器的本地文件系统中。",[429,5077,5078,5079,5084,5085,599],{},"不过，相比于独立运行的 Obsidian 桌面客户端，网页端还存在一些局限性。由于浏览器沙箱环境的限制，某些依赖于 Electron 或 Node.js 特有 API 的功能或第三方插件将无法正常工作。详情请参阅 Ignis 官方文档中的 ",[569,5080,5083],{"href":5081,"rel":5082},"https:\u002F\u002Fignis.thiefling.com\u002Fdocs\u002Fusing\u002Flimitations\u002F",[1655],"局限性说明"," 以及 ",[569,5086,5089],{"href":5087,"rel":5088},"https:\u002F\u002Fignis.thiefling.com\u002Fdocs\u002Fusing\u002Fplugin-compatibility\u002F",[1655],"插件兼容性列表",[547,5091,5093],{"id":5092},"部署-ignis","部署 Ignis",[429,5095,5096,5097,5099,5100,5103,5104,5107],{},"我们将使用 Docker 在 VPS 上安装 ",[442,5098,4656],{},"，并将其映射挂载到本地的 ",[645,5101,5102],{},".\u002Fvaults"," 文件夹中。随后，我们将在服务器上通过 ",[442,5105,5106],{},"Synch CLI"," 命令行客户端将该本地目录与我们之前设置 of 远程同步知识库进行实时同步。",[429,5109,5110,5111,5113,5114,5118],{},"由于 ",[442,5112,4656],{}," 本身没有内置的身份验证机制，为了确保隐私，我们必须将其安全地隐藏在 ",[442,5115,5116],{},[569,5117,3990],{"href":363}," 私有网络中。",[586,5120,5122],{"id":5121},"创建-dns-记录","创建 DNS 记录",[435,5124],{"src":5125,"alt":5126,"style":5127},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fcloudflare-dns-a-record-ignis.webp","在 Cloudflare 中为 Ignis 网页端配置 DNS A 记录","max-width: 552px; width: 100%; height: auto;",[586,5129,4844],{"id":5130},"将域名添加至-caddyfile-1",[429,5132,5133,5134,5137],{},"在您的 Caddyfile 中以相同的方式为 ",[645,5135,5136],{},"obsidian.pafor.me"," 配置反向代理：",[664,5139,5141],{"className":3070,"code":5140,"language":3072,"meta":424,"style":424},"{$OBSIDIAN_DOMAIN} {\n  encode zstd gzip\n  reverse_proxy host.docker.internal:9898\n}\n",[645,5142,5143,5154,5158,5167],{"__ignoreMap":424},[672,5144,5145,5147,5150,5152],{"class":674,"line":675},[672,5146,3079],{"class":682},[672,5148,5149],{"class":2013},"$OBSIDIAN_DOMAIN",[672,5151,3085],{"class":682},[672,5153,3088],{"class":682},[672,5155,5156],{"class":674,"line":741},[672,5157,3093],{"class":2013},[672,5159,5160,5162,5164],{"class":674,"line":614},[672,5161,3098],{"class":2013},[672,5163,1277],{"class":682},[672,5165,5166],{"class":1312},"9898\n",[672,5168,5169],{"class":674,"line":776},[672,5170,1181],{"class":682},[586,5172,5174],{"id":5173},"使用-docker-启动-ignis","使用 Docker 启动 Ignis",[429,5176,5177,5178,3254],{},"在 VPS 上将以下 Docker Compose 配置保存为 ",[645,5179,5180],{},"ignis-docker-compose.yml",[664,5182,5184],{"className":1158,"code":5183,"language":1160,"meta":424,"style":424},"services:\n  ignis:\n    image: nobbe\u002Fignis:latest\n    ports:\n      - \"9898:8080\"\n    environment:\n      # match these to your host user (run: id)\n      - PUID=1000\n      - PGID=1000\n      - WS_ORIGINS=https:\u002F\u002Fobsidian.pafor.me\n    volumes:\n      - .\u002Fvaults:\u002Fvaults\n      - .\u002Fdata:\u002Fapp\u002Fdata\n      - obsidian-app:\u002Fapp\u002Fobsidian-app\n    restart: unless-stopped\n\nvolumes:\n  obsidian-app:\n",[645,5185,5186,5192,5199,5208,5214,5225,5231,5236,5243,5250,5257,5263,5270,5277,5284,5292,5296,5302],{"__ignoreMap":424},[672,5187,5188,5190],{"class":674,"line":675},[672,5189,1259],{"class":1258},[672,5191,1262],{"class":682},[672,5193,5194,5197],{"class":674,"line":741},[672,5195,5196],{"class":1258},"  ignis",[672,5198,1262],{"class":682},[672,5200,5201,5203,5205],{"class":674,"line":614},[672,5202,1328],{"class":1258},[672,5204,1277],{"class":682},[672,5206,5207],{"class":686}," nobbe\u002Fignis:latest\n",[672,5209,5210,5212],{"class":674,"line":776},[672,5211,1274],{"class":1258},[672,5213,1262],{"class":682},[672,5215,5216,5218,5220,5223],{"class":674,"line":782},[672,5217,1395],{"class":682},[672,5219,683],{"class":682},[672,5221,5222],{"class":686},"9898:8080",[672,5224,701],{"class":682},[672,5226,5227,5229],{"class":674,"line":827},[672,5228,1362],{"class":1258},[672,5230,1262],{"class":682},[672,5232,5233],{"class":674,"line":832},[672,5234,5235],{"class":737},"      # match these to your host user (run: id)\n",[672,5237,5238,5240],{"class":674,"line":838},[672,5239,1395],{"class":682},[672,5241,5242],{"class":686}," PUID=1000\n",[672,5244,5245,5247],{"class":674,"line":850},[672,5246,1395],{"class":682},[672,5248,5249],{"class":686}," PGID=1000\n",[672,5251,5252,5254],{"class":674,"line":855},[672,5253,1395],{"class":682},[672,5255,5256],{"class":686}," WS_ORIGINS=https:\u002F\u002Fobsidian.pafor.me\n",[672,5258,5259,5261],{"class":674,"line":861},[672,5260,1418],{"class":1258},[672,5262,1262],{"class":682},[672,5264,5265,5267],{"class":674,"line":883},[672,5266,1395],{"class":682},[672,5268,5269],{"class":686}," .\u002Fvaults:\u002Fvaults\n",[672,5271,5272,5274],{"class":674,"line":888},[672,5273,1395],{"class":682},[672,5275,5276],{"class":686}," .\u002Fdata:\u002Fapp\u002Fdata\n",[672,5278,5279,5281],{"class":674,"line":894},[672,5280,1395],{"class":682},[672,5282,5283],{"class":686}," obsidian-app:\u002Fapp\u002Fobsidian-app\n",[672,5285,5286,5288,5290],{"class":674,"line":908},[672,5287,1447],{"class":1258},[672,5289,1277],{"class":682},[672,5291,1452],{"class":686},[672,5293,5294],{"class":674,"line":913},[672,5295,773],{"emptyLinePlaceholder":772},[672,5297,5298,5300],{"class":674,"line":919},[672,5299,1479],{"class":1258},[672,5301,1262],{"class":682},[672,5303,5304,5307],{"class":674,"line":928},[672,5305,5306],{"class":1258},"  obsidian-app",[672,5308,1262],{"class":682},[455,5310,5311,5322,5336],{},[458,5312,5313,5314,5317,5318,5321],{},"在主机端使用 ",[645,5315,5316],{},"9898"," 端口，因为 ",[645,5319,5320],{},"8080"," 是一个非常常用且容易冲突的端口。",[458,5323,5324,5325,5328,5329,1124,5332,5335],{},"在您的 VPS 上运行 ",[645,5326,5327],{},"id"," 命令，获取当前主机用户的 ",[645,5330,5331],{},"UID",[645,5333,5334],{},"GID","，并将其填写到配置文件中，以确保文件系统具备正确的读写权限。",[458,5337,5338,5339,5342],{},"配置 ",[645,5340,5341],{},"WS_ORIGINS","，仅允许来自您指定域名的 WebSocket 连接，提高安全性。",[429,5344,5345,5346,5348],{},"启动 ",[442,5347,4656],{}," 容器：",[664,5350,5352],{"className":666,"code":5351,"language":668,"meta":424,"style":424},"docker compose -f ignis-docker-compose.yml up -d\n",[645,5353,5354],{"__ignoreMap":424},[672,5355,5356,5358,5360,5362,5365,5367],{"class":674,"line":675},[672,5357,922],{"class":678},[672,5359,964],{"class":686},[672,5361,1551],{"class":686},[672,5363,5364],{"class":686}," ignis-docker-compose.yml",[672,5366,1562],{"class":686},[672,5368,1565],{"class":686},[429,5370,5371,5372,5375,5376,5379],{},"当您在网页浏览器中访问您的域名时，将会弹出 ",[442,5373,5374],{},"'Vault Manager'","（知识库管理器）。由于此时文件夹为空，它不会显示任何本地知识库。在下一节中，我们将配置 ",[442,5377,5378],{},"'Synch CLI'","，从我们之前配置的远程同步服务器中拉取笔记。",[435,5381],{"src":5382,"alt":5383,"style":5384},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fignis-vault-manager-empty.webp","Ignis 网页客户端中当前为空的知识库管理器","max-width: 466px; width: 100%; height: auto;",[586,5386,5388],{"id":5387},"解决-docker-带来的防火墙失效问题","解决 Docker 带来的防火墙失效问题",[429,5390,5391,5392,5395,5396,5399,5400,5403],{},"默认情况下，Docker 会自动在系统底层插入自己的 DNAT 与 FORWARD 链规则，直接将外部公网流量转发至活动的容器端口。这会完全绕过 Ubuntu 默认的 UFW 或 iptables ",[645,5393,5394],{},"INPUT"," 链防火墙保护。为了阻止外部未经授权的访问并保持容器的绝对私有，我们需要手动将以下规则添加至 ",[645,5397,5398],{},"iptables"," 中的 ",[645,5401,5402],{},"DOCKER-USER"," 链：",[664,5405,5407],{"className":666,"code":5406,"language":668,"meta":424,"style":424},"# 阻断所有外部公网流量的直接访问\nsudo iptables -I DOCKER-USER -i ext_if -j DROP \n\n# 仅允许来自您的 Cloudflare WARP 客户端私有 IP 的访问流量\nsudo iptables -I DOCKER-USER -i ext_if -s 100.96.0.10 -j ACCEPT\n",[645,5408,5409,5414,5442,5446,5451],{"__ignoreMap":424},[672,5410,5411],{"class":674,"line":675},[672,5412,5413],{"class":737},"# 阻断所有外部公网流量的直接访问\n",[672,5415,5416,5418,5421,5424,5427,5430,5433,5436,5439],{"class":674,"line":741},[672,5417,841],{"class":678},[672,5419,5420],{"class":686}," iptables",[672,5422,5423],{"class":686}," -I",[672,5425,5426],{"class":686}," DOCKER-USER",[672,5428,5429],{"class":686}," -i",[672,5431,5432],{"class":686}," ext_if",[672,5434,5435],{"class":686}," -j",[672,5437,5438],{"class":686}," DROP",[672,5440,5441],{"class":2013}," \n",[672,5443,5444],{"class":674,"line":614},[672,5445,773],{"emptyLinePlaceholder":772},[672,5447,5448],{"class":674,"line":776},[672,5449,5450],{"class":737},"# 仅允许来自您的 Cloudflare WARP 客户端私有 IP 的访问流量\n",[672,5452,5453,5455,5457,5459,5461,5463,5465,5468,5471,5473],{"class":674,"line":782},[672,5454,841],{"class":678},[672,5456,5420],{"class":686},[672,5458,5423],{"class":686},[672,5460,5426],{"class":686},[672,5462,5429],{"class":686},[672,5464,5432],{"class":686},[672,5466,5467],{"class":686}," -s",[672,5469,5470],{"class":1312}," 100.96.0.10",[672,5472,5435],{"class":686},[672,5474,5475],{"class":686}," ACCEPT\n",[586,5477,5479],{"id":5478},"配置-synch-cli-命令行同步工具","配置 Synch CLI 命令行同步工具",[429,5481,5482,5484],{},[442,5483,5106],{}," 是一款无界面的命令行工具，即使在没有安装 Obsidian 桌面应用的远程服务器上，它也能让本地目录与远程知识库进行实时同步。",[429,5486,5487,5488,5491,5492,5494,5495,5498,5499,5084,5502,1081,5505,1124,5508,5511,5512,5515,5516,5519],{},"从您之前克隆的 ",[645,5489,5490],{},"synch"," 仓库源码中构建 ",[442,5493,5106],{},"。构建过程需要 ",[442,5496,5497],{},"Node.js >= 22.5","（因为 CLI 依赖于 ",[645,5500,5501],{},"node:sqlite",[645,5503,5504],{},"fetch",[645,5506,5507],{},"WebSocket",[645,5509,5510],{},"WebCrypto"," 等全局浏览器原生 API）和 ",[442,5513,5514],{},"pnpm","（由于整个仓库是一个使用了 ",[645,5517,5518],{},"pnpm@10.33.0"," 版本管理器的 pnpm 工作区）：",[664,5521,5523],{"className":666,"code":5522,"language":668,"meta":424,"style":424},"# Check versions\nnode --version   # must be >= 22.5\npnpm --version\n\n# In the repos root\npnpm install\n\n# Build the CLI bundle\npnpm -C apps\u002Fcli build\n\n# After a successful build you have `apps\u002Fcli\u002Fdist\u002Fsynch.js`. Make it executable and put it on your PATH\nchmod +x apps\u002Fcli\u002Fdist\u002Fsynch.js\nln -sf \"$PWD\u002Fapps\u002Fcli\u002Fdist\u002Fsynch.js\" \"$HOME\u002F.local\u002Fbin\u002Fsynch\"\n\n# Verification\nsynch --help\n",[645,5524,5525,5530,5541,5547,5551,5556,5563,5567,5572,5585,5589,5594,5605,5633,5637,5642],{"__ignoreMap":424},[672,5526,5527],{"class":674,"line":675},[672,5528,5529],{"class":737},"# Check versions\n",[672,5531,5532,5535,5538],{"class":674,"line":741},[672,5533,5534],{"class":678},"node",[672,5536,5537],{"class":686}," --version",[672,5539,5540],{"class":737},"   # must be >= 22.5\n",[672,5542,5543,5545],{"class":674,"line":614},[672,5544,5514],{"class":678},[672,5546,925],{"class":686},[672,5548,5549],{"class":674,"line":776},[672,5550,773],{"emptyLinePlaceholder":772},[672,5552,5553],{"class":674,"line":782},[672,5554,5555],{"class":737},"# In the repos root\n",[672,5557,5558,5560],{"class":674,"line":827},[672,5559,5514],{"class":678},[672,5561,5562],{"class":686}," install\n",[672,5564,5565],{"class":674,"line":832},[672,5566,773],{"emptyLinePlaceholder":772},[672,5568,5569],{"class":674,"line":838},[672,5570,5571],{"class":737},"# Build the CLI bundle\n",[672,5573,5574,5576,5579,5582],{"class":674,"line":850},[672,5575,5514],{"class":678},[672,5577,5578],{"class":686}," -C",[672,5580,5581],{"class":686}," apps\u002Fcli",[672,5583,5584],{"class":686}," build\n",[672,5586,5587],{"class":674,"line":855},[672,5588,773],{"emptyLinePlaceholder":772},[672,5590,5591],{"class":674,"line":861},[672,5592,5593],{"class":737},"# After a successful build you have `apps\u002Fcli\u002Fdist\u002Fsynch.js`. Make it executable and put it on your PATH\n",[672,5595,5596,5599,5602],{"class":674,"line":883},[672,5597,5598],{"class":678},"chmod",[672,5600,5601],{"class":686}," +x",[672,5603,5604],{"class":686}," apps\u002Fcli\u002Fdist\u002Fsynch.js\n",[672,5606,5607,5610,5613,5615,5618,5621,5623,5625,5628,5631],{"class":674,"line":888},[672,5608,5609],{"class":678},"ln",[672,5611,5612],{"class":686}," -sf",[672,5614,683],{"class":682},[672,5616,5617],{"class":2013},"$PWD",[672,5619,5620],{"class":686},"\u002Fapps\u002Fcli\u002Fdist\u002Fsynch.js",[672,5622,690],{"class":682},[672,5624,683],{"class":682},[672,5626,5627],{"class":2013},"$HOME",[672,5629,5630],{"class":686},"\u002F.local\u002Fbin\u002Fsynch",[672,5632,701],{"class":682},[672,5634,5635],{"class":674,"line":894},[672,5636,773],{"emptyLinePlaceholder":772},[672,5638,5639],{"class":674,"line":908},[672,5640,5641],{"class":737},"# Verification\n",[672,5643,5644,5646],{"class":674,"line":913},[672,5645,5490],{"class":678},[672,5647,5648],{"class":686}," --help\n",[429,5650,5651,5652,5655],{},"由于 Synch CLI 运行在与您的 Synch remote 虚拟同步服务端相同的 VPS 上，它能够直接自动连接至本地的 API 服务端口。如果您将它们部署在不同的服务器上，请运行 ",[645,5653,5654],{},"synch login --api-url \u003Cremote-synch-api-url>"," 来手动定义您的远程目标 API 端点。",[429,5657,5658],{},[435,5659],{"alt":5660,"src":5661},"在终端中输入自定义 API URL 运行 synch login 登录命令","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fsynch-login-api-url-terminal.webp",[429,5663,5664,5665,5668],{},"在您的 VPS 终端中运行 ",[645,5666,5667],{},"synch login"," 命令，您将获得一个用于身份验证的登录 URL：",[429,5670,5671],{},[435,5672],{"alt":5673,"src":5674},"终端输出显示的 Synch CLI 认证 URL","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fsynch-login-auth-url-terminal.webp",[429,5676,5677],{},"使用与您在 Obsidian 桌面端 Synchrun 插件中注册的相同邮箱地址，通过该网页链接进行登录授权。",[429,5679,5680],{},[435,5681],{"alt":5682,"src":5683},"Synch CLI 授权网页端登录成功","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fsynch-web-login-success.webp",[429,5685,5686,5687,5690],{},"运行 ",[645,5688,5689],{},"synch vault connect --vault ~\u002Fvaults\u002F\u003Cvaultname> --vault-id asadqe-7b29-4677-fsad-234asdafasd"," 来将您 VPS 上的本地知识库目录与远程自建服务器上的知识库进行关联：",[429,5692,5693,5694,5697,5698,5701,5702,5705],{},"您可以通过打开桌面端 Obsidian 中的 ",[442,5695,5696],{},"Synchrun"," 插件设置，点击 ",[442,5699,5700],{},"“管理远程知识库”（Manage remote vaults）"," 来找到您的远程知识库 ID。该操作会打开一个网页并列出您所有的远程知识库，每个库旁边都附带有一个 GUID 格式的唯一标识符（例如：",[645,5703,5704],{},"123e4567-e89b-12d3-a456-426614174000","）：",[429,5707,5708,5713],{},[435,5709],{"src":5710,"alt":5711,"style":5712},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fsynchrun-manage-remote-vaults.webp","在 Synchrun 插件中管理远程知识库","max-width: 582px; width: 100%; height: auto;",[435,5714],{"alt":5715,"src":5716},"在 Synchrun 中定位唯一的远程知识库 ID","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fsynchrun-remote-vault-id.webp",[429,5718,5719,5720,5723],{},"在提示时输入您的知识库密码以确立关联。关联成功后，运行 ",[645,5721,5722],{},"synch sync --vault ~\u002Fvaults\u002F\u003Cvault-name>"," 来进行您的首次全量同步。首次同步根据您的文件大小，可能会耗费一些时间。",[429,5725,5726],{},[435,5727],{"alt":5728,"src":5729},"Synch CLI 中显示首次拉取同步知识库的进度","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fsynch-cli-initial-sync-progress.webp",[429,5731,5732,5733,5736,5737,5740],{},"为了让同步全自动进行，我们可以配置并启用一个 ",[645,5734,5735],{},"systemd"," 系统守护服务，在后台持续运行 ",[645,5738,5739],{},"synch watch"," 监听文件变化，以确保 VPS 上的笔记在系统开机时即可实现毫秒级自动同步：",[664,5742,5744],{"className":666,"code":5743,"language":668,"meta":424,"style":424},"sudo tee \u002Fetc\u002Fsystemd\u002Fsystem\u002Fsynch-watch.service \u003C\u003C'EOF'\n[Unit]\nDescription=Synch vault watcher\nAfter=network-online.target\nWants=network-online.target\n\n[Service]\nType=simple\nUser=\u003Cusername>\nExecStart=\u002Fhome\u002F\u003Cusername>\u002F.local\u002Fbin\u002Fsynch watch --vault \u002Fhome\u002F\u003Cusername>\u002Fvaults\u002F\u003Cvault-name>\nWorkingDirectory=\u002Fhome\u002F\u003Cusername>\u002Fvaults\nEnvironment=\"PATH=\u002Fhome\u002F\u003Cusername>\u002F.local\u002Fbin:\u002Fhome\u002F\u003Cusername>\u002F.cargo\u002Fbin:\u002Fusr\u002Flocal\u002Fsbin:\u002Fusr\u002Flocal\u002Fbin:\u002Fusr\u002Fsbin:\u002Fusr\u002Fbin:\u002Fsbin:\u002Fbin\"\nEnvironment=\"HOME=\u002Fhome\u002F\u003Cusername>\"\nRestart=always\nRestartSec=5\n\n[Install]\nWantedBy=multi-user.target\nEOF\nsudo systemctl daemon-reload\nsudo systemctl enable --now synch-watch.service\n",[645,5745,5746,5761,5766,5771,5776,5781,5785,5790,5795,5800,5805,5810,5815,5820,5825,5830,5834,5839,5844,5849,5858],{"__ignoreMap":424},[672,5747,5748,5750,5752,5755,5758],{"class":674,"line":675},[672,5749,841],{"class":678},[672,5751,815],{"class":686},[672,5753,5754],{"class":686}," \u002Fetc\u002Fsystemd\u002Fsystem\u002Fsynch-watch.service",[672,5756,5757],{"class":682}," \u003C\u003C",[672,5759,5760],{"class":682},"'EOF'\n",[672,5762,5763],{"class":674,"line":741},[672,5764,5765],{"class":686},"[Unit]\n",[672,5767,5768],{"class":674,"line":614},[672,5769,5770],{"class":686},"Description=Synch vault watcher\n",[672,5772,5773],{"class":674,"line":776},[672,5774,5775],{"class":686},"After=network-online.target\n",[672,5777,5778],{"class":674,"line":782},[672,5779,5780],{"class":686},"Wants=network-online.target\n",[672,5782,5783],{"class":674,"line":827},[672,5784,773],{"emptyLinePlaceholder":772},[672,5786,5787],{"class":674,"line":832},[672,5788,5789],{"class":686},"[Service]\n",[672,5791,5792],{"class":674,"line":838},[672,5793,5794],{"class":686},"Type=simple\n",[672,5796,5797],{"class":674,"line":850},[672,5798,5799],{"class":686},"User=\u003Cusername>\n",[672,5801,5802],{"class":674,"line":855},[672,5803,5804],{"class":686},"ExecStart=\u002Fhome\u002F\u003Cusername>\u002F.local\u002Fbin\u002Fsynch watch --vault \u002Fhome\u002F\u003Cusername>\u002Fvaults\u002F\u003Cvault-name>\n",[672,5806,5807],{"class":674,"line":861},[672,5808,5809],{"class":686},"WorkingDirectory=\u002Fhome\u002F\u003Cusername>\u002Fvaults\n",[672,5811,5812],{"class":674,"line":883},[672,5813,5814],{"class":686},"Environment=\"PATH=\u002Fhome\u002F\u003Cusername>\u002F.local\u002Fbin:\u002Fhome\u002F\u003Cusername>\u002F.cargo\u002Fbin:\u002Fusr\u002Flocal\u002Fsbin:\u002Fusr\u002Flocal\u002Fbin:\u002Fusr\u002Fsbin:\u002Fusr\u002Fbin:\u002Fsbin:\u002Fbin\"\n",[672,5816,5817],{"class":674,"line":888},[672,5818,5819],{"class":686},"Environment=\"HOME=\u002Fhome\u002F\u003Cusername>\"\n",[672,5821,5822],{"class":674,"line":894},[672,5823,5824],{"class":686},"Restart=always\n",[672,5826,5827],{"class":674,"line":908},[672,5828,5829],{"class":686},"RestartSec=5\n",[672,5831,5832],{"class":674,"line":913},[672,5833,773],{"emptyLinePlaceholder":772},[672,5835,5836],{"class":674,"line":919},[672,5837,5838],{"class":686},"[Install]\n",[672,5840,5841],{"class":674,"line":928},[672,5842,5843],{"class":686},"WantedBy=multi-user.target\n",[672,5845,5846],{"class":674,"line":933},[672,5847,5848],{"class":682},"EOF\n",[672,5850,5851,5853,5855],{"class":674,"line":948},[672,5852,841],{"class":678},[672,5854,899],{"class":686},[672,5856,5857],{"class":686}," daemon-reload\n",[672,5859,5860,5862,5864,5866,5869],{"class":674,"line":953},[672,5861,841],{"class":678},[672,5863,899],{"class":686},[672,5865,902],{"class":686},[672,5867,5868],{"class":686}," --now",[672,5870,5871],{"class":686}," synch-watch.service\n",[429,5873,5874,5875,5877],{},"现在，在浏览器中打开 ",[645,5876,5136],{},"，您会发现其用户界面和排版布局与桌面端原生 App 几乎完全一致：",[435,5879],{"src":5880,"alt":5881,"style":5882},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fignis-web-interface-desktop-view.webp","在桌面端显示 Obsidian 知识库的 Ignis 网页界面","max-width: 593px; width: 100%; height: auto;",[429,5884,5885],{},"点击左下角的设置图标可以发现，除了需要手动重新安装第三方社区插件外，几乎所有的 Obsidian 核心配置与功能均已完美保留：",[435,5887],{"src":5888,"alt":5889,"style":5890},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fignis-settings-community-plugins.webp","Ignis 网页界面中的社区第三方插件设置","max-width: 597px; width: 100%; height: auto;",[429,5892,5893],{},"为了测试整个同步闭环，您可以通过 Ignis 网页端直接新建一篇笔记：",[435,5895],{"src":5896,"alt":5897,"style":5890},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fignis-create-new-note-web.webp","通过 Ignis 网页界面新建一篇 Markdown 笔记",[429,5899,5900,5901,5903],{},"该笔记会立即被同步回您的 Obsidian 桌面客户端。需要注意的是，空白文件夹不会在 ",[442,5902,4656],{}," 网页端中显示。",[435,5905],{"src":5906,"alt":5907,"style":5908},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fobsidian-desktop-synced-note.webp","新创建的笔记已成功同步到本地 Obsidian 桌面客户端","max-width: 502px; width: 100%; height: auto;",[429,5910,5911,5912,5914],{},"在移动端手机浏览器上访问 ",[645,5913,5136],{}," 的实际效果：",[429,5916,5917,5922],{},[435,5918],{"src":5919,"alt":5920,"style":5921},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fignis-mobile-view-sidebar.webp","在移动端手机浏览器上访问 Ignis 网页客户端的侧边栏菜单","max-width: 269px; width: 100%; height: auto;",[435,5923],{"src":5924,"alt":5925,"style":5921},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fignis-mobile-view-editor.webp","在移动端手机浏览器上访问 Ignis 网页客户端的 Markdown 编辑器",[429,5927,5928,5929,5931,5932,5935],{},"当您在 ",[442,5930,4656],{}," 网页端中删除笔记时，它们会被安全地移至本地知识库的 ",[645,5933,5934],{},"~\u002Fvaults\u002F\u003Cvault-name>\u002F.trash"," 垃圾桶文件夹中，以防误删。",[447,5937,5939],{"id":5938},"自建-obsidian-同步服务的一些结语","自建 Obsidian 同步服务的一些结语",[429,5941,5942,5943,5945,5946,5948,5949,5951],{},"通过将 ",[442,5944,4647],{}," 与 ",[442,5947,4656],{}," 结合，您可以使用完全处于自己掌控之下的 VPS 服务器硬件，无缝地实现 Obsidian 笔记库的多端同步与网页端访问。而将这些服务整体托管于 ",[442,5950,3990],{}," 私有网络之中，又为您提供了极致的安全物理边界，从根本上阻断了公网暴露带来的安全隐患。",[429,5953,5954,5955,5957],{},"当然，",[442,5956,4656],{}," 的初衷 spiritual 并客套不是为了完全替代本地的 Obsidian 桌面客户端。相反，它更像是一个极其便利的临时桥梁，供您在没有携带主力电脑时，能够随时随地通过任意浏览器快速存取和编辑自己的笔记。对于日常高强度的写作与重度笔记库管理，本地原生客户端仍然是更加舒适、高效的选择。",[429,5959,5960,5961,5964],{},"由于 Synch 采用了坚固的端到端加密机制，您的远程知识库密码必须具备足够强的复杂度以抵御暴力破解攻击。同时，请务必牢记该密码，因为同步服务端不会存储任何未加密的",[442,5962,5963],{},"知识库秘钥","。一旦遗忘该密码，您的全部笔记数据将彻底无法恢复。此外，由于所有数据均保存在您的自建 VPS 上，您需要自行承担并妥善做好服务器的主机安全防护、以及自动快照与备份管理。",[429,5966,5967,5968,5970],{},"尽管 ",[442,5969,4647],{}," 内置了加密的历史版本管理和已删除文件恢复机制，能为您规避绝大多数意外数据丢失，但为了万无一失，我们依然强烈建议您在第三方物理介质上定期保留一份独立的 Obsidian 知识库离线备份。",[447,5972,5974],{"id":5973},"references","References",[455,5976,5977,5984,5991],{},[458,5978,5979],{},[569,5980,5983],{"href":5981,"rel":5982},"https:\u002F\u002Fsynch.run\u002Fself-hosting-docker\u002F",[1655],"Synch Deploy with Docker Compose",[458,5985,5986],{},[569,5987,5990],{"href":5988,"rel":5989},"https:\u002F\u002Fignis.thiefling.com\u002Fdocs\u002Fserver\u002Fdeploy\u002F",[1655],"Ignis Deploy with Docker",[458,5992,5993],{},[569,5994,5997],{"href":5995,"rel":5996},"https:\u002F\u002Fsynch.run\u002Fblog\u002Fencryption-and-decryption\u002F",[1655],"How does end-to-end encryption work in Synch?",[2640,5999,6000],{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}",{"title":424,"searchDepth":741,"depth":614,"links":6002},[6003,6012,6021,6022],{"id":4688,"depth":741,"text":4689,"children":6004},[6005,6009],{"id":4730,"depth":614,"text":4731,"children":6006},[6007,6008],{"id":4734,"depth":776,"text":4734},{"id":4748,"depth":776,"text":4749},{"id":4956,"depth":614,"text":4957,"children":6010},[6011],{"id":4960,"depth":776,"text":4961},{"id":5069,"depth":741,"text":5070,"children":6013},[6014],{"id":5092,"depth":614,"text":5093,"children":6015},[6016,6017,6018,6019,6020],{"id":5121,"depth":776,"text":5122},{"id":5130,"depth":776,"text":4844},{"id":5173,"depth":776,"text":5174},{"id":5387,"depth":776,"text":5388},{"id":5478,"depth":776,"text":5479},{"id":5938,"depth":741,"text":5939},{"id":5973,"depth":741,"text":5974},[6024],"productivity","2026-09-15","本文详细介绍如何利用开源工具 Synch 与 Ignis 在您的 VPS 上搭建私有同步服务器，从而在多台电脑、手机以及平板设备之间安全地同步您的 Obsidian 知识库。我们还将所有服务全部部署在 Cloudflare Zero Trust 私有网络中，从而完全阻断来自公网的恶意扫描与未授权访问，保障数据隐私安全。","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002FZH-Sync-Obsidian-Across-Devices.webp","使用自建 Synch 平台和 Ignis 网页端在 Cloudflare Zero Trust 安全私有网络中同步多端 Obsidian 本地知识库的架构图",{"schemaOrg":6030,"robots":2704,"sitemap":6033},[6031,6032],{"@type":4619,"headline":4629,"description":6026,"image":6027},{"@type":2686,"name":4629,"description":6026,"image":6027},{"lastmod":6034},"2026-09-16",{"title":6036,"description":6026,"ogTitle":4629,"ogDescription":6026,"twitterTitle":4629,"twitterDescription":6026},"基于自建 Synch 与 Ignis 实现 Obsidian 跨设备安全同步","zh\u002Farticle\u002Fsync-obsidian-across-devices",[6039,6040,6041,6042],"自建服务","Obsidian","云端同步","Zero Trust","qUymzYxHVbtcLzhIfa6H_SfwK2NWnW9W0EcGJC30Pbc",[6045,7278,7279],{"id":6046,"title":6047,"author":424,"body":6048,"category":7242,"date":7244,"description":7245,"extension":2678,"image":7246,"imageAlt":7247,"isPublished":772,"meta":7248,"minRead":888,"navigation":772,"path":355,"seo":7272,"stem":7274,"tags":7275,"updatedAt":2715,"__hash__":7277},"article\u002Fzh\u002Farticle\u002Fbringing-buzz-to-deepseek-harness.md","为 DeepSeek Harness 接入 Buzz 协作平台：构建自托管 Nostr 消息网关的完整实践",{"type":426,"value":6049,"toc":7226},[6050,6056,6077,6080,6083,6087,6092,6133,6136,6195,6199,6206,6485,6488,6492,6496,6502,6506,6520,6524,6535,6581,6588,6592,6595,6627,6630,6635,6676,6684,6690,6698,6704,6735,6749,6753,6762,6786,6807,6848,6854,6860,6866,6873,6879,6884,6892,6905,6911,6921,6956,6959,6965,6972,6978,6982,6985,7139,7142,7183,7187,7193,7197,7223],[429,6051,6052],{},[435,6053],{"alt":6054,"src":6055},"DeepSeek Harness 消息网关连接至 Block Buzz 频道的运行概览","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002Fdsh-buzz-nostr-gateway-overview.webp",[429,6057,6058,6059,6066,6067,6071,6072,6076],{},"DeepSeek Harness（DSH）的官方插件 ",[442,6060,6061],{},[569,6062,6065],{"href":6063,"rel":6064},"https:\u002F\u002Fgithub.com\u002Fa792883583\u002Fdsh-message-gateway",[1655],"dsh-message-gateway","，能够将 DeepSeek Harness 助手无缝扩展至 Discord、Telegram、微信等多种主流即时通讯平台。该插件仓库已被 Fork 并进行了二次开发，旨在将 ",[442,6068,6069],{},[569,6070,423],{"href":383}," 接入支持列表。Fork 后的开源代码仓库位于 GitHub：",[569,6073,6074],{"href":6074,"rel":6075},"https:\u002F\u002Fgithub.com\u002FTech-Voyage-Dev\u002Fdsh-message-gateway",[1655]," 。",[574,6078],{"description":2677,"image":2679,"image-alt":2680,"label":6079,"min-read":4858,"title":423,"to":383},"前置准备指南",[429,6081,6082],{},"DSH 助手作为一个全功能成员加入 Buzz Nostr 中继，既能接收私信（DM），也能接收被 @mention 提及的频道消息，并通过与 Web UI 完全相同的独立会话智能体管线输出响应。",[447,6084,6086],{"id":6085},"dsh-message-gateway-插件架构剖析","dsh-message-gateway 插件架构剖析",[429,6088,6089,6091],{},[442,6090,6065],{}," 插件的系统架构清晰划分为宿主端与客户端两大部分：",[455,6093,6094,6123],{},[458,6095,6096,3254,6099,6102,6103,6106,6107,6110,6111,6114,6115,6118,6119,6122],{},[442,6097,6098],{},"宿主端（Node 环境）",[645,6100,6101],{},"gateway-store","（凭证与配置持久化存储，位于 ",[645,6104,6105],{},"~\u002F.dsh\u002Fgateway.json","）、",[645,6108,6109],{},"platforms.ts","（支持平台定义与连通性自检）、",[645,6112,6113],{},"routes.ts","（对外暴露的 ",[645,6116,6117],{},"\u002Fgateway\u002F*"," 路由端点）以及 ",[645,6120,6121],{},"bridge-manager.ts","（常驻网关桥接器：负责按会话维护独立 Agent 实例并统一管理流式响应推送）。",[458,6124,6125,6128,6129,6132],{},[442,6126,6127],{},"客户端（浏览器前端）","：侧边栏的“",[442,6130,6131],{},"Message platforms","”可视化配置页面，负责录入密钥参数、发起连通性测试以及直观监控网关实时在线状态。",[429,6134,6135],{},"为网关接入一个全新通讯平台通常需要经历以下三步：",[591,6137,6138,6156,6170],{},[458,6139,6140,6143,6144,6147,6148,6151,6152,6155],{},[442,6141,6142],{},"实现 Bridge 桥接类","：提供 ",[645,6145,6146],{},"start\u002Fstop\u002Fstatus"," 生命周期方法以及 ",[645,6149,6150],{},"onText(text, frame)"," 消息回调，结构规范与现有的 ",[645,6153,6154],{},"wecom-bridge.ts"," 完全一致。",[458,6157,6158,6161,6162,6165,6166,6169],{},[442,6159,6160],{},"接入 bridge-manager 调度器","：复用既有的多会话调度管线（",[645,6163,6164],{},"ensureAgentForKey"," + ",[645,6167,6168],{},"pendingMap","），并将底层文本输出流挂载至该平台的专用回复接收器。",[458,6171,6172,6175,6176,5945,6179,6182,6183,6186,6187,6190,6191,6194],{},[442,6173,6174],{},"对接持久化存储与配置路由","：在 ",[645,6177,6178],{},"\u002Fgateway\u002Fsave",[645,6180,6181],{},"\u002Fgateway\u002Fdelete"," 逻辑中实现：",[442,6184,6185],{},"保存配置即自动启动桥接服务，删除配置则优雅停止桥接服务","，配合 ",[645,6188,6189],{},"autoStartXxx"," 状态标记确保 ",[645,6192,6193],{},"dsh web"," 守护进程开机自动重连。",[447,6196,6198],{"id":6197},"buzz-网关桥接实现nostr-协议标准与事件生命周期","Buzz 网关桥接实现：Nostr 协议标准与事件生命周期",[429,6200,6201,6202,6205],{},"本次接入直接使用 ",[442,6203,6204],{},"DeepSeek Harness"," 自行编写完成了完整的 Buzz 适配桥接器。底层严格遵循了如下 Nostr 协议规范标准：",[6207,6208,6209,6224],"table",{},[6210,6211,6212],"thead",{},[6213,6214,6215,6221],"tr",{},[6216,6217,6218],"th",{},[442,6219,6220],{},"维度 \u002F 阶段",[6216,6222,6223],{},"协议实现规范与技术细节",[6225,6226,6227,6249,6267,6294,6312,6337,6362,6384,6398,6412,6431,6448,6462],"tbody",{},[6213,6228,6229,6235],{},[6230,6231,6232],"td",{},[442,6233,6234],{},"底层传输（Transport）",[6230,6236,6237,6238,6241,6242,6245,6246],{},"单条经过 NIP-42 鉴权认证的 WebSocket 链路；默认中继连接地址为 ",[645,6239,6240],{},"ws:\u002F\u002Flocalhost:3000","；输入的 ",[645,6243,6244],{},"http(s):\u002F\u002F"," 会自动规整为 ",[645,6247,6248],{},"ws(s):\u002F\u002F",[6213,6250,6251,6256],{},[6230,6252,6253],{},[442,6254,6255],{},"鉴权认证（Auth）",[6230,6257,6258,6259,6262,6263,6266],{},"AUTH 事件 ",[645,6260,6261],{},"kind 22242","，携带标签 ",[645,6264,6265],{},"[[\"relay\", url], [\"challenge\", challenge]]","，内容为空字符串，由 Agent 的私钥完成签名",[6213,6268,6269,6274],{},[6230,6270,6271],{},[442,6272,6273],{},"订阅机制（Subs）",[6230,6275,6276,3254,6279,6282,6283,6286,6287,6290,6291],{},[442,6277,6278],{},"严格基于频道隔离",[645,6280,6281],{},"REQ {\"kinds\":[9], \"#h\":[\u003Cuuid>]}"," — 每个频道独立建立一条订阅。全局性的 ",[645,6284,6285],{},"kinds:[9]"," 虽能收到 EOSE 但绝不广播推送；多值 ",[645,6288,6289],{},"#h"," 标签过滤在协议中",[442,6292,6293],{},"无法正常分发",[6213,6295,6296,6301],{},[6230,6297,6298],{},[442,6299,6300],{},"频道发现（Discovery）",[6230,6302,6303,6304,6307,6308,6311],{},"历史元数据回溯查询 ",[645,6305,6306],{},"REQ {kinds:[39000]}"," 提取频道详情（其中 ",[645,6309,6310],{},"type == \"dm\""," 用于标记单聊私信频道）",[6213,6313,6314,6319],{},[6230,6315,6316],{},[442,6317,6318],{},"成员变动订阅",[6230,6320,6321,6322,6325,6326,6328,6329,6332,6333,6336],{},"实时长连接订阅 ",[645,6323,6324],{},"REQ {kinds:[44100,44101], \"#p\":[Agent 公钥], since: now-60s}"," — 44100 为入群，44101 为被移出，均附带 ",[645,6327,429],{},"+",[645,6330,6331],{},"h","；成员关系变更时",[442,6334,6335],{},"无需重连","即可动态热更新订阅状态",[6213,6338,6339,6344],{},[6230,6340,6341],{},[442,6342,6343],{},"即时聊天事件",[6230,6345,6346,6349,6350,6353,6354,6357,6358,6361],{},[645,6347,6348],{},"kind 9"," 事件，携带 ",[645,6351,6352],{},"[\"h\", channel]"," 频道标签，可选附带 ",[645,6355,6356],{},"[\"e\", replyTo]"," 回复目标与 ",[645,6359,6360],{},"[\"p\", mention]"," 被提及者标签",[6213,6363,6364,6369],{},[6230,6365,6366],{},[442,6367,6368],{},"原位更新编辑",[6230,6370,6371,6374,6375,5945,6377,6380,6381,6383],{},[645,6372,6373],{},"kind 40003"," 事件，附带 ",[645,6376,6331],{},[645,6378,6379],{},"e"," 目标标签；内容完全替换；中继单包上限 64 KB → 严控载荷 ≤ 60,000 B；超长回复分块处理 — 首块用于原位编辑替换，超出部分作为回复串线程的 ",[645,6382,6348],{}," 消息追加",[6213,6385,6386,6391],{},[6230,6387,6388],{},[442,6389,6390],{},"CLOSED 异常帧处理",[6230,6392,6393,6394,6397],{},"鉴权未完成前收到 ",[645,6395,6396],{},"auth-required"," 属于正常引导阶段（完成 AUTH 后重新拉起订阅）；鉴权完成后遇断连 → 阶梯式限次重试（最多 3 次，间隔 0\u002F1\u002F2 秒退避）；整链重连时全量重构上下文",[6213,6399,6400,6405],{},[6230,6401,6402],{},[442,6403,6404],{},"中继拉取上限",[6230,6406,6407,6408,6411],{},"每次订阅最多拉取 2000 条历史事件，即使配置了 ",[645,6409,6410],{},"since"," 过滤参数，中继仍按自最新向过去的时间倒序返回",[6213,6413,6414,6419],{},[6230,6415,6416],{},[442,6417,6418],{},"消息命中判定",[6230,6420,6421,6422,6424,6425,6427,6428,6430],{},"仅当满足以下任一条件时才激活处理入站 ",[645,6423,6348],{},"：(a) ",[645,6426,429],{}," 标签明确包含自身公钥，(b) 处于 DM 私信频道，(c) 回复关联的 ",[645,6429,6379],{}," 根事件为自身发出的消息。自动过滤自身公钥发送的内容（彻底杜绝自环）",[6213,6432,6433,6438],{},[6230,6434,6435],{},[442,6436,6437],{},"出站 @ 提及",[6230,6439,6440,6441,6444,6445,6447],{},"出站内容按纯文本原样发布 — 中继端不对正文中的 ",[645,6442,6443],{},"@"," 符号进行预校验；",[645,6446,429],{}," 标签填入当前对话原作者以及至多 7 位其他被提及者的公钥（单条上限 8 位）",[6213,6449,6450,6455],{},[6230,6451,6452],{},[442,6453,6454],{},"私聊消息（DM）",[6230,6456,6457,6458,6461],{},"依赖中继作用域内的明文受限频道（元数据标注 ",[645,6459,6460],{},"type: \"dm\"","） — 当前桥接实现中未引入 NIP-04\u002F44 复杂非对称端到端加密",[6213,6463,6464,6469],{},[6230,6465,6466],{},[442,6467,6468],{},"媒体附件（入站）",[6230,6470,6471,6472,6475,6476,4189,6478,4189,6481,6484],{},"NIP-92 ",[645,6473,6474],{},"imeta"," 规范（",[645,6477,4458],{},[645,6479,6480],{},"sha256",[645,6482,6483],{},"m","）→ 常规 HTTP(S) 流式下载，本地校验 SHA-256 完整性，单文件限制 20 MB，每条消息最多 4 张；出站图片发布暂无官方中继协议路径，现阶段不支持出站图片",[429,6486,6487],{},"Buzz 适配网关的启动引导时序图如下：",[435,6489],{"src":6490,"alt":6491},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002Fdsh-buzz-bootstrap.webp","展示 Buzz 网关引导连接与 NIP-42 协议身份鉴权流程的时序图",[547,6493,6495],{"id":6494},"基于-nostr-40003-事件原位编辑实现的实时流式输出","基于 Nostr 40003 事件原位编辑实现的实时流式输出",[429,6497,6498,6499,3254],{},"Nostr 协议缺乏原生打字中（Typing）状态通知，且底层事件设计为严格只增不改。为了让对话过程具备行云流水的实时交互感，Buzz 适配网关",[442,6500,6501],{},"通过原位编辑巧妙模拟了流式打字输出",[435,6503],{"src":6504,"alt":6505},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002Fdsh-buzz-reply.webp","基于 kind 40003 事件原位编辑模拟打字流式响应的逻辑流程图",[455,6507,6508],{},[458,6509,6510],{},[6511,6512,6513,6514,6516,6517,6519],"em",{},"网关首先秒级发出一条 ",[645,6515,6348],{}," 占位消息，随后在 Agent 推理过程中按设定的节流阈值连续发射 ",[645,6518,6373],{}," 原位编辑事件逐步追加渲染内容，并在推理终点落定最终文本。这一设计思路与 Telegram、Discord 桥接器的实现方式一脉相承。",[547,6521,6523],{"id":6522},"通过聊天指令打通-deepseek-harness-本地工作区","通过聊天指令打通 DeepSeek Harness 本地工作区",[429,6525,6526,6527,6530,6531,6534],{},"DSH Web 界面所支持的“工作区（Workspaces）”核心能力依赖于底层 ",[645,6528,6529],{},"@deepseek-ai\u002Fdsh-workspace"," 模块中的 ",[645,6532,6533],{},"workspaceRegistry"," 服务：",[664,6536,6540],{"className":6537,"code":6538,"language":6539,"meta":424,"style":424},"language-typescript shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","const existing = await ctx.workspaceRegistry.resolveByPath(request.path);\n","typescript",[645,6541,6542],{"__ignoreMap":424},[672,6543,6544,6547,6550,6553,6557,6560,6563,6565,6567,6570,6573,6575,6578],{"class":674,"line":675},[672,6545,6546],{"class":1280},"const",[672,6548,6549],{"class":2013}," existing ",[672,6551,6552],{"class":682},"=",[672,6554,6556],{"class":6555},"s7zQu"," await",[672,6558,6559],{"class":2013}," ctx",[672,6561,6562],{"class":682},".",[672,6564,6533],{"class":2013},[672,6566,6562],{"class":682},[672,6568,6569],{"class":785},"resolveByPath",[672,6571,6572],{"class":2013},"(request",[672,6574,6562],{"class":682},[672,6576,6577],{"class":2013},"path)",[672,6579,6580],{"class":682},";\n",[429,6582,6583,6584,6587],{},"Buzz 桥接器通过引入全新的聊天斜杠指令 ",[645,6585,6586],{},"\u002Fworkspace \u003C目录路径>","，允许在群聊中直接向 DSH 注册并绑定本地现存的文件夹。在此之后，该会话下的所有交互都将牢牢锚定在此目录中，并能实时无缝同步在 DSH Web UI 端查看。",[435,6589],{"src":6590,"alt":6591},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002Fdsh-buzz-workspace.webp","通过网关聊天指令动态注册并绑定 DeepSeek Harness 本地工作区的架构示意图",[429,6593,6594],{},"开发与使用过程中需重点明确的三大设计机制：",[455,6596,6597,6607,6617],{},[458,6598,6599,6602,6603,6606],{},[442,6600,6601],{},"变更目录等同于开启全新会话","：会话的工作目录（",[645,6604,6605],{},"cwd","）在初始化生成 Session Header 时即完成写入，后续在生命周期内不可直接原地篡改。",[458,6608,6609,6612,6613,6616],{},[442,6610,6611],{},"目标本地目录必须预先存在","：底层 ",[645,6614,6615],{},"create"," 注册函数会对路径进行强校验，若路径在宿主机不存在将直接抛出异常拒绝绑定。",[458,6618,6619,6622,6623,6626],{},[442,6620,6621],{},"高度安全敏感指令","：通过网关衍生的会话均赋予 ",[442,6624,6625],{},"auto-approve","（自动批准命令执行）特权，拥有对目标文件夹直接进行读写和工具操作的完全访问权。",[447,6628,6629],{"id":6629},"安装与配置全流程指南",[591,6631,6632],{},[458,6633,6634],{},"在终端运行以下指令完成插件拉取与启动：",[664,6636,6638],{"className":666,"code":6637,"language":668,"meta":424,"style":424},"dsh plugin --profile web add https:\u002F\u002Fgithub.com\u002FTech-Voyage-Dev\u002Fdsh-message-gateway.git\n\n# Start DSH web\ndsh web\n",[645,6639,6640,6660,6664,6669],{"__ignoreMap":424},[672,6641,6642,6645,6648,6651,6654,6657],{"class":674,"line":675},[672,6643,6644],{"class":678},"dsh",[672,6646,6647],{"class":686}," plugin",[672,6649,6650],{"class":686}," --profile",[672,6652,6653],{"class":686}," web",[672,6655,6656],{"class":686}," add",[672,6658,6659],{"class":686}," https:\u002F\u002Fgithub.com\u002FTech-Voyage-Dev\u002Fdsh-message-gateway.git\n",[672,6661,6662],{"class":674,"line":741},[672,6663,773],{"emptyLinePlaceholder":772},[672,6665,6666],{"class":674,"line":614},[672,6667,6668],{"class":737},"# Start DSH web\n",[672,6670,6671,6673],{"class":674,"line":776},[672,6672,6644],{"class":678},[672,6674,6675],{"class":686}," web\n",[591,6677,6678],{"start":741},[458,6679,6680,6681,6683],{},"待 DSH Web 界面启动并用浏览器打开后，点击界面侧边栏中的“",[442,6682,6131],{},"”图标：",[429,6685,6686],{},[435,6687],{"alt":6688,"src":6689},"DeepSeek Harness Web UI 侧边栏高亮显示的 Message platforms 配置菜单项","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002Fdsh-web-ui-message-platforms-sidebar-icon.webp",[591,6691,6692],{"start":614},[458,6693,6694,6695,6697],{},"在左侧平台列表中选择“",[442,6696,444],{},"”：",[429,6699,6700],{},[435,6701],{"alt":6702,"src":6703},"DeepSeek Harness 消息网关内的 Buzz 协议参数与密钥对配置面板","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002Fdsh-message-gateway-buzz-config-panel.webp",[591,6705,6706,6717,6728],{"start":776},[458,6707,6708,6709,6712,6713,6716],{},"点击“",[442,6710,6711],{},"Generate keypair","”按钮即时生成全新的 Nostr 身份密钥对。请务必将生成的 ",[645,6714,6715],{},"npub"," 公钥妥善复制暂存，后续步骤将作为关键身份凭证。",[458,6718,6719,6720,6723,6724,6727],{},"准确填入您的 ",[442,6721,6722],{},"Relay URL","（中继地址）以及需要监听订阅的 ",[442,6725,6726],{},"Channels","（允许访问的频道 UUID 白名单列表）。",[458,6729,6730,6731,6734],{},"点击底部的“",[442,6732,6733],{},"Save","”按钮完成保存。",[429,6736,6737,6738,6741,6742,6745,6746,6748],{},"表单提交后，系统将持久化保存配置并",[442,6739,6740],{},"立即启动 Buzz 网关服务","。私钥 ",[645,6743,6744],{},"nsec"," 作为最高机密凭证被自动保护，仅独立存放在宿主机本地的 ",[645,6747,6105],{}," 文件中。",[547,6750,6752],{"id":6751},"将-dsh-智能体注册至-buzz-nostr-中继服务","将 DSH 智能体注册至 Buzz Nostr 中继服务",[429,6754,6755,6758,6759,6761],{},[442,6756,6757],{},"将 DSH 助手作为新成员注册加入中继","。此处公钥填入上文所生成的 ",[645,6760,6715],{}," 字符串：",[664,6763,6765],{"className":666,"code":6764,"language":668,"meta":424,"style":424},"docker compose exec relay buzz-admin add-member --pubkey npub123123123\n",[645,6766,6767],{"__ignoreMap":424},[672,6768,6769,6771,6773,6775,6777,6779,6781,6783],{"class":674,"line":675},[672,6770,922],{"class":678},[672,6772,964],{"class":686},[672,6774,1692],{"class":686},[672,6776,1695],{"class":686},[672,6778,1698],{"class":686},[672,6780,1701],{"class":686},[672,6782,1704],{"class":686},[672,6784,6785],{"class":686}," npub123123123\n",[429,6787,6788,6791,6792,6794,6795,6798,6799,6802,6803,6806],{},[442,6789,6790],{},"将 DSH 助手加入特定的沟通频道","。仅加入中继并不会让助手自动出现在频道成员列表中。需要通过 ",[645,6793,1833],{}," 进一步执行入群操作。注意此处 ",[645,6796,6797],{},"--pubkey"," 参数必须使用 ",[442,6800,6801],{},"HEX 16 进制公钥","格式，而非 npub 格式（在上一步执行 ",[645,6804,6805],{},"buzz-admin add-member"," 时，终端输出中会打印对应的 HEX 公钥）：",[664,6808,6810],{"className":666,"code":6809,"language":668,"meta":424,"style":424},"buzz channels add-member --channel \u003CCHANNEL_UUID> --pubkey \u003CAGENT_HEX> --role member\n",[645,6811,6812],{"__ignoreMap":424},[672,6813,6814,6816,6818,6820,6822,6824,6826,6828,6830,6832,6834,6837,6840,6842,6845],{"class":674,"line":675},[672,6815,2065],{"class":678},[672,6817,2068],{"class":686},[672,6819,1701],{"class":686},[672,6821,2120],{"class":686},[672,6823,2336],{"class":682},[672,6825,2339],{"class":686},[672,6827,2342],{"class":2013},[672,6829,2017],{"class":682},[672,6831,1704],{"class":686},[672,6833,2336],{"class":682},[672,6835,6836],{"class":686},"AGENT_HE",[672,6838,6839],{"class":2013},"X",[672,6841,2017],{"class":682},[672,6843,6844],{"class":686}," --role",[672,6846,6847],{"class":686}," member\n",[574,6849],{"description":6850,"image":2679,"image-alt":2680,"label":6851,"min-read":4001,"title":6852,"to":6853},"手把手教您安装和配置 buzz-cli，以便在 Nostr 中继上管理频道、成员密钥以及 AI 智能体的角色权限。","CLI 指南","如何安装并使用 buzz-cli","\u002Farticle\u002Fself-hosting-buzz-as-the-workspace-where-ai-agents-become-colleagues#install-buzz-cli",[429,6855,6856,6857,6859],{},"随后可通过 ",[645,6858,1833],{}," 灵活更新 DSH 助手在 Nostr 中继中的公开资料，设置更具辨识度的昵称：",[429,6861,6862],{},[435,6863],{"alt":6864,"src":6865},"使用 buzz-cli 命令行工具更新 DSH 助手在 Nostr 中继上的公开个人资料","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002Fdsh-assistant-buzz-cli-profile-update.webp",[429,6867,6868,6869,6872],{},"在客户端向 DSH 助手发送一次 ",[442,6870,6871],{},"Wave","（Buzz 平台独特的 DM 私信打招呼动作）。助手随后返回回复，代表网关通讯已完全就绪：",[429,6874,6875],{},[435,6876],{"alt":6877,"src":6878},"在 Buzz 客户端向 DeepSeek Harness 助手发送 Wave 私信进行连通性验证","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002Fdsh-buzz-dm-wave-greeting-reply.webp",[429,6880,6881],{},[6511,6882,6883],{},"向 DSH 助手发送 Wave 私信打招呼 — 桥接网关正常秒级响应。",[547,6885,6887,6888,6891],{"id":6886},"通过-workspace-指令开启本地工作区联动","通过 ",[645,6889,6890],{},"\u002Fworkspace"," 指令开启本地工作区联动",[429,6893,5110,6894,6897,6898,6901,6902,6904],{},[645,6895,6896],{},"allowWorkspace"," 配置项出于环境安全考虑默认处于禁用（",[645,6899,6900],{},"false","）状态，未经配置直接向助手发送 ",[645,6903,6890],{}," 命令会被系统拦截拒绝：",[429,6906,6907],{},[435,6908],{"alt":6909,"src":6910},"在未开启 allowWorkspace 权限时发送 \u002Fworkspace 命令被系统安全拦截的提示","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002Fdsh-buzz-workspace-command-rejected-error.webp",[429,6912,6913,6914,6917,6918,6920],{},"打开配置文件 ",[645,6915,6916],{},"~\u002F.dsh\u002Fprofiles\u002Fweb\u002Fcordis.patch.yml"," 添加开关配置，随后重启 ",[645,6919,6193],{}," 服务即可：",[664,6922,6924],{"className":1158,"code":6923,"language":1160,"meta":424,"style":424},"- id: ui-message-gateway\n  config:\n    allowWorkspace: true\n",[645,6925,6926,6939,6946],{"__ignoreMap":424},[672,6927,6928,6931,6934,6936],{"class":674,"line":675},[672,6929,6930],{"class":682},"-",[672,6932,6933],{"class":1258}," id",[672,6935,1277],{"class":682},[672,6937,6938],{"class":686}," ui-message-gateway\n",[672,6940,6941,6944],{"class":674,"line":741},[672,6942,6943],{"class":1258},"  config",[672,6945,1262],{"class":682},[672,6947,6948,6951,6953],{"class":674,"line":614},[672,6949,6950],{"class":1258},"    allowWorkspace",[672,6952,1277],{"class":682},[672,6954,2234],{"class":6955},"sfNiH",[429,6957,6958],{},"配置生效并重启后即可顺利绑定：",[429,6960,6961],{},[435,6962],{"alt":6963,"src":6964},"在 Buzz 频道成功执行 \u002Fworkspace 命令完成本地工作区绑定的确认消息","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002Fdsh-buzz-workspace-command-success-confirmation.webp",[429,6966,6967,6968,6971],{},"实用贴士：此命令默认假设工作区目录名（例如截图中的 ",[645,6969,6970],{},"TechVoyage","）直接位于当前用户的个人主目录之下；若目录处于其他深层路径，请务必传入完整绝对路径。通过 Buzz 频道中注册绑定好的新会话，也都会完全同步在 DeepSeek Harness Web 界面上显示。",[429,6973,6974],{},[435,6975],{"alt":6976,"src":6977},"DeepSeek Harness Web UI 中展示从 Buzz 频道自动同步关联的活跃工作区会话","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002Fdsh-web-ui-synced-workspace-session.webp",[547,6979,6981],{"id":6980},"buzz-频道支持的完整可用指令","Buzz 频道支持的完整可用指令",[429,6983,6984],{},"其他平台支持的几乎全部原生功能在 Buzz 中均可顺畅运行：",[6207,6986,6987,6997],{},[6210,6988,6989],{},[6213,6990,6991,6994],{},[6216,6992,6993],{},"指令语法",[6216,6995,6996],{},"功能说明",[6225,6998,6999,7009,7019,7029,7039,7049,7059,7069,7079,7102,7122],{},[6213,7000,7001,7006],{},[6230,7002,7003],{},[645,7004,7005],{},"\u002Fworkspace \u003Cfolder>",[6230,7007,7008],{},"将本地已存在的文件夹注册绑定为当前对话专属的工作区环境（受配置项开关保护）",[6213,7010,7011,7016],{},[6230,7012,7013],{},[645,7014,7015],{},"\u002Fhelp",[6230,7017,7018],{},"打印并列出所有支持的命令清单",[6213,7020,7021,7026],{},[6230,7022,7023],{},[645,7024,7025],{},"\u002Ftime",[6230,7027,7028],{},"获取并输出当前服务器系统时间",[6213,7030,7031,7036],{},[6230,7032,7033],{},[645,7034,7035],{},"\u002Fnew",[6230,7037,7038],{},"丢弃旧上下文，原地重置开启全新会话",[6213,7040,7041,7046],{},[6230,7042,7043],{},[645,7044,7045],{},"\u002Fclear",[6230,7047,7048],{},"清空当前上下文所有历史对话流",[6213,7050,7051,7056],{},[6230,7052,7053],{},[645,7054,7055],{},"\u002Fstatus",[6230,7057,7058],{},"查看当前 Buzz 消息桥接器的实时在线状态",[6213,7060,7061,7066],{},[6230,7062,7063],{},[645,7064,7065],{},"\u002Fstats",[6230,7067,7068],{},"查看当前系统活跃会话总量及所有接入平台（包含 Buzz）的桥接连接详细状态",[6213,7070,7071,7076],{},[6230,7072,7073],{},[645,7074,7075],{},"\u002Fcommands",[6230,7077,7078],{},"输出全量指令的底层规范与参数描述文档",[6213,7080,7081,7086],{},[6230,7082,7083],{},[645,7084,7085],{},"@path\u002Fto\u002Ffile",[6230,7087,7088,7089,7091,7092,1081,7094,7097,7098,7101],{},"与 Web 端的 ",[645,7090,6443],{}," 文件提及功能完全一致：Agent 自动相对于工作区读取文件内容；单独发送 ",[645,7093,6443],{},[645,7095,7096],{},"@前缀"," 或使用 ",[645,7099,7100],{},"\u002Ffiles \u003C前缀>"," 可返回文件\u002F文件夹列表",[6213,7103,7104,7109],{},[6230,7105,7106],{},[645,7107,7108],{},"\u002Fmodel",[6230,7110,7111,7114,7115,7117,7118,7121],{},[645,7112,7113],{},"[provider model effort]"," — 校验有效后实时切换该会话的底层推理大模型与思考深度；单独输入 ",[645,7116,7108],{}," 显示支持的候选列表，",[645,7119,7120],{},"\u002Fmodel reset"," 恢复系统默认设置",[6213,7123,7124,7129],{},[6230,7125,7126],{},[645,7127,7128],{},"\u002Feffort",[6230,7130,7131,7134,7135,7138],{},[645,7132,7133],{},"\u003Cid>"," 仅针对支持思考深度的模型调整 reasoning effort；",[645,7136,7137],{},"\u002Feffort reset"," 恢复默认推理深度配置",[547,7140,7141],{"id":7141},"核心安全架构总结",[455,7143,7144,7156,7170],{},[458,7145,7146,7149,7150,7152,7153,7155],{},[442,7147,7148],{},"私钥资产隔离保护","：Agent 专属的私钥 ",[442,7151,6744],{}," 仅保存在宿主机的 ",[645,7154,6105],{}," 中（0600 文件只读权限，原子写入机制） — 永远不会通过 API 端点对外暴露，也不会打印至日常调试日志中。",[458,7157,7158,7161,7162,7165,7166,7169],{},[442,7159,7160],{},"全链路加密签名验签","：每一个入站的 Nostr 事件在投递给 Agent 执行之前，都会严密执行",[442,7163,7164],{},"密码学数字签名检验","（",[645,7167,7168],{},"verifyEvent","）、消息防重放判重、自发自收环路过滤以及 @提及权限校验。",[458,7171,7172,7175,7176,7178,7179,7182],{},[442,7173,7174],{},"本地工作区指令受限保护","：由于网关会话默认开启特权自动批准机制，",[645,7177,6890],{}," 目录注册能力默认处于禁用状态，必须由开发者在配置文件中明确开启（",[645,7180,7181],{},"allowWorkspace: true","），严防非预期提权暴露敏感目录。",[447,7184,7186],{"id":7185},"结语拥抱-buzz-去中心化人机协作时代","结语：拥抱 Buzz 去中心化人机协作时代",[429,7188,7189,7190,7192],{},"在将 Buzz 接入 ",[645,7191,6065],{}," 的探索过程中，最大的技术挑战在于严密契合 Nostr 协议的去中心化事件生命周期与事件约束规范。所幸插件本身优秀的架构底座已经将多 Agent 会话管理与命令分发高度抽象，一旦建立起可靠的事件监听与原位流式编辑链路，整个桥接网关便能呈现出超预期的流畅度与生产级稳定性。",[447,7194,7196],{"id":7195},"参考文献与资料","参考文献与资料：",[455,7198,7199,7207,7215],{},[458,7200,7201,7206],{},[569,7202,7205],{"href":7203,"rel":7204},"https:\u002F\u002Fgithub.com\u002Fa792883583\u002Fdsh-message-gateway\u002Fblob\u002Fmain\u002Fdocs\u002Farchitecture.md",[1655],"dsh-message-gateway architecture guide"," — 官方网关架构指南、扩展实践与安全规范",[458,7208,7209,7214],{},[569,7210,7213],{"href":7211,"rel":7212},"https:\u002F\u002Fgithub.com\u002Fnbd-wtf\u002Fnostr-tools",[1655],"nostr-tools"," — 底层调用的核心 Nostr JavaScript 客户端库",[458,7216,7217,7222],{},[569,7218,7221],{"href":7219,"rel":7220},"https:\u002F\u002Fgithub.com\u002Fbytedance\u002Fdeer-flow\u002Fblob\u002Fmain\u002Fbackend\u002Fdocs\u002FIM_CHANNEL_CONNECTIONS.md",[1655],"deer-flow IM channel connections"," — 即时通讯平台多通道连接架构设计参考",[2640,7224,7225],{},"html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}",{"title":424,"searchDepth":741,"depth":614,"links":7227},[7228,7229,7233,7240,7241],{"id":6085,"depth":741,"text":6086},{"id":6197,"depth":741,"text":6198,"children":7230},[7231,7232],{"id":6494,"depth":614,"text":6495},{"id":6522,"depth":614,"text":6523},{"id":6629,"depth":741,"text":6629,"children":7234},[7235,7236,7238,7239],{"id":6751,"depth":614,"text":6752},{"id":6886,"depth":614,"text":7237},"通过 \u002Fworkspace 指令开启本地工作区联动",{"id":6980,"depth":614,"text":6981},{"id":7141,"depth":614,"text":7141},{"id":7185,"depth":741,"text":7186},{"id":7195,"depth":741,"text":7196},[2675,2674,2065,7243],"deepseek-harness","2026-09-30","深入解析如何通过 Nostr 协议将 DeepSeek Harness 接入 Block Buzz 协作平台：手把手配置 NIP-42 鉴权认证、基于 40003 事件的原位流式编辑输出、频道独立会话管理与本地工作区指令联动，为开发团队构建起安全可控、开箱即用的人机协同智能体开发环境与全新工作流程。","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002FZH-Bringing-Buzz-to-DeepSeek-Harness.webp","一张高颜值的 16:9 科技质感卡片，具有深蓝色与琥珀色调，插图展示如何为 DeepSeek Harness 接入 Block Buzz 协作平台并构建自托管 Nostr 协议网关，中央配有高对比度毛玻璃面板与精致中文排版。",{"schemaOrg":7249,"robots":2704,"sitemap":7271},[7250,7251],{"@type":2684,"headline":6047,"description":7245,"image":7246},{"@type":2686,"name":6047,"description":7245,"image":7246,"step":7252},[7253,7256,7259,7262,7265,7268],{"@type":2689,"name":7254,"text":7255},"阶段一：安装与启动消息网关插件","执行 dsh plugin add 命令安装 dsh-message-gateway 并启动 dsh web 服务。",{"@type":2689,"name":7257,"text":7258},"阶段二：访问 Message platforms 配置中心","通过浏览器打开 DSH Web 界面并导航至 Message platforms 菜单。",{"@type":2689,"name":7260,"text":7261},"阶段三：配置 Buzz 桥接参数与生成密钥对","即时生成 Nostr 身份密钥对，准确填入 Relay URL 与订阅频道 UUID 列表。",{"@type":2689,"name":7263,"text":7264},"阶段四：将智能体注册加入 Buzz 中继服务","使用 buzz-admin 命令行工具将 DSH 助手的 npub 公钥加入中继成员。",{"@type":2689,"name":7266,"text":7267},"阶段五：将智能体加入指定的团队频道","使用 buzz-cli 命令行工具将 16 进制 HEX 公钥加入频道成员名单。",{"@type":2689,"name":7269,"text":7270},"阶段六：开启本地工作区绑定权限","在 cordis.patch.yml 中开启 allowWorkspace 配置以允许目录挂载指令。",{"lastmod":7244},{"title":7273,"description":7245,"ogTitle":6047,"ogDescription":7245,"twitterTitle":6047,"twitterDescription":7245},"DeepSeek Harness Buzz 插件开发：构建 Nostr 协议网关与实时流式输出的完整教程","zh\u002Farticle\u002Fbringing-buzz-to-deepseek-harness",[6204,444,2711,7276,6065],"AI智能体","-Uv9S6aUiVlNLLDrGF-a3NbzGbjT5AnW8AjMaIbu1Ao",{"id":2720,"title":2721,"author":2715,"body":2722,"category":4609,"date":4611,"description":4612,"extension":2678,"image":4613,"imageAlt":4614,"isPublished":772,"meta":4615,"minRead":959,"navigation":772,"path":379,"seo":4622,"stem":4623,"tags":4624,"updatedAt":2706,"__hash__":4626},{"id":7280,"title":7281,"author":424,"body":7282,"category":7850,"date":7851,"description":7852,"extension":2678,"image":7853,"imageAlt":7854,"isPublished":772,"meta":7855,"minRead":741,"navigation":772,"path":367,"seo":7859,"stem":7861,"tags":7862,"updatedAt":2715,"__hash__":7866},"article\u002Fzh\u002Farticle\u002Fhow-ai-agent-skills-replace-nuxt-app-scaffolding-scripts.md","从传统初始化模板脚本到智能体：AI Agent 技能如何优雅地取代 Nuxt 应用程序脚手架构建脚本",{"type":426,"value":7283,"toc":7843},[7284,7298,7302,7305,7401,7404,7432,7438,7442,7457,7460,7477,7481,7492,7662,7666,7749,7753,7762,7782,7789,7804,7814,7817,7823,7826,7832,7840],[429,7285,7286,7287,1124,7290,7293,7294,7297],{},"当我们使用 Nuxt 框架启动一个新应用时，总是需要经历一系列繁琐的初始化步骤，比如安装各种依赖模块，以及配置 ",[645,7288,7289],{},"nuxt.config.ts",[645,7291,7292],{},"wrangler.jsonc"," 等文件。传统的脚本固然可以解决一部分问题，但随着项目定制化需求的增加，脚本的局限性也迅速暴露出来。这正是我们探索并尝试用 ",[442,7295,7296],{},"AI 智能体技能 (Agent Skill)"," 取代传统脚本的原因。",[447,7299,7301],{"id":7300},"传统-shell-脚本擅长什么","传统 Shell 脚本擅长什么",[429,7303,7304],{},"传统的 Shell 脚本非常适合按顺序执行一组固定的指令，且其中的所有决策都是在代码中预先写死的（Hardcoded）。",[664,7306,7308],{"className":666,"code":7307,"language":668,"meta":424,"style":424},"#!\u002Fusr\u002Fbin\u002Fenv bash\nset -e\n\nnpx nuxi@latest init \"$1\" --template minimal --packageManager pnpm --no-gitInit -M @nuxt\u002Fui,@nuxthub\u002Fcore,@vueuse\u002Fnuxt\n\ncd \"$1\"\n\ncp ~\u002Ftemplates\u002Fnuxt.config.ts .\ncp ~\u002Ftemplates\u002Fwrangler.jsonc .\n",[645,7309,7310,7315,7322,7326,7365,7369,7379,7383,7392],{"__ignoreMap":424},[672,7311,7312],{"class":674,"line":675},[672,7313,7314],{"class":737},"#!\u002Fusr\u002Fbin\u002Fenv bash\n",[672,7316,7317,7320],{"class":674,"line":741},[672,7318,7319],{"class":785},"set",[672,7321,1628],{"class":686},[672,7323,7324],{"class":674,"line":614},[672,7325,773],{"emptyLinePlaceholder":772},[672,7327,7328,7330,7333,7336,7338,7342,7344,7347,7350,7353,7356,7359,7362],{"class":674,"line":776},[672,7329,4110],{"class":678},[672,7331,7332],{"class":686}," nuxi@latest",[672,7334,7335],{"class":686}," init",[672,7337,683],{"class":682},[672,7339,7341],{"class":7340},"sHdIc","$1",[672,7343,690],{"class":682},[672,7345,7346],{"class":686}," --template",[672,7348,7349],{"class":686}," minimal",[672,7351,7352],{"class":686}," --packageManager",[672,7354,7355],{"class":686}," pnpm",[672,7357,7358],{"class":686}," --no-gitInit",[672,7360,7361],{"class":686}," -M",[672,7363,7364],{"class":686}," @nuxt\u002Fui,@nuxthub\u002Fcore,@vueuse\u002Fnuxt\n",[672,7366,7367],{"class":674,"line":782},[672,7368,773],{"emptyLinePlaceholder":772},[672,7370,7371,7373,7375,7377],{"class":674,"line":827},[672,7372,996],{"class":785},[672,7374,683],{"class":682},[672,7376,7341],{"class":7340},[672,7378,701],{"class":682},[672,7380,7381],{"class":674,"line":832},[672,7382,773],{"emptyLinePlaceholder":772},[672,7384,7385,7387,7390],{"class":674,"line":838},[672,7386,1004],{"class":678},[672,7388,7389],{"class":686}," ~\u002Ftemplates\u002Fnuxt.config.ts",[672,7391,1313],{"class":686},[672,7393,7394,7396,7399],{"class":674,"line":850},[672,7395,1004],{"class":678},[672,7397,7398],{"class":686}," ~\u002Ftemplates\u002Fwrangler.jsonc",[672,7400,1313],{"class":686},[429,7402,7403],{},"但在面对以下开发痛点时，这种脚本就无能为力了：",[455,7405,7406,7412,7422],{},[458,7407,7408,7411],{},[442,7409,7410],{},"固定的默认值。"," 该脚本将 Nuxt UI 模块写死了。如果我们想换成 Ant Design UI 呢？每增加一个可选的模块，就需要用户提供更多的命令行参数。",[458,7413,7414,7417,7418,7421],{},[442,7415,7416],{},"无法理解用户的真实意图。"," “帮我建一个博客网站”需要引入 ",[645,7419,7420],{},"@nuxt\u002Fcontent","；“帮我建一个带订阅邮件功能的网站”则需要 Cloudflare D1 和 Drizzle ORM。普通的 Shell 脚本根本无法识别这些细微的语义差别——针对每种细微的变体，你都必须重新写一个脚本。",[458,7423,7424,7427,7428,7431],{},[442,7425,7426],{},"在不知不觉中悄然过时。"," Nuxt 框架在大版本迭代时，其目录规范往往会发生显著改变。例如 Nuxt 4 将默认的源码目录更改为了 ",[645,7429,7430],{},"app\u002F","。如果你继续运行为 Nuxt 3 编写的脚手架脚本，它会在后台静默地生成错误的目录结构，且绝不会向用户发出任何警报。",[429,7433,7434,7437],{},[442,7435,7436],{},"应用脚手架的构建","本质上是一个需要“因地制宜做出决策”的问题，而不仅仅是“按步骤执行”。当决策变量增加时，传统的脚本机制完全无法实现规模化扩展。",[447,7439,7441],{"id":7440},"为什么要使用-ai-智能体技能取代传统脚本","为什么要使用 AI 智能体技能取代传统脚本？",[429,7443,7444,7445,7448,7449,7452,7453,7456],{},"智能体技能 (Agent Skill) 并非只是一段死板运行的程序代码，而是一套",[442,7446,7447],{},"供 AI 智能体遵循的结构化知识库","。它包含一个核心的 ",[645,7450,7451],{},"SKILL.md"," 指南，并可以无缝捆绑该任务所需的任何其他文件（如参考文档、配置模板和可执行脚本）。我们在 ",[569,7454,7455],{"href":351},"什么是AI Agent技能？深入探讨其工作原理并手把手教你如何构建高效、可复用的Agent技能"," 一文中详细剖析了智能体技能的工作原理。",[429,7458,7459],{},"智能体技能在保留了脚本执行力度的同时 upright 注入了脚本所匮乏的合理决策能力：",[455,7461,7462,7465,7468,7471,7474],{},[458,7463,7464],{},"能够推断用户的意图，自动评估该应用是否需要搭配数据库。",[458,7466,7467],{},"根据指定的候选清单，智能判断并按需安装可选模块。例如，只有在用户明确提出相关需求时，才会オプトイン (Opt-in) 导入 Nuxt Content、i18n 多语言和流量分析模块。",[458,7469,7470],{},"能够敏锐适应当前的开发生态，使用最新的 Nuxt 框架规范、针对 Cloudflare 绑定的 NuxtHub 以及用于部署的 Wrangler 命令行工具。",[458,7472,7473],{},"具备强大的自我修复能力，能够在某一步骤失败时自律分析原因并重新尝试。",[458,7475,7476],{},"在最终交付项目前，能够严格按照最终检查清单 (Checklist) 进行校验，确保交付质量。",[447,7478,7480],{"id":7479},"我们的-nuxt-cloudflare-脚手架智能体技能技术内幕","我们的 Nuxt & Cloudflare 脚手架智能体技能技术内幕",[429,7482,7483,7484,7491],{},"这个开源技能 ",[569,7485,7488],{"href":7486,"rel":7487},"https:\u002F\u002Fgithub.com\u002FTech-Voyage-Dev\u002Fscaffold-nuxt-cloudflare-app-skill",[1655],[645,7489,7490],{},"scaffold-nuxt-cloudflare-app-skill"," 包含了一整套面向生产环境的自律构建流程：",[591,7493,7494,7526,7546,7571,7601,7640,7648],{},[458,7495,7496,5046,7499],{},[442,7497,7498],{},"自动澄清无法推断的模糊要点",[455,7500,7501,7512,7518],{},[458,7502,7503,7504,7507,7508,7511],{},"确认首选的 UI 框架（默认是 ",[442,7505,7506],{},"Nuxt UI","，也可选择 ",[442,7509,7510],{},"Antdv Next","）；",[458,7513,7514,7515,7511],{},"确认是否需要数据库支持（如 ",[442,7516,7517],{},"Cloudflare D1",[458,7519,7520,7521,3741,7524,599],{},"确认是否需要额外模块，例如用于构建 CMS 功能的 ",[645,7522,7523],{},"@nuxtjs\u002Fi18n",[645,7525,7420],{},[458,7527,7528,7531,7532,7535,7536,7538,7539,1124,7542,7545],{},[442,7529,7530],{},"初始化基础应用框架","：运行 ",[645,7533,7534],{},"pnpm dlx nuxi@latest init"," 命令，使用 ",[645,7537,5514],{}," 包管理器初始化最新版的 Nuxt 框架。随后配置原生构建白名单 (native-build allowlists)，以确保 Cloudflare 的构建环境能够顺利编译 ",[645,7540,7541],{},"better-sqlite3",[645,7543,7544],{},"sharp"," 等原生依赖包。",[458,7547,7548,7551,7552,3741,7555,1081,7558,1081,7561,1081,7564,1081,7567,7570],{},[442,7549,7550],{},"基于决策表按需安装模块","：自动安装 ",[645,7553,7554],{},"@nuxt\u002Fui",[645,7556,7557],{},"@antdv-next\u002Fnuxt",[645,7559,7560],{},"@nuxt\u002Fimage",[645,7562,7563],{},"@nuxtjs\u002Fseo",[645,7565,7566],{},"@nuxthub\u002Fcore",[645,7568,7569],{},"@vueuse\u002Fnuxt","，并在选中时条件分支安装 Drizzle\u002FD1、Nuxt Content 以及 i18n。",[458,7572,7573,5046,7576],{},[442,7574,7575],{},"科学合理的目录结构布局",[455,7577,7578,7583,7588,7593,7598],{},[458,7579,7580,7582],{},[645,7581,7430],{}," (Nuxt 4 规范)",[458,7584,7585],{},[645,7586,7587],{},"server\u002F",[458,7589,7590],{},[645,7591,7592],{},"shared\u002F",[458,7594,7595],{},[645,7596,7597],{},"tests\u002F",[458,7599,7600],{},"根目录下的各类标准配置文件。",[458,7602,7603,5046,7608],{},[442,7604,7605,7606],{},"精细配置 ",[645,7607,7289],{},[455,7609,7610,7619,7626,7633],{},[458,7611,7612,7613,1124,7616],{},"为 SEO 配置 ",[645,7614,7615],{},"site.url",[645,7617,7618],{},"site.name",[458,7620,7621,7622,7625],{},"写入用于 Cloudflare 绑定的 NuxtHub ",[645,7623,7624],{},"hub"," 配置块",[458,7627,7628,7629,7632],{},"自动配置 ",[645,7630,7631],{},"routeRules"," 路由与缓存规则",[458,7634,7635,7636,7639],{},"写入最新的 ",[645,7637,7638],{},"compatibilityDate"," 兼容性日期",[458,7641,7642],{},[442,7643,7644,7645,7647],{},"科学生成 ",[645,7646,7292],{}," 配置文件并进行云资源绑定",[458,7649,7650,7653,7654,7657,7658,7661],{},[442,7651,7652],{},"配置 Vitest 测试框架与 ESLint 代码规范","，随后运行",[442,7655,7656],{},"最终校验清单","，在后台实际执行 ",[645,7659,7660],{},"pnpm install && pnpm dev"," 进行沙箱运行测试，全部通过后方才宣告构建成功。",[447,7663,7665],{"id":7664},"传统-shell-脚本-vs-ai-智能体技能维度对比","传统 Shell 脚本 vs AI 智能体技能：维度对比",[6207,7667,7668,7681],{},[6210,7669,7670],{},[6213,7671,7672,7675,7678],{},[6216,7673,7674],{},"对比维度",[6216,7676,7677],{},"传统 Shell 脚本",[6216,7679,7680],{},"AI 智能体技能",[6225,7682,7683,7694,7705,7716,7727,7738],{},[6213,7684,7685,7688,7691],{},[6230,7686,7687],{},"意图识别能力",[6230,7689,7690],{},"❌ 行为完全写死",[6230,7692,7693],{},"✅ 自动理解自然语言并按需适配",[6213,7695,7696,7699,7702],{},[6230,7697,7698],{},"动态决策能力",[6230,7700,7701],{},"❌ 仅限硬编码的参数判断",[6230,7703,7704],{},"✅ 运行时动态推敲最佳方案",[6213,7706,7707,7710,7713],{},[6230,7708,7709],{},"生态更新适应度",[6230,7711,7712],{},"❌ 需开发者手动重写代码",[6230,7714,7715],{},"✅ 自动感知当前技术栈规范并适配",[6213,7717,7718,7721,7724],{},[6230,7719,7720],{},"容错与恢复机制",[6230,7722,7723],{},"❌ 一旦出错立即中断退出",[6230,7725,7726],{},"✅ 自动定位错误、自愈并继续运行",[6213,7728,7729,7732,7735],{},[6230,7730,7731],{},"成果质量校验",[6230,7733,7734],{},"❌ 缺乏质量校验机制",[6230,7736,7737],{},"✅ 依托最终检查清单进行闭环测试",[6213,7739,7740,7743,7746],{},[6230,7741,7742],{},"长期维护成本",[6230,7744,7745],{},"❌ 参数膨胀、逻辑混乱、易崩坏",[6230,7747,7748],{},"✅ 只需维护人可读的 Markdown 设计文件",[447,7750,7752],{"id":7751},"如何使用-npx-skills-命令行工具安装-ai-智能体技能","如何使用 npx skills 命令行工具安装 AI 智能体技能",[429,7754,7755,7756,7761],{},"只需一行简单的命令，即可通过 ",[569,7757,7760],{"href":7758,"rel":7759},"https:\u002F\u002Fgithub.com\u002Fvercel-labs\u002Fskills",[1655],"skills CLI"," 工具完成该技能的无缝导入：",[664,7763,7765],{"className":666,"code":7764,"language":668,"meta":424,"style":424},"npx skills add https:\u002F\u002Fgithub.com\u002FTech-Voyage-Dev\u002Fscaffold-nuxt-cloudflare-app-skill.git -g\n",[645,7766,7767],{"__ignoreMap":424},[672,7768,7769,7771,7774,7776,7779],{"class":674,"line":675},[672,7770,4110],{"class":678},[672,7772,7773],{"class":686}," skills",[672,7775,6656],{"class":686},[672,7777,7778],{"class":686}," https:\u002F\u002Fgithub.com\u002FTech-Voyage-Dev\u002Fscaffold-nuxt-cloudflare-app-skill.git",[672,7780,7781],{"class":686}," -g\n",[429,7783,7784,7785],{},"该工具会自动克隆仓库、定位技能文件，并询问您希望将此技能关联到本地系统所支持的 77 个智能体中的哪一个：\n",[435,7786],{"alt":7787,"src":7788},"在终端中运行 npx skills add 命令行工具来全局安装 Nuxt 脚手架构建技能的界面","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FHow%20AI%20Agent%20Skills%20Replace%20Nuxt%20App%20Scaffolding%20Scripts\u002Fnpx-skills-add-scaffold-nuxt-installation.webp",[429,7790,7791,7792,7795,7796,7799,7800],{},"我们强烈推荐选择 ",[442,7793,7794],{},"Symlink (符号链接)"," 方式。这种模式下，技能只需在 ",[645,7797,7798],{},"~\u002F.agents\u002Fskills"," 目录中下载一次，所有被勾选的智能体都将指向这同一份原始文件。\n",[435,7801],{"alt":7802,"src":7803},"终端中显示的集中式 Agent 技能安装摘要以及软链接 (Symlink) 路径配置详情","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FHow%20AI%20Agent%20Skills%20Replace%20Nuxt%20App%20Scaffolding%20Scripts\u002Fnpx-skills-installation-summary-details.webp",[455,7805,7806],{},[458,7807,7808],{},[6511,7809,7810,7811,599],{},"如果您希望深入了解如何有效避免技能碎片化并在一处集中管理它们，请参阅我们的这篇深度好文：",[569,7812,7813],{"href":359},"使用 npx skills 工具来彻底解决不同 AI 智能体（如 Claude Code 或 Kimi）技能碎片化问题",[429,7815,7816],{},"完成安装后，打开 Claude Code 终端，输入内置命令即可确认该技能已成功激活。",[429,7818,7819],{},[435,7820],{"alt":7821,"src":7822},"Claude Code 命令行终端中显示的全新安装且已激活可用的 \u002Fscaffold-nuxt 斜杠快捷命令","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FHow%20AI%20Agent%20Skills%20Replace%20Nuxt%20App%20Scaffolding%20Scripts\u002Fclaude-code-scaffold-nuxt-slash-command-active.webp",[429,7824,7825],{},"接下来，您只需输入一句简单的自然语言，即可瞬间搞定复杂的工程脚手架搭建：",[7827,7828,7829],"blockquote",{},[429,7830,7831],{},"\"Scaffold a new Nuxt app deployed to Cloudflare Workers — Nuxt UI, a blog section, and a D1 database\"",[429,7833,7834,7835,7839],{},"该脚手架技能完全开源，欢迎访问我们的 ",[569,7836,7838],{"href":7486,"rel":7837},[1655],"GitHub 仓库"," 提交 Feedback 并上手体验！",[2640,7841,7842],{},"html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":424,"searchDepth":741,"depth":614,"links":7844},[7845,7846,7847,7848,7849],{"id":7300,"depth":741,"text":7301},{"id":7440,"depth":741,"text":7441},{"id":7479,"depth":741,"text":7480},{"id":7664,"depth":741,"text":7665},{"id":7751,"depth":741,"text":7752},[2675],"2026-08-25","轻松在 Cloudflare Workers 上快速构建 Nuxt 应用程序脚手架。深入剖析并学习我们如何使用功能强大、极其灵活、支持自我修复且拥有决策能力的 AI 智能体技能来彻底取代脆弱的传统 Shell 脚本，并详细演示如何通过官方 the npx skills 命令行工具将其无缝安装到您的开发工作流中。","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FHow%20AI%20Agent%20Skills%20Replace%20Nuxt%20App%20Scaffolding%20Scripts\u002FZH-How-AI-Agent-Skills-Replace-Nuxt-App-Scaffolding-Scripts.webp","Nuxt应用在Cloudflare及Serverless上的脚手架构建：传统Shell脚本与AI智能体技能对比。分析为什么智能体技能优于传统初始化脚本。",{"schemaOrg":7856,"robots":2704,"sitemap":7858},[7857],{"@type":2684,"headline":7281,"description":7852,"image":7853},{"lastmod":7851},{"title":7860,"description":7852,"ogTitle":7281,"ogDescription":7852,"twitterTitle":7281,"twitterDescription":7852},"Nuxt应用在Cloudflare及Serverless上的脚手架构建：传统Shell脚本与AI智能体技能对比","zh\u002Farticle\u002Fhow-ai-agent-skills-replace-nuxt-app-scaffolding-scripts",[7863,2714,7864,7865],"Nuxt","AI Agent","Scaffolding","cjXSEDECxsBr5bmHuYXOSYY0oFEz98tTOLGuKo9KYag",1792490001332]