[{"data":1,"prerenderedAt":7866},["ShallowReactive",2],{"published-article-paths":3,"search-navigation":348,"\u002Ftw\u002Farticle\u002Fself-hosting-buzz-as-the-workspace-where-ai-agents-become-colleagues":421,"\u002Ftw\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":263,"seo":2707,"stem":2709,"tags":2710,"updatedAt":2715,"__hash__":2716},"article\u002Ftw\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 複製並貼上到 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-前提條件","0. 前提條件",[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\u002FTW-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},"\u002Ftw\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\u002FTW-Self-Hosting-Buzz-As-The-Workspace-Where-AI-Agents-Become-Colleagues.webp","一張高顏值的 16:9 科技質感卡片，具有深藍色 and 橙色色調，插圖展示如何在 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 協作中繼伺服器","tw\u002Farticle\u002Fself-hosting-buzz-as-the-workspace-where-ai-agents-become-colleagues",[2711,2712,444,2713,2714],"Nostr","Docker","Caddy","Cloudflare",null,"IBYHxp-6BbUZwuDc9Hxf1yMQj3uMpBUTAm2W1CTRUic",{"surround":2718,"related":6043},[2719,4626],{"id":2720,"title":2721,"author":2715,"body":2722,"category":4608,"date":4610,"description":4611,"extension":2678,"image":4612,"imageAlt":4613,"isPublished":772,"meta":4614,"minRead":959,"navigation":772,"path":261,"seo":4621,"stem":4622,"tags":4623,"updatedAt":2706,"__hash__":4625},"article\u002Ftw\u002Farticle\u002Fself-hosted-travel-planner-trek.md","使用Docker與TREK自託管您的個性化智能旅行日程：一站式深度規劃並輕鬆管理預訂、財務和行李清單",{"type":426,"value":2723,"toc":4567},[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,3211,3215,3222,3226,3229,3321,3325,3328,3332,3339,3343,3346,3364,3375,3379,3382,3393,3397,3401,3412,3416,3420,3423,3427,3431,3434,3439,3442,3447,3453,3457,3461,3464,3468,3480,3485,3491,3496,3500,3503,3508,3513,3516,3523,3527,3530,3533,3543,3549,3554,3561,3566,3570,3576,3581,3584,3589,3593,3599,3603,3608,3612,3615,3618,3623,3628,3633,3637,3644,3649,3654,3659,3664,3668,3674,3679,3685,3689,3692,3696,3702,3707,3712,3718,3723,3728,3733,3747,3751,3756,3777,3782,3785,3789,3792,3797,3800,3848,3852,3859,3865,3870,3876,3881,3887,3892,3898,3901,3906,3913,3918,3924,3928,3935,3940,3943,3947,3951,3957,3961,3964,3971,3975,3982,3986,3998,4003,4007,4011,4021,4031,4036,4043,4048,4055,4059,4062,4228,4231,4235,4238,4243,4246,4252,4256,4263,4267,4270,4275,4282,4287,4291,4302,4373,4389,4392,4397,4401,4405,4416,4493,4506,4509,4513,4517,4520,4522,4525,4528,4537,4541,4564],[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,3201,3202,3205,3206],{},"按一下 ",[442,3203,3204],{},"Admin（管理員）"," 索引標籤並更新您的電子信箱：",[435,3207],{"src":3208,"alt":3209,"style":3210},"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,3212,3214],{"id":3213},"_31-備份策略","3.1 備份策略",[429,3216,3217,3218],{},"在管理員後台，可以非常方便地配置帶有保留策略的自動備份方案：\n",[435,3219],{"src":3220,"alt":3221,"style":3039},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-admin-backup-retention-policy.webp","設定自動備份排程與保留規則",[586,3223,3225],{"id":3224},"_32-將上傳的檔案儲存到cloudflare-r2","3.2 將上傳的檔案儲存到Cloudflare R2",[429,3227,3228],{},"將上傳的檔案、照片和備份資料保存在Cloudflare R2中，能夠讓您的VPS磁碟保持乾淨和輕量。TREK全面支援S3相容的儲存後端，而Cloudflare R2正是這一需求的完美解決方案。",[591,3230,3231,3238,3250,3261,3272,3284,3295,3310],{},[458,3232,3233,3234,3237],{},"新建一個名為 ",[645,3235,3236],{},"trek"," 的R2儲存桶。",[458,3239,1674,3240,3243,3244,3245],{},[442,3241,3242],{},"Account Details（帳戶詳情）"," 區域，找到您的帳戶ID：","\n  ",[435,3246],{"src":3247,"alt":3248,"style":3249},"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,3251,3201,3252,3255,3244,3256],{},[442,3253,3254],{},"Manage API Tokens（管理API權杖）","：",[435,3257],{"src":3258,"alt":3259,"style":3260},"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,3262,3201,3263,3266,3244,3267],{},[442,3264,3265],{},"Create Account API token（建立帳戶API權杖）","，並授予針對該桶的讀寫權限：",[435,3268],{"src":3269,"alt":3270,"style":3271},"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,3273,3274,3275,3278,3244,3279],{},"在管理員面板中，按一下 ",[442,3276,3277],{},"Storage（儲存）"," 配置頁：",[435,3280],{"src":3281,"alt":3282,"style":3283},"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,3285,3201,3286,3289,3244,3290],{},[442,3287,3288],{},"Add Backend（新增後端）"," 按鈕，填入您的Endpoint（端點）、Bucket（儲存桶名稱）和API憑證：",[435,3291],{"src":3292,"alt":3293,"style":3294},"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,3296,3201,3297,3300,3301,3304,3244,3305],{},[442,3298,3299],{},"Apply（套用）","，然後按一下 ",[442,3302,3303],{},"Test（測試）"," 連結。當看到「Connection OK」字樣时，說明連線測試成功：",[435,3306],{"src":3307,"alt":3308,"style":3309},"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,3311,3312,3313,3255,3244,3316],{},"将所有儲存類別切換為Cloudflare R2并按一下 ",[442,3314,3315],{},"Save changes（儲存修改）",[435,3317],{"src":3318,"alt":3319,"style":3320},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-switch-storage-categories-r2.webp","將所有檔案儲存分類路由至 Cloudflare R2","max-width: 653px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[586,3322,3324],{"id":3323},"_33-通行鑰passkey登入","3.3 通行鑰（Passkey）登入",[429,3326,3327],{},"TREK支援通行鑰、雙重身份驗證（2FA）以及基於OIDC的單一登入。如果想開啟通行鑰，請在設定中輸入您的網域名稱和Allowed Origins（允許的來源），然後儲存即可：",[435,3329],{"src":3330,"alt":3331,"style":3039},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-passkey-allowed-origins-settings.webp","註冊用於安全金鑰（Passkey）身分驗證的允許來源",[429,3333,3334,3335,3338],{},"如果沒有正確配置 ",[442,3336,3337],{},"Allowed Origins","，通行鑰註冊將會失敗。",[586,3340,3342],{"id":3341},"_34-google-maps-api金鑰","3.4 Google Maps API金鑰",[429,3344,3345],{},"配置Google Maps金鑰可以讓您的地點檢索功能變得更豐富，自動補充評分、營業时间和地點實景圖。如果您不配置金鑰，TREK會預設降級使用免費的OpenStreetMap（只是不顯示評分和實景照片）。",[429,3347,3348,3349,3354,3355,3358,3359],{},"造訪此",[569,3350,3353],{"href":3351,"rel":3352},"https:\u002F\u002Fmapsplatform.google.com\u002Fmaps-demo-key\u002F",[1655],"連結","並按一下 ",[442,3356,3357],{},"Get demo key"," 即可申請一個測試金鑰：                                                  ",[435,3360],{"src":3361,"alt":3362,"style":3363},"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,3365,3366,3367,3370,3371],{},"將獲取到的API Key貼上到設定中，然後按一下 ",[442,3368,3369],{},"Test"," 驗證連線是否通暢：\n",[435,3372],{"src":3373,"alt":3374,"style":3039},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-google-maps-key-test-connection.webp","在設定中驗證 Google Maps API 金鑰的連通性",[586,3376,3378],{"id":3377},"_35-ai整合","3.5 AI整合",[429,3380,3381],{},"內建的AI解析引擎主要用於處理您的預訂確認郵件和PDF，將它們自動轉換為結構化的預訂資料。",[429,3383,3384,3385,3388,3389,3392],{},"按一下左側選單中的 ",[442,3386,3387],{},"Addons（附加元件）"," 並啟用 ",[442,3390,3391],{},"AI Parsing","。選擇「OpenAI」（或其他相容的AI提供商）並填寫相應的憑證資訊：",[435,3394],{"src":3395,"alt":3396,"style":3039},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-addons-enable-ai-parsing-openai.webp","啟用附帶 OpenAI 整合的 AI 解析外掛",[586,3398,3400],{"id":3399},"_36-mcp存取權限","3.6 MCP存取權限",[429,3402,3403,3404,3407,3408,3411],{},"同樣在 ",[442,3405,3406],{},"Addons"," 選項中，開啟 ",[442,3409,3410],{},"MCP"," 協定：",[435,3413],{"src":3414,"alt":3415,"style":3039},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-addons-enable-mcp.webp","啟用 Model Context Protocol MCP 伺服器外掛",[586,3417,3419],{"id":3418},"_37-外掛推薦","3.7 外掛推薦",[429,3421,3422],{},"以下幾款官方外掛非常推薦您順手啟用：",[435,3424],{"src":3425,"alt":3426,"style":3039},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-recommended-addons-plugins-activation.webp","活躍的推薦外掛與擴充功能列表",[586,3428,3430],{"id":3429},"_38-建立您的日常使用帳戶","3.8 建立您的日常使用帳戶",[429,3432,3433],{},"在平時規劃旅行時，建議使用一般使用者帳戶，而非管理員帳戶。讓我們在後台建立一個日常帳戶並登入：",[435,3435],{"src":3436,"alt":3437,"style":3438},"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,3440,3441],{},"登入後，建議立刻綁定通行鑰或設定2FA來強化該帳戶的安全層級：",[435,3443],{"src":3444,"alt":3445,"style":3446},"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,3448,3201,3449,3452],{},[442,3450,3451],{},"+ Add a passkey","，輸入目前密碼，然後按照瀏覽器提示完成安全確認：",[435,3454],{"src":3455,"alt":3456,"style":3039},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-add-passkey-confirm-password.webp","確認密碼以註冊新的硬體安全金鑰",[547,3458,3460],{"id":3459},"_4-測試您的部署匯入歷史出行資料","4. 測試您的部署：匯入歷史出行資料",[429,3462,3463],{},"快速上手並熟悉TREK系統的一個極佳方式是，將您過去走過的旅行足跡錄入其中。",[586,3465,3467],{"id":3466},"_41-建立旅行計劃","4.1 建立旅行計劃",[429,3469,3201,3470,3473,3474,1124,3477,3255],{},[442,3471,3472],{},"+ New Trip（新建旅行）","，並根據那次歷史旅行的真實起止時間設定 ",[442,3475,3476],{},"Start Date",[442,3478,3479],{},"End Date",[435,3481],{"src":3482,"alt":3483,"style":3484},"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,3486,3487,3488,3255],{},"上傳一張好看的封面圖（可以直接將圖片拖入或從剪貼簿貼上），接著按一下 ",[442,3489,3490],{},"Create New Trip",[435,3492],{"src":3493,"alt":3494,"style":3495},"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,3497,3499],{"id":3498},"_42-匯入預訂資訊","4.2 匯入預訂資訊",[429,3501,3502],{},"將您當時留存的機票、火車票和其他交通工具預訂確認檔案直接拖放到上傳區域：",[435,3504],{"src":3505,"alt":3506,"style":3507},"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,3509],{"src":3510,"alt":3511,"style":3512},"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,3514,3515],{},"由於我們已經啟用了AI解析引擎，預訂確認PDF檔案會被自動分析，提取出結構化的預訂日程。",[429,3517,3518,3519,3522],{},"檢查解析結果無誤后，按一下 ",[442,3520,3521],{},"Add"," 將其正式寫入預訂資料中：",[435,3524],{"src":3525,"alt":3526,"style":3039},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-review-parsed-booking-details.webp","審查由 AI 擷取的結構化預訂細節",[429,3528,3529],{},"如果有些預訂確認僅保存在郵件中，您可以將其匯出為PDF格式并上傳，同樣可以走這套提取流程。",[429,3531,3532],{},"在系統中，已匯入的預訂資訊會以極具現代感的方式呈現：",[429,3534,3535,3539],{},[435,3536],{"src":3537,"alt":3538,"style":3039},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-trip-bookings-timeline-view.webp","旅行預訂的完整時間軸展示",[435,3540],{"src":3541,"alt":3542,"style":3039},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-booking-confirmation-details.webp","已確認交通預訂的詳細檢視",[429,3544,1674,3545,3548],{},[442,3546,3547],{},"Plan（日程規劃）"," 頁面中，所有的飯店和住宿點都會在地圖上被優雅地標註出來：",[435,3550],{"src":3551,"alt":3552,"style":3553},"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,3555,3556,3557,3560],{},"按一下上方的 ",[442,3558,3559],{},"Atlas（旅行足跡）","，您將能从清單和世界地圖上直觀地看到所有已拜訪的国家：",[435,3562],{"src":3563,"alt":3564,"style":3565},"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,3567,3569],{"id":3568},"_43-新增旅行同伴","4.3 新增旅行同伴",[429,3571,3201,3572,3575],{},[442,3573,3574],{},"Share（分享）"," 按鈕：",[435,3577],{"src":3578,"alt":3579,"style":3580},"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,3582,3583],{},"在彈出的對話方塊底部，可以直接新增旅行同伴為Guest（嘉賓）：",[435,3585],{"src":3586,"alt":3587,"style":3588},"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,3590,3592],{"id":3591},"_44-記錄旅行費用","4.4 記錄旅行費用",[429,3594,3201,3595,3598],{},[442,3596,3597],{},"Add expense（新增開銷）","，來記錄那些無法透過PDF預訂單自動解析的雜項支出，例如境外險、當地公共交通費、臨時SIM卡等：",[435,3600],{"src":3601,"alt":3602,"style":3039},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-add-custom-expense-form.webp","在支出表單中輸入詳細的消費數據",[435,3604],{"src":3605,"alt":3606,"style":3607},"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,3609,3611],{"id":3610},"_45-拆分旅行階段","4.5 拆分旅行階段",[429,3613,3614],{},"該功能需要提前在後台激活“Trip Segment”外掛。",[429,3616,3617],{},"對於那些超長週期的旅程，將其拆分為不同的階段能讓脈絡更清晰，每個階段都可以有自己獨立的預訂項目、待辦事項和成本帳單：",[435,3619],{"src":3620,"alt":3621,"style":3622},"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,3624],{"src":3625,"alt":3626,"style":3627},"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,3629],{"src":3630,"alt":3631,"style":3632},"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,3634,3636],{"id":3635},"_46-建立journal日誌並查看旅行足跡atlas","4.6 建立Journal（日誌）並查看旅行足跡（Atlas）",[429,3638,3639,3640,3643],{},"您還可以將幾次旅行串聯成一個 ",[442,3641,3642],{},"Journey（旅程）","，並圖文並茂地撰寫遊記故事，方便分享給您的朋友們：",[435,3645],{"src":3646,"alt":3647,"style":3648},"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,3650],{"src":3651,"alt":3652,"style":3653},"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,3655],{"src":3656,"alt":3657,"style":3658},"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,3660],{"src":3661,"alt":3662,"style":3663},"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,3665,3667],{"id":3666},"_5-設計自訂行程與行李清單","5. 設計自訂行程與行李清單",[429,3669,3201,3670,3673],{},[442,3671,3672],{},"+ New Trip","，輸入旅行的專屬名稱並指定起止日期：",[435,3675],{"src":3676,"alt":3677,"style":3678},"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,3680,3681,3684],{},[442,3682,3683],{},"如果具體的出行時間還沒有敲定，可以將日期項留空。"," 此時系統會顯示一個「天數配置（最高支援365天）」欄位，您可以先設計每日的遊玩內容，等後續買好機票後再一鍵錨定日期。",[586,3686,3688],{"id":3687},"_51-新增地點景點","5.1 新增地點\u002F景點",[429,3690,3691],{},"這是旅行規劃中最耗時的一步，但TREK提供了四種極具效率的方式來協助您新增地點：",[435,3693],{"src":3694,"alt":3695,"style":3039},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-add-places-methods-overview.webp","向行程新增新地點的多種途徑",[429,3697,3698,3701],{},[442,3699,3700],{},"1. 直接在地圖上右鍵點擊："," 會該座標處直接建立新地點，其標準地址會被系統自動逆地理編碼解析出來：",[435,3703],{"src":3704,"alt":3705,"style":3706},"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,3708],{"src":3709,"alt":3710,"style":3711},"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,3713,3714,3717],{},[442,3715,3716],{},"2. 按一下 + Add Place\u002FActivity："," 在搜尋框中直接透過關鍵字進行檢索",[435,3719],{"src":3720,"alt":3721,"style":3722},"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,3724],{"src":3725,"alt":3726,"style":3727},"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,3729],{"src":3730,"alt":3731,"style":3732},"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,3734,3735,3738,3739,3742,3743,3746],{},[442,3736,3737],{},"3. 直接貼上Google地圖分享連結："," （如 ",[645,3740,3741],{},"maps.app.goo.gl\u002F…"," 或 ",[645,3744,3745],{},"maps.google.com\u002F…","）貼上到檢索欄中。TREK會自動抓取該地點的名稱、地址和經緯度：",[435,3748],{"src":3749,"alt":3750,"style":3309},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-paste-google-maps-share-link.webp","直接從貼上的 Google 地圖分享連結解析地點",[435,3752],{"src":3753,"alt":3754,"style":3755},"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,3757,3758,3761,3762,3765,3766,3742,3769,3772,3773,3776],{},[442,3759,3760],{},"4. 批次匯入資料："," 這是最輕鬆的方案。如果您在Google Maps中維護著自己的「想去清單」，可以將其匯出為 ",[645,3763,3764],{},".gpx"," 檔案（",[645,3767,3768],{},".kml",[645,3770,3771],{},".kmz"," 格式亦支援），然後按一下右側面板的 ",[442,3774,3775],{},"Import file","，一鍵拉取所有資料：",[435,3778],{"src":3779,"alt":3780,"style":3781},"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,3783,3784],{},"推薦您可以先把所有感興趣的項目都新增進來。至於如何將它們科學地歸入到每一天的日程中，後續可以直接在面板裡拖拽處理。",[586,3786,3788],{"id":3787},"_52-每日日程與備忘","5.2 每日日程與備忘",[429,3790,3791],{},"Day Plan（每日計劃）的核心邏輯是將所有的目的地按每日訪問順序進行排序。整個介面是一個可以折疊、支援任意拖放的模組：",[435,3793],{"src":3794,"alt":3795,"style":3796},"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,3798,3799],{},"這些細節機制設計得極其精妙實用：",[455,3801,3802,3812,3822,3832],{},[458,3803,3804,3807,3808],{},[442,3805,3806],{},"中間移動方式","：按一下每日日程左上角的公車圖示，可以設定各節點之間的過渡交通方式（如地鐵、自駕、甚至是直達航班）：\n",[435,3809],{"src":3810,"alt":3811,"style":3039},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-day-plan-commuting-transport-button.webp","登記日行程各段之間的通勤交通方式",[458,3813,3814,3817,3818],{},[442,3815,3816],{},"每日備忘","：按一下左下角的便簽圖示可以附加各種客製化提醒（例如：「今天需要提早出發」、「美術館門票需提前預約」）：\n",[435,3819],{"src":3820,"alt":3821,"style":3039},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-day-plan-icon-tagged-notes-button.webp","為天行程新增顯眼的、帶有圖示的自訂備註",[458,3823,3824,3827,3828],{},[442,3825,3826],{},"指定時間段","：從右側拖拽地點並給它分配一個開始時間。設定了時間的地點會自動在地圖上生成推薦的行進路線：\n",[435,3829],{"src":3830,"alt":3831,"style":3039},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-day-plan-timed-places-routing.webp","帶時間點的地點之間自動計算的交通路線",[458,3833,3834,3835,3838,3839,3842,3843,599],{},"關於智慧路線優化（",[442,3836,3837],{},"Route optimisation","）以及氣候（",[442,3840,3841],{},"Weather","），您可以查閱 ",[569,3844,3847],{"href":3845,"rel":3846},"https:\u002F\u002Fgithub.com\u002Fliketrek\u002FTREK\u002Fwiki\u002FDay-Plans-and-Notes",[1655],"Day Plans and Notes的Wiki文件",[586,3849,3851],{"id":3850},"_53-收藏夾可重複使用的地點清單","5.3 收藏夾：可重複使用的地點清單",[429,3853,3854,3855,3858],{},"Collections（收藏夾）允許使用者在具體的旅行專案之外，保存並分類管理自己精心收集的寶藏地點。您可以將其打包分享給朋友。這些地點在加入旅行時是採用",[442,3856,3857],{},"複製","的方式，因此在旅行日程中對其進行的任何個性化標註，都不會破壞您收藏夾裡的原始乾淨資料。",[429,3860,3861,3862,3255],{},"按一下頂部選單列中的 ",[442,3863,3864],{},"Collections",[435,3866],{"src":3867,"alt":3868,"style":3869},"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,3871,3201,3872,3875],{},[442,3873,3874],{},"+ New list"," 建立新的分類列表：",[435,3877],{"src":3878,"alt":3879,"style":3880},"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,3882,3201,3883,3886],{},[442,3884,3885],{},"+ Add a place"," 並填入該地點的詳細情況：",[435,3888],{"src":3889,"alt":3890,"style":3891},"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,3893,3894,3897],{},[442,3895,3896],{},"注意："," 收藏夾內的搜尋元件偶爾可能會因網路原因失效，如果發生該情況，您可以透過手動輸入來建立。",[429,3899,3900],{},"當地點帶有準確的GPS座標時，它們會精美地展示在地圖中：",[435,3902],{"src":3903,"alt":3904,"style":3905},"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,3907,3908,3909,3912],{},"如需批次整理這些地標，可以按一下 ",[442,3910,3911],{},"checkbox（勾選框）"," 圖示：",[435,3914],{"src":3915,"alt":3916,"style":3917},"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,3919,3920,3921,3255],{},"多選目標後，按一下 ",[442,3922,3923],{},"Assign label（分配標籤）",[435,3925],{"src":3926,"alt":3927,"style":3755},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-collections-group-assign-label.webp","為選定的收藏地點分配描述性標籤",[429,3929,3930,3931,3934],{},"在分配之前，先按一下 ",[442,3932,3933],{},"Manage labels（管理標籤）"," 來新建一些醒目的彩色分組標籤：",[435,3936],{"src":3937,"alt":3938,"style":3939},"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,3941,3942],{},"按一下一個具體標籤，接著選擇一鍵綁定：",[435,3944],{"src":3945,"alt":3946,"style":3565},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-collections-confirm-label-selection.webp","套用自訂標籤至分群的地點",[586,3948,3950],{"id":3949},"_54-費用與預算","5.4 費用與預算",[429,3952,1674,3953,3956],{},[442,3954,3955],{},"Costs（財務管理）"," 頁面中，我們可以錄入其他的預備預算和旅途支出。",[435,3958],{"src":3959,"alt":3960,"style":3796},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-costs-budget-overall-expenses-list.webp","完整的支出表格與餘額結算帳本",[429,3962,3963],{},"在結伴出行時，您可以在此頁記錄每個人的墊付帳單，並選定分攤規則。",[429,3965,3966,3967,3970],{},"系統的結算後台採用了一種貪心匹配演算法，計算並生成",[442,3968,3969],{},"最簡化的轉帳精算方案","，幫大家用最少的轉帳次數輕鬆對齊帳目。",[547,3972,3974],{"id":3973},"_6-利用model-context-protocolmcp實現ai驅動的旅行規劃","6. 利用Model Context Protocol（MCP）實現AI驅動的旅行規劃",[429,3976,3977,3978,3981],{},"TREK內建了 ",[442,3979,3980],{},"MCP（模型上下文協定）伺服器","。這意味著，AI代理可以直接「讀寫」您的行程規劃資料。它提供了超過150个精細的原子工具和30個核心資料源，全方位覆蓋行程、地點、帳目、行李、預訂和多人協作。",[586,3983,3985],{"id":3984},"_61-cloudflare-zero-trust網路配置","6.1 Cloudflare Zero Trust網路配置",[429,3987,3988,3989,3992,3993,599],{},"由於我們的自託管服務執行在 ",[569,3990,3991],{"href":363},"Cloudflare Zero Trust"," 內網環境下，我們需要在「Split Tunnels（分流隧道）」配置中，將該服務的網域加入到 Inclusion List（包含\u002F直連白名單）中。否則在進行 OAuth 登入授權探索時，介面呼叫會被網路策略阻斷。具體的配置排障可以參考這個 GitHub 討論貼：",[569,3994,3997],{"href":3995,"rel":3996},"https:\u002F\u002Fgithub.com\u002Fliketrek\u002FTREK\u002Fissues\u002F1463",[1655],"GitHub Issue",[574,3999],{"description":4000,"image":577,"image-alt":4001,"label":579,"min-read":4002,"title":571,"to":363},"本文深入探討如何使用 Cloudflare WARP 與 Zero Trust 技術，在完全不需要開啟任何防火牆入站連接埠的情況下，安全地將您的 Hermes Agent 暴露到私有網路中，從而實現全球範圍內的安全存取。這為您構建專屬私有遠端 AI 基礎架構打下堅實基礎。","透過 Cloudflare Zero Trust 和 WARP 隧道安全地將 Hermes Agent 暴露至私有網路","5",[435,4004],{"src":4005,"alt":4006,"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,4008,4010],{"id":4009},"_62-claude-desktop用戶端配置","6.2 Claude Desktop用戶端配置",[429,4012,3201,4013,4016,4017],{},[442,4014,4015],{},"+ New Client"," 創設一個新的 AI 用戶端介面：\n",[435,4018],{"src":4019,"alt":4020,"style":3039},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-register-new-mcp-client.webp","在設定中註冊新的自訂用戶端權杖",[429,4022,4023,4024,4027,4028,3255],{},"選擇 ",[442,4025,4026],{},"Claude Desktop"," 項目，然後按一下 ",[442,4029,4030],{},"Register Client（註冊用戶端）",[435,4032],{"src":4033,"alt":4034,"style":4035},"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,4037,4038,4039,4042],{},"系統此時會展示唯一的 Client ID 和 Client Secret，請妥善保存。接著按一下 ",[442,4040,4041],{},"Client Configuration（用戶端配置）"," 調出我們需要在本地寫入的 JSON 程式碼片段：",[435,4044],{"src":4045,"alt":4046,"style":4047},"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,4049,4050,4051,4054],{},"在 Claude Desktop 軟體中，按一下 ",[442,4052,4053],{},"Edit Config"," 會在編輯器中打開您本地的 MCP server 檔案：",[435,4056],{"src":4057,"alt":4058,"style":3039},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Fclaude-desktop-mcp-config-json.webp","編輯 Claude Desktop 的本機 MCP 設定檔 json",[429,4060,4061],{},"將 TREK 的 MCP 程式碼區塊貼上進去，並把佔位符部分替換為上一步生成的用戶端憑證：",[664,4063,4065],{"className":3070,"code":4064,"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,4066,4067,4082,4095,4117,4131,4143,4154,4165,4211,4216,4221],{"__ignoreMap":424},[672,4068,4069,4072,4075,4077,4080],{"class":674,"line":675},[672,4070,4071],{"class":682},"  \"",[672,4073,4074],{"class":686},"mcpServers",[672,4076,690],{"class":682},[672,4078,4079],{"class":2013},": ",[672,4081,1167],{"class":682},[672,4083,4084,4087,4089,4091,4093],{"class":674,"line":741},[672,4085,4086],{"class":682},"    \"",[672,4088,3236],{"class":1280},[672,4090,690],{"class":682},[672,4092,1277],{"class":682},[672,4094,3088],{"class":682},[672,4096,4097,4100,4103,4105,4107,4109,4112,4114],{"class":674,"line":614},[672,4098,4099],{"class":682},"      \"",[672,4101,4102],{"class":678},"command",[672,4104,690],{"class":682},[672,4106,1277],{"class":682},[672,4108,683],{"class":682},[672,4110,4111],{"class":686},"npx",[672,4113,690],{"class":682},[672,4115,4116],{"class":682},",\n",[672,4118,4119,4121,4124,4126,4128],{"class":674,"line":776},[672,4120,4099],{"class":682},[672,4122,4123],{"class":678},"args",[672,4125,690],{"class":682},[672,4127,1277],{"class":682},[672,4129,4130],{"class":682}," [\n",[672,4132,4133,4136,4139,4141],{"class":674,"line":782},[672,4134,4135],{"class":682},"        \"",[672,4137,4138],{"class":686},"mcp-remote",[672,4140,690],{"class":682},[672,4142,4116],{"class":682},[672,4144,4145,4147,4150,4152],{"class":674,"line":827},[672,4146,4135],{"class":682},[672,4148,4149],{"class":686},"https:\u002F\u002Ftrek.pafor.me\u002Fmcp",[672,4151,690],{"class":682},[672,4153,4116],{"class":682},[672,4155,4156,4158,4161,4163],{"class":674,"line":832},[672,4157,4135],{"class":682},[672,4159,4160],{"class":686},"--static-oauth-client-info",[672,4162,690],{"class":682},[672,4164,4116],{"class":682},[672,4166,4167,4169,4171,4174,4177,4179,4181,4183,4186,4188,4191,4193,4196,4198,4200,4202,4205,4207,4209],{"class":674,"line":838},[672,4168,4135],{"class":682},[672,4170,3079],{"class":686},[672,4172,4173],{"class":2013},"\\\"",[672,4175,4176],{"class":686},"client_id",[672,4178,4173],{"class":2013},[672,4180,4079],{"class":686},[672,4182,4173],{"class":2013},[672,4184,4185],{"class":686},"\u003Cyour_client_id>",[672,4187,4173],{"class":2013},[672,4189,4190],{"class":686},", ",[672,4192,4173],{"class":2013},[672,4194,4195],{"class":686},"client_secret",[672,4197,4173],{"class":2013},[672,4199,4079],{"class":686},[672,4201,4173],{"class":2013},[672,4203,4204],{"class":686},"\u003Cyour_client_secret>",[672,4206,4173],{"class":2013},[672,4208,3085],{"class":686},[672,4210,701],{"class":682},[672,4212,4213],{"class":674,"line":850},[672,4214,4215],{"class":682},"      ]\n",[672,4217,4218],{"class":674,"line":855},[672,4219,4220],{"class":682},"    }\n",[672,4222,4223,4226],{"class":674,"line":861},[672,4224,4225],{"class":682},"  }",[672,4227,4116],{"class":2013},[429,4229,4230],{},"重新啟動 Claude Desktop 用戶端。此時在 Local MCP servers（本地MCP服務）列表中就會看到 TREK 已經成功連線：",[435,4232],{"src":4233,"alt":4234,"style":3039},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Fclaude-desktop-mcp-trek-server-connected.webp","在 Claude 介面中驗證活躍的 TREK 連線狀態",[429,4236,4237],{},"現在，您可以直接用日常口語來下達規劃指令了：",[435,4239],{"src":4240,"alt":4241,"style":4242},"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,4244,4245],{},"例如，我们用純中文錄入一筆非標準化的日常開支：",[664,4247,4250],{"className":4248,"code":4249,"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,4251,4249],{"__ignoreMap":424},[435,4253],{"src":4254,"alt":4255,"style":3039},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Fclaude-desktop-mcp-add-expense-response.webp","Claude 呼叫工具自動記錄一筆支出",[429,4257,4258,4259,4262],{},"回到後台，重新整理 ",[442,4260,4261],{},"Costs"," 面板。我們可以看到這筆打車費用已經被精確地記錄下來，且因為命令中並未提及“由誰付款”，系統體貼地將付款人項歸納為了“No one paid yet（尚未有人支付）”：",[435,4264],{"src":4265,"alt":4266,"style":3210},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-costs-page-mcp-parsed-expense.webp","在費用檢視中確認最新由 AI 解析的支出",[429,4268,4269],{},"管理行李清單的方式也完全一致：",[435,4271],{"src":4272,"alt":4273,"style":4274},"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,4276,4277,4278,4281],{},"再次重新整理 ",[442,4279,4280],{},"Packing List"," 頁面，指定的这三樣出行裝備已經被整齊地加入到了清單之中：",[435,4283],{"src":4284,"alt":4285,"style":4286},"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,4288,4290],{"id":4289},"_63-gemini-cli動態註冊","6.3 Gemini CLI（動態註冊）",[429,4292,4293,4294,4297,4298,4301],{},"Gemini CLI 對 ",[442,4295,4296],{},"Dynamic Registration（動態註冊機制）"," 提供了極佳的支援，這使得您完全無需在系統後台手動預註冊任何用戶端憑證。直接將以下程式碼追加到您本地的 ",[645,4299,4300],{},".gemini\u002Fsettings.json"," 檔案中：",[664,4303,4305],{"className":3070,"code":4304,"language":3072,"meta":424,"style":424},"    \"trek\": {\n      \"httpUrl\": \"https:\u002F\u002Ftrek.pafor.me\u002Fmcp\",\n      \"oauth\": {\n        \"enabled\": true\n      }\n    }\n",[645,4306,4307,4319,4338,4351,4364,4369],{"__ignoreMap":424},[672,4308,4309,4311,4313,4315,4317],{"class":674,"line":675},[672,4310,4086],{"class":682},[672,4312,3236],{"class":686},[672,4314,690],{"class":682},[672,4316,4079],{"class":2013},[672,4318,1167],{"class":682},[672,4320,4321,4323,4326,4328,4330,4332,4334,4336],{"class":674,"line":741},[672,4322,4099],{"class":682},[672,4324,4325],{"class":1280},"httpUrl",[672,4327,690],{"class":682},[672,4329,1277],{"class":682},[672,4331,683],{"class":682},[672,4333,4149],{"class":686},[672,4335,690],{"class":682},[672,4337,4116],{"class":682},[672,4339,4340,4342,4345,4347,4349],{"class":674,"line":614},[672,4341,4099],{"class":682},[672,4343,4344],{"class":1280},"oauth",[672,4346,690],{"class":682},[672,4348,1277],{"class":682},[672,4350,3088],{"class":682},[672,4352,4353,4355,4358,4360,4362],{"class":674,"line":776},[672,4354,4135],{"class":682},[672,4356,4357],{"class":678},"enabled",[672,4359,690],{"class":682},[672,4361,1277],{"class":682},[672,4363,2234],{"class":682},[672,4365,4366],{"class":674,"line":782},[672,4367,4368],{"class":682},"      }\n",[672,4370,4371],{"class":674,"line":827},[672,4372,4220],{"class":682},[429,4374,4375,4376,4379,4380,4383,4384],{},"在終端機執行 ",[645,4377,4378],{},"gemini"," 指令，並在隨後拉起的網頁授權頁面中按一下 ",[442,4381,4382],{},"Approve（批准）"," 即可：\n",[435,4385],{"src":4386,"alt":4387,"style":4388},"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,4390,4391],{},"現在便可以透過極簡的命令列終端機向 AI 提問了：",[435,4393],{"src":4394,"alt":4395,"style":4396},"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,4398],{"src":4399,"alt":4400,"style":3658},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Fgemini-cli-mcp-display-itinerary.webp","Gemini CLI 成功展示結構化的旅行資訊",[586,4402,4404],{"id":4403},"_64-kimi-cli動態註冊","6.4 Kimi CLI（動態註冊）",[429,4406,4407,4408,4411,4412,4415],{},"原理基本相同。請在本地 ",[645,4409,4410],{},"\u002FUsers\u002F\u003C您的用戶名>\u002F.kimi\u002F"," 目錄下找到 ",[645,4413,4414],{},"mcp.json"," 並寫入以下連線配置：",[664,4417,4419],{"className":3070,"code":4418,"language":3072,"meta":424,"style":424},"    \"trek\": {\n      \"type\": \"http\",\n      \"url\": \"https:\u002F\u002Ftrek.pafor.me\u002Fmcp\",\n      \"auth\": \"oauth\"\n    }\n",[645,4420,4421,4433,4453,4472,4489],{"__ignoreMap":424},[672,4422,4423,4425,4427,4429,4431],{"class":674,"line":675},[672,4424,4086],{"class":682},[672,4426,3236],{"class":686},[672,4428,690],{"class":682},[672,4430,4079],{"class":2013},[672,4432,1167],{"class":682},[672,4434,4435,4437,4440,4442,4444,4446,4449,4451],{"class":674,"line":741},[672,4436,4099],{"class":682},[672,4438,4439],{"class":1280},"type",[672,4441,690],{"class":682},[672,4443,1277],{"class":682},[672,4445,683],{"class":682},[672,4447,4448],{"class":686},"http",[672,4450,690],{"class":682},[672,4452,4116],{"class":682},[672,4454,4455,4457,4460,4462,4464,4466,4468,4470],{"class":674,"line":614},[672,4456,4099],{"class":682},[672,4458,4459],{"class":1280},"url",[672,4461,690],{"class":682},[672,4463,1277],{"class":682},[672,4465,683],{"class":682},[672,4467,4149],{"class":686},[672,4469,690],{"class":682},[672,4471,4116],{"class":682},[672,4473,4474,4476,4479,4481,4483,4485,4487],{"class":674,"line":776},[672,4475,4099],{"class":682},[672,4477,4478],{"class":1280},"auth",[672,4480,690],{"class":682},[672,4482,1277],{"class":682},[672,4484,683],{"class":682},[672,4486,4344],{"class":686},[672,4488,701],{"class":682},[672,4490,4491],{"class":674,"line":782},[672,4492,4220],{"class":682},[429,4494,4375,4495,4498,4499,4502,4503],{},[645,4496,4497],{},"kimi mcp auth trek"," 並在網頁上按一下 ",[442,4500,4501],{},"Approve"," 完成快速授權：\n",[435,4504],{"src":4386,"alt":4387,"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,2602],{"id":2602},[429,4523,4524],{},"透過 MCP 將 AI 代理接入您的日常旅行規劃，可以幫您省去那些因手動鍵入繁多的航班和酒店確認單而產生的大量枯燥勞動。不僅如此，AI 還能根據您指定的具體出行節點和所處季節，智慧推薦周邊的特色景點。僅僅透過幾句隨意的對話，AI 就能輕鬆打通從前期靈感檢索、行程路線設計，再到後期預算拆分和行李打包的完整全鏈路。",[429,4526,4527],{},"不過在目前的版本中，依然存在一些微小的體驗瑕疵。例如：透過 PDF 智慧解析匯入訂單時，帳單貨幣會預設對齊到旅行專案的主貨幣，而不是當時實際刷卡結算的付款貨幣。此外，在 Collections 收藏夾中新建清單列表時，如果在列表尚未保存時就給它配置封面，該封面可能在保存後失效（您需要在列表正式建立後，點擊「編輯」來重新添加並保存，即可解決）。",[429,4529,4530,4531,4536],{},"此外，因為它需要您擁有一定的 VPS 運維基礎來親自執行這套程序，對一般使用者確實存在一些上手門檻。TREK 更適合那些重度旅行愛好者、數位游牧以及對於自身出行資料隱私和排版有著高水準要求的極客使用者。我們由衷地建議您在下定決心搭建自託管服務之前，可以先在 ",[569,4532,4535],{"href":4533,"rel":4534},"https:\u002F\u002Fdemo.liketrek.com\u002F",[1655],"demo.liketrek.com"," 上完整試用一下官方提供的公測 DEMO，看它是否切中您的日常痛點。",[547,4538,4540],{"id":4539},"參考資料","參考資料:",[455,4542,4543,4550,4557],{},[458,4544,4545],{},[569,4546,4549],{"href":4547,"rel":4548},"https:\u002F\u002Fgithub.com\u002Fliketrek\u002FTREK\u002Fwiki\u002FQuick-Start",[1655],"TREK Quick Start",[458,4551,4552],{},[569,4553,4556],{"href":4554,"rel":4555},"https:\u002F\u002Fgithub.com\u002Fliketrek\u002FTREK\u002Fwiki\u002FTroubleshooting",[1655],"TREK Troubleshooting",[458,4558,4559],{},[569,4560,4563],{"href":4561,"rel":4562},"https:\u002F\u002Fgithub.com\u002Fliketrek\u002FTREK\u002Fwiki\u002FMCP-Scopes",[1655],"TREK MCP Scopes",[2640,4565,4566],{},"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":4568},[4569,4574,4575,4585,4593,4599,4605,4606,4607],{"id":2735,"depth":614,"text":2736,"children":4570},[4571,4572,4573],{"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":4576},[4577,4578,4579,4580,4581,4582,4583,4584],{"id":3213,"depth":776,"text":3214},{"id":3224,"depth":776,"text":3225},{"id":3323,"depth":776,"text":3324},{"id":3341,"depth":776,"text":3342},{"id":3377,"depth":776,"text":3378},{"id":3399,"depth":776,"text":3400},{"id":3418,"depth":776,"text":3419},{"id":3429,"depth":776,"text":3430},{"id":3459,"depth":614,"text":3460,"children":4586},[4587,4588,4589,4590,4591,4592],{"id":3466,"depth":776,"text":3467},{"id":3498,"depth":776,"text":3499},{"id":3568,"depth":776,"text":3569},{"id":3591,"depth":776,"text":3592},{"id":3610,"depth":776,"text":3611},{"id":3635,"depth":776,"text":3636},{"id":3666,"depth":614,"text":3667,"children":4594},[4595,4596,4597,4598],{"id":3687,"depth":776,"text":3688},{"id":3787,"depth":776,"text":3788},{"id":3850,"depth":776,"text":3851},{"id":3949,"depth":776,"text":3950},{"id":3973,"depth":614,"text":3974,"children":4600},[4601,4602,4603,4604],{"id":3984,"depth":776,"text":3985},{"id":4009,"depth":776,"text":4010},{"id":4289,"depth":776,"text":4290},{"id":4403,"depth":776,"text":4404},{"id":4515,"depth":614,"text":4516},{"id":2602,"depth":614,"text":2602},{"id":4539,"depth":614,"text":4540},[4609,2675],"travel","2026-09-01","本文詳細介紹如何使用Docker部署開源旅行規劃系統TREK。我們將帶您配置Caddy反向代理和Cloudflare R2物件儲存，實現資料的安全備份與圖片的高效載入。此外，還將演示如何利用MCP（模型上下文協定）連接Claude等AI代理，通過自然语言對話一鍵生成您的專屬旅行日程，開啟完美旅程。","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002FTW-Self-hosted-travel-planner-TREK.webp","在一張溫和的羊皮紙背景上，高品質極簡風格的TREK自託管旅行規劃器儀表板3D插圖。",{"schemaOrg":4615,"robots":2704,"sitemap":4620},[4616,4617],{"@type":2686,"headline":2721,"description":4611},{"@type":4618,"headline":4619,"description":4611},"Article","如何自託管AI旅行規劃器TREK：基於Docker、Caddy與Cloudflare R2的終極部署教程",{"lastmod":4610},{"title":4619,"description":4611,"ogTitle":2721,"ogDescription":4611,"twitterTitle":2721,"twitterDescription":4611},"tw\u002Farticle\u002Fself-hosted-travel-planner-trek",[2712,4624,2713,2714,3410],"TREK","4z3qxnioPNFhbOX0uBxJtousA1aOkRBZl0xQJeZeC7M",{"id":4627,"title":4628,"author":424,"body":4629,"category":6022,"date":6024,"description":6025,"extension":2678,"image":6026,"imageAlt":6027,"isPublished":772,"meta":6028,"minRead":838,"navigation":772,"path":271,"seo":6034,"stem":6036,"tags":6037,"updatedAt":2715,"__hash__":6042},"article\u002Ftw\u002Farticle\u002Fsync-obsidian-across-devices.md","如何在多台裝置之間安全地同步 Obsidian 本地筆記庫",{"type":426,"value":4630,"toc":6000},[4631,4634,4639,4648,4657,4674,4679,4685,4689,4694,4708,4724,4727,4731,4734,4740,4745,4749,4753,4804,4810,4840,4844,4851,4858,4865,4917,4920,4935,4941,4953,4957,4961,4967,4972,4983,5004,5009,5021,5026,5031,5036,5051,5054,5058,5061,5066,5070,5075,5089,5093,5107,5118,5122,5127,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,5964,5970,5974,5997],[429,4632,4633],{},"Obsidian 是一款本地優先的知識管理應用。每一個筆記在裝置上都是一個本地 Markdown 檔案，並完全處於您的掌控之中。然而，我們通常希望在筆記型電腦、手機和其他裝置上共享同一個本地筆記庫，或者希望在某些時候能夠透過網頁瀏覽器遠端存取它。",[435,4635],{"src":4636,"alt":4637,"style":4638},"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,4640,4641,4642,4647],{},"市面上有許多針對 Obsidian 的同步方案，但在衝突處理、加密和數據自主權方面，它們或多或少都做出了一些妥協。",[569,4643,4646],{"href":4644,"rel":4645},"https:\u002F\u002Fgithub.com\u002Fhjinco\u002Fsynch",[1655],"Synch"," 是一款開源應用，它可以在自建伺服器上實現具備端到端加密和衝突解決機制的 Obsidian 筆記庫同步。",[429,4649,4650,4651,4656],{},"雖然 Obsidian 的本地優先方案在絕大多數情况下都能完美運作，但在某些場景下，我們可能仍需要透過網頁瀏覽器遠端存取並編輯筆記。",[569,4652,4655],{"href":4653,"rel":4654},"https:\u002F\u002Fgithub.com\u002FNystik-gh\u002Fignis",[1655],"Ignis"," 是一款開源應用，它能夠讓網頁瀏覽器中以接近原生的體驗執行 Obsidian，讓您能够直接讀取和編輯筆記庫。",[429,4658,4659,4660,4663,4664,1124,4666,4668,4669,4673],{},"在本文中，我們將在一台 ",[442,4661,4662],{},"VPS","（虛擬專用伺服器）上部署 ",[442,4665,4646],{},[442,4667,4655],{},"，並將它們安全地託管在 ",[442,4670,4671],{},[569,4672,3991],{"href":363}," 私有網路中，而無需將它們直接暴露在公網上。",[435,4675],{"src":4676,"alt":4677,"style":4678},"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,4680],{"description":4681,"image":4682,"image-alt":4683,"label":579,"min-read":580,"title":4684,"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,4686,4688],{"id":4687},"使用-synch-安全同步-obsidian-筆記庫","使用 Synch 安全同步 Obsidian 筆記庫",[429,4690,4691,4693],{},[442,4692,4646],{}," 提供以下特性：",[455,4695,4696,4699,4702,4705],{},[458,4697,4698],{},"偵測到變更時立即即時同步您的筆記庫",[458,4700,4701],{},"並在上傳前對筆記庫資料進行端到端加密",[458,4703,4704],{},"支援從歷史版本記錄中進行復原",[458,4706,4707],{},"內建自動衝突解決機制",[429,4709,4710,4712,4713,4716,4717,4720,4721,4723],{},[442,4711,4646],{}," 會在您的本地裝置上生成一個隨機的 32 位元組",[442,4714,4715],{},"筆記庫金鑰","（Vault Key），該金鑰專門用於加密您的筆記庫資料。當您建立遠端筆記庫時，您需要設定一個",[442,4718,4719],{},"筆記庫密碼","。該密碼用於保護您的",[442,4722,4715],{},"，以便能夠將金鑰安全地儲存在伺服器上，並在其他裝置上進行解密。",[429,4725,4726],{},"筆記的衝突解決是在用戶端裝置上完成的，而不是在伺服器端。如果兩台裝置同時編輯同一個筆記，伺服器會保留最先到達的版本，並通知另一台裝置其本地版本已過期。隨後，該裝置會自動將伺服器上的最新版本與其本地變更進行合併，然後再將合併後的最終筆記上傳。",[547,4728,4730],{"id":4729},"在您的-vps-上部署-synch","在您的 VPS 上部署 Synch",[586,4732,4733],{"id":4733},"建立網域名稱解析",[429,4735,4736,4737,4739],{},"在 Cloudflare 中建立一條 A 記錄，並將其代理狀態設定為",[442,4738,713],{},"（繞過 Cloudflare CDN）。",[435,4741],{"src":4742,"alt":4743,"style":4744},"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,4746,4748],{"id":4747},"在-ubuntu-上使用-docker-安裝-synch","在 Ubuntu 上使用 Docker 安裝 Synch",[4750,4751,4752],"h5",{"id":4752},"克隆倉庫",[664,4754,4756],{"className":666,"code":4755,"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,4757,4758,4770,4775,4780,4787,4791,4796],{"__ignoreMap":424},[672,4759,4760,4762,4764,4767],{"class":674,"line":675},[672,4761,981],{"class":678},[672,4763,984],{"class":686},[672,4765,4766],{"class":686}," https:\u002F\u002Fgithub.com\u002Fhjinco\u002Fsynch.git",[672,4768,4769],{"class":2013},"       \n",[672,4771,4772],{"class":674,"line":741},[672,4773,4774],{"class":2013},"        \n",[672,4776,4777],{"class":674,"line":614},[672,4778,4779],{"class":737},"# Navigate to the API folder\n",[672,4781,4782,4784],{"class":674,"line":776},[672,4783,996],{"class":785},[672,4785,4786],{"class":686}," synch\u002Fapps\u002Fapi\n",[672,4788,4789],{"class":674,"line":782},[672,4790,4774],{"class":2013},[672,4792,4793],{"class":674,"line":827},[672,4794,4795],{"class":737},"# Copy the example environment file:\n",[672,4797,4798,4800,4802],{"class":674,"line":832},[672,4799,1004],{"class":678},[672,4801,1007],{"class":686},[672,4803,1010],{"class":686},[4750,4805,1020,4807,4809],{"id":4806},"編輯-env-變數",[645,4808,1023],{}," 變數",[455,4811,4812,4818,4834],{},[458,4813,4814,4817],{},[645,4815,4816],{},"PUBLIC_URL=synch.pafor.me","：輸入您的 Synch 伺服器公网網域名稱（即在上一步中建立的網域名称）。",[458,4819,4820,1124,4823,4826,4827,4830,4831,4833],{},[645,4821,4822],{},"BETTER_AUTH_SECRET",[645,4824,4825],{},"SYNC_TOKEN_SECRET","：請使用此 ",[569,4828,4829],{"href":1064},"線上金鑰產生工具"," 或在終端機中執行兩次 ",[645,4832,1069],{}," 來產生高強度的隨機金鑰。",[458,4835,4836,4839],{},[645,4837,4838],{},"AUTH_ALLOWED_EMAILS","：允許註冊並建立帳號的電子信箱列表（用英文逗號分隔）。",[4750,4841,4843],{"id":4842},"将网域添加至-caddyfile","将网域添加至 Caddyfile",[429,4845,4846,4847,599],{},"有關如何將 Cloudflare DNS 模組整合到 Caddy 中並使用 Docker 容器啟動的詳細設定方法，請參閱我們的 ",[569,4848,4850],{"href":4849},"\u002Farticle\u002Fself-hosting-buzz-as-the-workspace-where-ai-agents-become-colleagues#_4-enable-https-with-caddy","自建 Buzz 協作平台文章",[574,4852],{"description":4853,"image":4854,"image-alt":4855,"label":4856,"min-read":4857,"title":423,"to":4849},"學習如何在 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,4859,4860,4861,4864],{},"在您的 Caddyfile 中添加 ",[645,4862,4863],{},"SYNCH_DOMAIN"," 設定，並將其反向代理指向 8787 連接埠（Synch 容器內部執行的連接埠）：",[664,4866,4868],{"className":3070,"code":4867,"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,4869,4870,4874,4881,4885,4889,4900,4904,4913],{"__ignoreMap":424},[672,4871,4872],{"class":674,"line":675},[672,4873,1167],{"class":682},[672,4875,4876,4879],{"class":674,"line":741},[672,4877,4878],{"class":2013},"  acme_dns cloudflare {env.CLOUDFLARE_API_TOKEN",[672,4880,1181],{"class":682},[672,4882,4883],{"class":674,"line":614},[672,4884,1181],{"class":2013},[672,4886,4887],{"class":674,"line":776},[672,4888,773],{"emptyLinePlaceholder":772},[672,4890,4891,4893,4896,4898],{"class":674,"line":782},[672,4892,3079],{"class":682},[672,4894,4895],{"class":2013},"$SYNCH_DOMAIN",[672,4897,3085],{"class":682},[672,4899,3088],{"class":682},[672,4901,4902],{"class":674,"line":827},[672,4903,3093],{"class":2013},[672,4905,4906,4908,4910],{"class":674,"line":832},[672,4907,3098],{"class":2013},[672,4909,1277],{"class":682},[672,4911,4912],{"class":1312},"8787\n",[672,4914,4915],{"class":674,"line":838},[672,4916,1181],{"class":682},[429,4918,4919],{},"啟動容器：",[664,4921,4923],{"className":666,"code":4922,"language":668,"meta":424,"style":424},"docker compose up -d\n",[645,4924,4925],{"__ignoreMap":424},[672,4926,4927,4929,4931,4933],{"class":674,"line":675},[672,4928,922],{"class":678},[672,4930,964],{"class":686},[672,4932,1562],{"class":686},[672,4934,1565],{"class":686},[429,4936,4937,4938,4940],{},"執行以下 ",[645,4939,679],{}," 命令以驗證服務的可用性：",[664,4942,4944],{"className":666,"code":4943,"language":668,"meta":424,"style":424},"curl https:\u002F\u002Fsynch.pafor.me\u002Fhealth\n",[645,4945,4946],{"__ignoreMap":424},[672,4947,4948,4950],{"class":674,"line":675},[672,4949,679],{"class":678},[672,4951,4952],{"class":686}," https:\u002F\u002Fsynch.pafor.me\u002Fhealth\n",[547,4954,4956],{"id":4955},"將-obsidian-用戶端連接至您的-synch-伺服器","將 Obsidian 用戶端連接至您的 Synch 伺服器",[586,4958,4960],{"id":4959},"在-obsidian-中安裝-synch-插件","在 Obsidian 中安裝 Synch 插件",[429,4962,4963,4964,3575],{},"打開 Obsidian 的「設定」（Settings），導覽至「第三方外掛」（Community plugins），然后點擊 ",[442,4965,4966],{},"「瀏覽」（Browse）",[435,4968],{"src":4969,"alt":4970,"style":4971},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fobsidian-community-plugins-browse.webp","在 Obsidian 設定中瀏覽第三方社群外掛","max-width: 523px; width: 100%; height: auto;",[429,4973,4974,4975,4978,4979],{},"搜尋並安裝 ",[442,4976,4977],{},"'Synchrun'"," 外掛：\n",[435,4980],{"src":4981,"alt":4982,"style":4744},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fobsidian-install-synchrun-plugin.webp","在 Obsidian 中安裝 Synchrun 同步外掛",[429,4984,4985,4986,4988,4989,4992,4993,4996,4997,5000,5001,599],{},"安裝完成後，打開 ",[442,4987,4977],{}," 外掛設定，並啟用 ",[442,4990,4991],{},"「使用自建伺服器」（Use a self-hosted server）","。隨後，在 ",[442,4994,4995],{},"「伺服器 URL」（Server URL）"," 欄位中輸入 ",[645,4998,4999],{},"https:\u002F\u002Fsynch.pafor.me","，並點擊 ",[442,5002,5003],{},"「儲存」（Save）",[435,5005],{"src":5006,"alt":5007,"style":5008},"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,5010,602,5011,5014,5015,5017,5018,5020],{},[442,5012,5013],{},"「在當前裝置上登入」（Sign in on this device）"," 按鈕。接著，使用您在 ",[645,5016,1023],{}," 中 ",[645,5019,4838],{}," 列表中指定的信箱地址進行註冊，註冊成功後您将看到以下授權頁面：",[435,5022],{"src":5023,"alt":5024,"style":5025},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fsynchrun-account-authorization-page.webp","Synchrun 外掛的帳號授權登入頁面","max-width: 494px; width: 100%; height: auto;",[429,5027,602,5028,3575],{},[442,5029,5030],{},"「允許 Obsidian 登入」（Allow Obsidian sign-in）",[435,5032],{"src":5033,"alt":5034,"style":5035},"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,5037,602,5038,5041,5042,5045,5046],{},[442,5039,5040],{},"「返回 Obsidian」（Return to Obsidian）"," 按鈕，隨後點擊 ",[442,5043,5044],{},"「建立筆記庫」（Create vault）","：\n",[435,5047],{"src":5048,"alt":5049,"style":5050},"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,5052,5053],{},"輸入您自訂的筆記庫名稱與高強度密碼來建立遠端筆記庫。",[435,5055],{"src":5056,"alt":5057,"style":1600},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fobsidian-synchrun-vault-password-setup.webp","為 Obsidian 遠端筆記庫設定高強度安全密碼",[429,5059,5060],{},"同步過程將立即開始，根據您的筆記庫檔案大小，這可能會需要一些時間。同步完成後，介面將顯示您所使用的總儲存空間。",[435,5062],{"src":5063,"alt":5064,"style":5065},"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,5067,5069],{"id":5068},"使用-ignis-實現基於瀏覽器的-obsidian-存取","使用 Ignis 實現基於瀏覽器的 Obsidian 存取",[429,5071,5072,5074],{},[442,5073,4655],{}," 透過將 Obsidian 的 Electron API 替換為 Web API，使得 Obsidian 的 JavaScript 程式碼能够直接在標準網頁瀏覽器中執行。您所有的 Markdown 筆記和附件都將直接儲存在託管伺服器的本地檔案系統中。",[429,5076,5077,5078,5083,5084,599],{},"不過，相比於獨立執行的 Obsidian 桌面用戶端，網頁端還存在一些局限性。由於瀏覽器沙箱環境的限制，某些依賴於 Electron 或 Node.js 特有 API 的功能或第三方外掛將無法正常運作。詳情請參閱 Ignis 官方文件中的 ",[569,5079,5082],{"href":5080,"rel":5081},"https:\u002F\u002Fignis.thiefling.com\u002Fdocs\u002Fusing\u002Flimitations\u002F",[1655],"局限性說明"," 以及 ",[569,5085,5088],{"href":5086,"rel":5087},"https:\u002F\u002Fignis.thiefling.com\u002Fdocs\u002Fusing\u002Fplugin-compatibility\u002F",[1655],"外掛相容性列表",[547,5090,5092],{"id":5091},"部署-ignis","部署 Ignis",[429,5094,5095,5096,5098,5099,5102,5103,5106],{},"我們將使用 Docker 在 VPS 上安裝 ",[442,5097,4655],{},"，並將其對應掛載到本地的 ",[645,5100,5101],{},".\u002Fvaults"," 資料夾中。隨後，我們將在伺服器上透過 ",[442,5104,5105],{},"Synch CLI"," 命令列用戶端將該本地目錄與我們之前設定的遠端同步筆記庫進行即時同步。",[429,5108,5109,5110,5112,5113,5117],{},"由於 ",[442,5111,4655],{}," 本身沒有內建的身份驗證機制，為了確保隱私，我們必須將其安全地隱藏在 ",[442,5114,5115],{},[569,5116,3991],{"href":363}," 私有網路中。",[586,5119,5121],{"id":5120},"建立-dns-記錄","建立 DNS 記錄",[435,5123],{"src":5124,"alt":5125,"style":5126},"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,5128,5130],{"id":5129},"將網域添加至-caddyfile","將網域添加至 Caddyfile",[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,3255],{},"在 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,4655],{}," 容器：",[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,5105],{}," 是一款無介面的命令列工具，即使在没有安裝 Obsidian 桌面應用的遠端伺服器上，它也能讓本地目錄與遠端筆記庫进行即時同步。",[429,5486,5487,5488,5491,5492,5494,5495,5498,5499,5083,5502,1081,5505,1124,5508,5511,5512,5515,5516,5519],{},"從您之前克隆的 ",[645,5489,5490],{},"synch"," 倉庫源碼中建置 ",[442,5493,5105],{},"。建置過程需要 ",[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 遠端同步伺服端相同的 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,4655],{}," 網頁端中顯示。",[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,4655],{}," 網頁端中刪除筆記時，它們會被安全地移至本地筆記庫的 ",[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,4646],{}," 與 ",[442,5947,4655],{}," 結合，您可以使用完全處於自己掌控之下的 VPS 伺服器硬體，無縫地實現 Obsidian 筆記庫的多端同步與網頁端存取。而將這些服務整體託管於 ",[442,5950,3991],{}," 私有網路之中，又為您提供了極致的安全物理邊界，從根本上阻断了公網暴露帶來的安全隱患。",[429,5953,5954,5955,5957],{},"當然，",[442,5956,4655],{}," 的初衷並不是為了完全替代本地的 Obsidian 桌面用戶端。相反，它更像是一個極其便利的臨時橋梁，供您在沒有攜帶主力電腦時，能夠隨時隨地透過任意瀏覽器快速存取和編輯自己的筆記。對於日常高強度的寫作與重度筆記庫管理，本地原生用戶端仍然是更加舒適、高效的選擇。",[429,5959,5960,5961,5963],{},"由於 Synch 採用了堅固的端到端加密機制，您的遠端筆記庫密碼必須具備足夠強的複雜度以抵禦暴力破解攻擊。同時，請務必牢記該密碼，因為同步伺服端不會儲存任何未加密的",[442,5962,4715],{},"。一旦遺忘該密碼，您的全部筆記資料將徹底無法復原。此外，由於所有資料均保存在您的自建 VPS 上，您需要自行承擔並妥善做好伺服器的主機安全防護、以及自動快照與備份管理。",[429,5965,5966,5967,5969],{},"儘管 ",[442,5968,4646],{}," 內建了加密歷史版本管理和已刪除檔案復原機制，能為您規避絕大多數意外資料遺失，但為了萬一失，我們依然強烈建議您在第三方實體介質上定期保留一份獨立的 Obsidian 筆記庫離線備份。",[447,5971,5973],{"id":5972},"references","References",[455,5975,5976,5983,5990],{},[458,5977,5978],{},[569,5979,5982],{"href":5980,"rel":5981},"https:\u002F\u002Fsynch.run\u002Fself-hosting-docker\u002F",[1655],"Synch Deploy with Docker Compose",[458,5984,5985],{},[569,5986,5989],{"href":5987,"rel":5988},"https:\u002F\u002Fignis.thiefling.com\u002Fdocs\u002Fserver\u002Fdeploy\u002F",[1655],"Ignis Deploy with Docker",[458,5991,5992],{},[569,5993,5996],{"href":5994,"rel":5995},"https:\u002F\u002Fsynch.run\u002Fblog\u002Fencryption-and-decryption\u002F",[1655],"How does end-to-end encryption work in Synch?",[2640,5998,5999],{},"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":6001},[6002,6011,6020,6021],{"id":4687,"depth":741,"text":4688,"children":6003},[6004,6008],{"id":4729,"depth":614,"text":4730,"children":6005},[6006,6007],{"id":4733,"depth":776,"text":4733},{"id":4747,"depth":776,"text":4748},{"id":4955,"depth":614,"text":4956,"children":6009},[6010],{"id":4959,"depth":776,"text":4960},{"id":5068,"depth":741,"text":5069,"children":6012},[6013],{"id":5091,"depth":614,"text":5092,"children":6014},[6015,6016,6017,6018,6019],{"id":5120,"depth":776,"text":5121},{"id":5129,"depth":776,"text":5130},{"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":5972,"depth":741,"text":5973},[6023],"productivity","2026-09-15","本文詳細介紹如何利用開源工具 Synch 與 Ignis 在您的 VPS 上搭建私有同步伺服器，從而在多台電腦、手機以及平板裝置之間安全地同步您的 Obsidian 筆記庫。我們還將所有服務全部部署在 Cloudflare Zero Trust 私有網路中，從而完全阻斷來自公網的惡意掃描與未授權存取，保障數據隱私安全。","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002FTW-Sync-Obsidian-Across-Devices.webp","使用自建 Synch 平台和 Ignis 網頁端在 Cloudflare Zero Trust 安全私有網路中同步多端 Obsidian 本地筆記庫的架構圖",{"schemaOrg":6029,"robots":2704,"sitemap":6032},[6030,6031],{"@type":4618,"headline":4628,"description":6025,"image":6026},{"@type":2686,"name":4628,"description":6025,"image":6026},{"lastmod":6033},"2026-09-16",{"title":6035,"description":6025,"ogTitle":4628,"ogDescription":6025,"twitterTitle":4628,"twitterDescription":6025},"基於自建 Synch 與 Ignis 實現 Obsidian 跨裝置安全同步","tw\u002Farticle\u002Fsync-obsidian-across-devices",[6038,6039,6040,6041],"自建服务","Obsidian","云端同步","Zero Trust","6DsOPDA5q5K5tiypqYFvhyUvxHAduTMMII_8Mf-xVXM",[6044,7277,7278],{"id":6045,"title":6046,"author":424,"body":6047,"category":7241,"date":7243,"description":7244,"extension":2678,"image":7245,"imageAlt":7246,"isPublished":772,"meta":7247,"minRead":894,"navigation":772,"path":355,"seo":7271,"stem":7273,"tags":7274,"updatedAt":2715,"__hash__":7276},"article\u002Ftw\u002Farticle\u002Fbringing-buzz-to-deepseek-harness.md","為 DeepSeek Harness 接入 Buzz 協作平台：構建自託管 Nostr 訊息閘道的完整實踐",{"type":426,"value":6048,"toc":7225},[6049,6055,6076,6079,6082,6086,6091,6132,6135,6194,6198,6205,6484,6487,6491,6495,6501,6505,6519,6523,6534,6580,6587,6591,6594,6626,6629,6634,6675,6683,6689,6697,6703,6734,6748,6752,6761,6785,6806,6847,6853,6859,6865,6872,6878,6883,6891,6904,6910,6920,6955,6958,6964,6971,6977,6981,6984,7138,7141,7182,7186,7192,7196,7222],[429,6050,6051],{},[435,6052],{"alt":6053,"src":6054},"DeepSeek Harness 訊息閘道連線至 Block Buzz 頻道的運作概觀","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002Fdsh-buzz-nostr-gateway-overview.webp",[429,6056,6057,6058,6065,6066,6070,6071,6075],{},"DeepSeek Harness（DSH）的官方外掛程式 ",[442,6059,6060],{},[569,6061,6064],{"href":6062,"rel":6063},"https:\u002F\u002Fgithub.com\u002Fa792883583\u002Fdsh-message-gateway",[1655],"dsh-message-gateway","，能夠將 DeepSeek Harness 助理無縫延伸至 Discord、Telegram、WeChat 等多種主流即時通訊平台。該外掛程式倉庫已被 Fork 並進行了二次開發，旨在將 ",[442,6067,6068],{},[569,6069,423],{"href":383}," 納入支援清單。Fork 後的開原始碼倉庫位於 GitHub：",[569,6072,6073],{"href":6073,"rel":6074},"https:\u002F\u002Fgithub.com\u002FTech-Voyage-Dev\u002Fdsh-message-gateway",[1655]," 。",[574,6077],{"description":2677,"image":2679,"image-alt":2680,"label":6078,"min-read":4857,"title":423,"to":383},"前置準備指南",[429,6080,6081],{},"DSH 助理作為一個全功能成員加入 Buzz Nostr 中繼伺服器，既能接收私人訊息（DM），也能接收被 @mention 提及的頻道訊息，並透過與 Web UI 完全相同的獨立工作階段智能體管線輸出回應。",[447,6083,6085],{"id":6084},"dsh-message-gateway-外掛架構剖析","dsh-message-gateway 外掛架構剖析",[429,6087,6088,6090],{},[442,6089,6064],{}," 外掛的系統架構清晰劃分為主機端與用戶端兩大部分：",[455,6092,6093,6122],{},[458,6094,6095,3255,6098,6101,6102,6105,6106,6109,6110,6113,6114,6117,6118,6121],{},[442,6096,6097],{},"主機端（Node 環境）",[645,6099,6100],{},"gateway-store","（憑證與設定持久化儲存，位於 ",[645,6103,6104],{},"~\u002F.dsh\u002Fgateway.json","）、",[645,6107,6108],{},"platforms.ts","（支援平台定義與連線測試）、",[645,6111,6112],{},"routes.ts","（對外暴露的 ",[645,6115,6116],{},"\u002Fgateway\u002F*"," 路由端點）以及 ",[645,6119,6120],{},"bridge-manager.ts","（常駐閘道橋接器：負責按對話維護獨立 Agent 執行個體並統一管理串流回應推送）。",[458,6123,6124,6127,6128,6131],{},[442,6125,6126],{},"用戶端（瀏覽器前端）","：側邊欄的「",[442,6129,6130],{},"Message platforms","」視覺化設定頁面，負責填寫金鑰參數、發起連線測試以及直觀監視閘道即時在線狀態。",[429,6133,6134],{},"為閘道接入一個全新通訊平台通常需要經歷以下三步：",[591,6136,6137,6155,6169],{},[458,6138,6139,6142,6143,6146,6147,6150,6151,6154],{},[442,6140,6141],{},"實作 Bridge 橋接類別","：提供 ",[645,6144,6145],{},"start\u002Fstop\u002Fstatus"," 生命週期方法以及 ",[645,6148,6149],{},"onText(text, frame)"," 訊息回呼，結構規範與現有的 ",[645,6152,6153],{},"wecom-bridge.ts"," 完全一致。",[458,6156,6157,6160,6161,6164,6165,6168],{},[442,6158,6159],{},"接入 bridge-manager 排程器","：複用既有的多工作階段排程管線（",[645,6162,6163],{},"ensureAgentForKey"," + ",[645,6166,6167],{},"pendingMap","），並將底層文字輸出串流掛載至該平台的專用回覆接收器。",[458,6170,6171,6174,6175,5945,6178,6181,6182,6185,6186,6189,6190,6193],{},[442,6172,6173],{},"對接持久化儲存與設定路由","：在 ",[645,6176,6177],{},"\u002Fgateway\u002Fsave",[645,6179,6180],{},"\u002Fgateway\u002Fdelete"," 邏輯中實作：",[442,6183,6184],{},"儲存設定即自動啟動橋接服務，刪除設定則優雅停止橋接服務","，配合 ",[645,6187,6188],{},"autoStartXxx"," 狀態旗標確保 ",[645,6191,6192],{},"dsh web"," 守護行程開機自動重新連線。",[447,6195,6197],{"id":6196},"buzz-閘道橋接實作nostr-協定標準與事件生命週期","Buzz 閘道橋接實作：Nostr 協定標準與事件生命週期",[429,6199,6200,6201,6204],{},"本次接入直接使用 ",[442,6202,6203],{},"DeepSeek Harness"," 自行編寫完成了完整的 Buzz 適配橋接器。底層嚴格遵循了如下 Nostr 協定規範標準：",[6206,6207,6208,6223],"table",{},[6209,6210,6211],"thead",{},[6212,6213,6214,6220],"tr",{},[6215,6216,6217],"th",{},[442,6218,6219],{},"維度 \u002F 階段",[6215,6221,6222],{},"協定實作規範與技術細節",[6224,6225,6226,6248,6266,6293,6311,6336,6361,6383,6397,6411,6430,6447,6461],"tbody",{},[6212,6227,6228,6234],{},[6229,6230,6231],"td",{},[442,6232,6233],{},"底層傳輸（Transport）",[6229,6235,6236,6237,6240,6241,6244,6245],{},"單條經過 NIP-42 鑑權認證的 WebSocket 鏈路；預設中繼連線位址為 ",[645,6238,6239],{},"ws:\u002F\u002Flocalhost:3000","；輸入的 ",[645,6242,6243],{},"http(s):\u002F\u002F"," 會自動正規化為 ",[645,6246,6247],{},"ws(s):\u002F\u002F",[6212,6249,6250,6255],{},[6229,6251,6252],{},[442,6253,6254],{},"鑑權認證（Auth）",[6229,6256,6257,6258,6261,6262,6265],{},"AUTH 事件 ",[645,6259,6260],{},"kind 22242","，攜帶標籤 ",[645,6263,6264],{},"[[\"relay\", url], [\"challenge\", challenge]]","，內容為空字串，由 Agent 的私密金鑰完成簽章",[6212,6267,6268,6273],{},[6229,6269,6270],{},[442,6271,6272],{},"訂閱機制（Subs）",[6229,6274,6275,3255,6278,6281,6282,6285,6286,6289,6290],{},[442,6276,6277],{},"嚴格基於頻道隔離",[645,6279,6280],{},"REQ {\"kinds\":[9], \"#h\":[\u003Cuuid>]}"," — 每個頻道獨立建立一條訂閱。全域性的 ",[645,6283,6284],{},"kinds:[9]"," 雖能收到 EOSE 但絕不廣播推送；多值 ",[645,6287,6288],{},"#h"," 標籤過濾在協定中",[442,6291,6292],{},"無法正常分發",[6212,6294,6295,6300],{},[6229,6296,6297],{},[442,6298,6299],{},"頻道探索（Discovery）",[6229,6301,6302,6303,6306,6307,6310],{},"歷史中繼資料回溯查詢 ",[645,6304,6305],{},"REQ {kinds:[39000]}"," 擷取頻道詳情（其中 ",[645,6308,6309],{},"type == \"dm\""," 用於標記單聊私訊頻道）",[6212,6312,6313,6318],{},[6229,6314,6315],{},[442,6316,6317],{},"成員異動訂閱",[6229,6319,6320,6321,6324,6325,6327,6328,6331,6332,6335],{},"即時長連線訂閱 ",[645,6322,6323],{},"REQ {kinds:[44100,44101], \"#p\":[Agent 公鑰], since: now-60s}"," — 44100 為加入群組，44101 為被移除，均附帶 ",[645,6326,429],{},"+",[645,6329,6330],{},"h","；成員關係變更時",[442,6333,6334],{},"無需重新連線","即可動態熱更新訂閱狀態",[6212,6337,6338,6343],{},[6229,6339,6340],{},[442,6341,6342],{},"即時聊天事件",[6229,6344,6345,6348,6349,6352,6353,6356,6357,6360],{},[645,6346,6347],{},"kind 9"," 事件，攜帶 ",[645,6350,6351],{},"[\"h\", channel]"," 頻道標籤，可選附帶 ",[645,6354,6355],{},"[\"e\", replyTo]"," 回覆目標與 ",[645,6358,6359],{},"[\"p\", mention]"," 被提及者標籤",[6212,6362,6363,6368],{},[6229,6364,6365],{},[442,6366,6367],{},"原位更新編輯",[6229,6369,6370,6373,6374,5945,6376,6379,6380,6382],{},[645,6371,6372],{},"kind 40003"," 事件，附帶 ",[645,6375,6330],{},[645,6377,6378],{},"e"," 目標標籤；內容完全替換；中繼伺服器單包上限 64 KB → 嚴控酬載 ≤ 60,000 B；超長回覆分塊處理 — 首塊用於原位編輯替換，超出部分作為回覆串討論串的 ",[645,6381,6347],{}," 訊息追加",[6212,6384,6385,6390],{},[6229,6386,6387],{},[442,6388,6389],{},"CLOSED 異常訊框處理",[6229,6391,6392,6393,6396],{},"鑑權未完成前收到 ",[645,6394,6395],{},"auth-required"," 屬於正常引導階段（完成 AUTH 後重新拉起訂閱）；鑑權完成後遇斷線 → 階梯式限次重試（最多 3 次，間隔 0\u002F1\u002F2 秒退避）；整鏈重連時全量重構上下文",[6212,6398,6399,6404],{},[6229,6400,6401],{},[442,6402,6403],{},"中繼拉取上限",[6229,6405,6406,6407,6410],{},"每次訂閱最多拉取 2000 條歷史事件，即使設定了 ",[645,6408,6409],{},"since"," 過濾參數，中繼伺服器仍按自最新向過去的時間倒序返回",[6212,6412,6413,6418],{},[6229,6414,6415],{},[442,6416,6417],{},"訊息命中判定",[6229,6419,6420,6421,6423,6424,6426,6427,6429],{},"僅當滿足以下任一條件時才啟動處理入站 ",[645,6422,6347],{},"：(a) ",[645,6425,429],{}," 標籤明確包含自身公鑰，(b) 處於 DM 私訊頻道，(c) 回覆關聯的 ",[645,6428,6378],{}," 根事件為自身發出的訊息。自動過濾自身公鑰發送的內容（徹底杜絕迴圈）",[6212,6431,6432,6437],{},[6229,6433,6434],{},[442,6435,6436],{},"出站 @ 提及",[6229,6438,6439,6440,6443,6444,6446],{},"出站內容按純文字原樣發布 — 中繼伺服器端不對正文中的 ",[645,6441,6442],{},"@"," 符號進行預先驗證；",[645,6445,429],{}," 標籤填入當前對話原作者以及至多 7 位其他被提及者的公鑰（單條上限 8 位）",[6212,6448,6449,6454],{},[6229,6450,6451],{},[442,6452,6453],{},"私聊訊息（DM）",[6229,6455,6456,6457,6460],{},"依賴中繼伺服器範圍內的明文受限頻道（中繼資料標註 ",[645,6458,6459],{},"type: \"dm\"","） — 當前橋接實作中未引入 NIP-04\u002F44 複雜非對稱端對端加密",[6212,6462,6463,6468],{},[6229,6464,6465],{},[442,6466,6467],{},"媒體附件（入站）",[6229,6469,6470,6471,6474,6475,4190,6477,4190,6480,6483],{},"NIP-92 ",[645,6472,6473],{},"imeta"," 規範（",[645,6476,4459],{},[645,6478,6479],{},"sha256",[645,6481,6482],{},"m","）→ 常規 HTTP(S) 串流下載，本地驗證 SHA-256 完整性，單檔限制 20 MB，每條訊息最多 4 張；出站圖片發布暫無官方中繼協定路徑，現階段不支援出站圖片",[429,6485,6486],{},"Buzz 適配閘道的啟動引導時序圖如下：",[435,6488],{"src":6489,"alt":6490},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002Fdsh-buzz-bootstrap.webp","展示 Buzz 閘道引導連線與 NIP-42 協定身分鑑權流程的時序圖",[547,6492,6494],{"id":6493},"基於-nostr-40003-事件原位編輯實現的即時串流輸出","基於 Nostr 40003 事件原位編輯實現的即時串流輸出",[429,6496,6497,6498,3255],{},"Nostr 協定缺乏原生鍵入中（Typing）狀態通知，且底層事件設計為嚴格只增不改。為了讓對話過程具備流暢的即時互動感，Buzz 適配閘道",[442,6499,6500],{},"透過原位編輯巧妙模擬了串流打字輸出",[435,6502],{"src":6503,"alt":6504},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002Fdsh-buzz-reply.webp","基於 kind 40003 事件原位編輯模擬打字串流回應的邏輯流程圖",[455,6506,6507],{},[458,6508,6509],{},[6510,6511,6512,6513,6515,6516,6518],"em",{},"閘道首先秒級發出一條 ",[645,6514,6347],{}," 預留位置訊息，隨後在 Agent 推理過程中按設定的節流閥值連續發射 ",[645,6517,6372],{}," 原位編輯事件逐步追加渲染內容，並在推理終點落定最終文字。這一設計思路與 Telegram、Discord 橋接器的實作方式一脈相承。",[547,6520,6522],{"id":6521},"透過聊天指令打通-deepseek-harness-本地工作區","透過聊天指令打通 DeepSeek Harness 本地工作區",[429,6524,6525,6526,6529,6530,6533],{},"DSH Web 介面所支援的「工作區（Workspaces）」核心能力依賴於底層 ",[645,6527,6528],{},"@deepseek-ai\u002Fdsh-workspace"," 模組中的 ",[645,6531,6532],{},"workspaceRegistry"," 服務：",[664,6535,6539],{"className":6536,"code":6537,"language":6538,"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,6540,6541],{"__ignoreMap":424},[672,6542,6543,6546,6549,6552,6556,6559,6562,6564,6566,6569,6572,6574,6577],{"class":674,"line":675},[672,6544,6545],{"class":1280},"const",[672,6547,6548],{"class":2013}," existing ",[672,6550,6551],{"class":682},"=",[672,6553,6555],{"class":6554},"s7zQu"," await",[672,6557,6558],{"class":2013}," ctx",[672,6560,6561],{"class":682},".",[672,6563,6532],{"class":2013},[672,6565,6561],{"class":682},[672,6567,6568],{"class":785},"resolveByPath",[672,6570,6571],{"class":2013},"(request",[672,6573,6561],{"class":682},[672,6575,6576],{"class":2013},"path)",[672,6578,6579],{"class":682},";\n",[429,6581,6582,6583,6586],{},"Buzz 橋接器透過引入全新的聊天斜線指令 ",[645,6584,6585],{},"\u002Fworkspace \u003C目錄路徑>","，允許在群聊中直接向 DSH 註冊並綁定本地現存的資料夾。在此之後，該工作階段下的所有互動都將牢牢錨定在此目錄中，並能即時無縫同步在 DSH Web UI 端查看。",[435,6588],{"src":6589,"alt":6590},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002Fdsh-buzz-workspace.webp","透過閘道聊天指令動態註冊並綁定 DeepSeek Harness 本地工作區的架構示意圖",[429,6592,6593],{},"開發與使用過程中需重點明確的三大設計機制：",[455,6595,6596,6606,6616],{},[458,6597,6598,6601,6602,6605],{},[442,6599,6600],{},"變更目錄等同於開啟全新工作階段","：工作階段的工作目錄（",[645,6603,6604],{},"cwd","）在初始化生成 Session Header 時即完成寫入，後續在生命週期內不可直接原地竄改。",[458,6607,6608,6611,6612,6615],{},[442,6609,6610],{},"目標本地目錄必須預先存在","：底層 ",[645,6613,6614],{},"create"," 註冊函式會對路徑進行嚴格驗證，若路徑在主機上不存在將直接擲出例外狀況拒絕綁定。",[458,6617,6618,6621,6622,6625],{},[442,6619,6620],{},"高度安全敏感指令","：透過閘道衍生的工作階段均賦予 ",[442,6623,6624],{},"auto-approve","（自動核准命令執行）特權，擁有對目標資料夾直接進行讀寫和工具操作的完全存取權。",[447,6627,6628],{"id":6628},"安裝與設定全流程指南",[591,6630,6631],{},[458,6632,6633],{},"在終端機執行以下指令完成外掛程式下載與啟動：",[664,6635,6637],{"className":666,"code":6636,"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,6638,6639,6659,6663,6668],{"__ignoreMap":424},[672,6640,6641,6644,6647,6650,6653,6656],{"class":674,"line":675},[672,6642,6643],{"class":678},"dsh",[672,6645,6646],{"class":686}," plugin",[672,6648,6649],{"class":686}," --profile",[672,6651,6652],{"class":686}," web",[672,6654,6655],{"class":686}," add",[672,6657,6658],{"class":686}," https:\u002F\u002Fgithub.com\u002FTech-Voyage-Dev\u002Fdsh-message-gateway.git\n",[672,6660,6661],{"class":674,"line":741},[672,6662,773],{"emptyLinePlaceholder":772},[672,6664,6665],{"class":674,"line":614},[672,6666,6667],{"class":737},"# Start DSH web\n",[672,6669,6670,6672],{"class":674,"line":776},[672,6671,6643],{"class":678},[672,6673,6674],{"class":686}," web\n",[591,6676,6677],{"start":741},[458,6678,6679,6680,6682],{},"待 DSH Web 介面啟動並用瀏覽器開啟後，按一下介面側邊欄中的「",[442,6681,6130],{},"」圖示：",[429,6684,6685],{},[435,6686],{"alt":6687,"src":6688},"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,6690,6691],{"start":614},[458,6692,6693,6694,6696],{},"在左側平台清單中選擇「",[442,6695,444],{},"」：",[429,6698,6699],{},[435,6700],{"alt":6701,"src":6702},"DeepSeek Harness 訊息閘道內的 Buzz 協定參數與金鑰對設定面板","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002Fdsh-message-gateway-buzz-config-panel.webp",[591,6704,6705,6716,6727],{"start":776},[458,6706,6707,6708,6711,6712,6715],{},"按一下「",[442,6709,6710],{},"Generate keypair","」按鈕即時生成全新的 Nostr 身分金鑰對。請務必將生成的 ",[645,6713,6714],{},"npub"," 公鑰妥善複製暫存，後續步驟將作為關鍵身分憑證。",[458,6717,6718,6719,6722,6723,6726],{},"準確填入您的 ",[442,6720,6721],{},"Relay URL","（中繼位址）以及需要監聽訂閱的 ",[442,6724,6725],{},"Channels","（允許存取的頻道 UUID 白名單清單）。",[458,6728,6729,6730,6733],{},"按一下底部的「",[442,6731,6732],{},"Save","」按鈕完成儲存。",[429,6735,6736,6737,6740,6741,6744,6745,6747],{},"表單提交後，系統將持久化儲存設定並",[442,6738,6739],{},"立即啟動 Buzz 閘道服務","。私密金鑰 ",[645,6742,6743],{},"nsec"," 作為最高機密憑證被自動保護，僅獨立存放在主機本地的 ",[645,6746,6104],{}," 檔案中。",[547,6749,6751],{"id":6750},"將-dsh-智能體註冊至-buzz-nostr-中繼服務","將 DSH 智能體註冊至 Buzz Nostr 中繼服務",[429,6753,6754,6757,6758,6760],{},[442,6755,6756],{},"將 DSH 助理作為新成員註冊加入中繼伺服器","。此處公鑰填入上文所生成的 ",[645,6759,6714],{}," 字串：",[664,6762,6764],{"className":666,"code":6763,"language":668,"meta":424,"style":424},"docker compose exec relay buzz-admin add-member --pubkey npub123123123\n",[645,6765,6766],{"__ignoreMap":424},[672,6767,6768,6770,6772,6774,6776,6778,6780,6782],{"class":674,"line":675},[672,6769,922],{"class":678},[672,6771,964],{"class":686},[672,6773,1692],{"class":686},[672,6775,1695],{"class":686},[672,6777,1698],{"class":686},[672,6779,1701],{"class":686},[672,6781,1704],{"class":686},[672,6783,6784],{"class":686}," npub123123123\n",[429,6786,6787,6790,6791,6793,6794,6797,6798,6801,6802,6805],{},[442,6788,6789],{},"將 DSH 助理加入特定的溝通頻道","。僅加入中繼並不會讓助理自動出現在頻道成員清單中。需要透過 ",[645,6792,1833],{}," 進一步執行入群操作。注意此處 ",[645,6795,6796],{},"--pubkey"," 參數必須使用 ",[442,6799,6800],{},"HEX 16 進位公鑰","格式，而非 npub 格式（在上一步執行 ",[645,6803,6804],{},"buzz-admin add-member"," 時，終端機輸出中會印出對應的 HEX 公鑰）：",[664,6807,6809],{"className":666,"code":6808,"language":668,"meta":424,"style":424},"buzz channels add-member --channel \u003CCHANNEL_UUID> --pubkey \u003CAGENT_HEX> --role member\n",[645,6810,6811],{"__ignoreMap":424},[672,6812,6813,6815,6817,6819,6821,6823,6825,6827,6829,6831,6833,6836,6839,6841,6844],{"class":674,"line":675},[672,6814,2065],{"class":678},[672,6816,2068],{"class":686},[672,6818,1701],{"class":686},[672,6820,2120],{"class":686},[672,6822,2336],{"class":682},[672,6824,2339],{"class":686},[672,6826,2342],{"class":2013},[672,6828,2017],{"class":682},[672,6830,1704],{"class":686},[672,6832,2336],{"class":682},[672,6834,6835],{"class":686},"AGENT_HE",[672,6837,6838],{"class":2013},"X",[672,6840,2017],{"class":682},[672,6842,6843],{"class":686}," --role",[672,6845,6846],{"class":686}," member\n",[574,6848],{"description":6849,"image":2679,"image-alt":2680,"label":6850,"min-read":4002,"title":6851,"to":6852},"手把手教您安裝與設定 buzz-cli，以便在 Nostr 中繼伺服器上管理頻道、成員金鑰以及 AI 智能體的角色權限。","CLI 指南","如何安裝並使用 buzz-cli","\u002Farticle\u002Fself-hosting-buzz-as-the-workspace-where-ai-agents-become-colleagues#install-buzz-cli",[429,6854,6855,6856,6858],{},"隨後可透過 ",[645,6857,1833],{}," 靈活更新 DSH 助理在 Nostr 中繼伺服器中的公開設定檔，設定更具識別度的暱稱：",[429,6860,6861],{},[435,6862],{"alt":6863,"src":6864},"使用 buzz-cli 命令列工具更新 DSH 助理在 Nostr 中繼伺服器上的公開個人資料","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002Fdsh-assistant-buzz-cli-profile-update.webp",[429,6866,6867,6868,6871],{},"在用戶端向 DSH 助理傳送一次 ",[442,6869,6870],{},"Wave","（Buzz 平台獨特的 DM 私訊打招呼動作）。助理隨後傳回回覆，代表閘道通訊已完全就緒：",[429,6873,6874],{},[435,6875],{"alt":6876,"src":6877},"在 Buzz 用戶端向 DeepSeek Harness 助理傳送 Wave 私訊進行連線性驗證","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002Fdsh-buzz-dm-wave-greeting-reply.webp",[429,6879,6880],{},[6510,6881,6882],{},"向 DSH 助理傳送 Wave 私訊打招呼 — 橋接閘道正常秒級回應。",[547,6884,6886,6887,6890],{"id":6885},"透過-workspace-指令開啟本地工作區聯動","透過 ",[645,6888,6889],{},"\u002Fworkspace"," 指令開啟本地工作區聯動",[429,6892,5109,6893,6896,6897,6900,6901,6903],{},[645,6894,6895],{},"allowWorkspace"," 設定項目出於環境安全考量預設處於停用（",[645,6898,6899],{},"false","）狀態，未經設定直接向助理發送 ",[645,6902,6889],{}," 命令會被系統攔截拒絕：",[429,6905,6906],{},[435,6907],{"alt":6908,"src":6909},"在未開啟 allowWorkspace 權限時發送 \u002Fworkspace 命令被系統安全攔截的提示","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002Fdsh-buzz-workspace-command-rejected-error.webp",[429,6911,6912,6913,6916,6917,6919],{},"開啟設定檔 ",[645,6914,6915],{},"~\u002F.dsh\u002Fprofiles\u002Fweb\u002Fcordis.patch.yml"," 新增開關設定，隨後重新啟動 ",[645,6918,6192],{}," 服務即可：",[664,6921,6923],{"className":1158,"code":6922,"language":1160,"meta":424,"style":424},"- id: ui-message-gateway\n  config:\n    allowWorkspace: true\n",[645,6924,6925,6938,6945],{"__ignoreMap":424},[672,6926,6927,6930,6933,6935],{"class":674,"line":675},[672,6928,6929],{"class":682},"-",[672,6931,6932],{"class":1258}," id",[672,6934,1277],{"class":682},[672,6936,6937],{"class":686}," ui-message-gateway\n",[672,6939,6940,6943],{"class":674,"line":741},[672,6941,6942],{"class":1258},"  config",[672,6944,1262],{"class":682},[672,6946,6947,6950,6952],{"class":674,"line":614},[672,6948,6949],{"class":1258},"    allowWorkspace",[672,6951,1277],{"class":682},[672,6953,2234],{"class":6954},"sfNiH",[429,6956,6957],{},"設定生效並重新啟動後即可順利綁定：",[429,6959,6960],{},[435,6961],{"alt":6962,"src":6963},"在 Buzz 頻道成功執行 \u002Fworkspace 命令完成本地工作區綁定的確認訊息","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002Fdsh-buzz-workspace-command-success-confirmation.webp",[429,6965,6966,6967,6970],{},"實用提示：此命令預設假設工作區目錄名（例如截圖中的 ",[645,6968,6969],{},"TechVoyage","）直接位於當前使用者的個人主目錄之下；若目錄處於其他深層路徑，請務必傳入完整絕對路徑。透過 Buzz 頻道中註冊綁定好的新工作階段，也都會完全同步在 DeepSeek Harness Web 介面上顯示。",[429,6972,6973],{},[435,6974],{"alt":6975,"src":6976},"DeepSeek Harness Web UI 中展示從 Buzz 頻道自動同步關聯的活躍工作階段","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002Fdsh-web-ui-synced-workspace-session.webp",[547,6978,6980],{"id":6979},"buzz-頻道支援的完整可用指令","Buzz 頻道支援的完整可用指令",[429,6982,6983],{},"其他平台支援的幾乎全部原生功能在 Buzz 中均可順暢運作：",[6206,6985,6986,6996],{},[6209,6987,6988],{},[6212,6989,6990,6993],{},[6215,6991,6992],{},"指令語法",[6215,6994,6995],{},"功能說明",[6224,6997,6998,7008,7018,7028,7038,7048,7058,7068,7078,7101,7121],{},[6212,6999,7000,7005],{},[6229,7001,7002],{},[645,7003,7004],{},"\u002Fworkspace \u003Cfolder>",[6229,7006,7007],{},"將本地已存在的資料夾註冊綁定為當前對話專屬的工作區環境（受設定項目開關保護）",[6212,7009,7010,7015],{},[6229,7011,7012],{},[645,7013,7014],{},"\u002Fhelp",[6229,7016,7017],{},"列印並列出所有支援的命令清單",[6212,7019,7020,7025],{},[6229,7021,7022],{},[645,7023,7024],{},"\u002Ftime",[6229,7026,7027],{},"取得並輸出當前伺服器系統時間",[6212,7029,7030,7035],{},[6229,7031,7032],{},[645,7033,7034],{},"\u002Fnew",[6229,7036,7037],{},"捨棄舊上下文，原地重設開啟全新工作階段",[6212,7039,7040,7045],{},[6229,7041,7042],{},[645,7043,7044],{},"\u002Fclear",[6229,7046,7047],{},"清空當前上下文所有歷史對話串流",[6212,7049,7050,7055],{},[6229,7051,7052],{},[645,7053,7054],{},"\u002Fstatus",[6229,7056,7057],{},"查看當前 Buzz 訊息橋接器的即時在線狀態",[6212,7059,7060,7065],{},[6229,7061,7062],{},[645,7063,7064],{},"\u002Fstats",[6229,7066,7067],{},"查看當前系統活躍工作階段總量及所有接入平台（包含 Buzz）的橋接連線詳細狀態",[6212,7069,7070,7075],{},[6229,7071,7072],{},[645,7073,7074],{},"\u002Fcommands",[6229,7076,7077],{},"輸出全量指令的底層規範與參數描述文件",[6212,7079,7080,7085],{},[6229,7081,7082],{},[645,7083,7084],{},"@path\u002Fto\u002Ffile",[6229,7086,7087,7088,7090,7091,1081,7093,7096,7097,7100],{},"與 Web 端的 ",[645,7089,6442],{}," 檔案提及功能完全一致：Agent 自動相對於工作區讀取檔案內容；單獨發送 ",[645,7092,6442],{},[645,7094,7095],{},"@前綴"," 或使用 ",[645,7098,7099],{},"\u002Ffiles \u003C前綴>"," 可傳回符合的檔案\u002F資料夾清單",[6212,7102,7103,7108],{},[6229,7104,7105],{},[645,7106,7107],{},"\u002Fmodel",[6229,7109,7110,7113,7114,7116,7117,7120],{},[645,7111,7112],{},"[provider model effort]"," — 驗證有效後即時切換該工作階段的底層推理大型語言模型與思考深度；單獨輸入 ",[645,7115,7107],{}," 顯示支援的候選清單，",[645,7118,7119],{},"\u002Fmodel reset"," 恢復系統預設設定",[6212,7122,7123,7128],{},[6229,7124,7125],{},[645,7126,7127],{},"\u002Feffort",[6229,7129,7130,7133,7134,7137],{},[645,7131,7132],{},"\u003Cid>"," 僅針對支援思考深度的模型調整 reasoning effort；",[645,7135,7136],{},"\u002Feffort reset"," 恢復預設推理深度設定",[547,7139,7140],{"id":7140},"核心安全架構總結",[455,7142,7143,7155,7169],{},[458,7144,7145,7148,7149,7151,7152,7154],{},[442,7146,7147],{},"私密金鑰資產隔離保護","：Agent 專屬的私密金鑰 ",[442,7150,6743],{}," 僅保存在主機的 ",[645,7153,6104],{}," 中（0600 檔案唯讀權限，不可部分完成寫入機制） — 永遠不會透過 API 端點對外暴露，也不會印至日常除錯記錄中。",[458,7156,7157,7160,7161,7164,7165,7168],{},[442,7158,7159],{},"全鏈路加密簽章驗章","：每一個入站的 Nostr 事件在投遞給 Agent 執行之前，都會嚴密執行",[442,7162,7163],{},"密碼學數位簽章檢驗","（",[645,7166,7167],{},"verifyEvent","）、訊息防重送判重、自發自收迴圈過濾以及 @提及權限驗證。",[458,7170,7171,7174,7175,7177,7178,7181],{},[442,7172,7173],{},"本地工作區指令受限保護","：由於閘道工作階段預設開啟特權自動核准機制，",[645,7176,6889],{}," 目錄註冊能力預設處於停用狀態，必須由開發者在設定檔中明確開啟（",[645,7179,7180],{},"allowWorkspace: true","），嚴防非預期提權暴露敏感目錄。",[447,7183,7185],{"id":7184},"結語擁抱-buzz-去中心化人機協同時代","結語：擁抱 Buzz 去中心化人機協同時代",[429,7187,7188,7189,7191],{},"在將 Buzz 接入 ",[645,7190,6064],{}," 的探索過程中，最大的技術挑戰在於嚴密契合 Nostr 協定的去中心化事件生命週期與事件約束規範。所幸外掛程式本身優秀的架構底座已經將多 Agent 工作階段管理與命令分發高度抽象，一旦建立起可靠的事件監聽與原位串流編輯鏈路，整個橋接閘道便能呈現出超預期的流暢度與生產級穩定性。",[447,7193,7195],{"id":7194},"參考文獻與資料","參考文獻與資料：",[455,7197,7198,7206,7214],{},[458,7199,7200,7205],{},[569,7201,7204],{"href":7202,"rel":7203},"https:\u002F\u002Fgithub.com\u002Fa792883583\u002Fdsh-message-gateway\u002Fblob\u002Fmain\u002Fdocs\u002Farchitecture.md",[1655],"dsh-message-gateway architecture guide"," — 官方閘道架構指南、擴充實踐與安全規範",[458,7207,7208,7213],{},[569,7209,7212],{"href":7210,"rel":7211},"https:\u002F\u002Fgithub.com\u002Fnbd-wtf\u002Fnostr-tools",[1655],"nostr-tools"," — 底層呼叫的核心 Nostr JavaScript 用戶端程式庫",[458,7215,7216,7221],{},[569,7217,7220],{"href":7218,"rel":7219},"https:\u002F\u002Fgithub.com\u002Fbytedance\u002Fdeer-flow\u002Fblob\u002Fmain\u002Fbackend\u002Fdocs\u002FIM_CHANNEL_CONNECTIONS.md",[1655],"deer-flow IM channel connections"," — 即時通訊平台多通道連線架構設計參考",[2640,7223,7224],{},"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":7226},[7227,7228,7232,7239,7240],{"id":6084,"depth":741,"text":6085},{"id":6196,"depth":741,"text":6197,"children":7229},[7230,7231],{"id":6493,"depth":614,"text":6494},{"id":6521,"depth":614,"text":6522},{"id":6628,"depth":741,"text":6628,"children":7233},[7234,7235,7237,7238],{"id":6750,"depth":614,"text":6751},{"id":6885,"depth":614,"text":7236},"透過 \u002Fworkspace 指令開啟本地工作區聯動",{"id":6979,"depth":614,"text":6980},{"id":7140,"depth":614,"text":7140},{"id":7184,"depth":741,"text":7185},{"id":7194,"depth":741,"text":7195},[2675,2674,2065,7242],"deepseek-harness","2026-09-30","深入解析如何透過 Nostr 協定將 DeepSeek Harness 接入 Block Buzz 協作平台：手把手配置 NIP-42 鑑權認證、基於 40003 事件的原位串流編輯輸出、頻道獨立工作階段管理與本地工作區指令聯動，為開發團隊建構安全可控、開箱即用的人機協同智能體開發環境與全新工作流程。","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002FTW-Bringing-Buzz-to-DeepSeek-Harness.webp","一張高顏值的 16:9 科技質感卡片，具有深藍色與琥珀色調，插圖展示如何為 DeepSeek Harness 接入 Block Buzz 協作平台並構建自託管 Nostr 協定閘道，中央配有高對比度毛玻璃面板與精緻正體中文排版。",{"schemaOrg":7248,"robots":2704,"sitemap":7270},[7249,7250],{"@type":2684,"headline":6046,"description":7244,"image":7245},{"@type":2686,"name":6046,"description":7244,"image":7245,"step":7251},[7252,7255,7258,7261,7264,7267],{"@type":2689,"name":7253,"text":7254},"階段一：安裝與啟動訊息閘道外掛程式","執行 dsh plugin add 命令安裝 dsh-message-gateway 並啟動 dsh web 服務。",{"@type":2689,"name":7256,"text":7257},"階段二：存取 Message platforms 設定中心","透過瀏覽器開啟 DSH Web 介面並巡覽至 Message platforms 功能表。",{"@type":2689,"name":7259,"text":7260},"階段三：設定 Buzz 橋接參數與產生金鑰對","即時產生 Nostr 身分金鑰對，準確填入 Relay URL 與訂閱頻道 UUID 清單。",{"@type":2689,"name":7262,"text":7263},"階段四：將智能體註冊加入 Buzz 中繼伺服器","使用 buzz-admin 命令列工具將 DSH 助理的 npub 公鑰加入中繼成員。",{"@type":2689,"name":7265,"text":7266},"階段五：將智能體加入指定的團隊頻道","使用 buzz-cli 命令列工具將 16 進位 HEX 公鑰加入頻道成員名單。",{"@type":2689,"name":7268,"text":7269},"階段六：開啟本地工作區綁定權限","在 cordis.patch.yml 中開啟 allowWorkspace 設定以允許目錄掛載指令。",{"lastmod":7243},{"title":7272,"description":7244,"ogTitle":6046,"ogDescription":7244,"twitterTitle":6046,"twitterDescription":7244},"DeepSeek Harness Buzz 外掛開發：構建 Nostr 協定閘道與即時串流輸出的完整教學","tw\u002Farticle\u002Fbringing-buzz-to-deepseek-harness",[6203,444,2711,7275,6064],"AI智能體","6tP_wMoFaCRxYZzuqtIt-fglvdLziQctY0T6KrEqia4",{"id":2720,"title":2721,"author":2715,"body":2722,"category":4608,"date":4610,"description":4611,"extension":2678,"image":4612,"imageAlt":4613,"isPublished":772,"meta":4614,"minRead":959,"navigation":772,"path":379,"seo":4621,"stem":4622,"tags":4623,"updatedAt":2706,"__hash__":4625},{"id":7279,"title":7280,"author":424,"body":7281,"category":7849,"date":7850,"description":7851,"extension":2678,"image":7852,"imageAlt":7853,"isPublished":772,"meta":7854,"minRead":741,"navigation":772,"path":367,"seo":7858,"stem":7860,"tags":7861,"updatedAt":2715,"__hash__":7865},"article\u002Ftw\u002Farticle\u002Fhow-ai-agent-skills-replace-nuxt-app-scaffolding-scripts.md","從傳統初始化範本腳本到智慧體：AI Agent 技能如何優雅地取代 Nuxt 應用程式的腳手架建構腳本",{"type":426,"value":7282,"toc":7842},[7283,7297,7301,7304,7400,7403,7431,7437,7441,7456,7459,7476,7480,7491,7661,7665,7748,7752,7761,7781,7788,7803,7813,7816,7822,7825,7831,7839],[429,7284,7285,7286,1124,7289,7292,7293,7296],{},"當我們使用 Nuxt 框架啟動一個新應用程式時，總是需要經歷一系列繁瑣的初始化步驟，比如安裝各種依賴模組，以及配置 ",[645,7287,7288],{},"nuxt.config.ts",[645,7290,7291],{},"wrangler.jsonc"," 等檔案。傳統的腳本固然可以解決一部分問題，但隨著專案客製化需求的增加，腳本的局限性也迅速暴露出來。這正是我們探索並嘗試用 ",[442,7294,7295],{},"AI Agent 技能 (Agent Skill)"," 取代傳統腳本的原因。",[447,7298,7300],{"id":7299},"傳統-shell-腳本擅長什麼","傳統 Shell 腳本擅長什麼",[429,7302,7303],{},"傳統的 Shell 腳本非常適合按順序執行一組固定的指令，且其中的所有決策都是在程式碼中預先寫死的 (Hardcoded)。",[664,7305,7307],{"className":666,"code":7306,"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,7308,7309,7314,7321,7325,7364,7368,7378,7382,7391],{"__ignoreMap":424},[672,7310,7311],{"class":674,"line":675},[672,7312,7313],{"class":737},"#!\u002Fusr\u002Fbin\u002Fenv bash\n",[672,7315,7316,7319],{"class":674,"line":741},[672,7317,7318],{"class":785},"set",[672,7320,1628],{"class":686},[672,7322,7323],{"class":674,"line":614},[672,7324,773],{"emptyLinePlaceholder":772},[672,7326,7327,7329,7332,7335,7337,7341,7343,7346,7349,7352,7355,7358,7361],{"class":674,"line":776},[672,7328,4111],{"class":678},[672,7330,7331],{"class":686}," nuxi@latest",[672,7333,7334],{"class":686}," init",[672,7336,683],{"class":682},[672,7338,7340],{"class":7339},"sHdIc","$1",[672,7342,690],{"class":682},[672,7344,7345],{"class":686}," --template",[672,7347,7348],{"class":686}," minimal",[672,7350,7351],{"class":686}," --packageManager",[672,7353,7354],{"class":686}," pnpm",[672,7356,7357],{"class":686}," --no-gitInit",[672,7359,7360],{"class":686}," -M",[672,7362,7363],{"class":686}," @nuxt\u002Fui,@nuxthub\u002Fcore,@vueuse\u002Fnuxt\n",[672,7365,7366],{"class":674,"line":782},[672,7367,773],{"emptyLinePlaceholder":772},[672,7369,7370,7372,7374,7376],{"class":674,"line":827},[672,7371,996],{"class":785},[672,7373,683],{"class":682},[672,7375,7340],{"class":7339},[672,7377,701],{"class":682},[672,7379,7380],{"class":674,"line":832},[672,7381,773],{"emptyLinePlaceholder":772},[672,7383,7384,7386,7389],{"class":674,"line":838},[672,7385,1004],{"class":678},[672,7387,7388],{"class":686}," ~\u002Ftemplates\u002Fnuxt.config.ts",[672,7390,1313],{"class":686},[672,7392,7393,7395,7398],{"class":674,"line":850},[672,7394,1004],{"class":678},[672,7396,7397],{"class":686}," ~\u002Ftemplates\u002Fwrangler.jsonc",[672,7399,1313],{"class":686},[429,7401,7402],{},"但在面對以下開發痛點时，這種腳本就無能為力了：",[455,7404,7405,7411,7421],{},[458,7406,7407,7410],{},[442,7408,7409],{},"固定的預設值。"," 該腳本將 Nuxt UI 模組寫死了。如果我們想換成 Ant Design UI 呢？每增加一個可選的模組，就需要使用者提供更多的命令列參數。",[458,7412,7413,7416,7417,7420],{},[442,7414,7415],{},"無法理解使用者的真實意圖。"," 「幫我建一個部落格網站」需要引入 ",[645,7418,7419],{},"@nuxt\u002Fcontent","；「幫我建一個帶訂閱電子報功能的網站」則需要 Cloudflare D1 和 Drizzle ORM。普通的 Shell 腳本根本無法識別這些細微的語意差別——針對每種細微的變體，你都必須重新寫一個腳本。",[458,7422,7423,7426,7427,7430],{},[442,7424,7425],{},"在不知不覺中悄然過時。"," Nuxt 框架在大版本迭代時，其目錄規範往往會發生顯著改變。例如 Nuxt 4 將預設的原始碼目錄更改為了 ",[645,7428,7429],{},"app\u002F","。如果你繼續執行為 Nuxt 3 編寫的腳手架腳本，它會在背景靜默地生成錯誤的目錄結構，且絕不會向使用者發出任何警報。",[429,7432,7433,7436],{},[442,7434,7435],{},"應用程式腳手架的建構","（Scaffolding）本質上是一個需要「因地制宜做出決策」的問題，而不僅僅是「按步驟執行」。當決策變數增加時，傳統的腳本機制完全無法實現規模化擴充。",[447,7438,7440],{"id":7439},"為什麼要使用-ai-agent-技能取代傳統腳本","為什麼要使用 AI Agent 技能取代傳統腳本？",[429,7442,7443,7444,7447,7448,7451,7452,7455],{},"Agent 技能 (Agent Skill) 並非只是一段死板執行的程式碼，而是一套",[442,7445,7446],{},"供 AI Agent 遵循的結構化知識庫","。它包含一個核心的 ",[645,7449,7450],{},"SKILL.md"," 指南，並可以無縫捆綁該任務所需的任何其他檔案（如參考文件、配置範本和可執行腳本）。我們在 ",[569,7453,7454],{"href":351},"什麼是 AI Agent 技能？深入探討其工作原理並手把手教你如何建構高效、可複用的Agent技能"," 一文中詳細剖析了 Agent 技能的工作原理。",[429,7457,7458],{},"Agent 技能在保留了腳本執行力度的同時，注入了腳本所匱乏的合理決策能力：",[455,7460,7461,7464,7467,7470,7473],{},[458,7462,7463],{},"能夠推斷使用者的意圖，自動評估該應用程式是否需要搭配資料庫。",[458,7465,7466],{},"根據指定的候選清單，智慧判斷並按需安裝可選模組。例如，只有在使用者明確提出相關需求時，才會選擇性（Opt-in）匯入 Nuxt Content、i18n 多語言和流量分析模組。",[458,7468,7469],{},"能夠敏銳適應當前的開發生態，使用最新的 Nuxt 框架規範、針對 Cloudflare 綁定的 NuxtHub 以及用於部署的 Wrangler 命令列工具。",[458,7471,7472],{},"具備強大的自我修復能力，能夠在某一步驟失敗時自律分析原因並重新嘗試。",[458,7474,7475],{},"在最終交付專案前，能夠嚴格按照最終檢查清單 (Checklist) 进行校驗，確保交付品質。",[447,7477,7479],{"id":7478},"我們的-nuxt-cloudflare-腳手架-agent-技能技術內幕","我們的 Nuxt & Cloudflare 腳手架 Agent 技能技術內幕",[429,7481,7482,7483,7490],{},"這個開源技能 ",[569,7484,7487],{"href":7485,"rel":7486},"https:\u002F\u002Fgithub.com\u002FTech-Voyage-Dev\u002Fscaffold-nuxt-cloudflare-app-skill",[1655],[645,7488,7489],{},"scaffold-nuxt-cloudflare-app-skill"," 包含了一整套面向生產環境的自律建構流程：",[591,7492,7493,7525,7545,7570,7600,7639,7647],{},[458,7494,7495,5045,7498],{},[442,7496,7497],{},"自動澄清無法推斷的模糊要點",[455,7499,7500,7511,7517],{},[458,7501,7502,7503,7506,7507,7510],{},"確認首選的 UI 框架（預設是 ",[442,7504,7505],{},"Nuxt UI","，也可選擇 ",[442,7508,7509],{},"Antdv Next","）；",[458,7512,7513,7514,7510],{},"確認是否需要資料庫支援（如 ",[442,7515,7516],{},"Cloudflare D1",[458,7518,7519,7520,3742,7523,599],{},"確認是否需要額外模組，例如用於建構 CMS 功能的 ",[645,7521,7522],{},"@nuxtjs\u002Fi18n",[645,7524,7419],{},[458,7526,7527,7530,7531,7534,7535,7537,7538,1124,7541,7544],{},[442,7528,7529],{},"初始化基礎應用程式框架","：執行 ",[645,7532,7533],{},"pnpm dlx nuxi@latest init"," 命令，使用 ",[645,7536,5514],{}," 套件管理器初始化最新版的 Nuxt 框架。隨後配置原生建構白名冊 (native-build allowlists)，以確保 Cloudflare 的建構環境能夠順利編譯 ",[645,7539,7540],{},"better-sqlite3",[645,7542,7543],{},"sharp"," 等原生依賴包。",[458,7546,7547,7550,7551,3742,7554,1081,7557,1081,7560,1081,7563,1081,7566,7569],{},[442,7548,7549],{},"基於決策表按需安裝模組","：自動安裝 ",[645,7552,7553],{},"@nuxt\u002Fui",[645,7555,7556],{},"@antdv-next\u002Fnuxt",[645,7558,7559],{},"@nuxt\u002Fimage",[645,7561,7562],{},"@nuxtjs\u002Fseo",[645,7564,7565],{},"@nuxthub\u002Fcore",[645,7567,7568],{},"@vueuse\u002Fnuxt","，並在選中時條件分支安裝 Drizzle\u002FD1、Nuxt Content 以及 i18n。",[458,7571,7572,5045,7575],{},[442,7573,7574],{},"科學合理的目錄結構布局",[455,7576,7577,7582,7587,7592,7597],{},[458,7578,7579,7581],{},[645,7580,7429],{}," (Nuxt 4 規範)",[458,7583,7584],{},[645,7585,7586],{},"server\u002F",[458,7588,7589],{},[645,7590,7591],{},"shared\u002F",[458,7593,7594],{},[645,7595,7596],{},"tests\u002F",[458,7598,7599],{},"根目錄下的各類標準設定檔案。",[458,7601,7602,5045,7607],{},[442,7603,7604,7605],{},"精細配置 ",[645,7606,7288],{},[455,7608,7609,7618,7625,7632],{},[458,7610,7611,7612,1124,7615],{},"為 SEO 配置 ",[645,7613,7614],{},"site.url",[645,7616,7617],{},"site.name",[458,7619,7620,7621,7624],{},"寫入用於 Cloudflare 綁定的 NuxtHub ",[645,7622,7623],{},"hub"," 配置區塊",[458,7626,7627,7628,7631],{},"自動配置 ",[645,7629,7630],{},"routeRules"," 路由與快取規則",[458,7633,7634,7635,7638],{},"寫入最新的 ",[645,7636,7637],{},"compatibilityDate"," 相容性日期",[458,7640,7641],{},[442,7642,7643,7644,7646],{},"科學生成 ",[645,7645,7291],{}," 設定檔案並進行雲端資源綁定",[458,7648,7649,7652,7653,7656,7657,7660],{},[442,7650,7651],{},"配置 Vitest 測試框架與 ESLint 程式碼規範","，隨後執行",[442,7654,7655],{},"最終校驗清單","，在背景實際執行 ",[645,7658,7659],{},"pnpm install && pnpm dev"," 進行沙箱執行測試，全部通過後方才宣告建構成功。",[447,7662,7664],{"id":7663},"傳統-shell-腳本-vs-ai-agent-技能維度對比","傳統 Shell 腳本 vs AI Agent 技能：維度對比",[6206,7666,7667,7680],{},[6209,7668,7669],{},[6212,7670,7671,7674,7677],{},[6215,7672,7673],{},"對比維度",[6215,7675,7676],{},"傳統 Shell 腳本",[6215,7678,7679],{},"AI Agent 技能",[6224,7681,7682,7693,7704,7715,7726,7737],{},[6212,7683,7684,7687,7690],{},[6229,7685,7686],{},"意圖識別能力",[6229,7688,7689],{},"❌ 行為完全寫死",[6229,7691,7692],{},"✅ 自動理解自然語言並按需適配",[6212,7694,7695,7698,7701],{},[6229,7696,7697],{},"動態決策能力",[6229,7699,7700],{},"❌ 僅限硬編碼的參數判斷",[6229,7702,7703],{},"✅ 執行時動態推敲最佳方案",[6212,7705,7706,7709,7712],{},[6229,7707,7708],{},"生态更新適應度",[6229,7710,7711],{},"❌ 需開發者手動重寫程式碼",[6229,7713,7714],{},"✅ 自動感知當前技術棧規範並適配",[6212,7716,7717,7720,7723],{},[6229,7718,7719],{},"容錯與復原機制",[6229,7721,7722],{},"❌ 一旦出錯立即中斷退出",[6229,7724,7725],{},"✅ 自動定位錯誤、自癒並繼續執行",[6212,7727,7728,7731,7734],{},[6229,7729,7730],{},"成果品質校驗",[6229,7732,7733],{},"❌ 缺乏品質校驗機制",[6229,7735,7736],{},"✅ 依托最終檢查清單進行閉環測試",[6212,7738,7739,7742,7745],{},[6229,7740,7741],{},"長期維護成本",[6229,7743,7744],{},"❌ 參數膨脹、邏輯混亂、易崩壞",[6229,7746,7747],{},"✅ 只需維護人可讀的 Markdown 設計檔案",[447,7749,7751],{"id":7750},"如何使用-npx-skills-命令行工具安裝-ai-agent-技能","如何使用 npx skills 命令行工具安裝 AI Agent 技能",[429,7753,7754,7755,7760],{},"只需一行簡單的指令，即可透過 ",[569,7756,7759],{"href":7757,"rel":7758},"https:\u002F\u002Fgithub.com\u002Fvercel-labs\u002Fskills",[1655],"skills CLI"," 工具完成該技能的無縫匯入：",[664,7762,7764],{"className":666,"code":7763,"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,7765,7766],{"__ignoreMap":424},[672,7767,7768,7770,7773,7775,7778],{"class":674,"line":675},[672,7769,4111],{"class":678},[672,7771,7772],{"class":686}," skills",[672,7774,6655],{"class":686},[672,7776,7777],{"class":686}," https:\u002F\u002Fgithub.com\u002FTech-Voyage-Dev\u002Fscaffold-nuxt-cloudflare-app-skill.git",[672,7779,7780],{"class":686}," -g\n",[429,7782,7783,7784],{},"該工具會自動克隆倉庫、定位技能檔案，並詢問您希望將此技能關聯到本地系統所支援的 77 個 Agent 中的哪一個：\n",[435,7785],{"alt":7786,"src":7787},"在終端機中執行 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,7789,7790,7791,7794,7795,7798,7799],{},"我們強烈推薦選擇 ",[442,7792,7793],{},"Symlink (符號連結)"," 方式。這種模式下，技能只需在 ",[645,7796,7797],{},"~\u002F.agents\u002Fskills"," 目錄中下載一次，所有被勾選的 Agent 都將指向這同一份原始檔案。\n",[435,7800],{"alt":7801,"src":7802},"終端機中顯示的集中式 Agent 技能安裝摘要以及軟連結 (Symlink) 路徑設定詳情","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FHow%20AI%20Agent%20Skills%20Replace%20Nuxt%20App%20Scaffolding%20Scripts\u002Fnpx-skills-installation-summary-details.webp",[455,7804,7805],{},[458,7806,7807],{},[6510,7808,7809,7810,599],{},"如果您希望深入了解如何有效避免技能碎片化並在一處集中管理它們，請參閱我們的這篇深度好文：",[569,7811,7812],{"href":359},"使用 npx skills 徹底解決不同 AI Agent（如 Claude Code 或 Kimi）技能碎片化問題",[429,7814,7815],{},"完成安裝後，打開 Claude Code 終端機，輸入內建指令即可確認該技能已成功啟用。",[429,7817,7818],{},[435,7819],{"alt":7820,"src":7821},"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,7823,7824],{},"接下來，您只需輸入一句簡單的自然語言，即可瞬間搞定複雜的工程腳手架搭建：",[7826,7827,7828],"blockquote",{},[429,7829,7830],{},"\"Scaffold a new Nuxt app deployed to Cloudflare Workers — Nuxt UI, a blog section, and a D1 database\"",[429,7832,7833,7834,7838],{},"該腳手架技能完全開源，歡迎訪問我們的 ",[569,7835,7837],{"href":7485,"rel":7836},[1655],"GitHub 倉庫"," 提交 Feedback 並上手體驗！",[2640,7840,7841],{},"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":7843},[7844,7845,7846,7847,7848],{"id":7299,"depth":741,"text":7300},{"id":7439,"depth":741,"text":7440},{"id":7478,"depth":741,"text":7479},{"id":7663,"depth":741,"text":7664},{"id":7750,"depth":741,"text":7751},[2675],"2026-08-25","輕鬆在 Cloudflare Workers 上快速建構 Nuxt 應用程式腳手架。深入剖析並學習我們如何使用功能強大、極具靈活性、能根據意圖決策且支援自我修復的 AI 智慧體技能，來徹底取代脆弱且難以維護的傳統 Shell 腳本，並詳細演示如何透過 npx skills 命令行工具將其無缝安裝到您的本地開發工作流中。","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FHow%20AI%20Agent%20Skills%20Replace%20Nuxt%20App%20Scaffolding%20Scripts\u002FTW-How-AI-Agent-Skills-Replace-Nuxt-App-Scaffolding-Scripts.webp","Nuxt 應用程式在 Cloudflare 上的腳手架建構：傳統 Shell 腳本與 AI 智慧體技能對比。分析為什麼智慧體技能優於傳統初始化腳本。",{"schemaOrg":7855,"robots":2704,"sitemap":7857},[7856],{"@type":2684,"headline":7280,"description":7851,"image":7852},{"lastmod":7850},{"title":7859,"description":7851,"ogTitle":7280,"ogDescription":7851,"twitterTitle":7280,"twitterDescription":7851},"Nuxt 應用程式在 Cloudflare 上的腳手架建構：傳統 Shell 腳本與 AI 智慧體技能對比","tw\u002Farticle\u002Fhow-ai-agent-skills-replace-nuxt-app-scaffolding-scripts",[7862,2714,7863,7864],"Nuxt","AI Agent","Scaffolding","7Hh5zal4sRkoJezAuNT3T7Bv8UlZZI9OVmJtSb0kBX4",1792490003469]