[{"data":1,"prerenderedAt":7691},["ShallowReactive",2],{"published-article-paths":3,"search-navigation":348,"\u002Fja\u002Farticle\u002Fself-hosting-buzz-as-the-workspace-where-ai-agents-become-colleagues":421,"\u002Fja\u002Farticle\u002Fself-hosting-buzz-as-the-workspace-where-ai-agents-become-colleagues-surround":2705},[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":2661,"date":2664,"description":2665,"extension":2666,"image":2667,"imageAlt":2668,"isPublished":771,"meta":2669,"minRead":849,"navigation":771,"path":195,"seo":2695,"stem":2697,"tags":2698,"updatedAt":2703,"__hash__":2704},"article\u002Fja\u002Farticle\u002Fself-hosting-buzz-as-the-workspace-where-ai-agents-become-colleagues.md","Block製Buzzを自己ホスト：人とAIエージェントが自律的に協働する次世代共有ワークスペースの構築","",{"type":426,"value":427,"toc":2631},"minimark",[428,432,439,447,452,455,495,499,505,543,547,552,566,574,582,586,591,606,612,662,701,705,714,720,724,727,967,971,1017,1023,1030,1038,1090,1096,1126,1130,1134,1154,1184,1189,1231,1240,1525,1529,1575,1580,1587,1592,1596,1620,1623,1629,1635,1639,1647,1653,1656,1662,1668,1697,1704,1710,1713,1719,1723,1726,1729,1732,1738,1741,1747,1753,1759,1764,1768,1779,1786,1792,1795,1801,1804,1811,1817,1824,1827,1835,1899,1908,1963,1966,2038,2044,2060,2066,2069,2115,2121,2124,2130,2133,2139,2143,2160,2176,2182,2280,2283,2289,2300,2349,2355,2361,2373,2389,2392,2398,2402,2409,2431,2441,2539,2551,2557,2564,2570,2573,2579,2582,2588,2591,2594,2597,2627],[429,430,431],"p",{},"複数のAIエージェントと協働する際、最も厄介な障害となるのが「文脈（コンテキスト）の断片化」です。会話が異なるツールに分散していると、最終的には人間が仲介役（ルーター）となり、Claude Codeの会話をコピーしてGemini CLIに貼り付け、さらにGemini CLIの出力をコピーしてHermes Agentに貼り付けるといった作業に追われることになります。このような手間は、人間の同僚が同じチームに加わることで、さらに増大します。",[429,433,434],{},[435,436],"img",{"alt":437,"src":438},"チャットチャンネルとアクティブなAIエージェントを表示するBuzz協働ワークスペースのユーザーインターフェース","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf-Hosting%20Buzz%20As%20The%20Workspace%20Where%20AI%20Agents%20Become%20Colleagues\u002Fbuzz-workspace-interface.webp",[429,440,441,442,446],{},"オープンソースの協働ワークスペースである",[443,444,445],"strong",{},"Buzz","は、人間のチームとAIエージェントを単一の統合された環境にシームレスに融合させます。ここでは、人間の同僚とAIエージェントが同じタスクやプロジェクトの履歴を共有し、お互いにスムーズに仕事を引き継ぐことができます。",[448,449,451],"h2",{"id":450},"blockのbuzzとは協働型aiエージェントワークスペース","Blockの「Buzz」とは？協働型AIエージェント・ワークスペース",[429,453,454],{},"Buzzは、Block（ジャック・ドーシーが率いる企業）が開発したオープンソースの協働ワークスペースであり、人間とAIエージェントが同じチャンネルやプロジェクトを共有して作業を行います。以下のような革新的な主要機能を備えています。",[456,457,458,465,471,477,483,489],"ul",{},[459,460,461,464],"li",{},[443,462,463],{},"共有コンテキスト："," 人間とエージェントはチャンネルを通じて共同作業を行います。会話やプロジェクトの全履歴はチャンネル内に集約されます。",[459,466,467,470],{},[443,468,469],{},"エージェント間通信："," エージェント同士は、異なるマシン間でさえも直接通信が可能です。あるエージェントが別のエージェントを@-メンションして仕事を引き継いだり、コードをクロスチェックしたりできます。",[459,472,473,476],{},[443,474,475],{},"メンション駆動型アクティベーション："," エージェントは@-メンションされた時のみ作動し、それ以外はバックグラウンドで待機します。メンションされると、チャンネル内の関連文脈を読み取って作業を開始します。",[459,478,479,482],{},[443,480,481],{},"統合されたアイデンティティ："," 人間とエージェントは同じアイデンティティ・システムを使用し、暗号鍵（クリプトグラフィック・キー）によって認証されます。",[459,484,485,488],{},[443,486,487],{},"コマンドの委任："," 人間の同僚に対して、自分のエージェントに命令を下す権限を付与できます。これにより、チーム全体で互いのデジタルアシスタントに指示を出し、活用し合うことが可能になります。",[459,490,491,494],{},[443,492,493],{},"セルフホスト対応："," サーバーをご自身でホストするため、データは完全に自身の管理下に置かれます。参加者の選定や運用ルールの定義も自由に行えます。",[448,496,498],{"id":497},"暗号技術とnostrに支えられたbuzzのアーキテクチャ","暗号技術とNostrに支えられたBuzzのアーキテクチャ",[429,500,501],{},[435,502],{"alt":503,"src":504},"暗号技術とNostrを搭載したBuzz協働ワークスペースのアーキテクチャ図","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf-Hosting%20Buzz%20As%20The%20Workspace%20Where%20AI%20Agents%20Become%20Colleagues\u002Fbuzz-nostr-cryptographic-architecture.webp",[456,506,507,513,519,525,531,537],{},[459,508,509,512],{},[443,510,511],{},"Nostrリレーがサーバーとして機能："," メッセージ、ワークフロー、リポジトリ、その他のイベントは暗号署名および検証され、Nostrリレーサーバーに保存されます。Nostrプロトコルは、WebSocketおよびREST APIを介した通信をネイティブにサポートしています。",[459,514,515,518],{},[443,516,517],{},"統合された暗号化アイデンティティ："," 人間とエージェントは、それぞれ独自の暗号鍵を使って認証を行います。このアイデンティティはクライアント側で管理され、サーバーに保存されることはありません。",[459,520,521,524],{},[443,522,523],{},"ファーストクラスとしてのエージェント："," すべてエージェントは、独自のアイデンティティ、チャンネルメンバーシップ、および監査証跡（オーディット・トレイル）を保持します。エージェントは、Agent Communication Protocol (ACP) を介してワークスペースに接続します。",[459,526,527,530],{},[443,528,529],{},"分散型Gitリポジトリ："," コードリポジトリはS3互換のオブジェクトストレージに保存され、タスク、プルリクエスト、コードレビューはNostrのイベントログ内で追跡されます。したがって、BuzzのGitリポジトリはGitHubではなく、Nostrリレー上でホストされます。",[459,532,533,536],{},[443,534,535],{},"NostrクライアントとしてのBuzzアプリ："," BuzzはNostrリレーとは独立しており、リレーのURLに接続するデスクトップ\u002Fモバイル用のクライアントアプリケーションです。",[459,538,539,542],{},[443,540,541],{},"インフラ構成："," PostgreSQLデータベースがイベント保存と全文検索を処理し、RedisがPub\u002FSubメッセージングを管理、S3互換のMinIOがメディアストレージとして使用されます。",[448,544,546],{"id":545},"blockのbuzzリレーをlinux-vpsに自己ホストする方法","BlockのBuzzリレーをLinux VPSに自己ホストする方法",[548,549,551],"h3",{"id":550},"_0-前提条件","0. 前提条件",[456,553,554,557,560,563],{},[459,555,556],{},"Linux VPS",[459,558,559],{},"ドメインがサーバーを指していること",[459,561,562],{},"DockerおよびDocker Composeプラグイン",[459,564,565],{},"Cloudflareアカウント（無料プラン）",[429,567,568,569,573],{},"このガイドでは、",[570,571,572],"a",{"href":363},"Cloudflare WARPでHermes Agentをプライベート ネットワークに公開する方法","を使用して、Cloudflareのプライベートネットワークの背後にあるUbuntu VPS上でNostrリレーを実行します。構成は、Docker Compose内の4つのサービス（リレー、PostgreSQL、Redis、MinIO）と、HTTPS用のCaddyです。",[575,576],"article-card",{"description":577,"image":578,"image-alt":579,"label":580,"min-read":581,"title":572,"to":363},"インバウンドのファイアウォールポートを開くことなく、Cloudflare WARPとZero Trustを使用してHermes Agentをグローバルに安全に公開し、アクセスする方法を学びます。","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FExposing%20Hermes%20Agent%20to%20Private%20Network%20Using%20Cloudflare%20WARP\u002FJA-Exposing-Hermes-Agent-to-Private-Network-Using-Cloudflare-WARP.webp","Cloudflare Zero TrustとWARPトンネルを使用してHermes Agentをプライベートネットワークに安全に公開する様子","関連ガイド","8",[548,583,585],{"id":584},"_1-cloudflare-dnsとapiトークン","1. Cloudflare DNSとAPIトークン",[587,588,590],"h4",{"id":589},"cloudflare-apiトークンの作成","Cloudflare APIトークンの作成",[592,593,594,601],"ol",{},[459,595,596,597,600],{},"右上のユーザーアイコンのドロップダウンメニューから、",[443,598,599],{},"Profile","をクリックします。",[459,602,603,600],{},[443,604,605],{},"API Tokens",[429,607,608],{},[435,609],{"alt":610,"src":611},"APIトークン作成メニューを表示するCloudflareのユーザープロファイルページ","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf-Hosting%20Buzz%20As%20The%20Workspace%20Where%20AI%20Agents%20Become%20Colleagues\u002Fcloudflare-profile-api-tokens.webp",[592,613,615,620,626,647,652,656,659],{"start":614},3,[459,616,617,600],{},[443,618,619],{},"Create Token",[459,621,622,625],{},[443,623,624],{},"Edit zone DNS","のテンプレートを使用します。",[459,627,628,629],{},"テンプレートを以下のように構成します：\n",[456,630,631,637],{},[459,632,633,636],{},[443,634,635],{},"Permissions",": Zone — DNS — Edit",[459,638,639,642,643],{},[443,640,641],{},"Zone Resources",": Include — Specific zone — ",[644,645,646],"code",{},"example.com",[459,648,649,600],{},[443,650,651],{},"Continue to summary",[459,653,654,600],{},[443,655,619],{},[459,657,658],{},"生成されたトークンはページを閉じると再表示されないため、必ずコピーしておいてください。",[459,660,661],{},"ターミナルで生成されたトークンが動作するか確認します：",[663,664,668],"pre",{"className":665,"code":666,"language":667,"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",[644,669,670],{"__ignoreMap":424},[671,672,675,679,683,687,690,693,695,698],"span",{"class":673,"line":674},"line",1,[671,676,678],{"class":677},"sBMFI","curl",[671,680,682],{"class":681},"sMK4o"," \"",[671,684,686],{"class":685},"sfazB","https:\u002F\u002Fapi.cloudflare.com\u002Fclient\u002Fv4\u002Fuser\u002Ftokens\u002Fverify",[671,688,689],{"class":681},"\"",[671,691,692],{"class":685}," -H",[671,694,682],{"class":681},[671,696,697],{"class":685},"Authorization: Bearer YOUR_TOKEN_HERE",[671,699,700],{"class":681},"\"\n",[587,702,704],{"id":703},"dnsレコード","DNSレコード",[456,706,707],{},[459,708,709,710,713],{},"Aレコードを作成し、プロキシステータスを「",[443,711,712],{},"DNS only","」（DNSのみ）に設定します。",[429,715,716],{},[435,717],{"alt":718,"src":719},"プロキシステータスをDNSのみに設定してCloudflareダッシュボードでBuzzドメインのDNS Aレコードを設定する様子","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf-Hosting%20Buzz%20As%20The%20Workspace%20Where%20AI%20Agents%20Become%20Colleagues\u002Fcloudflare-dns-a-record-configuration.webp",[548,721,723],{"id":722},"_2-ubuntuへのdockerのインストール","2. UbuntuへのDockerのインストール",[429,725,726],{},"以下のコマンドを実行して、UbuntuにDockerをインストールします：",[663,728,730],{"className":665,"code":729,"language":667,"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",[644,731,732,738,767,773,779,824,829,835,847,852,858,880,885,891,905,910,916,925,930,945,950,956],{"__ignoreMap":424},[671,733,734],{"class":673,"line":674},[671,735,737],{"class":736},"sHwdD","# Add Docker's official GPG key and set up the Docker repository\n",[671,739,741,743,746,749,752,755,758,761,764],{"class":673,"line":740},2,[671,742,678],{"class":677},[671,744,745],{"class":685}," -fsSL",[671,747,748],{"class":685}," https:\u002F\u002Fdownload.docker.com\u002Flinux\u002Fubuntu\u002Fgpg",[671,750,751],{"class":681}," |",[671,753,754],{"class":677}," sudo",[671,756,757],{"class":685}," gpg",[671,759,760],{"class":685}," --dearmor",[671,762,763],{"class":685}," -o",[671,765,766],{"class":685}," \u002Fusr\u002Fshare\u002Fkeyrings\u002Fdocker-archive-keyring.gpg\n",[671,768,769],{"class":673,"line":614},[671,770,772],{"emptyLinePlaceholder":771},true,"\n",[671,774,776],{"class":673,"line":775},4,[671,777,778],{"class":736},"# Add the official Docker repository\n",[671,780,782,786,788,791,794,797,800,803,806,808,810,812,815,818,821],{"class":673,"line":781},5,[671,783,785],{"class":784},"s2Zo4","echo",[671,787,682],{"class":681},[671,789,790],{"class":685},"deb [arch=amd64 signed-by=\u002Fusr\u002Fshare\u002Fkeyrings\u002Fdocker-archive-keyring.gpg] https:\u002F\u002Fdownload.docker.com\u002Flinux\u002Fubuntu ",[671,792,793],{"class":681},"$(",[671,795,796],{"class":677},"lsb_release",[671,798,799],{"class":685}," -cs",[671,801,802],{"class":681},")",[671,804,805],{"class":685}," stable",[671,807,689],{"class":681},[671,809,751],{"class":681},[671,811,754],{"class":677},[671,813,814],{"class":685}," tee",[671,816,817],{"class":685}," \u002Fetc\u002Fapt\u002Fsources.list.d\u002Fdocker.list",[671,819,820],{"class":681}," >",[671,822,823],{"class":685}," \u002Fdev\u002Fnull\n",[671,825,827],{"class":673,"line":826},6,[671,828,772],{"emptyLinePlaceholder":771},[671,830,832],{"class":673,"line":831},7,[671,833,834],{"class":736},"# Update package list\n",[671,836,838,841,844],{"class":673,"line":837},8,[671,839,840],{"class":677},"sudo",[671,842,843],{"class":685}," apt",[671,845,846],{"class":685}," update\n",[671,848,850],{"class":673,"line":849},9,[671,851,772],{"emptyLinePlaceholder":771},[671,853,855],{"class":673,"line":854},10,[671,856,857],{"class":736},"# Install Docker Engine, Docker Community Edition, and containerd runtime\n",[671,859,861,863,865,868,871,874,877],{"class":673,"line":860},11,[671,862,840],{"class":677},[671,864,843],{"class":685},[671,866,867],{"class":685}," install",[671,869,870],{"class":685}," docker-ce",[671,872,873],{"class":685}," docker-ce-cli",[671,875,876],{"class":685}," containerd.io",[671,878,879],{"class":685}," -y\n",[671,881,883],{"class":673,"line":882},12,[671,884,772],{"emptyLinePlaceholder":771},[671,886,888],{"class":673,"line":887},13,[671,889,890],{"class":736},"# Start automatically when the system boots\n",[671,892,894,896,899,902],{"class":673,"line":893},14,[671,895,840],{"class":677},[671,897,898],{"class":685}," systemctl",[671,900,901],{"class":685}," enable",[671,903,904],{"class":685}," docker\n",[671,906,908],{"class":673,"line":907},15,[671,909,772],{"emptyLinePlaceholder":771},[671,911,913],{"class":673,"line":912},16,[671,914,915],{"class":736},"# Verify docker is installed\n",[671,917,919,922],{"class":673,"line":918},17,[671,920,921],{"class":677},"docker",[671,923,924],{"class":685}," --version\n",[671,926,928],{"class":673,"line":927},18,[671,929,772],{"emptyLinePlaceholder":771},[671,931,933,935,937,939,942],{"class":673,"line":932},19,[671,934,840],{"class":677},[671,936,843],{"class":685},[671,938,867],{"class":685},[671,940,941],{"class":685}," -y",[671,943,944],{"class":685}," docker-compose-plugin\n",[671,946,948],{"class":673,"line":947},20,[671,949,772],{"emptyLinePlaceholder":771},[671,951,953],{"class":673,"line":952},21,[671,954,955],{"class":736},"# Verify the compose plugin is installed\n",[671,957,959,961,964],{"class":673,"line":958},22,[671,960,921],{"class":677},[671,962,963],{"class":685}," compose",[671,965,966],{"class":685}," version\n",[548,968,970],{"id":969},"_3-クローンと設定","3. クローンと設定",[663,972,974],{"className":665,"code":973,"language":667,"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",[644,975,976,987,991,999,1010],{"__ignoreMap":424},[671,977,978,981,984],{"class":673,"line":674},[671,979,980],{"class":677},"git",[671,982,983],{"class":685}," clone",[671,985,986],{"class":685}," https:\u002F\u002Fgithub.com\u002Fblock\u002Fbuzz.git\n",[671,988,989],{"class":673,"line":740},[671,990,772],{"emptyLinePlaceholder":771},[671,992,993,996],{"class":673,"line":614},[671,994,995],{"class":784},"cd",[671,997,998],{"class":685}," buzz\u002Fdeploy\u002Fcompose\n",[671,1000,1001,1004,1007],{"class":673,"line":775},[671,1002,1003],{"class":677},"cp",[671,1005,1006],{"class":685}," .env.example",[671,1008,1009],{"class":685}," .env\n",[671,1011,1012,1015],{"class":673,"line":781},[671,1013,1014],{"class":677},"nano",[671,1016,1009],{"class":685},[429,1018,1019,1022],{},[644,1020,1021],{},".env","ファイルをグループごとに編集します：",[456,1024,1025],{},[459,1026,1027],{},[443,1028,1029],{},"ドメイン設定:",[663,1031,1036],{"className":1032,"code":1034,"language":1035},[1033],"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",[644,1037,1034],{"__ignoreMap":424},[456,1039,1040,1050],{},[459,1041,1042,1045,1046,1049],{},[443,1043,1044],{},"オーナーキー設定:"," ",[644,1047,1048],{},"RELAY_OWNER_PUBKEY","には、64文字の16進数パブリックキー（公開鍵）を設定する必要があります。まずデスクトップアプリでアイデンティティを生成し（「Create a new identity key」→npub形式のパブリックIDをコピー）、それを16進数（Hex）に変換します。",[459,1051,1052,1055],{},[443,1053,1054],{},"シークレット（Secrets）の設定:",[456,1056,1057,1068,1083],{},[459,1058,1059,1063,1064,1067],{},[570,1060,1062],{"href":1061},"\u002Fja\u002Ftools\u002Fsecret-key-hex","オンラインツール","を使用するか、",[644,1065,1066],{},"openssl rand -hex 32","を実行（計7回実行）して、シークレットキーを生成します。",[459,1069,1070,1071,1074,1075,1078,1079,1082],{},"すべての",[644,1072,1073],{},"CHANGE_ME","プレースホルダーを置き換えます：",[644,1076,1077],{},"BUZZ_RELAY_PRIVATE_KEY","、",[644,1080,1081],{},"BUZZ_GIT_HOOK_HMAC_SECRET","、Postgres\u002FRedis\u002FTypesenseのパスワード、およびS3のアクセスキー\u002Fシークレットキー。",[459,1084,1085,1086,1089],{},"プレースホルダーが残っていると、コンテナが再起動ループに陥る最も一般的な原因になります。",[644,1087,1088],{},"grep CHANGE_ME .env","を実行して、変更漏れがないか確認してください。",[663,1091,1094],{"className":1092,"code":1093,"language":1035},[1033],"    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",[644,1095,1093],{"__ignoreMap":424},[456,1097,1098],{},[459,1099,1100,1103],{},[443,1101,1102],{},"その他の設定:",[456,1104,1105,1112],{},[459,1106,1107,1108,1111],{},"先ほど生成したAPIトークンを環境変数",[644,1109,1110],{},"CLOUDFLARE_API_TOKEN","として追加します。これはCaddyの自動証明書更新に必要です。",[459,1113,1114,1115,1117,1118,1121,1122,1125],{},"Buzzはデフォルトで誰でも参加できるオープンな設定になっています。安全のために",[644,1116,1048],{},"を設定し、",[644,1119,1120],{},"BUZZ_REQUIRE_RELAY_MEMBERSHIP=true","および",[644,1123,1124],{},"BUZZ_REQUIRE_AUTH_TOKEN=true","を有効にしてください。",[548,1127,1129],{"id":1128},"_4-caddyによるhttpsの有効化","4. CaddyによるHTTPSの有効化",[587,1131,1133],{"id":1132},"cloudflare-dnsモジュールを組み込んだカスタムcaddyイメージのビルド","Cloudflare DNSモジュールを組み込んだカスタムCaddyイメージのビルド",[456,1135,1136,1151],{},[459,1137,1138,1139,1142,1143,1146,1147,1150],{},"CaddyにCloudflareを用いたDNS-01チャレンジを設定します。DNS-01は、プラグインが",[443,1140,1141],{},"パブリックDNS","にTXTレコード",[644,1144,1145],{},"_acme-challenge.buzz.pafor.me","を書き込み、Let's Encryptがパブリックインターネット経由でそのレコードを確認してドメインの所有権を検証する仕組みです。そのため、",[644,1148,1149],{},"pafor.me","がCloudflareアカウント上でパブリックゾーンとして登録されている必要があります（Zero Trust\u002FWARPのプライベートDNS内だけに存在するプライベートホスト名では動作しません）。プライベートにしか解決できない場合、DNS-01は失敗し、別の証明書取得アプローチが必要になります。",[459,1152,1153],{},"Caddyfileに以下を追記します：",[663,1155,1159],{"className":1156,"code":1157,"language":1158,"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",[644,1160,1161,1166,1180],{"__ignoreMap":424},[671,1162,1163],{"class":673,"line":674},[671,1164,1165],{"class":681},"{\n",[671,1167,1168,1171,1174,1177],{"class":673,"line":740},[671,1169,1170],{"class":685},"  acme_dns cloudflare",[671,1172,1173],{"class":681}," {",[671,1175,1176],{"class":685},"env.CLOUDFLARE_API_TOKEN",[671,1178,1179],{"class":681},"}\n",[671,1181,1182],{"class":673,"line":614},[671,1183,1179],{"class":681},[456,1185,1186],{},[459,1187,1188],{},"Dockerfile.caddyを以下の内容で作成します（compose.caddy.ymlから呼び出されます）：",[663,1190,1192],{"className":1156,"code":1191,"language":1158,"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",[644,1193,1194,1199,1203,1208,1213,1217,1222,1226],{"__ignoreMap":424},[671,1195,1196],{"class":673,"line":674},[671,1197,1198],{"class":685},"FROM caddy:2-builder AS builder\n",[671,1200,1201],{"class":673,"line":740},[671,1202,772],{"emptyLinePlaceholder":771},[671,1204,1205],{"class":673,"line":614},[671,1206,1207],{"class":685},"RUN xcaddy build \\\n",[671,1209,1210],{"class":673,"line":775},[671,1211,1212],{"class":685},"    --with github.com\u002Fcaddy-dns\u002Fcloudflare\n",[671,1214,1215],{"class":673,"line":781},[671,1216,772],{"emptyLinePlaceholder":771},[671,1218,1219],{"class":673,"line":826},[671,1220,1221],{"class":685},"FROM caddy:2-alpine\n",[671,1223,1224],{"class":673,"line":831},[671,1225,772],{"emptyLinePlaceholder":771},[671,1227,1228],{"class":673,"line":837},[671,1229,1230],{"class":685},"COPY --from=builder \u002Fusr\u002Fbin\u002Fcaddy \u002Fusr\u002Fbin\u002Fcaddy\n",[456,1232,1233],{},[459,1234,1235,1236,1239],{},"Cloudflareモジュールを含むイメージを使用し、APIトークンを渡すように",[644,1237,1238],{},"compose.caddy.yml","を編集します：",[663,1241,1243],{"className":1156,"code":1242,"language":1158,"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",[644,1244,1245,1254,1261,1276,1280,1287,1294,1305,1315,1325,1332,1339,1349,1356,1366,1376,1382,1394,1405,1412,1419,1426,1433,1444,1452,1460,1465,1473,1481,1489,1500,1508,1515],{"__ignoreMap":424},[671,1246,1247,1251],{"class":673,"line":674},[671,1248,1250],{"class":1249},"swJcz","services",[671,1252,1253],{"class":681},":\n",[671,1255,1256,1259],{"class":673,"line":740},[671,1257,1258],{"class":1249},"  relay",[671,1260,1253],{"class":681},[671,1262,1263,1266,1269,1273],{"class":673,"line":614},[671,1264,1265],{"class":1249},"    ports",[671,1267,1268],{"class":681},":",[671,1270,1272],{"class":1271},"spNyl"," !reset",[671,1274,1275],{"class":681}," []\n",[671,1277,1278],{"class":673,"line":775},[671,1279,772],{"emptyLinePlaceholder":771},[671,1281,1282,1285],{"class":673,"line":781},[671,1283,1284],{"class":1249},"  caddy",[671,1286,1253],{"class":681},[671,1288,1289,1292],{"class":673,"line":826},[671,1290,1291],{"class":1249},"    build",[671,1293,1253],{"class":681},[671,1295,1296,1299,1301],{"class":673,"line":831},[671,1297,1298],{"class":1249},"      context",[671,1300,1268],{"class":681},[671,1302,1304],{"class":1303},"sbssI"," .\n",[671,1306,1307,1310,1312],{"class":673,"line":837},[671,1308,1309],{"class":1249},"      dockerfile",[671,1311,1268],{"class":681},[671,1313,1314],{"class":685}," Dockerfile.caddy\n",[671,1316,1317,1320,1322],{"class":673,"line":849},[671,1318,1319],{"class":1249},"    image",[671,1321,1268],{"class":681},[671,1323,1324],{"class":685}," buzz-caddy:cloudflare\n",[671,1326,1327,1330],{"class":673,"line":854},[671,1328,1329],{"class":1249},"    depends_on",[671,1331,1253],{"class":681},[671,1333,1334,1337],{"class":673,"line":860},[671,1335,1336],{"class":1249},"      relay",[671,1338,1253],{"class":681},[671,1340,1341,1344,1346],{"class":673,"line":882},[671,1342,1343],{"class":1249},"        condition",[671,1345,1268],{"class":681},[671,1347,1348],{"class":685}," service_healthy\n",[671,1350,1351,1354],{"class":673,"line":887},[671,1352,1353],{"class":1249},"    environment",[671,1355,1253],{"class":681},[671,1357,1358,1361,1363],{"class":673,"line":893},[671,1359,1360],{"class":1249},"      BUZZ_DOMAIN",[671,1362,1268],{"class":681},[671,1364,1365],{"class":685}," ${BUZZ_DOMAIN:?set BUZZ_DOMAIN}\n",[671,1367,1368,1371,1373],{"class":673,"line":907},[671,1369,1370],{"class":1249},"      CLOUDFLARE_API_TOKEN",[671,1372,1268],{"class":681},[671,1374,1375],{"class":685}," ${CLOUDFLARE_API_TOKEN:?set CLOUDFLARE_API_TOKEN}\n",[671,1377,1378,1380],{"class":673,"line":912},[671,1379,1265],{"class":1249},[671,1381,1253],{"class":681},[671,1383,1384,1387,1389,1392],{"class":673,"line":918},[671,1385,1386],{"class":681},"      -",[671,1388,682],{"class":681},[671,1390,1391],{"class":685},"${CADDY_HTTP_PORT:-80}:80",[671,1393,700],{"class":681},[671,1395,1396,1398,1400,1403],{"class":673,"line":927},[671,1397,1386],{"class":681},[671,1399,682],{"class":681},[671,1401,1402],{"class":685},"${CADDY_HTTPS_PORT:-443}:443",[671,1404,700],{"class":681},[671,1406,1407,1410],{"class":673,"line":932},[671,1408,1409],{"class":1249},"    volumes",[671,1411,1253],{"class":681},[671,1413,1414,1416],{"class":673,"line":947},[671,1415,1386],{"class":681},[671,1417,1418],{"class":685}," .\u002FCaddyfile:\u002Fetc\u002Fcaddy\u002FCaddyfile:ro\n",[671,1420,1421,1423],{"class":673,"line":952},[671,1422,1386],{"class":681},[671,1424,1425],{"class":685}," buzz-caddy-data:\u002Fdata\n",[671,1427,1428,1430],{"class":673,"line":958},[671,1429,1386],{"class":681},[671,1431,1432],{"class":685}," buzz-caddy-config:\u002Fconfig\n",[671,1434,1436,1439,1441],{"class":673,"line":1435},23,[671,1437,1438],{"class":1249},"    restart",[671,1440,1268],{"class":681},[671,1442,1443],{"class":685}," unless-stopped\n",[671,1445,1447,1450],{"class":673,"line":1446},24,[671,1448,1449],{"class":1249},"    networks",[671,1451,1253],{"class":681},[671,1453,1455,1457],{"class":673,"line":1454},25,[671,1456,1386],{"class":681},[671,1458,1459],{"class":685}," buzz-net\n",[671,1461,1463],{"class":673,"line":1462},26,[671,1464,772],{"emptyLinePlaceholder":771},[671,1466,1468,1471],{"class":673,"line":1467},27,[671,1469,1470],{"class":1249},"volumes",[671,1472,1253],{"class":681},[671,1474,1476,1479],{"class":673,"line":1475},28,[671,1477,1478],{"class":1249},"  buzz-caddy-data",[671,1480,1253],{"class":681},[671,1482,1484,1487],{"class":673,"line":1483},29,[671,1485,1486],{"class":1249},"    labels",[671,1488,1253],{"class":681},[671,1490,1492,1495,1497],{"class":673,"line":1491},30,[671,1493,1494],{"class":1249},"      com.buzz.volume",[671,1496,1268],{"class":681},[671,1498,1499],{"class":685}," caddy-data\n",[671,1501,1503,1506],{"class":673,"line":1502},31,[671,1504,1505],{"class":1249},"  buzz-caddy-config",[671,1507,1253],{"class":681},[671,1509,1511,1513],{"class":673,"line":1510},32,[671,1512,1486],{"class":1249},[671,1514,1253],{"class":681},[671,1516,1518,1520,1522],{"class":673,"line":1517},33,[671,1519,1494],{"class":1249},[671,1521,1268],{"class":681},[671,1523,1524],{"class":685}," caddy-config\n",[587,1526,1528],{"id":1527},"dockerコンテナの起動","Dockerコンテナの起動",[663,1530,1532],{"className":665,"code":1531,"language":667,"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",[644,1533,1534,1557,1561,1566],{"__ignoreMap":424},[671,1535,1536,1538,1540,1543,1546,1548,1551,1554],{"class":673,"line":674},[671,1537,921],{"class":677},[671,1539,963],{"class":685},[671,1541,1542],{"class":685}," -f",[671,1544,1545],{"class":685}," compose.yml",[671,1547,1542],{"class":685},[671,1549,1550],{"class":685}," compose.caddy.yml",[671,1552,1553],{"class":685}," up",[671,1555,1556],{"class":685}," -d\n",[671,1558,1559],{"class":673,"line":740},[671,1560,772],{"emptyLinePlaceholder":771},[671,1562,1563],{"class":673,"line":614},[671,1564,1565],{"class":736},"#Check the Docker status\n",[671,1567,1568,1570,1572],{"class":673,"line":775},[671,1569,921],{"class":677},[671,1571,963],{"class":685},[671,1573,1574],{"class":685}," ps\n",[435,1576],{"src":1577,"alt":1578,"style":1579},"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,1581,1582,1583,1586],{},"ブラウザを開き、",[644,1584,1585],{},"http:\u002F\u002Fbuzz.pafor.me","にアクセスしてリレーが正常に稼働しているか確認します。",[435,1588],{"src":1589,"alt":1590,"style":1591},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf-Hosting%20Buzz%20As%20The%20Workspace%20Where%20AI%20Agents%20Become%20Colleagues\u002Fbuzz-relay-running-browser-verification.webp","自己ホストしたBlockのBuzzリレーからの正常な応答を表示するブラウザの検証画面","max-width: 500px; width: 100%; height: auto;",[548,1593,1595],{"id":1594},"ステップ-5初日からの自動バックアップ設定","ステップ 5：初日からの自動バックアップ設定",[663,1597,1599],{"className":665,"code":1598,"language":667,"meta":424,"style":424},"mkdir -p \u002Fbuzz_backups\ncrontab -e\n",[644,1600,1601,1612],{"__ignoreMap":424},[671,1602,1603,1606,1609],{"class":673,"line":674},[671,1604,1605],{"class":677},"mkdir",[671,1607,1608],{"class":685}," -p",[671,1610,1611],{"class":685}," \u002Fbuzz_backups\n",[671,1613,1614,1617],{"class":673,"line":740},[671,1615,1616],{"class":677},"crontab",[671,1618,1619],{"class":685}," -e\n",[429,1621,1622],{},"毎晩データベースのダンプを出力するcronジョブを設定します：",[663,1624,1627],{"className":1625,"code":1626,"language":1035},[1033],"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",[644,1628,1626],{"__ignoreMap":424},[429,1630,1631,1632,1634],{},"注意：",[644,1633,1077],{},"は恒久的なものとして厳重に管理してください。このキーで署名されたイベントは、キーが変更されると検証に失敗します。データベースをリストアしても、新しい鍵と組み合わせた場合は同じリレーとして認識されません。",[448,1636,1638],{"id":1637},"buzzデスクトップクライアントとnostrアイデンティティのセットアップ","BuzzデスクトップクライアントとNostrアイデンティティのセットアップ",[429,1640,1641,1646],{},[570,1642,1643],{"href":1643,"rel":1644},"https:\u002F\u002Fgithub.com\u002Fblock\u002Fbuzz\u002Freleases",[1645],"nofollow"," からBuzzデスクトップアプリをダウンロードして起動します。プロファイルの設定を進め、「Join or create a community」のページまで進みます。",[429,1648,1649],{},[435,1650],{"alt":1651,"src":1652},"コミュニティへの参加または作成を行う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,1654,1655],{},"「Join a community」をクリックし、ご自身のパブリックキー（公開鍵）をコピーします。",[429,1657,1658],{},[435,1659],{"alt":1660,"src":1661},"コミュニティに参加する前に公開鍵アイデンティティを表示する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,1663,1664,1667],{},[443,1665,1666],{},"VPS上","で以下のコマンドを実行し、自身を最初のメンバーとして追加します：",[663,1669,1671],{"className":665,"code":1670,"language":667,"meta":424,"style":424},"docker compose exec relay buzz-admin add-member --pubkey npub1yourkeyhere\n",[644,1672,1673],{"__ignoreMap":424},[671,1674,1675,1677,1679,1682,1685,1688,1691,1694],{"class":673,"line":674},[671,1676,921],{"class":677},[671,1678,963],{"class":685},[671,1680,1681],{"class":685}," exec",[671,1683,1684],{"class":685}," relay",[671,1686,1687],{"class":685}," buzz-admin",[671,1689,1690],{"class":685}," add-member",[671,1692,1693],{"class":685}," --pubkey",[671,1695,1696],{"class":685}," npub1yourkeyhere\n",[429,1698,1699,1700,1703],{},"コミュニティURLに",[644,1701,1702],{},"wss:\u002F\u002Fbuzz.pafor.me","を入力し、「Next」をクリックします。",[429,1705,1706],{},[435,1707],{"alt":1708,"src":1709},"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,1711,1712],{},"表示名を入力し、「Next」ボタンをクリックします。",[429,1714,1715],{},[435,1716],{"alt":1717,"src":1718},"表示名を入力する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",[548,1720,1722],{"id":1721},"チャンネルとaiエージェント","チャンネルとAIエージェント",[429,1724,1725],{},"チャンネルはタスクやプロジェクトごとのグループです。タスクごとにチャンネルを作成し、人間とAIエージェントをそこに参加させます。",[429,1727,1728],{},"チャンネル内のすべてのアクティビティは自動的に共有されるため、各メンバーに個別に指示を繰り返す必要はありません。すべてのエージェントは「@」を使ってメンションでき、該当のメッセージ履歴を読み込みます。また、エージェント同士が互いにメンションし合うことも可能です。",[429,1730,1731],{},"事前に設定されたエージェントにダイレクトメッセージ（DM）を送信してみましょう",[429,1733,1734],{},[435,1735],{"alt":1736,"src":1737},"Buzz協働デスクトップクライアントでAIエージェントにダイレクトメッセージを送信する様子","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf-Hosting%20Buzz%20As%20The%20Workspace%20Where%20AI%20Agents%20Become%20Colleagues\u002Fbuzz-desktop-client-dm-agent.webp",[429,1739,1740],{},"チャンネルを作成し、いくつかのエージェントを追加してみましょう",[429,1742,1743],{},[435,1744],{"alt":1745,"src":1746},"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,1748,1749],{},[435,1750],{"alt":1751,"src":1752},"新しく作成したチャンネルに人間のメンバーと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,1754,1755],{},[435,1756],{"alt":1757,"src":1758},"統合されたチャット履歴とプロジェクトタスクを表示するアクティブなチャンネル画面","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf-Hosting%20Buzz%20As%20The%20Workspace%20Where%20AI%20Agents%20Become%20Colleagues\u002Fbuzz-desktop-client-channel-view.webp",[435,1760],{"src":1761,"alt":1762,"style":1763},"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;",[548,1765,1767],{"id":1766},"エージェントランタイムの有効化","エージェント・ランタイムの有効化",[429,1769,1770,1771,1774,1775,1778],{},"プリセットされたランタイムは、",[644,1772,1773],{},"~\u002F.local\u002Fbin","などの標準ディレクトリにある起動用バイナリ（例：",[644,1776,1777],{},"hermes-acp","）の自動検出に依存しています。非標準の場所にツールがインストールされている場合、Buzzはそれを検出できません。",[429,1780,1781,1782,1785],{},"Kimi Codeの場合、エージェントIDはkimiであり、Buzzは",[644,1783,1784],{},"~\u002F.local\u002Fbin\u002Fkimi","にあるバイナリを探します。以下のようにシンボリックリンクを作成することで解決できます。",[663,1787,1790],{"className":1788,"code":1789,"language":1035},[1033],"ln -s kimi-cli \u002FUsers\u002F\u003Cuser>\u002F.local\u002Fbin\u002Fkimi\n",[644,1791,1789],{"__ignoreMap":424},[429,1793,1794],{},"これにより、Kimi Codeがエージェントのランタイム一覧に表示されます。",[429,1796,1797],{},[435,1798],{"alt":1799,"src":1800},"Kimiを含む設定済みのAIエージェントランタイムを表示するBuzzアプリの設定画面","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf-Hosting%20Buzz%20As%20The%20Workspace%20Where%20AI%20Agents%20Become%20Colleagues\u002Fbuzz-settings-agent-runtimes-list.webp",[548,1802,1803],{"id":1803},"プロジェクトとリポジトリ",[429,1805,1806,1807,1810],{},"まず、Settings → Experimentsで「",[443,1808,1809],{},"Projects","」機能を有効化します：",[429,1812,1813],{},[435,1814],{"alt":1815,"src":1816},"Buzzの設定タブで実験的機能である「Projects」を有効にする様子","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf-Hosting%20Buzz%20As%20The%20Workspace%20Where%20AI%20Agents%20Become%20Colleagues\u002Fbuzz-settings-experiments-projects.webp",[429,1818,1819,1820,1823],{},"現時点では、プロジェクトの作成は",[644,1821,1822],{},"buzz-cli","を介して行う必要があります（将来のリリースではUIから直接作成可能になる予定です）。",[587,1825,1826],{"id":1826},"buzz-cliのインストール",[429,1828,1829,1831,1832,1834],{},[443,1830,1666],{},"で以下のコマンドを実行し、",[644,1833,1822],{},"をインストールします：",[663,1836,1838],{"className":665,"code":1837,"language":667,"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",[644,1839,1840,1851,1858,1871],{"__ignoreMap":424},[671,1841,1842,1844,1846,1848],{"class":673,"line":674},[671,1843,840],{"class":677},[671,1845,843],{"class":685},[671,1847,867],{"class":685},[671,1849,1850],{"class":685}," cargo\n",[671,1852,1853,1855],{"class":673,"line":740},[671,1854,995],{"class":784},[671,1856,1857],{"class":685}," ~\u002Fbuzz\n",[671,1859,1860,1863,1865,1868],{"class":673,"line":614},[671,1861,1862],{"class":677},"cargo",[671,1864,867],{"class":685},[671,1866,1867],{"class":685}," --path",[671,1869,1870],{"class":685}," crates\u002Fbuzz-cli\n",[671,1872,1873,1875,1878,1881,1884,1887,1890,1893,1896],{"class":673,"line":775},[671,1874,785],{"class":784},[671,1876,1877],{"class":681}," '",[671,1879,1880],{"class":685},"export PATH=\"$HOME\u002F.cargo\u002Fbin:$PATH\"",[671,1882,1883],{"class":681},"'",[671,1885,1886],{"class":681}," >>",[671,1888,1889],{"class":685}," ~\u002F.bashrc",[671,1891,1892],{"class":681}," &&",[671,1894,1895],{"class":784}," source",[671,1897,1898],{"class":685}," ~\u002F.bashrc\n",[429,1900,1901,1902,1904,1905,1907],{},"オンラインツールまたは",[644,1903,1822],{},"を使用して公開鍵と秘密鍵のペアを生成します。このペアは、Nostrリレーにおける",[644,1906,1822],{},"のアイデンティティとなります。",[663,1909,1911],{"className":665,"code":1910,"language":667,"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",[644,1912,1913,1935,1939,1944],{"__ignoreMap":424},[671,1914,1915,1917,1920,1923,1926,1929,1932],{"class":673,"line":674},[671,1916,921],{"class":677},[671,1918,1919],{"class":685}," run",[671,1921,1922],{"class":685}," --rm",[671,1924,1925],{"class":685}," --entrypoint",[671,1927,1928],{"class":685}," \u002Fusr\u002Flocal\u002Fbin\u002Fbuzz-admin",[671,1930,1931],{"class":685}," ghcr.io\u002Fblock\u002Fbuzz:main",[671,1933,1934],{"class":685}," generate-key\n",[671,1936,1937],{"class":673,"line":740},[671,1938,772],{"emptyLinePlaceholder":771},[671,1940,1941],{"class":673,"line":614},[671,1942,1943],{"class":736},"# Use the generated Public Key\n",[671,1945,1946,1948,1950,1952,1954,1956,1958,1960],{"class":673,"line":775},[671,1947,921],{"class":677},[671,1949,963],{"class":685},[671,1951,1681],{"class":685},[671,1953,1684],{"class":685},[671,1955,1687],{"class":685},[671,1957,1690],{"class":685},[671,1959,1693],{"class":685},[671,1961,1962],{"class":685}," generated_Public_key\n",[429,1964,1965],{},"CLIの設定を行います：",[663,1967,1969],{"className":665,"code":1968,"language":667,"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",[644,1970,1971,1976,2009,2013],{"__ignoreMap":424},[671,1972,1973],{"class":673,"line":674},[671,1974,1975],{"class":736},"# Copy the Secret key as the BUZZ_PRIVATE_KEY\n",[671,1977,1978,1980,1982,1985,1987,1990,1993,1996,1999,2003,2006],{"class":673,"line":740},[671,1979,785],{"class":784},[671,1981,1877],{"class":681},[671,1983,1984],{"class":685},"export BUZZ_PRIVATE_KEY=\"nsec1...\"",[671,1986,1883],{"class":681},[671,1988,1989],{"class":681},"  >>",[671,1991,1992],{"class":685}," \u002Fhome\u002F",[671,1994,1995],{"class":681},"\u003C",[671,1997,1998],{"class":685},"use",[671,2000,2002],{"class":2001},"sTEyZ","r",[671,2004,2005],{"class":681},">",[671,2007,2008],{"class":685},"\u002F.bashrc\n",[671,2010,2011],{"class":673,"line":614},[671,2012,772],{"emptyLinePlaceholder":771},[671,2014,2015,2017,2019,2022,2024,2026,2028,2030,2032,2034,2036],{"class":673,"line":775},[671,2016,785],{"class":784},[671,2018,1877],{"class":681},[671,2020,2021],{"class":685},"export BUZZ_RELAY_URL=\"wss:\u002F\u002Fbuzz.pafor.me\"",[671,2023,1883],{"class":681},[671,2025,1989],{"class":681},[671,2027,1992],{"class":685},[671,2029,1995],{"class":681},[671,2031,1998],{"class":685},[671,2033,2002],{"class":2001},[671,2035,2005],{"class":681},[671,2037,2008],{"class":685},[429,2039,2040,2041,2043],{},"以下のコマンドを実行して、",[644,2042,1822],{},"が正常に設定されているか確認します：",[663,2045,2047],{"className":665,"code":2046,"language":667,"meta":424,"style":424},"buzz channels list\n",[644,2048,2049],{"__ignoreMap":424},[671,2050,2051,2054,2057],{"class":673,"line":674},[671,2052,2053],{"class":677},"buzz",[671,2055,2056],{"class":685}," channels",[671,2058,2059],{"class":685}," list\n",[429,2061,2062],{},[435,2063],{"alt":2064,"src":2065},"アクティブなチャンネルを一覧表示して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",[587,2067,2068],{"id":2068},"buzz-cliによるプロジェクト作成",[663,2070,2072],{"className":665,"code":2071,"language":667,"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",[644,2073,2074,2079],{"__ignoreMap":424},[671,2075,2076],{"class":673,"line":674},[671,2077,2078],{"class":736},"# --channel refers to the UUID of the channel\n",[671,2080,2081,2083,2086,2089,2092,2095,2098,2100,2103,2105,2108,2110,2113],{"class":673,"line":740},[671,2082,2053],{"class":677},[671,2084,2085],{"class":685}," repos",[671,2087,2088],{"class":685}," create",[671,2090,2091],{"class":685}," --id",[671,2093,2094],{"class":685}," TestKOA",[671,2096,2097],{"class":685}," --name",[671,2099,1877],{"class":681},[671,2101,2102],{"class":685},"Display Name",[671,2104,1883],{"class":681},[671,2106,2107],{"class":685}," --channel",[671,2109,682],{"class":681},[671,2111,2112],{"class":685},"bd92b3d1-8fac-441c-a9ac-2b2f3aac5c5b",[671,2114,700],{"class":681},[429,2116,2117,2118,2120],{},"プロジェクトは作成者（オーナー）しか削除できません。",[644,2119,1822],{},"で作成された「Display Name」プロジェクトは、現在のCLIに削除コマンドが実装されていないため、この方法では削除できません。",[429,2122,2123],{},"Buzzデスクトップアプリに戻り、プロジェクトが作成されていることを確認します。",[429,2125,2126],{},[435,2127],{"alt":2128,"src":2129},"プロジェクトの正常な作成を確認する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,2131,2132],{},"リポジトリがProjectsビューに追加されると、それ以降はUI右上隅の「+」ボタンから簡単にリポジトリを追加できるようになります。",[429,2134,2135],{},[435,2136],{"alt":2137,"src":2138},"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",[587,2140,2142],{"id":2141},"既存のgitリポジトリの登録","既存のGitリポジトリの登録",[429,2144,2145,2146,2149,2150,2153,2154,2159],{},"Gitリポジトリが存在するマシンに",[644,2147,2148],{},"git-credential-nostr","をインストールします。これには",[443,2151,2152],{},"Git 2.46以上","とRustのビルド環境（toolchain）が必要です。詳細についてはこちらの",[570,2155,2158],{"href":2156,"rel":2157},"https:\u002F\u002Fgithub.com\u002Fblock\u002Fbuzz\u002Ftree\u002Fmain\u002Fcrates\u002Fgit-credential-nostr",[1645],"Readme","を参照してください。",[663,2161,2163],{"className":665,"code":2162,"language":667,"meta":424,"style":424},"cargo install --path crates\u002Fgit-credential-nostr\n",[644,2164,2165],{"__ignoreMap":424},[671,2166,2167,2169,2171,2173],{"class":673,"line":674},[671,2168,1862],{"class":677},[671,2170,867],{"class":685},[671,2172,1867],{"class":685},[671,2174,2175],{"class":685}," crates\u002Fgit-credential-nostr\n",[429,2177,2178,2179,2181],{},"Buzzリレーでの認証用に",[644,2180,2148],{},"を設定します：",[663,2183,2185],{"className":665,"code":2184,"language":667,"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",[644,2186,2187,2192,2208,2222,2226,2231,2240,2267],{"__ignoreMap":424},[671,2188,2189],{"class":673,"line":674},[671,2190,2191],{"class":736},"# 1. Register the helper and enable per-path credentials.\n",[671,2193,2194,2196,2199,2202,2205],{"class":673,"line":740},[671,2195,980],{"class":677},[671,2197,2198],{"class":685}," config",[671,2200,2201],{"class":685}," --global",[671,2203,2204],{"class":685}," credential.helper",[671,2206,2207],{"class":685}," nostr\n",[671,2209,2210,2212,2214,2216,2219],{"class":673,"line":614},[671,2211,980],{"class":677},[671,2213,2198],{"class":685},[671,2215,2201],{"class":685},[671,2217,2218],{"class":685}," credential.useHttpPath",[671,2220,2221],{"class":681}," true\n",[671,2223,2224],{"class":673,"line":775},[671,2225,772],{"emptyLinePlaceholder":771},[671,2227,2228],{"class":673,"line":781},[671,2229,2230],{"class":736},"# 2. Store your nsec in a key file (must be 0600). Replace \"nsec1...\" with your private key\n",[671,2232,2233,2235,2237],{"class":673,"line":826},[671,2234,1605],{"class":677},[671,2236,1608],{"class":685},[671,2238,2239],{"class":685}," ~\u002F.nostr\n",[671,2241,2242,2244,2246,2249,2251,2253,2256,2258,2261,2264],{"class":673,"line":831},[671,2243,785],{"class":784},[671,2245,682],{"class":681},[671,2247,2248],{"class":685},"nsec1...",[671,2250,689],{"class":681},[671,2252,820],{"class":681},[671,2254,2255],{"class":685}," ~\u002F.nostr\u002Fkey",[671,2257,1892],{"class":681},[671,2259,2260],{"class":677}," chmod",[671,2262,2263],{"class":1303}," 600",[671,2265,2266],{"class":685}," ~\u002F.nostr\u002Fkey\n",[671,2268,2269,2271,2273,2275,2278],{"class":673,"line":837},[671,2270,980],{"class":677},[671,2272,2198],{"class":685},[671,2274,2201],{"class":685},[671,2276,2277],{"class":685}," nostr.keyfile",[671,2279,2266],{"class":685},[429,2281,2282],{},"Buzzリレー上にリポジトリを作成します：",[663,2284,2287],{"className":2285,"code":2286,"language":1035},[1033],"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",[644,2288,2286],{"__ignoreMap":424},[429,2290,2291,2292,2295,2296,2299],{},"最初の",[644,2293,2294],{},"git push","時に、",[644,2297,2298],{},"remote: missing Authorization header","（認証ヘッダー不足）のエラーが発生します。これを解決するには、リポジトリIDをBuzzのチャンネルに関連付ける（バインドする）必要があります。チャンネルのメンバーシップに基づいてGitの書き込み権限（ACL）が制御されるためです。",[663,2301,2303],{"className":665,"code":2302,"language":667,"meta":424,"style":424},"buzz repos bind --id koa-email-routing --channel \u003CCHANNEL_UUID>\n\n# push the code again\ngit push\n",[644,2304,2305,2333,2337,2342],{"__ignoreMap":424},[671,2306,2307,2309,2311,2314,2316,2319,2321,2324,2327,2330],{"class":673,"line":674},[671,2308,2053],{"class":677},[671,2310,2085],{"class":685},[671,2312,2313],{"class":685}," bind",[671,2315,2091],{"class":685},[671,2317,2318],{"class":685}," koa-email-routing",[671,2320,2107],{"class":685},[671,2322,2323],{"class":681}," \u003C",[671,2325,2326],{"class":685},"CHANNEL_UUI",[671,2328,2329],{"class":2001},"D",[671,2331,2332],{"class":681},">\n",[671,2334,2335],{"class":673,"line":740},[671,2336,772],{"emptyLinePlaceholder":771},[671,2338,2339],{"class":673,"line":614},[671,2340,2341],{"class":736},"# push the code again\n",[671,2343,2344,2346],{"class":673,"line":775},[671,2345,980],{"class":677},[671,2347,2348],{"class":685}," push\n",[429,2350,2351,2352,2354],{},"Buzzデスクトップアプリでプロジェクトを確認した際、以下のようにGitの読み込みに失敗する場合があります。これはデスクトップアプリが",[443,2353,2152],{},"を要求するためであり、アプリを直接起動した際に古いバージョンのGitが検出されていることが原因です。",[429,2356,2357],{},[435,2358],{"alt":2359,"src":2360},"ローカルのGitバージョンが2.46未満であるためにBuzzクライアントで発生した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,2362,2363,2364,2367,2368,2159],{},"シェルの設定ファイル等で、",[644,2365,2366],{},"launchctl setenv PATH \"\u002Fopt\u002Fhomebrew\u002Fbin:\u002Fusr\u002Flocal\u002Fbin:\u002Fusr\u002Fbin:\u002Fbin:\u002Fusr\u002Fsbin:\u002Fsbin\"","のようにPATH環境変数をエクスポートし、シェル経由でBuzzアプリを起動してください。詳細についてはこちらの",[570,2369,2372],{"href":2370,"rel":2371},"https:\u002F\u002Fgithub.com\u002Fblock\u002Fbuzz\u002Fissues\u002F5348",[1645],"Issue",[663,2374,2376],{"className":665,"code":2375,"language":667,"meta":424,"style":424},"open -a Buzz\n",[644,2377,2378],{"__ignoreMap":424},[671,2379,2380,2383,2386],{"class":673,"line":674},[671,2381,2382],{"class":677},"open",[671,2384,2385],{"class":685}," -a",[671,2387,2388],{"class":685}," Buzz\n",[429,2390,2391],{},"Buzzアプリで「Projects」を再度確認すると、無事にリポジトリの詳細が読み込まれているはずです。",[429,2393,2394],{},[435,2395],{"alt":2396,"src":2397},"Gitリポジトリの詳細とコミットログが正常に読み込まれた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",[448,2399,2401],{"id":2400},"qrコードによるbuzzモバイルアプリとの同期","QRコードによるBuzzモバイルアプリとの同期",[429,2403,2404,2405,2408],{},"BuzzモバイルアプリとのペアリングはHTTPSプロトコルのみを受け付けます。また、VPS上ではデフォルトで",[644,2406,2407],{},"buzz-pair-relay","が起動していません。",[663,2410,2412],{"className":665,"code":2411,"language":667,"meta":424,"style":424},"cd ~\u002Fbuzz\ncargo install --path crates\u002Fbuzz-pair-relay\n",[644,2413,2414,2420],{"__ignoreMap":424},[671,2415,2416,2418],{"class":673,"line":674},[671,2417,995],{"class":784},[671,2419,1857],{"class":685},[671,2421,2422,2424,2426,2428],{"class":673,"line":740},[671,2423,1862],{"class":677},[671,2425,867],{"class":685},[671,2427,1867],{"class":685},[671,2429,2430],{"class":685}," crates\u002Fbuzz-pair-relay\n",[429,2432,2433,2434,2437,2438,2440],{},"以下を",[644,2435,2436],{},"compose.yml","に追加し、",[644,2439,2407],{},"サービスを定義します：",[663,2442,2444],{"className":1156,"code":2443,"language":1158,"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",[644,2445,2446,2453,2462,2482,2488,2498,2504,2515,2523,2529],{"__ignoreMap":424},[671,2447,2448,2451],{"class":673,"line":674},[671,2449,2450],{"class":1249},"  pair",[671,2452,1253],{"class":681},[671,2454,2455,2457,2459],{"class":673,"line":740},[671,2456,1319],{"class":1249},[671,2458,1268],{"class":681},[671,2460,2461],{"class":685}," ${BUZZ_IMAGE:-ghcr.io\u002Fblock\u002Fbuzz:main}\n",[671,2463,2464,2467,2469,2472,2474,2477,2479],{"class":673,"line":614},[671,2465,2466],{"class":1249},"    entrypoint",[671,2468,1268],{"class":681},[671,2470,2471],{"class":681}," [",[671,2473,689],{"class":681},[671,2475,2476],{"class":685},"\u002Fusr\u002Flocal\u002Fbin\u002Fbuzz-pair-relay",[671,2478,689],{"class":681},[671,2480,2481],{"class":681},"]\n",[671,2483,2484,2486],{"class":673,"line":775},[671,2485,1353],{"class":1249},[671,2487,1253],{"class":681},[671,2489,2490,2493,2495],{"class":673,"line":781},[671,2491,2492],{"class":1249},"      BUZZ_PAIR_RELAY_BIND_ADDR",[671,2494,1268],{"class":681},[671,2496,2497],{"class":685}," 0.0.0.0:5000\n",[671,2499,2500,2502],{"class":673,"line":826},[671,2501,1265],{"class":1249},[671,2503,1253],{"class":681},[671,2505,2506,2508,2510,2513],{"class":673,"line":831},[671,2507,1386],{"class":681},[671,2509,682],{"class":681},[671,2511,2512],{"class":685},"${BUZZ_PAIR_RELAY_PORT:-5000}:5000",[671,2514,700],{"class":681},[671,2516,2517,2519,2521],{"class":673,"line":837},[671,2518,1438],{"class":1249},[671,2520,1268],{"class":681},[671,2522,1443],{"class":685},[671,2524,2525,2527],{"class":673,"line":849},[671,2526,1449],{"class":1249},[671,2528,1253],{"class":681},[671,2530,2531,2534,2537],{"class":673,"line":854},[671,2532,2533],{"class":681},"      [",[671,2535,2536],{"class":685},"buzz-net",[671,2538,2481],{"class":681},[429,2540,2541,2543,2544,1121,2547,2550],{},[644,2542,1021],{},"ファイルに",[644,2545,2546],{},"BUZZ_PAIRING_RELAY_URL",[644,2548,2549],{},"BUZZ_PAIR_RELAY_PORT","を追記します：",[663,2552,2555],{"className":2553,"code":2554,"language":1035},[1033],"BUZZ_PAIRING_RELAY_URL=wss:\u002F\u002Fbuzz.pafor.me\u002Fpair\nBUZZ_PAIR_RELAY_PORT=5000\n",[644,2556,2554],{"__ignoreMap":424},[429,2558,2559,2560,2563],{},"Buzzデスクトップの「Settings」から「",[443,2561,2562],{},"Mobile","」を開きます：",[429,2565,2566],{},[435,2567],{"alt":2568,"src":2569},"モバイルデバイスの設定タブを表示するBuzzアプリの設定ダイアログ","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf-Hosting%20Buzz%20As%20The%20Workspace%20Where%20AI%20Agents%20Become%20Colleagues\u002Fbuzz-settings-mobile-tab.webp",[429,2571,2572],{},"「Start pairing」をクリックするとQRコードが生成されます。モバイルデバイスのBuzzアプリでこのQRコードをスキャンし、「Code Match」をクリックするとペアリングが完了します。",[429,2574,2575],{},[435,2576],{"alt":2577,"src":2578},"Buzzモバイルアプリとの同期用にデスクトップクライアントで安全なペアリングQRコードを生成する様子","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,2580,2581],{},"モバイルアプリ上のエージェントは、デスクトップアプリ側で対応するエージェントが稼働している場合のみ利用可能です。エージェントを動作させるには、デスクトップマシンを起動しておく必要があります。",[429,2583,2584],{},[435,2585],{"alt":2586,"src":2587},"同期されたアクティブなAIアシスタントエージェントを表示するBuzzモバイルアプリ画面","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf-Hosting%20Buzz%20As%20The%20Workspace%20Where%20AI%20Agents%20Become%20Colleagues\u002Fbuzz-mobile-app-active-agents.webp",[448,2589,2590],{"id":2590},"おわりに",[429,2592,2593],{},"BuzzはいくつかのバグやUIの制限があり、大規模な本番環境への導入には時期尚早ですが、少人数のチームや個人の開発者にとっては非常に刺激的なツールです。人間とAIが真に同僚として協働する、自律的な「AIネイティブ」な未来のワークスペースをいち早く体験することができます。",[448,2595,2596],{"id":2596},"参考資料",[456,2598,2599,2606,2613,2620],{},[459,2600,2601],{},[570,2602,2605],{"href":2603,"rel":2604},"https:\u002F\u002Fgithub.com\u002Fblock\u002Fbuzz",[1645],"Buzz releases",[459,2607,2608],{},[570,2609,2612],{"href":2610,"rel":2611},"https:\u002F\u002Fblock.xyz\u002Finside\u002Fintroducing-buzz-where-humans-and-agents-work-together",[1645],"Introducing Buzz",[459,2614,2615],{},[570,2616,2619],{"href":2617,"rel":2618},"https:\u002F\u002Fwww.hostinger.com\u002Ftutorials\u002Fwhat-is-buzz",[1645],"What is buzz",[459,2621,2622],{},[570,2623,2626],{"href":2624,"rel":2625},"https:\u002F\u002Fmiget.com\u002Fblog\u002Fhow-to-self-host-buzz",[1645],"How to self-host Buzz (Miget)",[2628,2629,2630],"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":740,"depth":614,"links":2632},[2633,2634,2635,2649,2658,2659,2660],{"id":450,"depth":740,"text":451},{"id":497,"depth":740,"text":498},{"id":545,"depth":740,"text":546,"children":2636},[2637,2638,2642,2643,2644,2648],{"id":550,"depth":614,"text":551},{"id":584,"depth":614,"text":585,"children":2639},[2640,2641],{"id":589,"depth":775,"text":590},{"id":703,"depth":775,"text":704},{"id":722,"depth":614,"text":723},{"id":969,"depth":614,"text":970},{"id":1128,"depth":614,"text":1129,"children":2645},[2646,2647],{"id":1132,"depth":775,"text":1133},{"id":1527,"depth":775,"text":1528},{"id":1594,"depth":614,"text":1595},{"id":1637,"depth":740,"text":1638,"children":2650},[2651,2652,2653],{"id":1721,"depth":614,"text":1722},{"id":1766,"depth":614,"text":1767},{"id":1803,"depth":614,"text":1803,"children":2654},[2655,2656,2657],{"id":1826,"depth":775,"text":1826},{"id":2068,"depth":775,"text":2068},{"id":2141,"depth":775,"text":2142},{"id":2400,"depth":740,"text":2401},{"id":2590,"depth":740,"text":2590},{"id":2596,"depth":740,"text":2596},[2662,2663,2053],"collaboration","ai-agents","2026-09-08","Blockが開発したAI協働スペース「Buzz」のNostrリレーを、Cloudflare DNSを介してUbuntu VPS上に自己ホストする方法を解説します。暗号鍵による安全な認証のもと、人間と各種AIエージェントがチャンネルやプロジェクトの履歴を共有し、自律的に連携するセキュアな作業環境を構築しましょう。","md","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf-Hosting%20Buzz%20As%20The%20Workspace%20Where%20AI%20Agents%20Become%20Colleagues\u002FJA-Self-Hosting-Buzz-As-The-Workspace-Where-AI-Agents-Become-Colleagues.webp","深みのあるブルーとオレンジのアクセントが効いたプレミアムな16:9のテックカード。Ubuntu VPS上にBlockのBuzzリレーを自己ホストする方法を表現し、すっきりとしたガラスモーフ調のパネルの中央にタイポグラフィを配置。",{"schemaOrg":2670,"robots":2692,"sitemap":2693},[2671,2673],{"@type":2672,"headline":423,"description":2665,"image":2667},"TechArticle",{"@type":2674,"name":423,"description":2665,"image":2667,"step":2675},"HowTo",[2676,2680,2683,2686,2689],{"@type":2677,"name":2678,"text":2679},"HowToStep","フェーズ1：Cloudflareのセットアップ","Cloudflare APIトークンを作成し、DNS設定を構成します。",{"@type":2677,"name":2681,"text":2682},"フェーズ2：Dockerのインストール","Ubuntu VPSにDocker Engineをセットアップしてインストールします。",{"@type":2677,"name":2684,"text":2685},"フェーズ3：クローンと構成","リポジトリをクローンし、compose环境変数を構成します。",{"@type":2677,"name":2687,"text":2688},"フェーズ4：Caddyの統合","Cloudflare DNSチャレンジモジュールを使用してカスタムCaddyをビルドします。",{"@type":2677,"name":2690,"text":2691},"フェーズ5：自動バックアップ","PostgreSQLを自動的にバックアップするためのcronジョブを設定します。","index, follow",{"lastmod":2694},"2026-09-03",{"title":2696,"description":2665,"ogTitle":423,"ogDescription":2665,"twitterTitle":423,"twitterDescription":2665},"BlockのAI共有スペース「Buzz」をUbuntu VPSに自己ホストする方法","ja\u002Farticle\u002Fself-hosting-buzz-as-the-workspace-where-ai-agents-become-colleagues",[2699,2700,445,2701,2702],"Nostr","Docker","Caddy","Cloudflare",null,"EE4T-Z1iblnIGKFh2wTTdhZWcCSPZKlWllLPKPhdosU",{"surround":2706,"related":5855},[2707,4454],{"id":2708,"title":2709,"author":2703,"body":2710,"category":4435,"date":4437,"description":4438,"extension":2666,"image":4439,"imageAlt":4440,"isPublished":771,"meta":4441,"minRead":958,"navigation":771,"path":193,"seo":4448,"stem":4449,"tags":4450,"updatedAt":2694,"__hash__":4453},"article\u002Fja\u002Farticle\u002Fself-hosted-travel-planner-trek.md","DockerとTREKで旅行プランをセルフホスト：日程、予約、旅費、持ち物リストを完全統合する究極のガイド",{"type":426,"value":2711,"toc":4394},[2712,2715,2718,2721,2725,2729,2871,2874,2880,2899,2902,2905,3009,3020,3023,3028,3031,3042,3046,3050,3053,3056,3096,3100,3103,3135,3138,3178,3181,3186,3194,3198,3205,3209,3212,3278,3282,3285,3289,3292,3296,3299,3307,3314,3318,3321,3324,3328,3332,3335,3339,3343,3346,3350,3354,3357,3362,3365,3370,3375,3379,3383,3386,3390,3395,3400,3403,3408,3412,3415,3420,3425,3428,3431,3435,3438,3441,3451,3454,3459,3462,3467,3471,3474,3479,3482,3487,3491,3494,3498,3503,3507,3510,3513,3518,3523,3528,3532,3539,3544,3549,3554,3559,3563,3568,3573,3576,3580,3583,3587,3593,3598,3603,3609,3614,3619,3624,3638,3642,3647,3668,3673,3676,3680,3683,3688,3691,3739,3743,3750,3753,3758,3763,3768,3773,3778,3784,3787,3792,3795,3800,3803,3807,3810,3815,3818,3822,3826,3829,3833,3836,3839,3843,3850,3854,3866,3872,3876,3880,3889,3892,3897,3900,3905,3908,3912,3915,4081,4084,4088,4091,4096,4099,4105,4109,4112,4116,4119,4124,4127,4132,4136,4143,4214,4226,4229,4234,4238,4242,4253,4330,4339,4342,4346,4350,4353,4355,4358,4361,4364,4368,4391],[429,2713,2714],{},"旅行計画の面倒なところは、航空券予約のPDF、ホテルの確認書、旅行仲間とのチャット履歴、訪れたい場所のリストなどが、あちこちに散らばってしまうことです。いざ合計支出を計算したり割り勘をしようとすると、膨大な旅行データの中からそれらを探し出すだけで大変な労力がかかります。",[429,2716,2717],{},"TREKは、セルフホスト可能なオープンソースの旅行プランナーであり、旅程、予約、予算、持ち物リストを一元管理できます。さらに、内蔵されているMCP（Model Context Protocol）サーバーを使用することで、AIエージェント（Claude Desktopなど）から旅行データを直接操作することが可能です。",[429,2719,2720],{},"本ガイドでは、デプロイ手順から、実際の旅行計画を最初から最後まで完全に管理する方法までをステップバイステップで詳しく解説します。",[548,2722,2724],{"id":2723},"_1-dockerを使用して旅行プランナーtrekをデプロイする方法","1. Dockerを使用して旅行プランナー「TREK」をデプロイする方法",[587,2726,2728],{"id":2727},"ubuntu-vpsにdockerをインストールする","Ubuntu VPSにDockerをインストールする",[663,2730,2732],{"className":665,"code":2731,"language":667,"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",[644,2733,2734,2738,2758,2762,2766,2798,2802,2806,2814,2818,2822,2838,2842,2846,2852,2856,2861],{"__ignoreMap":424},[671,2735,2736],{"class":673,"line":674},[671,2737,737],{"class":736},[671,2739,2740,2742,2744,2746,2748,2750,2752,2754,2756],{"class":673,"line":740},[671,2741,678],{"class":677},[671,2743,745],{"class":685},[671,2745,748],{"class":685},[671,2747,751],{"class":681},[671,2749,754],{"class":677},[671,2751,757],{"class":685},[671,2753,760],{"class":685},[671,2755,763],{"class":685},[671,2757,766],{"class":685},[671,2759,2760],{"class":673,"line":614},[671,2761,772],{"emptyLinePlaceholder":771},[671,2763,2764],{"class":673,"line":775},[671,2765,778],{"class":736},[671,2767,2768,2770,2772,2774,2776,2778,2780,2782,2784,2786,2788,2790,2792,2794,2796],{"class":673,"line":781},[671,2769,785],{"class":784},[671,2771,682],{"class":681},[671,2773,790],{"class":685},[671,2775,793],{"class":681},[671,2777,796],{"class":677},[671,2779,799],{"class":685},[671,2781,802],{"class":681},[671,2783,805],{"class":685},[671,2785,689],{"class":681},[671,2787,751],{"class":681},[671,2789,754],{"class":677},[671,2791,814],{"class":685},[671,2793,817],{"class":685},[671,2795,820],{"class":681},[671,2797,823],{"class":685},[671,2799,2800],{"class":673,"line":826},[671,2801,772],{"emptyLinePlaceholder":771},[671,2803,2804],{"class":673,"line":831},[671,2805,834],{"class":736},[671,2807,2808,2810,2812],{"class":673,"line":837},[671,2809,840],{"class":677},[671,2811,843],{"class":685},[671,2813,846],{"class":685},[671,2815,2816],{"class":673,"line":849},[671,2817,772],{"emptyLinePlaceholder":771},[671,2819,2820],{"class":673,"line":854},[671,2821,857],{"class":736},[671,2823,2824,2826,2828,2830,2832,2834,2836],{"class":673,"line":860},[671,2825,840],{"class":677},[671,2827,843],{"class":685},[671,2829,867],{"class":685},[671,2831,870],{"class":685},[671,2833,873],{"class":685},[671,2835,876],{"class":685},[671,2837,879],{"class":685},[671,2839,2840],{"class":673,"line":882},[671,2841,772],{"emptyLinePlaceholder":771},[671,2843,2844],{"class":673,"line":887},[671,2845,915],{"class":736},[671,2847,2848,2850],{"class":673,"line":893},[671,2849,921],{"class":677},[671,2851,924],{"class":685},[671,2853,2854],{"class":673,"line":907},[671,2855,772],{"emptyLinePlaceholder":771},[671,2857,2858],{"class":673,"line":912},[671,2859,2860],{"class":736},"# Starts automatically when your system boots\n",[671,2862,2863,2865,2867,2869],{"class":673,"line":918},[671,2864,840],{"class":677},[671,2866,898],{"class":685},[671,2868,901],{"class":685},[671,2870,904],{"class":685},[587,2872,2873],{"id":2873},"暗号化キーの生成",[429,2875,2876,2877,2879],{},"TREKは機密データの暗号化にキーを使用します。以下のコマンドまたはこちらの",[570,2878,1062],{"href":1061},"を使用して、暗号化キーを生成してください：",[663,2881,2883],{"className":665,"code":2882,"language":667,"meta":424,"style":424},"openssl rand -hex 32\n",[644,2884,2885],{"__ignoreMap":424},[671,2886,2887,2890,2893,2896],{"class":673,"line":674},[671,2888,2889],{"class":677},"openssl",[671,2891,2892],{"class":685}," rand",[671,2894,2895],{"class":685}," -hex",[671,2897,2898],{"class":1303}," 32\n",[429,2900,2901],{},"生成したキーは安全な場所に保管してください。キーを紛失すると、暗号化されたデータへのアクセス手段が失われます。",[587,2903,2904],{"id":2904},"コンテナの起動",[663,2906,2908],{"className":665,"code":2907,"language":667,"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",[644,2909,2910,2922,2932,2942,2959,2975,2985,2994,3004],{"__ignoreMap":424},[671,2911,2912,2914,2916,2919],{"class":673,"line":674},[671,2913,921],{"class":677},[671,2915,1919],{"class":685},[671,2917,2918],{"class":685}," -d",[671,2920,2921],{"class":2001}," \\\n",[671,2923,2924,2927,2930],{"class":673,"line":740},[671,2925,2926],{"class":685},"  --name",[671,2928,2929],{"class":685}," trek",[671,2931,2921],{"class":2001},[671,2933,2934,2937,2940],{"class":673,"line":614},[671,2935,2936],{"class":685},"  -p",[671,2938,2939],{"class":685}," 3000:3000",[671,2941,2921],{"class":2001},[671,2943,2944,2947,2950,2952,2955,2957],{"class":673,"line":775},[671,2945,2946],{"class":685},"  -e",[671,2948,2949],{"class":685}," ENCRYPTION_KEY=",[671,2951,689],{"class":681},[671,2953,2954],{"class":685},"\u003Cgenerated_key>",[671,2956,689],{"class":681},[671,2958,2921],{"class":2001},[671,2960,2961,2963,2966,2968,2971,2973],{"class":673,"line":781},[671,2962,2946],{"class":685},[671,2964,2965],{"class":685}," APP_URL=",[671,2967,689],{"class":681},[671,2969,2970],{"class":685},"https:\u002F\u002Ftrek.pafor.me",[671,2972,689],{"class":681},[671,2974,2921],{"class":2001},[671,2976,2977,2980,2983],{"class":673,"line":826},[671,2978,2979],{"class":685},"  -v",[671,2981,2982],{"class":685}," .\u002Fdata:\u002Fapp\u002Fdata",[671,2984,2921],{"class":2001},[671,2986,2987,2989,2992],{"class":673,"line":831},[671,2988,2979],{"class":685},[671,2990,2991],{"class":685}," .\u002Fuploads:\u002Fapp\u002Fuploads",[671,2993,2921],{"class":2001},[671,2995,2996,2999,3002],{"class":673,"line":837},[671,2997,2998],{"class":685},"  --restart",[671,3000,3001],{"class":685}," unless-stopped",[671,3003,2921],{"class":2001},[671,3005,3006],{"class":673,"line":849},[671,3007,3008],{"class":685},"  mauriceboe\u002Ftrek:latest\n",[456,3010,3011],{},[459,3012,3013,3019],{},[443,3014,3015,3018],{},[644,3016,3017],{},"APP_URL","を正しく設定する必要があります"," — MCPサーバーのOAuthディスカバリーフローは、このURLに依存しています。デプロイの初期段階から、最終的な公開HTTPSアドレスを設定してください。",[429,3021,3022],{},"初回起動時はイメージのプルに少し時間がかかります：",[435,3024],{"src":3025,"alt":3026,"style":3027},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-docker-pull-image.webp","TREKのDocker pullおよびrunのログ","max-width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[429,3029,3030],{},"起動状態を確認します：",[663,3032,3034],{"className":665,"code":3033,"language":667,"meta":424,"style":424},"docker ps\n",[644,3035,3036],{"__ignoreMap":424},[671,3037,3038,3040],{"class":673,"line":674},[671,3039,921],{"class":677},[671,3041,1574],{"class":685},[435,3043],{"src":3044,"alt":3045,"style":3027},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-docker-ps-status.webp","docker psによる起動中コンテナのステータス確認",[548,3047,3049],{"id":3048},"_2-caddyリバースプロキシによるドメインルーティングとsslの設定","2. CaddyリバースプロキシによるドメインルーティングとSSLの設定",[429,3051,3052],{},"パスキーやMCP用のOAuthを利用するには、HTTPSの導入が必須です。ドメインは、無料のSSL証明書とDDoS保護機能を提供するCloudflareでホストされています。",[429,3054,3055],{},"ポート3000を指すセキュアなリバースプロキシサーバーとして、Caddyをセットアップします。Caddyfileの記述例は以下の通りです：",[663,3057,3061],{"className":3058,"code":3059,"language":3060,"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",[644,3062,3063,3077,3082,3092],{"__ignoreMap":424},[671,3064,3065,3068,3071,3074],{"class":673,"line":674},[671,3066,3067],{"class":681},"{",[671,3069,3070],{"class":2001},"$TREK_DOMAIN",[671,3072,3073],{"class":681},"}",[671,3075,3076],{"class":681}," {\n",[671,3078,3079],{"class":673,"line":740},[671,3080,3081],{"class":2001},"  encode zstd gzip\n",[671,3083,3084,3087,3089],{"class":673,"line":614},[671,3085,3086],{"class":2001},"  reverse_proxy host.docker.internal",[671,3088,1268],{"class":681},[671,3090,3091],{"class":1303},"3000\n",[671,3093,3094],{"class":673,"line":775},[671,3095,1179],{"class":681},[548,3097,3099],{"id":3098},"_3-初期設定と管理者アカウントのセキュアなセットアップ","3. 初期設定と管理者アカウントのセキュアなセットアップ",[429,3101,3102],{},"管理者アカウントを作成する方法は2つあります：",[456,3104,3105,3116],{},[459,3106,3107,3108,3111,3112,3115],{},"**環境変数",[644,3109,3110],{},"ADMIN_EMAIL","と",[644,3113,3114],{},"ADMIN_PASSWORD","**を直接指定して、その値でアカウントを作成する。",[459,3117,3118,3119,3122,3123,3126,3127,3130,3131,3134],{},"TREKが自動でメールアドレス",[644,3120,3121],{},"admin@trek.local","、ユーザー名",[644,3124,3125],{},"admin","を作成し、",[443,3128,3129],{},"コンテナログにランダム生成されたパスワードを出力する","。",[644,3132,3133],{},"docker logs trek","を実行してパスワードを確認します。",[429,3136,3137],{},"もしログからパスワードが見つからない場合は、以下のコマンドでリセットしてください：",[663,3139,3141],{"className":665,"code":3140,"language":667,"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",[644,3142,3143],{"__ignoreMap":424},[671,3144,3145,3147,3149,3152,3155,3158,3160,3163,3165,3168,3170,3172,3175],{"class":673,"line":674},[671,3146,921],{"class":677},[671,3148,1681],{"class":685},[671,3150,3151],{"class":685}," -it",[671,3153,3154],{"class":685}," -e",[671,3156,3157],{"class":685}," RESET_ADMIN_EMAIL=admin@trek.local",[671,3159,3154],{"class":685},[671,3161,3162],{"class":685}," RESET_ADMIN_PASSWORD=",[671,3164,1883],{"class":681},[671,3166,3167],{"class":685},"YourNewPassword",[671,3169,1883],{"class":681},[671,3171,2929],{"class":685},[671,3173,3174],{"class":685}," node",[671,3176,3177],{"class":685}," server\u002Freset-admin.js\n",[429,3179,3180],{},"初回のログイン時にパスワードの変更を求められます。",[435,3182],{"src":3183,"alt":3184,"style":3185},"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,3187,3188,3189],{},"Admin（管理）をクリックし、メールアドレスを更新します：",[435,3190],{"src":3191,"alt":3192,"style":3193},"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;",[587,3195,3197],{"id":3196},"_31-バックアップ","3.1 バックアップ",[429,3199,3200,3201],{},"管理画面で保存期間ポリシーを設定し、自動バックアップを有効にします：\n",[435,3202],{"src":3203,"alt":3204,"style":3027},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-admin-backup-retention-policy.webp","自動バックアップスケジュールと保持ルールの設定",[587,3206,3208],{"id":3207},"_32-アップロードされたファイルをcloudflare-r2に保存する","3.2 アップロードされたファイルをCloudflare R2に保存する",[429,3210,3211],{},"アップロードしたファイルや写真、バックアップをCloudflare R2に格納することで、VPSのディスク領域をクリーンかつ軽量に保てます。TREKはS3互換のバックエンドをサポートしており、Cloudflare R2はこれに完璧に適合します。",[592,3213,3214,3221,3230,3238,3246,3254,3262,3270],{},[459,3215,3216,3217,3220],{},"「",[644,3218,3219],{},"trek","」という名前のR2バケットを作成します。",[459,3222,3223,3224,3225],{},"Account Details（アカウント詳細）セクションで、あなたのアカウントIDを確認します：","\n  ",[435,3226],{"src":3227,"alt":3228,"style":3229},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Fcloudflare-r2-account-details-id.webp","CloudflareポータルでのアカウントID of TREKの確認","max-width: 325px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[459,3231,3232,3224,3233],{},"Manage API Tokens（APIトークンの管理）をクリックします：",[435,3234],{"src":3235,"alt":3236,"style":3237},"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;",[459,3239,3240,3224,3241],{},"バケットに対する読み取り\u002F書き込み権限を持つCreate Account API token（アカウントAPIトークンの作成）をクリックします：",[435,3242],{"src":3243,"alt":3244,"style":3245},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Fcloudflare-r2-create-token-permissions.webp","読み取り\u002F書き込み権限を持つR2アクセストークンの作成","max-width: 360px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[459,3247,3248,3224,3249],{},"管理画面のADMINISTRATION（管理）パネルでStorage（ストレージ）をクリックします：",[435,3250],{"src":3251,"alt":3252,"style":3253},"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;",[459,3255,3256,3224,3257],{},"Add Backend（バックエンドの追加）ボタンをクリックし、エンドポイント、バケット名、クレデンシャル情報を入力します：",[435,3258],{"src":3259,"alt":3260,"style":3261},"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;",[459,3263,3264,3224,3265],{},"Apply（適用）をクリックした後、Test（テスト）のリンクボタンをクリックします。「Connection OK」と表示されることを確認してください：",[435,3266],{"src":3267,"alt":3268,"style":3269},"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;",[459,3271,3272,3224,3273],{},"すべてのストレージカテゴリをCloudflare R2に切り替え、Save changes（変更を保存）をクリックします：",[435,3274],{"src":3275,"alt":3276,"style":3277},"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;",[587,3279,3281],{"id":3280},"_33-パスキーログイン","3.3 パスキーログイン",[429,3283,3284],{},"TREKはパスキー、2要素認証（2FA）、およびOIDCによるシングルサインオンをサポートしています。パスキーを有効にするには、設定画面でドメイン名と許可されたオリジン（Allowed Origins）を入力し、Save（保存）をクリックします：",[435,3286],{"src":3287,"alt":3288,"style":3027},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-passkey-allowed-origins-settings.webp","安全なパスキー認証のための許可されたオリジンの登録",[429,3290,3291],{},"許可されたオリジンを正しく設定しないと、パスキーの登録が失敗します。",[587,3293,3295],{"id":3294},"_34-google-maps-apiキー","3.4 Google Maps APIキー",[429,3297,3298],{},"Google MapsのAPIキーを登録すると、場所の検索時に評価、営業時間、写真などの情報が自動的に追加されます。キーを登録しない場合、TREKは自動的にOpenStreetMapを使用します（その場合、評価や写真は表示されません）。",[429,3300,3301,3302],{},"こちらのリンクからGet demo keyをクリックしてキーを取得します：                                                  ",[435,3303],{"src":3304,"alt":3305,"style":3306},"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,3308,3309,3310],{},"キーを設定画面に貼り付け、Test（テスト）をクリックして接続を確認します：\n",[435,3311],{"src":3312,"alt":3313,"style":3027},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-google-maps-key-test-connection.webp","設定画面でのGoogle Maps APIキーの接続検証",[587,3315,3317],{"id":3316},"_35-ai統合","3.5 AI統合",[429,3319,3320],{},"AIモデルは、予約確認メールやPDFを解析し、構造化された予約データに変換するために使用されます。",[429,3322,3323],{},"左メニューのAddons（アドオン）をクリックし、AI Parsingを有効にします。「OpenAI」（またはその他の互換プロバイダー）を選択し、プロバイダーの詳細情報を入力します：",[435,3325],{"src":3326,"alt":3327,"style":3027},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-addons-enable-ai-parsing-openai.webp","OpenAI連携によるAI解析アドオンの有効化",[587,3329,3331],{"id":3330},"_36-mcpアクセス","3.6 MCPアクセス",[429,3333,3334],{},"Addons（アドオン）の配下で、MCPを有効にします：",[435,3336],{"src":3337,"alt":3338,"style":3027},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-addons-enable-mcp.webp","Model Context Protocol MCPサーバーアドオンの有効化",[587,3340,3342],{"id":3341},"_37-プラグイン","3.7 プラグイン",[429,3344,3345],{},"以下の推奨プラグインを有効にすることをお勧めします：",[435,3347],{"src":3348,"alt":3349,"style":3027},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-recommended-addons-plugins-activation.webp","有効化された推奨プラグインおよびアドオンの一覧",[587,3351,3353],{"id":3352},"_38-普段使い用ユーザーの作成","3.8 普段使い用ユーザーの作成",[429,3355,3356],{},"旅行計画は、管理者アカウントではなく一般ユーザーアカウントで行うのが基本です。通常のユーザーを作成し、そちらでログインし直します：",[435,3358],{"src":3359,"alt":3360,"style":3361},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-create-regular-user-form.webp","TREKパネルでの一般ユーザーアカウント of TREKの作成","max-width: 420px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[429,3363,3364],{},"ログインしたら、パスキーを追加するか、2要素認証（2FA）を設定してセキュリティを強化しましょう：",[435,3366],{"src":3367,"alt":3368,"style":3369},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-user-security-passkey-2fa-setup.webp","パスキーと2要素認証によるユーザーセキュリティ設定","max-width: 381px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[456,3371,3372],{},[459,3373,3374],{},"Add a passkeyをクリックし、現在のパスワードを入力して認証します：",[435,3376],{"src":3377,"alt":3378,"style":3027},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-add-passkey-confirm-password.webp","新しいハードウェアパスキーの登録用パスワード確認",[548,3380,3382],{"id":3381},"_4-デプロイのテスト過去の旅行データのインポート","4. デプロイのテスト：過去の旅行データのインポート",[429,3384,3385],{},"TREKを使いこなすには、過去の旅行データを登録してみるのが一番の近道です。",[587,3387,3389],{"id":3388},"_41-旅行プランの作成","4.1 旅行プランの作成",[456,3391,3392],{},[459,3393,3394],{},"New Tripをクリックし、旅行の実際の過去の期間に合わせてStart Date（開始日）とEnd Date（終了日）を設定します：",[435,3396],{"src":3397,"alt":3398,"style":3399},"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,3401,3402],{},"カバー画像をアップロード（ドラッグ＆ドロップ、またはクリップボードから貼り付け）し、Create New Tripをクリックします：",[435,3404],{"src":3405,"alt":3406,"style":3407},"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;",[587,3409,3411],{"id":3410},"_42-予約情報のインポート","4.2 予約情報のインポート",[429,3413,3414],{},"飛行機、電車、その他の交通機関の予約確認書などのファイルをここにドロップします：",[435,3416],{"src":3417,"alt":3418,"style":3419},"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,3421],{"src":3422,"alt":3423,"style":3424},"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,3426,3427],{},"AIモデルが有効になっていると、予約確認書のPDFが解析され、構造化された予約データが抽出されます。",[429,3429,3430],{},"抽出された結果を確認し、Add（追加）をクリックして予約詳細を確定します：",[435,3432],{"src":3433,"alt":3434,"style":3027},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-review-parsed-booking-details.webp","AIによって抽出された構造化された予約情報の確認",[429,3436,3437],{},"予約情報がメール本文にしかない場合は、メールをPDFとして書き出してアップロードすれば、同様に自動抽出パイプラインが適用されます。",[429,3439,3440],{},"以下のスクリーンショットは、インポートされた予約情報の表示例です：",[429,3442,3443,3447],{},[435,3444],{"src":3445,"alt":3446,"style":3027},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-trip-bookings-timeline-view.webp","旅行予約の包括的なタイムライン表示",[435,3448],{"src":3449,"alt":3450,"style":3027},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-booking-confirmation-details.webp","確認済みの交通機関予約の詳細表示",[429,3452,3453],{},"Plan（計画）ページでは、すべての宿泊施設が地図上に表示されます：",[435,3455],{"src":3456,"alt":3457,"style":3458},"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,3460,3461],{},"トップメニューのAtlasをクリックすると、これまでに訪れた国のリストと地図が表示されます：",[435,3463],{"src":3464,"alt":3465,"style":3466},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-atlas-countries-visited-summary.webp","個人アトラストラッカーにおける旅行履歴の概要","max-width: 407px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[587,3468,3470],{"id":3469},"_43-同行者の追加","4.3 同行者の追加",[429,3472,3473],{},"Share（共有）ボタンをクリックします：",[435,3475],{"src":3476,"alt":3477,"style":3478},"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,3480,3481],{},"ダイアログの下部でゲストを追加できます：",[435,3483],{"src":3484,"alt":3485,"style":3486},"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;",[587,3488,3490],{"id":3489},"_44-経費の記録","4.4 経費の記録",[429,3492,3493],{},"海外旅行保険、現地交通費、SIMカード代など、予約確認書以外の支出を記録するには、Add expense（経費を追加）をクリックします：",[435,3495],{"src":3496,"alt":3497,"style":3027},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-add-custom-expense-form.webp","経費入力フォームへの詳細な出費データの入力",[435,3499],{"src":3500,"alt":3501,"style":3502},"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;",[587,3504,3506],{"id":3505},"_45-旅行セグメント行程の分割","4.5 旅行セグメント（行程の分割）",[429,3508,3509],{},"この機能を使用するには、「Trip Segment」プラグインがインストールされている必要があります。",[429,3511,3512],{},"長期の旅行をいくつかのセグメントに分割することで、各期間の予約、訪れる場所、経費が整理され、見やすくなります：",[435,3514],{"src":3515,"alt":3516,"style":3517},"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,3519],{"src":3520,"alt":3521,"style":3522},"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,3524],{"src":3525,"alt":3526,"style":3527},"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;",[587,3529,3531],{"id":3530},"_46-ジャーニーの作成とアトラスの確認","4.6 ジャーニーの作成とアトラスの確認",[429,3533,3534,3535,3538],{},"複数の旅行を「",[443,3536,3537],{},"Journey","（ジャーニー）」としてまとめ、ストーリーを書いて友人たちに冒険を共有できます：",[435,3540],{"src":3541,"alt":3542,"style":3543},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-create-new-journey-group.webp","複数の旅行を1つのビジュアルジャーニーに統合","max-width: 441px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[435,3545],{"src":3546,"alt":3547,"style":3548},"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,3550],{"src":3551,"alt":3552,"style":3553},"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,3555],{"src":3556,"alt":3557,"style":3558},"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;",[548,3560,3562],{"id":3561},"_5-カスタム旅程と持ち物リストの設計","5. カスタム旅程と持ち物リストの設計",[456,3564,3565],{},[459,3566,3567],{},"New Tripをクリックし、旅行名と日程を入力します：",[435,3569],{"src":3570,"alt":3571,"style":3572},"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,3574,3575],{},"**日程がまだ未定の場合は、日付欄を空欄のままにしてください。**代わりに「日数（最大365日）」を指定するフィールドが表示されます。まずは計画を立て、日程は後から決定することができます。",[587,3577,3579],{"id":3578},"_51-場所スポットの追加","5.1 場所（スポット）の追加",[429,3581,3582],{},"旅行計画の中で最も時間がかかるのがスポットの追加ですが、TREKにはいくつかの効率的な方法が用意されています：",[435,3584],{"src":3585,"alt":3586,"style":3027},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-add-places-methods-overview.webp","旅程に新しいスポットを追加するマルチチャネル方式の概要",[429,3588,3589,3592],{},[443,3590,3591],{},"1. 地図上を右クリック","して、その地点に直接スポットを作成する。住所は自動的に逆ジオコーディング（住所の自動取得）されます：",[435,3594],{"src":3595,"alt":3596,"style":3597},"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,3599],{"src":3600,"alt":3601,"style":3602},"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,3604,3605,3608],{},[443,3606,3607],{},"2. + Add Place\u002FActivity","をクリックして、名称で検索する",[435,3610],{"src":3611,"alt":3612,"style":3613},"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,3615],{"src":3616,"alt":3617,"style":3618},"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,3620],{"src":3621,"alt":3622,"style":3623},"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,3625,3626,3629,3630,3633,3634,3637],{},[443,3627,3628],{},"3. Googleマップの共有URL","（",[644,3631,3632],{},"maps.app.goo.gl\u002F…"," または ",[644,3635,3636],{},"maps.google.com\u002F…","）を検索窓に貼り付ける。TREKがスポット名、住所、座標を自動で解析・抽出します：",[435,3639],{"src":3640,"alt":3641,"style":3269},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-paste-google-maps-share-link.webp","貼り付けられたGoogleマップの共有リンクから場所を直接解析",[435,3643],{"src":3644,"alt":3645,"style":3646},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-google-maps-parsed-location.webp","GoogleマップのURLからの座標抽出に成功","max-width: 543px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[429,3648,3649,3652,3653,3629,3656,3659,3660,3663,3664,3667],{},[443,3650,3651],{},"4. 一括インポート"," — これが最も簡単な方法です。Googleマップでお気に入りのリスト（「行きたい場所」など）を作成している場合、それを",[644,3654,3655],{},".gpx",[644,3657,3658],{},".kml","や",[644,3661,3662],{},".kmz","も対応）としてエクスポートし、右側パネル of ",[443,3665,3666],{},"Import file","をクリックしてアップロードすれば、すべての場所を一度にインポートできます：",[435,3669],{"src":3670,"alt":3671,"style":3672},"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,3674,3675],{},"日程に収まるかどうかを気にする必要はありません。まずは興味のある場所をすべて追加し、日程への割り当ては後から行います。",[587,3677,3679],{"id":3678},"_52-日ごとの計画とメモ","5.2 日ごとの計画とメモ",[429,3681,3682],{},"「Day Plan」では、スポットを日ごとに整理し、訪問順を設定できます。折りたたみ可能な日別のリストになっており、すべてドラッグ＆ドロップで操作可能です：",[435,3684],{"src":3685,"alt":3686,"style":3687},"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,3689,3690],{},"以下の便利な詳細機能が備わっています：",[456,3692,3693,3703,3713,3723],{},[459,3694,3695,3698,3699],{},[443,3696,3697],{},"スポット間の移動手段",": 日次プランの左上にあるバスのアイコンをクリックすると、その日の移動手段（電車、バス、フライトなど）を追加できます：\n",[435,3700],{"src":3701,"alt":3702,"style":3027},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-day-plan-commuting-transport-button.webp","日中のセグメント間を繋ぐ交通手段の登録",[459,3704,3705,3708,3709],{},[443,3706,3707],{},"デイメモ（日ごとのメモ）",": 日次プランの左下にあるノートのアイコンから、アイコン付きのメモを添付できます（例：「今日は早めに出発する」「この美術館は要予約」）：\n",[435,3710],{"src":3711,"alt":3712,"style":3027},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-day-plan-icon-tagged-notes-button.webp","見やすいアイコン付きカスタムメモを日毎に追加",[459,3714,3715,3718,3719],{},[443,3716,3717],{},"タイムスロットの設定",": 右側のパネルから場所をドラッグして日付にドロップし、時間を割り当てます。時間が設定された場所は、地図上で自動的に経路接続されます：\n",[435,3720],{"src":3721,"alt":3722,"style":3027},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-day-plan-timed-places-routing.webp","時間設定されたスポット間の自動計算ルート表示",[459,3724,3725,3726,3729,3730,3733,3734,2159],{},"ルートの最適化（",[443,3727,3728],{},"Route optimisation","）および天気（",[443,3731,3732],{},"Weather","）については、",[570,3735,3738],{"href":3736,"rel":3737},"https:\u002F\u002Fgithub.com\u002Fliketrek\u002FTREK\u002Fwiki\u002FDay-Plans-and-Notes",[1645],"Day Plans and NotesのWikiページ",[587,3740,3742],{"id":3741},"_53-コレクション再利用可能なスポットリスト","5.3 コレクション：再利用可能なスポットリスト",[429,3744,3745,3746,3749],{},"コレクション機能を使用すると、特定の旅行とは無関係に、お気に入りのスポットリストを保存・管理できます。友人と共有したり、次回の旅行にそのまま活用したりできます。スポットは旅行プランに",[443,3747,3748],{},"コピー","されるため、旅行内の情報を編集しても元のコレクションには影響しません（その逆も同様です）。",[429,3751,3752],{},"上部メニューのCollections（コレクション）をクリックします：",[435,3754],{"src":3755,"alt":3756,"style":3757},"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;",[456,3759,3760],{},[459,3761,3762],{},"New listをクリックして、新しいリストを作成します：",[435,3764],{"src":3765,"alt":3766,"style":3767},"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;",[456,3769,3770],{},[459,3771,3772],{},"Add a placeをクリックし、詳細を入力します：",[435,3774],{"src":3775,"alt":3776,"style":3777},"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,3779,3780,3783],{},[443,3781,3782],{},"注意:"," 「Add a place」ダイアログ内の検索機能は、うまく機能しない場合があるため、その際は詳細を手動で入力する必要があります。",[429,3785,3786],{},"場所のジオ座標が利用可能な場合、それらは地図上に表示されます：",[435,3788],{"src":3789,"alt":3790,"style":3791},"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,3793,3794],{},"スポットをラベルで整理するには、チェックボックスのアイコンをクリックします：",[435,3796],{"src":3797,"alt":3798,"style":3799},"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,3801,3802],{},"グループ化したいスポットを選択し、Assign label（ラベルを割り当て）をクリックします：",[435,3804],{"src":3805,"alt":3806,"style":3646},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-collections-group-assign-label.webp","選択したコレクションスポットへの説明ラベルの割り当て",[429,3808,3809],{},"事前にラベルを作成するには、Manage labels（ラベルの管理）をクリックします：",[435,3811],{"src":3812,"alt":3813,"style":3814},"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,3816,3817],{},"ラベルを選択して、Assign labelをクリックします：",[435,3819],{"src":3820,"alt":3821,"style":3466},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-collections-confirm-label-selection.webp","グループスポットへのカスタムラベルの適用",[587,3823,3825],{"id":3824},"_54-費用と予算","5.4 費用と予算",[429,3827,3828],{},"旅行中のその他の費用は、「Costs」（費用）ページから追加できます。",[435,3830],{"src":3831,"alt":3832,"style":3687},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-costs-budget-overall-expenses-list.webp","包括的な経費一覧表とバランス清算台帳",[429,3834,3835],{},"同じページで、同行者が支払った金額を追加し、割り勘を設定することができます。",[429,3837,3838],{},"精算（Settlement）パネルは、グリーディー・マッチング（貪欲法）アルゴリズムを実行して、誰が誰にいくら支払うべきかを計算し、送金回数が最小限になる精算方法を提案します。",[548,3840,3842],{"id":3841},"_6-model-context-protocol-mcpを活用したai駆動の旅行計画","6. Model Context Protocol (MCP)を活用したAI駆動の旅行計画",[429,3844,3845,3846,3849],{},"TREKには",[443,3847,3848],{},"MCP（Model Context Protocol）サーバー","が内蔵されています。これにより、AIエージェントがあなたの旅行データに直接アクセスして、読み書きすることができます。旅行、スポット、予算、持ち物、予約、コラボレーションなど、150以上のツールと30の主要なリソースをカバーしています。",[587,3851,3853],{"id":3852},"_61-cloudflare-zero-trust","6.1 Cloudflare Zero Trust",[429,3855,3856,3857,3860,3861],{},"TREKを",[570,3858,3859],{"href":363},"Cloudflare Zero Trust","環境の配下で運用している場合、ドメインをスプリットトンネル（Split Tunnels）のインクルージョンリスト（除外・バイパスリスト）に追加する必要があります。そうしないと、OAuth認証時に問題が発生する可能性があります。詳細については、こちらのGitHub Issueを参照してください：",[570,3862,3865],{"href":3863,"rel":3864},"https:\u002F\u002Fgithub.com\u002Fliketrek\u002FTREK\u002Fissues\u002F1463",[1645],"GitHub Issue",[575,3867],{"description":3868,"image":578,"image-alt":3869,"label":580,"min-read":3870,"title":3871,"to":363},"ファイアウォールのインバウンドポートを開くことなく、Cloudflare WARPとZero Trustを使用してグローバルかつ安全にHermes Agentへアクセスし、プライベートネットワークに公開する方法を詳しく解説します。","Cloudflare Zero TrustとWARPトンネルを使用してHermes Agentをプライベートネットワークに安全に公開","5","Cloudflare WARPでHermes Agentをプライベートネットワークに公開する方法",[435,3873],{"src":3874,"alt":3875,"style":3027},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Fcloudflare-zero-trust-split-tunnels-domain.webp","Cloudflare Warpスプリットトンネルへのカスタムドメインの追加",[587,3877,3879],{"id":3878},"_62-claude-desktop","6.2 Claude Desktop",[456,3881,3882],{},[459,3883,3884,3885],{},"New Client（新規クライアント）をクリックして、AIエージェントクライアントを作成します：\n",[435,3886],{"src":3887,"alt":3888,"style":3027},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-register-new-mcp-client.webp","設定画面での新規カスタムクライアントトークンの登録",[429,3890,3891],{},"Claude Desktopタブを選択し、Register Client（クライアントを登録）をクリックします：",[435,3893],{"src":3894,"alt":3895,"style":3896},"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,3898,3899],{},"クライアントIDとクライアントシークレットのペアが表示されます。これらを安全な場所に保存してください。次に、Client Configuration（クライアント設定）をクリックして、MCP設定を表示します：",[435,3901],{"src":3902,"alt":3903,"style":3904},"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,3906,3907],{},"Claude DesktopでEdit Configをクリックし、ローカルのMCPサーバー設定ファイルを開きます：",[435,3909],{"src":3910,"alt":3911,"style":3027},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Fclaude-desktop-mcp-config-json.webp","Claude DesktopのローカルMCP設定JSONファイルの編集",[429,3913,3914],{},"TREKの設定を貼り付け、プレースホルダー部分をご自身の情報に置き換えます：",[663,3916,3918],{"className":3058,"code":3917,"language":3060,"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",[644,3919,3920,3935,3948,3970,3984,3996,4007,4018,4064,4069,4074],{"__ignoreMap":424},[671,3921,3922,3925,3928,3930,3933],{"class":673,"line":674},[671,3923,3924],{"class":681},"  \"",[671,3926,3927],{"class":685},"mcpServers",[671,3929,689],{"class":681},[671,3931,3932],{"class":2001},": ",[671,3934,1165],{"class":681},[671,3936,3937,3940,3942,3944,3946],{"class":673,"line":740},[671,3938,3939],{"class":681},"    \"",[671,3941,3219],{"class":1271},[671,3943,689],{"class":681},[671,3945,1268],{"class":681},[671,3947,3076],{"class":681},[671,3949,3950,3953,3956,3958,3960,3962,3965,3967],{"class":673,"line":614},[671,3951,3952],{"class":681},"      \"",[671,3954,3955],{"class":677},"command",[671,3957,689],{"class":681},[671,3959,1268],{"class":681},[671,3961,682],{"class":681},[671,3963,3964],{"class":685},"npx",[671,3966,689],{"class":681},[671,3968,3969],{"class":681},",\n",[671,3971,3972,3974,3977,3979,3981],{"class":673,"line":775},[671,3973,3952],{"class":681},[671,3975,3976],{"class":677},"args",[671,3978,689],{"class":681},[671,3980,1268],{"class":681},[671,3982,3983],{"class":681}," [\n",[671,3985,3986,3989,3992,3994],{"class":673,"line":781},[671,3987,3988],{"class":681},"        \"",[671,3990,3991],{"class":685},"mcp-remote",[671,3993,689],{"class":681},[671,3995,3969],{"class":681},[671,3997,3998,4000,4003,4005],{"class":673,"line":826},[671,3999,3988],{"class":681},[671,4001,4002],{"class":685},"https:\u002F\u002Ftrek.pafor.me\u002Fmcp",[671,4004,689],{"class":681},[671,4006,3969],{"class":681},[671,4008,4009,4011,4014,4016],{"class":673,"line":831},[671,4010,3988],{"class":681},[671,4012,4013],{"class":685},"--static-oauth-client-info",[671,4015,689],{"class":681},[671,4017,3969],{"class":681},[671,4019,4020,4022,4024,4027,4030,4032,4034,4036,4039,4041,4044,4046,4049,4051,4053,4055,4058,4060,4062],{"class":673,"line":837},[671,4021,3988],{"class":681},[671,4023,3067],{"class":685},[671,4025,4026],{"class":2001},"\\\"",[671,4028,4029],{"class":685},"client_id",[671,4031,4026],{"class":2001},[671,4033,3932],{"class":685},[671,4035,4026],{"class":2001},[671,4037,4038],{"class":685},"\u003Cyour_client_id>",[671,4040,4026],{"class":2001},[671,4042,4043],{"class":685},", ",[671,4045,4026],{"class":2001},[671,4047,4048],{"class":685},"client_secret",[671,4050,4026],{"class":2001},[671,4052,3932],{"class":685},[671,4054,4026],{"class":2001},[671,4056,4057],{"class":685},"\u003Cyour_client_secret>",[671,4059,4026],{"class":2001},[671,4061,3073],{"class":685},[671,4063,700],{"class":681},[671,4065,4066],{"class":673,"line":849},[671,4067,4068],{"class":681},"      ]\n",[671,4070,4071],{"class":673,"line":854},[671,4072,4073],{"class":681},"    }\n",[671,4075,4076,4079],{"class":673,"line":860},[671,4077,4078],{"class":681},"  }",[671,4080,3969],{"class":2001},[429,4082,4083],{},"Claude Desktopを再起動すると、ローカルMCPサーバー（Local MCP servers）に接続されたTREKサーバーが表示されます：",[435,4085],{"src":4086,"alt":4087,"style":3027},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Fclaude-desktop-mcp-trek-server-connected.webp","Claudeの画面内でのTREK接続アクティブステータスの確認",[429,4089,4090],{},"これで、自然言語プロンプトを実行できます：",[435,4092],{"src":4093,"alt":4094,"style":4095},"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,4097,4098],{},"自然言語で支出を追加してみましょう：",[663,4100,4103],{"className":4101,"code":4102,"language":1035,"meta":424},[1033],"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",[644,4104,4102],{"__ignoreMap":424},[435,4106],{"src":4107,"alt":4108,"style":3027},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Fclaude-desktop-mcp-add-expense-response.webp","ツールを使って自動的に経費を記録するClaudeの応答",[429,4110,4111],{},"「Costs」ページを確認すると、支払人が言及されなかったため、「まだ誰も支払っていません（No one paid yet）」という状態で支出が作成されます：",[435,4113],{"src":4114,"alt":4115,"style":3193},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-costs-page-mcp-parsed-expense.webp","経費画面での新規登録されたAI解析支出の確認",[429,4117,4118],{},"持ち物リストへの追加も同様に行うことができます：",[435,4120],{"src":4121,"alt":4122,"style":4123},"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,4125,4126],{},"「Packing List」ページを更新すると、3つのアイテムが追加されています：",[435,4128],{"src":4129,"alt":4130,"style":4131},"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;",[587,4133,4135],{"id":4134},"_63-gemini-cli動的登録","6.3 Gemini CLI（動的登録）",[429,4137,4138,4139,4142],{},"Gemini CLIは動的登録（Dynamic Registration）をサポートしているため、事前にクライアントを登録する必要はありません。",[644,4140,4141],{},".gemini\u002Fsettings.json","に以下を追加してください：",[663,4144,4146],{"className":3058,"code":4145,"language":3060,"meta":424,"style":424},"    \"trek\": {\n      \"httpUrl\": \"https:\u002F\u002Ftrek.pafor.me\u002Fmcp\",\n      \"oauth\": {\n        \"enabled\": true\n      }\n    }\n",[644,4147,4148,4160,4179,4192,4205,4210],{"__ignoreMap":424},[671,4149,4150,4152,4154,4156,4158],{"class":673,"line":674},[671,4151,3939],{"class":681},[671,4153,3219],{"class":685},[671,4155,689],{"class":681},[671,4157,3932],{"class":2001},[671,4159,1165],{"class":681},[671,4161,4162,4164,4167,4169,4171,4173,4175,4177],{"class":673,"line":740},[671,4163,3952],{"class":681},[671,4165,4166],{"class":1271},"httpUrl",[671,4168,689],{"class":681},[671,4170,1268],{"class":681},[671,4172,682],{"class":681},[671,4174,4002],{"class":685},[671,4176,689],{"class":681},[671,4178,3969],{"class":681},[671,4180,4181,4183,4186,4188,4190],{"class":673,"line":614},[671,4182,3952],{"class":681},[671,4184,4185],{"class":1271},"oauth",[671,4187,689],{"class":681},[671,4189,1268],{"class":681},[671,4191,3076],{"class":681},[671,4193,4194,4196,4199,4201,4203],{"class":673,"line":775},[671,4195,3988],{"class":681},[671,4197,4198],{"class":677},"enabled",[671,4200,689],{"class":681},[671,4202,1268],{"class":681},[671,4204,2221],{"class":681},[671,4206,4207],{"class":673,"line":781},[671,4208,4209],{"class":681},"      }\n",[671,4211,4212],{"class":673,"line":826},[671,4213,4073],{"class":681},[429,4215,4216,4217,4220,4221],{},"ターミナルで",[644,4218,4219],{},"gemini","を実行し、認証プロンプトが表示されたらApprove（承認）をクリックします：\n",[435,4222],{"src":4223,"alt":4224,"style":4225},"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,4227,4228],{},"シンプルなプロンプトから始めてみましょう：",[435,4230],{"src":4231,"alt":4232,"style":4233},"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,4235],{"src":4236,"alt":4237,"style":3553},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Fgemini-cli-mcp-display-itinerary.webp","構造化された旅行情報を正常に表示するGemini CLI",[587,4239,4241],{"id":4240},"_64-kimi-cli動的登録","6.4 Kimi CLI（動的登録）",[429,4243,4244,4245,4248,4249,4252],{},"やり方は同様です。",[644,4246,4247],{},"\u002FUsers\u002F\u003Cuser>\u002F.kimi\u002F","フォルダにある",[644,4250,4251],{},"mcp.json","に以下を追加します：",[663,4254,4256],{"className":3058,"code":4255,"language":3060,"meta":424,"style":424},"    \"trek\": {\n      \"type\": \"http\",\n      \"url\": \"https:\u002F\u002Ftrek.pafor.me\u002Fmcp\",\n      \"auth\": \"oauth\"\n    }\n",[644,4257,4258,4270,4290,4309,4326],{"__ignoreMap":424},[671,4259,4260,4262,4264,4266,4268],{"class":673,"line":674},[671,4261,3939],{"class":681},[671,4263,3219],{"class":685},[671,4265,689],{"class":681},[671,4267,3932],{"class":2001},[671,4269,1165],{"class":681},[671,4271,4272,4274,4277,4279,4281,4283,4286,4288],{"class":673,"line":740},[671,4273,3952],{"class":681},[671,4275,4276],{"class":1271},"type",[671,4278,689],{"class":681},[671,4280,1268],{"class":681},[671,4282,682],{"class":681},[671,4284,4285],{"class":685},"http",[671,4287,689],{"class":681},[671,4289,3969],{"class":681},[671,4291,4292,4294,4297,4299,4301,4303,4305,4307],{"class":673,"line":614},[671,4293,3952],{"class":681},[671,4295,4296],{"class":1271},"url",[671,4298,689],{"class":681},[671,4300,1268],{"class":681},[671,4302,682],{"class":681},[671,4304,4002],{"class":685},[671,4306,689],{"class":681},[671,4308,3969],{"class":681},[671,4310,4311,4313,4316,4318,4320,4322,4324],{"class":673,"line":775},[671,4312,3952],{"class":681},[671,4314,4315],{"class":1271},"auth",[671,4317,689],{"class":681},[671,4319,1268],{"class":681},[671,4321,682],{"class":681},[671,4323,4185],{"class":685},[671,4325,700],{"class":681},[671,4327,4328],{"class":673,"line":781},[671,4329,4073],{"class":681},[429,4331,4216,4332,4335,4336],{},[644,4333,4334],{},"kimi mcp auth trek","を実行し、Approveをクリックします：\n",[435,4337],{"src":4223,"alt":4224,"style":4338},"max-width: 453px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[429,4340,4341],{},"認証されると、利用可能なツールが一覧表示されます：",[435,4343],{"src":4344,"alt":4345,"style":3027},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Fkimi-cli-mcp-authorized-tools-list.webp","認証成功後に使用可能なツール一覧を表示するKimi CLI",[548,4347,4349],{"id":4348},"_7-モバイルでの利用体験","7. モバイルでの利用体験",[429,4351,4352],{},"TREKは、モバイルデバイスではPWA（Progressive Web App）として動作します。サービスワーカーがマップタイルやAPIデータをキャッシュするため、オフライン環境でも旅程を確認することができます。ただし、ネイティブアプリと比較すると、プッシュ通知に多少の遅延が発生する場合があります。",[548,4354,2590],{"id":2590},[429,4356,4357],{},"MCPを介してAIエージェントを接続することで、フライトや宿泊施設の予約データを手動で入力する手間を大幅に削減できます。また、AIエージェントは旅行日程や季節に応じたお勧めの観光スポットを提案することも可能です。AIエージェントとの一度の対話で、リサーチや旅程の作成から、予算管理、持ち物リストの整理まで、旅行計画のすべてのステップをカバーできます。",[429,4359,4360],{},"ただし、いくつか軽微な不具合も見受けられます。例えば、PDFから予約をインポートする際、実際に支払った通貨ではなく、旅行の基本通貨（デフォルト通貨）に自動設定されてしまうことがあります。また、「Collections」で新しいリストを作成する際、作成時に入力したカバー画像が保存後に消えてしまうことがあります（ただし、編集画面から手動で再追加することは可能です）。",[429,4362,4363],{},"また、ご自身のサーバーにこれをホストする必要があるため、導入には多少の技術的なハードルがあります。TREKは主に、頻繁に旅行に行き、旅のデータをこだわりを持って整理したい方向けに設計されています。セルフホストを検討する前に、demo.liketrek.comで公式デモを試してみることをお勧めします。",[548,4365,4367],{"id":4366},"参考リンク","参考リンク:",[456,4369,4370,4377,4384],{},[459,4371,4372],{},[570,4373,4376],{"href":4374,"rel":4375},"https:\u002F\u002Fgithub.com\u002Fliketrek\u002FTREK\u002Fwiki\u002FQuick-Start",[1645],"TREK Quick Start",[459,4378,4379],{},[570,4380,4383],{"href":4381,"rel":4382},"https:\u002F\u002Fgithub.com\u002Fliketrek\u002FTREK\u002Fwiki\u002FTroubleshooting",[1645],"TREK Troubleshooting",[459,4385,4386],{},[570,4387,4390],{"href":4388,"rel":4389},"https:\u002F\u002Fgithub.com\u002Fliketrek\u002FTREK\u002Fwiki\u002FMCP-Scopes",[1645],"TREK MCP Scopes",[2628,4392,4393],{},"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":740,"depth":614,"links":4395},[4396,4401,4402,4412,4420,4426,4432,4433,4434],{"id":2723,"depth":614,"text":2724,"children":4397},[4398,4399,4400],{"id":2727,"depth":775,"text":2728},{"id":2873,"depth":775,"text":2873},{"id":2904,"depth":775,"text":2904},{"id":3048,"depth":614,"text":3049},{"id":3098,"depth":614,"text":3099,"children":4403},[4404,4405,4406,4407,4408,4409,4410,4411],{"id":3196,"depth":775,"text":3197},{"id":3207,"depth":775,"text":3208},{"id":3280,"depth":775,"text":3281},{"id":3294,"depth":775,"text":3295},{"id":3316,"depth":775,"text":3317},{"id":3330,"depth":775,"text":3331},{"id":3341,"depth":775,"text":3342},{"id":3352,"depth":775,"text":3353},{"id":3381,"depth":614,"text":3382,"children":4413},[4414,4415,4416,4417,4418,4419],{"id":3388,"depth":775,"text":3389},{"id":3410,"depth":775,"text":3411},{"id":3469,"depth":775,"text":3470},{"id":3489,"depth":775,"text":3490},{"id":3505,"depth":775,"text":3506},{"id":3530,"depth":775,"text":3531},{"id":3561,"depth":614,"text":3562,"children":4421},[4422,4423,4424,4425],{"id":3578,"depth":775,"text":3579},{"id":3678,"depth":775,"text":3679},{"id":3741,"depth":775,"text":3742},{"id":3824,"depth":775,"text":3825},{"id":3841,"depth":614,"text":3842,"children":4427},[4428,4429,4430,4431],{"id":3852,"depth":775,"text":3853},{"id":3878,"depth":775,"text":3879},{"id":4134,"depth":775,"text":4135},{"id":4240,"depth":775,"text":4241},{"id":4348,"depth":614,"text":4349},{"id":2590,"depth":614,"text":2590},{"id":4366,"depth":614,"text":4367},[4436,2663],"travel","2026-09-01","Dockerを使用してオープンソースの旅行プランナー「TREK」をデプロイし、CaddyリバースプロキシやCloudflare R2と連携させてセキュアに運用する方法を徹底解説。さらに、MCP経由でAIエージェントと接続し、自然言語で旅行の予約、旅費、持ち物リストを自動整理・一元管理してスマートに旅を計画しましょう。","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002FJA-Self-hosted-travel-planner-TREK.webp","温かみのある羊皮紙の背景に表示された、TREKセルフホスト旅行プランナーダッシュボードの高品質ミニマリスト3Dイラスト。",{"schemaOrg":4442,"robots":2692,"sitemap":4447},[4443,4444],{"@type":2674,"headline":2709,"description":4438},{"@type":4445,"headline":4446,"description":4438},"Article","セルフホスト型AI旅行プランナー「TREK」の構築方法：Dockerによる簡単デプロイと便利な活用術",{"lastmod":4437},{"title":4446,"description":4438,"ogTitle":2709,"ogDescription":4438,"twitterTitle":2709,"twitterDescription":4438},"ja\u002Farticle\u002Fself-hosted-travel-planner-trek",[2700,4451,2701,2702,4452],"TREK","MCP","EEKRUAZ6vDrf0BiekEf_HPy9TiOvDIrZQrpAkxNubms",{"id":4455,"title":4456,"author":424,"body":4457,"category":5834,"date":5836,"description":5837,"extension":2666,"image":5838,"imageAlt":5839,"isPublished":771,"meta":5840,"minRead":831,"navigation":771,"path":203,"seo":5846,"stem":5848,"tags":5849,"updatedAt":2703,"__hash__":5854},"article\u002Fja\u002Farticle\u002Fsync-obsidian-across-devices.md","自ホスト型SynchとIgnisを導入しObsidian保管庫を複数デバイス間で安全に同期する方法",{"type":426,"value":4458,"toc":5812},[4459,4462,4467,4476,4485,4499,4504,4511,4515,4520,4534,4551,4554,4558,4561,4568,4573,4577,4581,4632,4638,4669,4673,4681,4688,4699,4751,4754,4769,4775,4787,4791,4795,4802,4807,4818,4835,4840,4853,4858,4864,4869,4884,4887,4891,4894,4899,4903,4908,4923,4927,4941,4950,4954,4959,4963,4973,5006,5010,5017,5145,5178,5183,5203,5209,5214,5217,5228,5300,5304,5309,5345,5474,5481,5487,5494,5500,5503,5509,5516,5530,5541,5548,5554,5561,5692,5698,5703,5706,5711,5714,5718,5724,5729,5735,5746,5755,5758,5769,5775,5781,5784,5786,5809],[429,4460,4461],{},"Obsidianは、ローカルファースト（ローカル優先）のナレッジ管理アプリです。すべてのノートはデバイス上のMarkdownファイルとして保存され、完全にユーザー自身の管理下に置かれます。しかし、ノートパソコン、スマートフォン、その他のデバイスで同じ保管庫（Vault）を共有したかったり、外出先からウェブブラウザ経由でアクセスしたかったりすることも少なくありません。",[435,4463],{"src":4464,"alt":4465,"style":4466},"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,4468,4469,4470,4475],{},"Obsidian向けにはいくつかの同期ソリューションが提供されていますが、コンフリクト（衝突）の処理、暗号化、またはデータの所有権（データ主権）などの面で、何らかのトレードオフを伴うのが一般的です。",[570,4471,4474],{"href":4472,"rel":4473},"https:\u002F\u002Fgithub.com\u002Fhjinco\u002Fsynch",[1645],"Synch","は、セルフホスト（自ホスト）サーバーを用いて、エンドツーエンド（端対端）の暗号化と自動コンフリクト処理を両立させながらObsidianの保管庫を同期できるオープンソースのアプリケーションです。",[429,4477,4478,4479,4484],{},"Obsidianのローカルファーストなアプローチはほとんどの場面で完璧に機能しますが、状況によってはウェブブラウザからリモートで保管庫にアクセスしたい場合もあります。",[570,4480,4483],{"href":4481,"rel":4482},"https:\u002F\u002Fgithub.com\u002FNystik-gh\u002Fignis",[1645],"Ignis","は、オープンソースのウェブクライアントであり、ウェブブラウザ上でObsidianをデスクトップアプリに近い形式で実行できるため、場所を問わず保管庫の閲覧・編集が可能です。",[429,4486,568,4487,4490,4491,3111,4493,4495,4496,4498],{},[443,4488,4489],{},"VPS","（仮想専用サーバー）上に",[443,4492,4474],{},[443,4494,4483],{},"をセットアップし、これらを公開インターネットにさらすのではなく、**",[570,4497,3859],{"href":363},"**のプライベートネットワーク内で安全にホストする手順を紹介します。",[435,4500],{"src":4501,"alt":4502,"style":4503},"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;",[575,4505],{"description":4506,"image":4507,"image-alt":4508,"label":4509,"min-read":581,"title":4510,"to":363},"インバウンド用のファイアウォールポートを開放することなく、Cloudflare WARPとZero Trustを用いて、Hermesエージェントをグローバルから安全に公開・アクセスする方法を解説します。","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エージェントをプライベートネットワークに安全に公開する様子","関連記事","Cloudflare WARPでHermesエージェントをプライベートに公開する方法",[448,4512,4514],{"id":4513},"synchによるobsidian保管庫の安全な同期","SynchによるObsidian保管庫の安全な同期",[429,4516,4517,4519],{},[443,4518,4474],{},"には以下の特徴があります：",[456,4521,4522,4525,4528,4531],{},[459,4523,4524],{},"変更が検出されると、即座に保管庫を同期",[459,4526,4527],{},"アップロード前に保管庫のデータを暗号化",[459,4529,4530],{},"バージョン履歴（履歴管理）からの復元が可能",[459,4532,4533],{},"自動コンフリクト処理を搭載",[429,4535,4536,4538,4539,4550],{},[443,4537,4474],{},"は、デバイス上でランダムな32バイトの",[443,4540,4541,4542,4549],{},"保管庫キー（Vault Key）",[443,4543,4544,4545,4548],{},"を生成し、これを用いてデータを暗号化します。リモート保管庫を作成する際に、",[443,4546,4547],{},"保管庫パスワード","を設定します。このパスワードは","保管庫キー","を保護するために使用され、サーバー上に安全に保管され、他のデバイスでロックを解除する際に必要となります。",[429,4552,4553],{},"コンフリクトの解決は、サーバー上ではなく、お使いのクライアントデバイス上で行われる点に注意してください。2つのデバイスが同じノートを同時に編集した場合、サーバーは最初に到着したバージョンを保持し、もう一方のデバイスを「古い（バージョン不一致）」状態としてマークします。古い状態のデバイスは、最終的なマージ後のノートをアップロードする前に、ローカルの変更内容に新しいバージョンを自動的にマージ（統合）します。",[548,4555,4557],{"id":4556},"vpsへのsynchの導入","VPSへのSynchの導入",[587,4559,4560],{"id":4560},"ドメイン名の作成",[429,4562,4563,4564,4567],{},"CloudflareでAレコードを作成し、プロキシステータスを ",[443,4565,4566],{},"「DNSのみ（DNS only）」","（CloudflareのCDNをバイパスする設定）に設定します。",[435,4569],{"src":4570,"alt":4571,"style":4572},"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;",[587,4574,4576],{"id":4575},"ubuntu上でdockerを用いたsynchのインストール","Ubuntu上でDockerを用いたSynchのインストール",[4578,4579,4580],"h5",{"id":4580},"リポジトリのクローン",[663,4582,4584],{"className":665,"code":4583,"language":667,"meta":424,"style":424},"git clone https:\u002F\u002Fgithub.com\u002Fhjinco\u002Fsynch.git       \n        \n# APIフォルダに移動\ncd synch\u002Fapps\u002Fapi\n        \n# 環境変数ファイルのサンプルをコピー\ncp .env.example .env\n",[644,4585,4586,4598,4603,4608,4615,4619,4624],{"__ignoreMap":424},[671,4587,4588,4590,4592,4595],{"class":673,"line":674},[671,4589,980],{"class":677},[671,4591,983],{"class":685},[671,4593,4594],{"class":685}," https:\u002F\u002Fgithub.com\u002Fhjinco\u002Fsynch.git",[671,4596,4597],{"class":2001},"       \n",[671,4599,4600],{"class":673,"line":740},[671,4601,4602],{"class":2001},"        \n",[671,4604,4605],{"class":673,"line":614},[671,4606,4607],{"class":736},"# APIフォルダに移動\n",[671,4609,4610,4612],{"class":673,"line":775},[671,4611,995],{"class":784},[671,4613,4614],{"class":685}," synch\u002Fapps\u002Fapi\n",[671,4616,4617],{"class":673,"line":781},[671,4618,4602],{"class":2001},[671,4620,4621],{"class":673,"line":826},[671,4622,4623],{"class":736},"# 環境変数ファイルのサンプルをコピー\n",[671,4625,4626,4628,4630],{"class":673,"line":831},[671,4627,1003],{"class":677},[671,4629,1006],{"class":685},[671,4631,1009],{"class":685},[4578,4633,4635,4637],{"id":4634},"env-ファイルの設定",[644,4636,1021],{}," ファイルの設定",[456,4639,4640,4646,4663],{},[459,4641,4642,4645],{},[644,4643,4644],{},"PUBLIC_URL=synch.pafor.me",": Synchサーバーの公開ドメイン名（前のステップで作成したドメイン名）を入力します。",[459,4647,4648,4651,4652,4655,4656,4659,4660,4662],{},[644,4649,4650],{},"BETTER_AUTH_SECRET"," と ",[644,4653,4654],{},"SYNC_TOKEN_SECRET",": この",[570,4657,4658],{"href":1061},"オンライン秘密鍵生成ツール","を使用するか、ターミナルで ",[644,4661,1066],{}," を2回実行して安全な鍵を生成します。",[459,4664,4665,4668],{},[644,4666,4667],{},"AUTH_ALLOWED_EMAILS",": アカウント作成とサインアップを許可するメールアドレスをカンマ区切りで指定します。",[4578,4670,4672],{"id":4671},"caddyfileへのドメインの追加","Caddyfileへのドメインの追加",[429,4674,4675,4676,4680],{},"Cloudflare DNSモジュールをCaddyに統合し、コンテナ内で起動する方法の詳細については、こちらの",[570,4677,4679],{"href":4678},"\u002Farticle\u002Fself-hosting-buzz-as-the-workspace-where-ai-agents-become-colleagues#_4-enable-https-with-caddy","セルフホストBuzzに関する記事","をご参照ください。",[575,4682],{"description":4683,"image":4684,"image-alt":4685,"label":4686,"min-read":4687,"title":423,"to":4678},"Dockerコンテナ内のCaddyが、Cloudflare DNS認証チャレンジを用いて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","自己ホスト型ワークスペースにおいて、SSL\u002FTLS証明書の自動生成のためにCloudflare DNS APIトークンを使用してCaddyを構成する構成図","セルフホストガイド","12",[429,4689,4690,4691,4694,4695,4698],{},"Caddyfileに ",[644,4692,4693],{},"SYNCH_DOMAIN"," ディレクティブを追加し、ポート ",[644,4696,4697],{},"8787","（Synchコンテナが使用するポート）を指定します：",[663,4700,4702],{"className":3058,"code":4701,"language":3060,"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",[644,4703,4704,4708,4715,4719,4723,4734,4738,4747],{"__ignoreMap":424},[671,4705,4706],{"class":673,"line":674},[671,4707,1165],{"class":681},[671,4709,4710,4713],{"class":673,"line":740},[671,4711,4712],{"class":2001},"  acme_dns cloudflare {env.CLOUDFLARE_API_TOKEN",[671,4714,1179],{"class":681},[671,4716,4717],{"class":673,"line":614},[671,4718,1179],{"class":2001},[671,4720,4721],{"class":673,"line":775},[671,4722,772],{"emptyLinePlaceholder":771},[671,4724,4725,4727,4730,4732],{"class":673,"line":781},[671,4726,3067],{"class":681},[671,4728,4729],{"class":2001},"$SYNCH_DOMAIN",[671,4731,3073],{"class":681},[671,4733,3076],{"class":681},[671,4735,4736],{"class":673,"line":826},[671,4737,3081],{"class":2001},[671,4739,4740,4742,4744],{"class":673,"line":831},[671,4741,3086],{"class":2001},[671,4743,1268],{"class":681},[671,4745,4746],{"class":1303},"8787\n",[671,4748,4749],{"class":673,"line":837},[671,4750,1179],{"class":681},[429,4752,4753],{},"コンテナを起動します：",[663,4755,4757],{"className":665,"code":4756,"language":667,"meta":424,"style":424},"docker compose up -d\n",[644,4758,4759],{"__ignoreMap":424},[671,4760,4761,4763,4765,4767],{"class":673,"line":674},[671,4762,921],{"class":677},[671,4764,963],{"class":685},[671,4766,1553],{"class":685},[671,4768,1556],{"class":685},[429,4770,4771,4772,4774],{},"次の ",[644,4773,678],{}," コマンドを実行して、稼働状況を確認します：",[663,4776,4778],{"className":665,"code":4777,"language":667,"meta":424,"style":424},"curl https:\u002F\u002Fsynch.pafor.me\u002Fhealth\n",[644,4779,4780],{"__ignoreMap":424},[671,4781,4782,4784],{"class":673,"line":674},[671,4783,678],{"class":677},[671,4785,4786],{"class":685}," https:\u002F\u002Fsynch.pafor.me\u002Fhealth\n",[548,4788,4790],{"id":4789},"obsidianとsynchサーバーの接続","ObsidianとSynchサーバーの接続",[587,4792,4794],{"id":4793},"obsidianへのsynchプラグインのインストール","ObsidianへのSynchプラグインのインストール",[429,4796,4797,4798,4801],{},"Obsidianの設定を開き、**「コミュニティプラグイン」",[443,4799,4800],{},"に移動して、","「閲覧（Browse）」**ボタンをクリックします：",[435,4803],{"src":4804,"alt":4805,"style":4806},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fobsidian-community-plugins-browse.webp","Obsidian設定でのコミュニティプラグインの閲覧","max-width: 523px; width: 100%; height: auto;",[429,4808,4809,4810,4813,4814],{},"検索バーで ",[443,4811,4812],{},"「Synchrun」"," を探し、インストールします：\n",[435,4815],{"src":4816,"alt":4817,"style":4572},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fobsidian-install-synchrun-plugin.webp","ObsidianへのSynchrunプラグインのインストール",[429,4819,4820,4822,4823,4826,4827,4834],{},[443,4821,4812],{}," のインストール完了後、プラグインの設定を開き、**「Use a self-hosted server（自ホストサーバーを使用）」",[443,4824,4825],{},"を有効にします。次に、","「Server URL」",[443,4828,4829,4830,4833],{},"フィールドに ",[644,4831,4832],{},"https:\u002F\u002Fsynch.pafor.me"," を入力し、","「Save」**をクリックします。",[435,4836],{"src":4837,"alt":4838,"style":4839},"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,4841,4842,4843,4846,4847,4849,4850,4852],{},"**「Account」**項目内にある ",[443,4844,4845],{},"「Sign in on this device（このデバイスでサインイン）」"," ボタンをクリックします。続いて、",[644,4848,1021],{}," ファイルの ",[644,4851,4667],{}," リストに指定したメールアドレスを使ってサインアップ（アカウント登録）を行います。完了後、以下の認証ページにリダイレクトされます：",[435,4854],{"src":4855,"alt":4856,"style":4857},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fsynchrun-account-authorization-page.webp","Synchrunのアカウント認証ページ","max-width: 494px; width: 100%; height: auto;",[429,4859,4860,4863],{},[443,4861,4862],{},"「Allow Obsidian sign-in（Obsidianへのサインインを許可）」"," ボタンをクリックします：",[435,4865],{"src":4866,"alt":4867,"style":4868},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fsynchrun-allow-obsidian-signin.webp","SynchのためのObsidianサインインの許可","max-width: 498px; width: 100%; height: auto;",[429,4870,4871,4874,4875,4878,4879],{},[443,4872,4873],{},"「Return to Obsidian（Obsidianに戻る）」"," ボタンをクリックし、次に ",[443,4876,4877],{},"「Create vault（保管庫の作成）」"," をクリックします：\n",[435,4880],{"src":4881,"alt":4882,"style":4883},"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,4885,4886],{},"リモート保管庫の名前と安全なパスワードを入力して作成します。",[435,4888],{"src":4889,"alt":4890,"style":1591},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fobsidian-synchrun-vault-password-setup.webp","Obsidianリモート保管庫の安全なパスワードの設定",[429,4892,4893],{},"これで自動的に同期処理が開始されます。お使いの保管庫の容量によって完了までにかかる時間は異なります。同期完了後、ストレージの総使用量が表示されます。",[435,4895],{"src":4896,"alt":4897,"style":4898},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fobsidian-synchrun-sync-completed-storage.webp","使用中の合計ストレージを示すSynchrun同期完了画面","max-width: 508px; width: 100%; height: auto;",[448,4900,4902],{"id":4901},"ignisによるブラウザベースのobsidianアクセス","IgnisによるブラウザベースのObsidianアクセス",[429,4904,4905,4907],{},[443,4906,4483],{},"は、Obsidianが使用するElectron APIをWeb APIに置き換えることで、標準的なウェブブラウザ上で直接ObsidianのJavaScriptコードを実行可能にするツールです。すべてのMarkdownファイルと添付ファイルは、ホストサーバー上のファイルシステムに直接保存されます。",[429,4909,4910,4911,4916,4917,4922],{},"ただし、スタンドアロン型のObsidianデスクトップアプリと比較して、いくつかの制限事項が存在します。ブラウザ環境に直接対応する機能がないElectron APIやNode.js APIに依存する一部の機能やサードパーティ製プラグインは動作しません。詳細な互換性については、Ignis公式の ",[570,4912,4915],{"href":4913,"rel":4914},"https:\u002F\u002Fignis.thiefling.com\u002Fdocs\u002Fusing\u002Flimitations\u002F",[1645],"Limitations（制限事項）"," および ",[570,4918,4921],{"href":4919,"rel":4920},"https:\u002F\u002Fignis.thiefling.com\u002Fdocs\u002Fusing\u002Fplugin-compatibility\u002F",[1645],"Plugin compatibility（プラグイン互換性）"," ガイドをご参照ください。",[548,4924,4926],{"id":4925},"ignisのセットアップ","Ignisのセットアップ",[429,4928,4929,4930,4932,4933,4936,4937,4940],{},"今回はDockerを使用し、VPS上に ",[443,4931,4483],{}," をインストールして、ローカルの ",[644,4934,4935],{},".\u002Fvaults"," フォルダにマウントします。この保管庫ディレクトリは、先ほど設定したリモート保管庫から最新のノートデータを取得するために、",[443,4938,4939],{},"Synch CLI","を用いてバックグラウンドで自動同期されます。",[429,4942,4943,4944,4946,4947,4949],{},"また、",[443,4945,4483],{},"には標準でユーザー認証機能が備わっていないため、外部からの不正アクセスを防ぐために、**",[570,4948,3859],{"href":363},"**のプライベートネットワークの背後に隠して安全を確保します。",[587,4951,4953],{"id":4952},"dnsレコードの作成","DNSレコードの作成",[435,4955],{"src":4956,"alt":4957,"style":4958},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fcloudflare-dns-a-record-ignis.webp","CloudflareでのIgnis Webクライアント用DNS Aレコードの構成","max-width: 552px; width: 100%; height: auto;",[587,4960,4962],{"id":4961},"caddyfileへのドメイン追加","Caddyfileへのドメイン追加",[429,4964,4965,4968,4969,4972],{},[644,4966,4967],{},"synch.pafor.me"," と同様に、Caddyfileに ",[644,4970,4971],{},"obsidian.pafor.me"," を追加します：",[663,4974,4976],{"className":3058,"code":4975,"language":3060,"meta":424,"style":424},"{$OBSIDIAN_DOMAIN} {\n  encode zstd gzip\n  reverse_proxy host.docker.internal:9898\n}\n",[644,4977,4978,4989,4993,5002],{"__ignoreMap":424},[671,4979,4980,4982,4985,4987],{"class":673,"line":674},[671,4981,3067],{"class":681},[671,4983,4984],{"class":2001},"$OBSIDIAN_DOMAIN",[671,4986,3073],{"class":681},[671,4988,3076],{"class":681},[671,4990,4991],{"class":673,"line":740},[671,4992,3081],{"class":2001},[671,4994,4995,4997,4999],{"class":673,"line":614},[671,4996,3086],{"class":2001},[671,4998,1268],{"class":681},[671,5000,5001],{"class":1303},"9898\n",[671,5003,5004],{"class":673,"line":775},[671,5005,1179],{"class":681},[587,5007,5009],{"id":5008},"dockerを使用したignisの起動","Dockerを使用したIgnisの起動",[429,5011,5012,5013,5016],{},"以下の docker-compose yml の内容を ",[644,5014,5015],{},"ignis-docker-compose.yml"," としてVPS上に保存します：",[663,5018,5020],{"className":1156,"code":5019,"language":1158,"meta":424,"style":424},"services:\n  ignis:\n    image: nobbe\u002Fignis:latest\n    ports:\n      - \"9898:8080\"\n    environment:\n      # お使いのホストユーザーのUID\u002FGIDに合わせて構成してください (確認コマンド: 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",[644,5021,5022,5028,5035,5044,5050,5061,5067,5072,5079,5086,5093,5099,5106,5113,5120,5128,5132,5138],{"__ignoreMap":424},[671,5023,5024,5026],{"class":673,"line":674},[671,5025,1250],{"class":1249},[671,5027,1253],{"class":681},[671,5029,5030,5033],{"class":673,"line":740},[671,5031,5032],{"class":1249},"  ignis",[671,5034,1253],{"class":681},[671,5036,5037,5039,5041],{"class":673,"line":614},[671,5038,1319],{"class":1249},[671,5040,1268],{"class":681},[671,5042,5043],{"class":685}," nobbe\u002Fignis:latest\n",[671,5045,5046,5048],{"class":673,"line":775},[671,5047,1265],{"class":1249},[671,5049,1253],{"class":681},[671,5051,5052,5054,5056,5059],{"class":673,"line":781},[671,5053,1386],{"class":681},[671,5055,682],{"class":681},[671,5057,5058],{"class":685},"9898:8080",[671,5060,700],{"class":681},[671,5062,5063,5065],{"class":673,"line":826},[671,5064,1353],{"class":1249},[671,5066,1253],{"class":681},[671,5068,5069],{"class":673,"line":831},[671,5070,5071],{"class":736},"      # お使いのホストユーザーのUID\u002FGIDに合わせて構成してください (確認コマンド: id)\n",[671,5073,5074,5076],{"class":673,"line":837},[671,5075,1386],{"class":681},[671,5077,5078],{"class":685}," PUID=1000\n",[671,5080,5081,5083],{"class":673,"line":849},[671,5082,1386],{"class":681},[671,5084,5085],{"class":685}," PGID=1000\n",[671,5087,5088,5090],{"class":673,"line":854},[671,5089,1386],{"class":681},[671,5091,5092],{"class":685}," WS_ORIGINS=https:\u002F\u002Fobsidian.pafor.me\n",[671,5094,5095,5097],{"class":673,"line":860},[671,5096,1409],{"class":1249},[671,5098,1253],{"class":681},[671,5100,5101,5103],{"class":673,"line":882},[671,5102,1386],{"class":681},[671,5104,5105],{"class":685}," .\u002Fvaults:\u002Fvaults\n",[671,5107,5108,5110],{"class":673,"line":887},[671,5109,1386],{"class":681},[671,5111,5112],{"class":685}," .\u002Fdata:\u002Fapp\u002Fdata\n",[671,5114,5115,5117],{"class":673,"line":893},[671,5116,1386],{"class":681},[671,5118,5119],{"class":685}," obsidian-app:\u002Fapp\u002Fobsidian-app\n",[671,5121,5122,5124,5126],{"class":673,"line":907},[671,5123,1438],{"class":1249},[671,5125,1268],{"class":681},[671,5127,1443],{"class":685},[671,5129,5130],{"class":673,"line":912},[671,5131,772],{"emptyLinePlaceholder":771},[671,5133,5134,5136],{"class":673,"line":918},[671,5135,1470],{"class":1249},[671,5137,1253],{"class":681},[671,5139,5140,5143],{"class":673,"line":927},[671,5141,5142],{"class":1249},"  obsidian-app",[671,5144,1253],{"class":681},[456,5146,5147,5158,5172],{},[459,5148,5149,5150,5153,5154,5157],{},"ポート ",[644,5151,5152],{},"8080"," は他のサービスと競合しやすいため、ホスト側では ",[644,5155,5156],{},"9898"," を使用します。",[459,5159,5160,5161,5164,5165,4651,5168,5171],{},"VPS上で ",[644,5162,5163],{},"id"," コマンドを実行し、お使いのホストユーザーの ",[644,5166,5167],{},"UID",[644,5169,5170],{},"GID"," を確認・設定して、適切なファイルシステム権限が適用されるようにします。",[459,5173,5174,5177],{},[644,5175,5176],{},"WS_ORIGINS"," を設定し、指定した独自ドメインのみからWebSocket接続を受け入れるよう制限します。",[429,5179,5180,5182],{},[443,5181,4483],{}," のコンテナを起動します：",[663,5184,5186],{"className":665,"code":5185,"language":667,"meta":424,"style":424},"docker compose -f ignis-docker-compose.yml up -d\n",[644,5187,5188],{"__ignoreMap":424},[671,5189,5190,5192,5194,5196,5199,5201],{"class":673,"line":674},[671,5191,921],{"class":677},[671,5193,963],{"class":685},[671,5195,1542],{"class":685},[671,5197,5198],{"class":685}," ignis-docker-compose.yml",[671,5200,1553],{"class":685},[671,5202,1556],{"class":685},[429,5204,5205,5206,5208],{},"ウェブブラウザで設定したドメインにアクセスすると、**「Vault Manager（保管庫マネージャー）」**が表示されます。まだ保管庫が作成されていないため、画面は空の状態です。次のセクションで、リモート保管庫とデータを同期するために ",[443,5207,4939],{}," の設定を行います。",[435,5210],{"src":5211,"alt":5212,"style":5213},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fignis-vault-manager-empty.webp","Ignis Webクライアントの空のVault Managerインターフェース","max-width: 466px; width: 100%; height: auto;",[587,5215,5216],{"id":5216},"ファイアウォールに関する注意点",[429,5218,5219,5220,5223,5224,5227],{},"Dockerの標準仕様として、コンテナを起動すると自動的にDNATおよびFORWARDルールがiptablesへ挿入され、外部からの通信がダイレクトに対象コンテナへルーティングされます。この挙動は、Ubuntuに標準搭載されているUFWやiptablesの ",[644,5221,5222],{},"INPUT"," チェーンによる制御をバイパスしてしまいます。コンテナを完全にプライベート化し、不要な通信を遮断するために、手動で以下のルールを ",[644,5225,5226],{},"iptables"," に適用します：",[663,5229,5231],{"className":665,"code":5230,"language":667,"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",[644,5232,5233,5238,5266,5270,5275],{"__ignoreMap":424},[671,5234,5235],{"class":673,"line":674},[671,5236,5237],{"class":736},"# 外部公開インターフェースからのトラフィックをすべて拒否\n",[671,5239,5240,5242,5245,5248,5251,5254,5257,5260,5263],{"class":673,"line":740},[671,5241,840],{"class":677},[671,5243,5244],{"class":685}," iptables",[671,5246,5247],{"class":685}," -I",[671,5249,5250],{"class":685}," DOCKER-USER",[671,5252,5253],{"class":685}," -i",[671,5255,5256],{"class":685}," ext_if",[671,5258,5259],{"class":685}," -j",[671,5261,5262],{"class":685}," DROP",[671,5264,5265],{"class":2001}," \n",[671,5267,5268],{"class":673,"line":614},[671,5269,772],{"emptyLinePlaceholder":771},[671,5271,5272],{"class":673,"line":775},[671,5273,5274],{"class":736},"# 許可する特定のCloudflare WARPクライアントのプライベートIPからのみアクセスを許可\n",[671,5276,5277,5279,5281,5283,5285,5287,5289,5292,5295,5297],{"class":673,"line":781},[671,5278,840],{"class":677},[671,5280,5244],{"class":685},[671,5282,5247],{"class":685},[671,5284,5250],{"class":685},[671,5286,5253],{"class":685},[671,5288,5256],{"class":685},[671,5290,5291],{"class":685}," -s",[671,5293,5294],{"class":1303}," 100.96.0.10",[671,5296,5259],{"class":685},[671,5298,5299],{"class":685}," ACCEPT\n",[587,5301,5303],{"id":5302},"synch-cliのセットアップ","Synch CLIのセットアップ",[429,5305,5306,5308],{},[443,5307,4939],{},"は、グラフィカルなUIを持たない（CUI用の）ツールであり、デスクトップ版のアプリケーション一式をインストールすることなく、リモートサーバー上で直接Obsidianの保管庫フォルダを同期させることができます。",[429,5310,5311,5312,5315,5316,5318,5319,5322,5323,5326,5327,4043,5330,4043,5333,5336,5337,5340,5341,5344],{},"先ほどクローンした ",[644,5313,5314],{},"synch"," リポジトリから、",[443,5317,4939],{},"をビルドします。ビルドには、",[443,5320,5321],{},"Node.js >= 22.5","（CLIが内部で ",[644,5324,5325],{},"node:sqlite"," や、",[644,5328,5329],{},"fetch",[644,5331,5332],{},"WebSocket",[644,5334,5335],{},"WebCrypto"," などのブラウザ互換APIに依存しているため）および ",[443,5338,5339],{},"pnpm","（リポジトリがバージョン ",[644,5342,5343],{},"10.33.0"," のpnpmワークスペースとして管理されているため）が必要です：",[663,5346,5348],{"className":665,"code":5347,"language":667,"meta":424,"style":424},"# バージョンの確認\nnode --version   # 22.5以上であることを確認\npnpm --version\n\n# リポジトリのルートディレクトリで\npnpm install\n\n# CLIのビルドを実行\npnpm -C apps\u002Fcli build\n\n# ビルドに成功すると、`apps\u002Fcli\u002Fdist\u002Fsynch.js` が生成されます。実行権限を付与し、パスの通った場所に配置します\nchmod +x apps\u002Fcli\u002Fdist\u002Fsynch.js\nln -sf \"$PWD\u002Fapps\u002Fcli\u002Fdist\u002Fsynch.js\" \"$HOME\u002F.local\u002Fbin\u002Fsynch\"\n\n# 正しく導入されたか確認\nsynch --help\n",[644,5349,5350,5355,5366,5372,5376,5381,5388,5392,5397,5410,5414,5419,5430,5458,5462,5467],{"__ignoreMap":424},[671,5351,5352],{"class":673,"line":674},[671,5353,5354],{"class":736},"# バージョンの確認\n",[671,5356,5357,5360,5363],{"class":673,"line":740},[671,5358,5359],{"class":677},"node",[671,5361,5362],{"class":685}," --version",[671,5364,5365],{"class":736},"   # 22.5以上であることを確認\n",[671,5367,5368,5370],{"class":673,"line":614},[671,5369,5339],{"class":677},[671,5371,924],{"class":685},[671,5373,5374],{"class":673,"line":775},[671,5375,772],{"emptyLinePlaceholder":771},[671,5377,5378],{"class":673,"line":781},[671,5379,5380],{"class":736},"# リポジトリのルートディレクトリで\n",[671,5382,5383,5385],{"class":673,"line":826},[671,5384,5339],{"class":677},[671,5386,5387],{"class":685}," install\n",[671,5389,5390],{"class":673,"line":831},[671,5391,772],{"emptyLinePlaceholder":771},[671,5393,5394],{"class":673,"line":837},[671,5395,5396],{"class":736},"# CLIのビルドを実行\n",[671,5398,5399,5401,5404,5407],{"class":673,"line":849},[671,5400,5339],{"class":677},[671,5402,5403],{"class":685}," -C",[671,5405,5406],{"class":685}," apps\u002Fcli",[671,5408,5409],{"class":685}," build\n",[671,5411,5412],{"class":673,"line":854},[671,5413,772],{"emptyLinePlaceholder":771},[671,5415,5416],{"class":673,"line":860},[671,5417,5418],{"class":736},"# ビルドに成功すると、`apps\u002Fcli\u002Fdist\u002Fsynch.js` が生成されます。実行権限を付与し、パスの通った場所に配置します\n",[671,5420,5421,5424,5427],{"class":673,"line":882},[671,5422,5423],{"class":677},"chmod",[671,5425,5426],{"class":685}," +x",[671,5428,5429],{"class":685}," apps\u002Fcli\u002Fdist\u002Fsynch.js\n",[671,5431,5432,5435,5438,5440,5443,5446,5448,5450,5453,5456],{"class":673,"line":887},[671,5433,5434],{"class":677},"ln",[671,5436,5437],{"class":685}," -sf",[671,5439,682],{"class":681},[671,5441,5442],{"class":2001},"$PWD",[671,5444,5445],{"class":685},"\u002Fapps\u002Fcli\u002Fdist\u002Fsynch.js",[671,5447,689],{"class":681},[671,5449,682],{"class":681},[671,5451,5452],{"class":2001},"$HOME",[671,5454,5455],{"class":685},"\u002F.local\u002Fbin\u002Fsynch",[671,5457,700],{"class":681},[671,5459,5460],{"class":673,"line":893},[671,5461,772],{"emptyLinePlaceholder":771},[671,5463,5464],{"class":673,"line":907},[671,5465,5466],{"class":736},"# 正しく導入されたか確認\n",[671,5468,5469,5471],{"class":673,"line":912},[671,5470,5314],{"class":677},[671,5472,5473],{"class":685}," --help\n",[429,5475,5476,5477,5480],{},"ビルドしたSynch CLIは、リモートのSynch保管庫が稼働しているのと同じVPS上で実行するため、ローカルのAPIサーバーに直接接続できます。もし別の独立したサーバーから同期を設定する場合は、",[644,5478,5479],{},"synch login --api-url \u003CリモートのSynchのAPIのURL>"," を実行してあらかじめ接続先を定義しておきます。",[429,5482,5483],{},[435,5484],{"alt":5485,"src":5486},"ターミナルでカスタムAPI URLを使用してsynch loginを実行する","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fsynch-login-api-url-terminal.webp",[429,5488,5489,5490,5493],{},"ターミナルで ",[644,5491,5492],{},"synch login"," を実行すると、認証用URLが提示されます：",[429,5495,5496],{},[435,5497],{"alt":5498,"src":5499},"Synch CLIの認証URLを示すターミナル出力","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fsynch-login-auth-url-terminal.webp",[429,5501,5502],{},"デスクトップ版ObsidianのSynchrunプラグインに登録したのと同じメールアドレスを用いて、提示されたウェブページからログインします。",[429,5504,5505],{},[435,5506],{"alt":5507,"src":5508},"Synch CLI認証のためのWebログインの成功","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fsynch-web-login-success.webp",[429,5510,5511,5512,5515],{},"ログイン後、",[644,5513,5514],{},"synch vault connect --vault ~\u002Fvaults\u002F\u003C保管庫名> --vault-id asadqe-7b29-4677-fsad-234asdafasd"," を実行して、VPS上のローカルディレクトリとリモートの保管庫を紐づけます。",[429,5517,5518,5519,5521,5522,5525,5526,5529],{},"リモート保管庫のID（Vault ID）は、デスクトップ版プラグインの ",[443,5520,4812],{}," 設定画面の ",[443,5523,5524],{},"「Manage remote vaults（リモート保管庫の管理）」"," から確認可能です。クリックするとウェブページが開き、固有のGUID（例: ",[644,5527,5528],{},"123e4567-e89b-12d3-a456-426614174000","）が設定された保管庫一覧が表示されます：",[429,5531,5532,5537],{},[435,5533],{"src":5534,"alt":5535,"style":5536},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fsynchrun-manage-remote-vaults.webp","Synchrunプラグインでのリモート保管庫の管理","max-width: 582px; width: 100%; height: auto;",[435,5538],{"alt":5539,"src":5540},"Synchrunでの一意のリモート保管庫IDの検索","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fsynchrun-remote-vault-id.webp",[429,5542,5543,5544,5547],{},"プロンプトの指示に従って保管庫のパスワードを入力すると、接続が確立されます。その後、",[644,5545,5546],{},"synch sync --vault ~\u002Fvaults\u002F\u003C保管庫名>"," を実行して最初の同期処理（イニシャル同期）を行います。初回はデータ量に応じて数分〜数十分ほどかかる場合があります。",[429,5549,5550],{},[435,5551],{"alt":5552,"src":5553},"Synch CLIでの初期保管庫同期の進行状況","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fsynch-cli-initial-sync-progress.webp",[429,5555,5556,5557,5560],{},"この同期処理を常時自動化するために、システム起動時にバックグラウンドで ",[644,5558,5559],{},"synch watch"," が自動実行され、変更を即座に反映できるように、systemdのサービスユニットを作成して有効化します：",[663,5562,5564],{"className":665,"code":5563,"language":667,"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",[644,5565,5566,5581,5586,5591,5596,5601,5605,5610,5615,5620,5625,5630,5635,5640,5645,5650,5654,5659,5664,5669,5678],{"__ignoreMap":424},[671,5567,5568,5570,5572,5575,5578],{"class":673,"line":674},[671,5569,840],{"class":677},[671,5571,814],{"class":685},[671,5573,5574],{"class":685}," \u002Fetc\u002Fsystemd\u002Fsystem\u002Fsynch-watch.service",[671,5576,5577],{"class":681}," \u003C\u003C",[671,5579,5580],{"class":681},"'EOF'\n",[671,5582,5583],{"class":673,"line":740},[671,5584,5585],{"class":685},"[Unit]\n",[671,5587,5588],{"class":673,"line":614},[671,5589,5590],{"class":685},"Description=Synch vault watcher\n",[671,5592,5593],{"class":673,"line":775},[671,5594,5595],{"class":685},"After=network-online.target\n",[671,5597,5598],{"class":673,"line":781},[671,5599,5600],{"class":685},"Wants=network-online.target\n",[671,5602,5603],{"class":673,"line":826},[671,5604,772],{"emptyLinePlaceholder":771},[671,5606,5607],{"class":673,"line":831},[671,5608,5609],{"class":685},"[Service]\n",[671,5611,5612],{"class":673,"line":837},[671,5613,5614],{"class":685},"Type=simple\n",[671,5616,5617],{"class":673,"line":849},[671,5618,5619],{"class":685},"User=\u003Cusername>\n",[671,5621,5622],{"class":673,"line":854},[671,5623,5624],{"class":685},"ExecStart=\u002Fhome\u002F\u003Cusername>\u002F.local\u002Fbin\u002Fsynch watch --vault \u002Fhome\u002F\u003Cusername>\u002Fvaults\u002F\u003Cvault-name>\n",[671,5626,5627],{"class":673,"line":860},[671,5628,5629],{"class":685},"WorkingDirectory=\u002Fhome\u002F\u003Cusername>\u002Fvaults\n",[671,5631,5632],{"class":673,"line":882},[671,5633,5634],{"class":685},"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",[671,5636,5637],{"class":673,"line":887},[671,5638,5639],{"class":685},"Environment=\"HOME=\u002Fhome\u002F\u003Cusername>\"\n",[671,5641,5642],{"class":673,"line":893},[671,5643,5644],{"class":685},"Restart=always\n",[671,5646,5647],{"class":673,"line":907},[671,5648,5649],{"class":685},"RestartSec=5\n",[671,5651,5652],{"class":673,"line":912},[671,5653,772],{"emptyLinePlaceholder":771},[671,5655,5656],{"class":673,"line":918},[671,5657,5658],{"class":685},"[Install]\n",[671,5660,5661],{"class":673,"line":927},[671,5662,5663],{"class":685},"WantedBy=multi-user.target\n",[671,5665,5666],{"class":673,"line":932},[671,5667,5668],{"class":681},"EOF\n",[671,5670,5671,5673,5675],{"class":673,"line":947},[671,5672,840],{"class":677},[671,5674,898],{"class":685},[671,5676,5677],{"class":685}," daemon-reload\n",[671,5679,5680,5682,5684,5686,5689],{"class":673,"line":952},[671,5681,840],{"class":677},[671,5683,898],{"class":685},[671,5685,901],{"class":685},[671,5687,5688],{"class":685}," --now",[671,5690,5691],{"class":685}," synch-watch.service\n",[429,5693,5694,5695,5697],{},"ブラウザで ",[644,5696,4971],{}," にアクセスしてみましょう。以下のように、デスクトップ版とほとんど見分けがつかない美しいインターフェースとノートレイアウトが表示されます：",[435,5699],{"src":5700,"alt":5701,"style":5702},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fignis-web-interface-desktop-view.webp","デスクトップでObsidian保管庫を表示するIgnis Webインターフェース","max-width: 593px; width: 100%; height: auto;",[429,5704,5705],{},"設定アイコンを開くと、ほぼすべての基本設定がそのまま引き継がれていることが確認できます。ただし、コミュニティプラグインについては、ブラウザ側で必要に応じて個別に再インストールを行う必要があります：",[435,5707],{"src":5708,"alt":5709,"style":5710},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fignis-settings-community-plugins.webp","Ignis Webインターフェースのコミュニティプラグイン設定","max-width: 597px; width: 100%; height: auto;",[429,5712,5713],{},"動作テストとして、このウェブ画面側から新しくノートを1枚追加してみます：",[435,5715],{"src":5716,"alt":5717,"style":5710},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fignis-create-new-note-web.webp","Ignis Webインターフェースを介した新しいMarkdownメモの作成",[429,5719,5720,5721,5723],{},"作成すると、即座にデスクトップ側のObsidianアプリにも同期され反映されることが確認できます。なお、中身が空のフォルダは ",[443,5722,4483],{}," の画面上には表示されない仕様になっています。",[435,5725],{"src":5726,"alt":5727,"style":5728},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fobsidian-desktop-synced-note.webp","新しく作成されたメモがObsidianデスクトップアプリに正常に同期されました","max-width: 502px; width: 100%; height: auto;",[429,5730,5731,5732,5734],{},"スマートフォンなどのモバイルブラウザから ",[644,5733,4971],{}," にアクセスした場合の表示：",[429,5736,5737,5742],{},[435,5738],{"src":5739,"alt":5740,"style":5741},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fignis-mobile-view-sidebar.webp","モバイルデバイスでのIgnis Webクライアントのサイドバーナビゲーション","max-width: 269px; width: 100%; height: auto;",[435,5743],{"src":5744,"alt":5745,"style":5741},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fignis-mobile-view-editor.webp","モバイルデバイスでのIgnis WebクライアントのMarkdownメモエディター",[429,5747,4943,5748,5750,5751,5754],{},[443,5749,4483],{},"上で不要になったノートを削除した場合、そのノートはローカル保管庫内の ",[644,5752,5753],{},"~\u002Fvaults\u002F\u003C保管庫名>\u002F.trash"," フォルダへ安全に移動（ゴミ箱行き）となります。",[448,5756,5757],{"id":5757},"自己ホスト型保管庫に関するまとめ",[429,5759,5760,5761,4651,5763,5765,5766,5768],{},"オープンソースの ",[443,5762,4474],{},[443,5764,4483],{}," を組み合わせることで、自分が完全に管理・所有するインフラ上で、メインのObsidian保管庫をデバイスを選ばず安全に同期・活用できるようになります。また、これらのサービスを ",[443,5767,3859],{}," の閉域プライベートネットワーク内に配置することで、あなたの大切な個人ノートを公開インターネットの脅威から完全に隔離・保護することが可能です。",[429,5770,5771,5772,5774],{},"なお、",[443,5773,4483],{},"はデスクトップ版のローカルアプリを100%代替することを狙って作られたものではありません。あくまで「手元に普段のパソコンがない時や、他環境のブラウザからノートを一時的に確認・編集したい場合」に重宝する、軽量かつ機動性に優れたウェブクライアントとしての役割を担います。普段のノート記述や細かなカスタマイズ、プラグインの本格的な利用には、引き続きObsidianのネイティブアプリを主軸として活用するのが最善です。",[429,5776,5777,5778,5780],{},"最後に、Synchはエンドツーエンドで強力に暗号化されているため、ブルートフォース（総当たり）攻撃からノートを守るためには、十分に強固なリモート保管庫パスワードの設定が必須です。万が一パスワードを紛失した場合、サーバー側には復号された ",[443,5779,4549],{}," は一切保存されていないため、データを復元することは絶対に不可能です。VPSのインスタンスのセキュリティ管理、および自動スナップショットやバックアップのメンテナンスも、怠らず適切に行ってください。",[429,5782,5783],{},"Synchの履歴管理機能やゴミ箱への退避機能によって、誤操作によるデータ消失の大半は防げますが、大切なナレッジを守るためにも、Obsidian保管庫全体の独立したバックアップを別途定期的に取得しておくことを強くお勧めします。",[448,5785,4366],{"id":4366},[456,5787,5788,5795,5802],{},[459,5789,5790],{},[570,5791,5794],{"href":5792,"rel":5793},"https:\u002F\u002Fsynch.run\u002Fself-hosting-docker\u002F",[1645],"Docker Composeを用いたSynchのデプロイ方法",[459,5796,5797],{},[570,5798,5801],{"href":5799,"rel":5800},"https:\u002F\u002Fignis.thiefling.com\u002Fdocs\u002Fserver\u002Fdeploy\u002F",[1645],"Dockerを用いたIgnisのデプロイ方法",[459,5803,5804],{},[570,5805,5808],{"href":5806,"rel":5807},"https:\u002F\u002Fsynch.run\u002Fblog\u002Fencryption-and-decryption\u002F",[1645],"Synchにおけるエンドツーエンド暗号化の仕組み",[2628,5810,5811],{},"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":740,"depth":614,"links":5813},[5814,5823,5832,5833],{"id":4513,"depth":740,"text":4514,"children":5815},[5816,5820],{"id":4556,"depth":614,"text":4557,"children":5817},[5818,5819],{"id":4560,"depth":775,"text":4560},{"id":4575,"depth":775,"text":4576},{"id":4789,"depth":614,"text":4790,"children":5821},[5822],{"id":4793,"depth":775,"text":4794},{"id":4901,"depth":740,"text":4902,"children":5824},[5825],{"id":4925,"depth":614,"text":4926,"children":5826},[5827,5828,5829,5830,5831],{"id":4952,"depth":775,"text":4953},{"id":4961,"depth":775,"text":4962},{"id":5008,"depth":775,"text":5009},{"id":5216,"depth":775,"text":5216},{"id":5302,"depth":775,"text":5303},{"id":5757,"depth":740,"text":5757},{"id":4366,"depth":740,"text":4366},[5835],"productivity","2026-09-15","Cloudflare Zero Trust環境において、自ホスト型のSynchとIgnisを導入し、複数デバイス間でObsidianの保管庫（Vault）を安全に同期・暗号化するとともに、ウェブブラウザ経由でノートを安全に閲覧・編集するための、強固なプライベートネットワーク構築手順を詳しく解説します。","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002FJA-Sync-Obsidian-Across-Devices.webp","セルフホストSynchとIgnisを使用し、Cloudflare Zero Trustプライベートネットワーク内で安全に複数デバイス間のObsidian保管庫を同期している図",{"schemaOrg":5841,"robots":2692,"sitemap":5844},[5842,5843],{"@type":4445,"headline":4456,"description":5837,"image":5838},{"@type":2674,"name":4456,"description":5837,"image":5838},{"lastmod":5845},"2026-09-16",{"title":5847,"description":5837,"ogTitle":4456,"ogDescription":5837,"twitterTitle":4456,"twitterDescription":5837},"Cloudflare Zero Trustによる安全なObsidian同期と自ホスト型Synch・Ignisの構築","ja\u002Farticle\u002Fsync-obsidian-across-devices",[5850,5851,5852,5853],"セルフホスト","Obsidian","同期","Zero Trust","vLEe3YjLuAqtVGuhjnjR-zFGxNLCqkKj0P9t3ekqnWE",[5856,7071,7072],{"id":5857,"title":5858,"author":424,"body":5859,"category":7035,"date":7037,"description":7038,"extension":2666,"image":7039,"imageAlt":7040,"isPublished":771,"meta":7041,"minRead":907,"navigation":771,"path":355,"seo":7065,"stem":7067,"tags":7068,"updatedAt":2703,"__hash__":7070},"article\u002Fja\u002Farticle\u002Fbringing-buzz-to-deepseek-harness.md","DeepSeek HarnessにBuzzを連携：自律型Nostrメッセージゲートウェイ構築実践ガイド",{"type":426,"value":5860,"toc":7019},[5861,5867,5886,5889,5892,5895,5900,5941,5944,6002,6006,6013,6289,6292,6296,6300,6307,6311,6325,6329,6340,6386,6393,6397,6400,6431,6434,6439,6480,6488,6494,6502,6508,6536,6550,6554,6563,6587,6611,6652,6658,6663,6669,6676,6682,6687,6694,6708,6714,6723,6758,6761,6767,6774,6780,6784,6787,6938,6941,6978,6982,6987,6990,7016],[429,5862,5863],{},[435,5864],{"alt":5865,"src":5866},"Block Buzzチャンネルに接続されたDeepSeek Harnessメッセージゲートウェイの概要","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002Fdsh-buzz-nostr-gateway-overview.webp",[429,5868,5869,5870,5875,5878,5880,5881,5885],{},"DeepSeek Harness（DSH）の公式プラグインである**",[570,5871,5874],{"href":5872,"rel":5873},"https:\u002F\u002Fgithub.com\u002Fa792883583\u002Fdsh-message-gateway",[1645],"dsh-message-gateway",[443,5876,5877],{},"は、Discord、Telegram、WeChatなどの多様なメッセージングプラットフォームへDeepSeek Harnessアシスタントを拡張します。本プラグインリポジトリがフォークおよび拡張され、対応プラットフォーム一覧に",[570,5879,423],{"href":383},"**が追加されました。フォークされたオープンソースリポジトリはGitHub（ ",[570,5882,5883],{"href":5883,"rel":5884},"https:\u002F\u002Fgithub.com\u002FTech-Voyage-Dev\u002Fdsh-message-gateway",[1645]," ）にて公開されています。",[575,5887],{"description":2665,"image":2667,"image-alt":2668,"label":5888,"min-read":4687,"title":423,"to":383},"事前準備ガイド",[429,5890,5891],{},"DSHアシスタントは正式なメンバーとしてBuzzリレーに参加し、ダイレクトメッセージ（DM）や自身が@メンションされたチャンネルメッセージを受信し、Web UIと全く同一のチャット単位のエージェント実行パイプラインを通じて応答します。",[448,5893,5894],{"id":5894},"dsh-message-gatewayプラグインの内部アーキテクチャ",[429,5896,5897,5899],{},[443,5898,5874],{},"プラグインのアーキテクチャは、大きく2つの領域に分かれています：",[456,5901,5902,5931],{},[459,5903,5904,5907,5908,5911,5912,5915,5916,5919,5920,3629,5923,5926,5927,5930],{},[443,5905,5906],{},"ホスト側","（Node環境）：",[644,5909,5910],{},"gateway-store","（認証情報管理、",[644,5913,5914],{},"~\u002F.dsh\u002Fgateway.json","）、",[644,5917,5918],{},"platforms.ts","（プラットフォーム定義と接続テスト）、",[644,5921,5922],{},"routes.ts",[644,5924,5925],{},"\u002Fgateway\u002F*","エンドポイント）、および",[644,5928,5929],{},"bridge-manager.ts","（常駐ブリッジ：チャットごとの独立エージェントセッションおよびストリーミング応答管理）。",[459,5932,5933,5936,5937,5940],{},[443,5934,5935],{},"クライアント側","（ブラウザ）：サイドバーの「",[443,5938,5939],{},"Message platforms","」設定ページ（認証情報の登録、接続確認、ステータス監視を担当）。",[429,5942,5943],{},"新しいプラットフォームを追加する際の実装手順は以下の3ステップです：",[592,5945,5946,5964,5978],{},[459,5947,5948,5951,5952,5955,5956,5959,5960,5963],{},[443,5949,5950],{},"ブリッジクラスの作成","：",[644,5953,5954],{},"wecom-bridge.ts","をベースに、",[644,5957,5958],{},"start\u002Fstop\u002Fstatus","メソッドおよび",[644,5961,5962],{},"onText(text, frame)","コールバックを実装。",[459,5965,5966,5969,5970,5973,5974,5977],{},[443,5967,5968],{},"bridge-managerへの配線","：既存のチャット別処理パイプライン（",[644,5971,5972],{},"ensureAgentForKey"," + ",[644,5975,5976],{},"pendingMap","）を再利用し、プラットフォーム固有の返信用シンクに接続。",[459,5979,5980,5951,5983,1121,5986,5989,5990,5993,5994,5997,5998,6001],{},[443,5981,5982],{},"ストレージおよびルーティング設定",[644,5984,5985],{},"\u002Fgateway\u002Fsave",[644,5987,5988],{},"\u002Fgateway\u002Fdelete","内において、",[443,5991,5992],{},"認証情報の保存でブリッジを開始し、削除で停止","するよう制御。さらに",[644,5995,5996],{},"dsh web","起動時に自動再接続するための",[644,5999,6000],{},"autoStartXxx","フラグを構成。",[448,6003,6005],{"id":6004},"buzzブリッジの実装nostrプロトコルとイベントライフサイクル","Buzzブリッジの実装：Nostrプロトコルとイベントライフサイクル",[429,6007,6008,6009,6012],{},"Buzzブリッジの実装には",[443,6010,6011],{},"DeepSeek Harness","本体が活用されました。本実装は以下のNostrプロトコル仕様に厳密に準拠しています：",[6014,6015,6016,6031],"table",{},[6017,6018,6019],"thead",{},[6020,6021,6022,6028],"tr",{},[6023,6024,6025],"th",{},[443,6026,6027],{},"項目",[6023,6029,6030],{},"仕様・動作詳細",[6032,6033,6034,6057,6075,6102,6119,6144,6168,6189,6203,6217,6236,6253,6267],"tbody",{},[6020,6035,6036,6042],{},[6037,6038,6039],"td",{},[443,6040,6041],{},"トランスポート",[6037,6043,6044,6045,6048,6049,6052,6053,6056],{},"NIP-42認証付きWebSocket接続（単一接続）；デフォルトは",[644,6046,6047],{},"ws:\u002F\u002Flocalhost:3000","；",[644,6050,6051],{},"http(s):\u002F\u002F","は自動的に",[644,6054,6055],{},"ws(s):\u002F\u002F","へ正規化",[6020,6058,6059,6064],{},[6037,6060,6061],{},[443,6062,6063],{},"認証",[6037,6065,6066,6067,6070,6071,6074],{},"AUTHイベント ",[644,6068,6069],{},"kind 22242","、タグ ",[644,6072,6073],{},"[[\"relay\", url], [\"challenge\", challenge]]","、空のコンテンツ、エージェント秘密鍵で署名",[6020,6076,6077,6082],{},[6037,6078,6079],{},[443,6080,6081],{},"購読（Subscription）",[6037,6083,6084,5951,6087,6090,6091,6094,6095,6098,6099],{},[443,6085,6086],{},"チャンネルスコープ",[644,6088,6089],{},"REQ {\"kinds\":[9], \"#h\":[\u003Cuuid>]}","（チャンネルごとに1つのREQ）。広域な",[644,6092,6093],{},"kinds:[9]","はEOSEを受け取りますがイベントは配信されず、複数値の",[644,6096,6097],{},"#h","フィルターは",[443,6100,6101],{},"無効",[6020,6103,6104,6109],{},[6037,6105,6106],{},[443,6107,6108],{},"チャンネル検出",[6037,6110,6111,6112,3629,6115,6118],{},"チャンネルメタデータ取得用の過去ログ問い合わせ ",[644,6113,6114],{},"REQ {kinds:[39000]}",[644,6116,6117],{},"type == \"dm\"","でダイレクトメッセージを判別）",[6020,6120,6121,6126],{},[6037,6122,6123],{},[443,6124,6125],{},"メンバーシップ管理",[6037,6127,6128,6129,6132,6133,6135,6136,6139,6140,6143],{},"リアルタイム購読 ",[644,6130,6131],{},"REQ {kinds:[44100,44101], \"#p\":[自公開鍵], since: now-60s}"," — 44100=追加、44101=離脱（",[644,6134,429],{},"+",[644,6137,6138],{},"h","タグを含む）。メンバー変更時は",[443,6141,6142],{},"再接続なし","で購読状態を即時更新",[6020,6145,6146,6151],{},[6037,6147,6148],{},[443,6149,6150],{},"チャットイベント",[6037,6152,6153,6156,6157,6160,6161,4043,6164,6167],{},[644,6154,6155],{},"kind 9","（タグ ",[644,6158,6159],{},"[\"h\", channel]","、任意指定で ",[644,6162,6163],{},"[\"e\", replyTo]",[644,6165,6166],{},"[\"p\", mention]","）",[6020,6169,6170,6175],{},[6037,6171,6172],{},[443,6173,6174],{},"インプレース編集",[6037,6176,6177,3629,6180,5973,6182,6185,6186,6188],{},[644,6178,6179],{},"kind 40003",[644,6181,6138],{},[644,6183,6184],{},"e","→対象ID）；コンテンツを全置換；リレーの上限64 KBに基づきペイロードは≤ 60,000 Bに制御；長文応答は分割（チャンク0は置換編集、超過分はスレッド形式の",[644,6187,6155],{},"で追加）",[6020,6190,6191,6196],{},[6037,6192,6193],{},[443,6194,6195],{},"CLOSEDフレーム制御",[6037,6197,6198,6199,6202],{},"AUTH前の",[644,6200,6201],{},"auth-required","は正常な初期化動作（AUTH完了後に購読再開）；AUTH後は制限付き再試行（最大3回、0\u002F1\u002F2秒バックオフ）；再接続時は全ステートを再構築",[6020,6204,6205,6210],{},[6037,6206,6207],{},[443,6208,6209],{},"リレー取得上限",[6037,6211,6212,6213,6216],{},"購読あたり最大2000件の履歴イベント（",[644,6214,6215],{},"since","指定時も含め、常に最新順で取得）",[6020,6218,6219,6224],{},[6037,6220,6221],{},[443,6222,6223],{},"メンション判定",[6037,6225,6226,6227,6229,6230,6232,6233,6235],{},"受信した",[644,6228,6155],{},"の処理条件：(a) ",[644,6231,429],{},"タグに自公開鍵が含まれる、(b) チャンネルがDM、(c) ",[644,6234,6184],{},"参照が自身のイベント（スレッド追跡）。自公開鍵の発信は無視（無限ループ防止）",[6020,6237,6238,6243],{},[6037,6239,6240],{},[443,6241,6242],{},"送信メンション",[6037,6244,6245,6246,6249,6250,6252],{},"送信テキストはそのまま発行（リレー側での",[644,6247,6248],{},"@","構文検証はなし）；",[644,6251,429],{},"タグには入力送信者＋言及された他の公開鍵を最大7件まで格納（合計最大8件）",[6020,6254,6255,6260],{},[6037,6256,6257],{},[443,6258,6259],{},"ダイレクトメッセージ",[6037,6261,6262,6263,6266],{},"リレーローカルの平文チャンネル（",[644,6264,6265],{},"type: \"dm\"","メタデータ）として処理 — 本ブリッジではNIP-04\u002F44暗号化は非使用",[6020,6268,6269,6274],{},[6037,6270,6271],{},[443,6272,6273],{},"添付ファイル（受信）",[6037,6275,6276,6277,3629,6280,4043,6282,4043,6285,6288],{},"NIP-92 ",[644,6278,6279],{},"imeta",[644,6281,4296],{},[644,6283,6284],{},"sha256",[644,6286,6287],{},"m","）→ 標準HTTP(S)でダウンロードしSHA-256検証、20 MB上限、1メッセージあたり最大4点；送信画像の公開は現行未サポート",[429,6290,6291],{},"Buzzブリッジのブートストラップ接続フローは以下の通りです：",[435,6293],{"src":6294,"alt":6295},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002Fdsh-buzz-bootstrap.webp","Buzzブリッジのブートストラップ接続とNIP-42認証プロセスを示すシーケンス図",[548,6297,6299],{"id":6298},"nostrインプレース編集kind-40003によるリアルタイムストリーミング","Nostrインプレース編集（Kind 40003）によるリアルタイムストリーミング",[429,6301,6302,6303,6306],{},"Nostrプロトコルにはネイティブな入力中インジケーターが存在せず、イベントは追記専用です。応答の体感速度とインタラクティブ性を高めるため、Buzzブリッジは",[443,6304,6305],{},"インプレース編集を用いた疑似ストリーミング","を実現しています：",[435,6308],{"src":6309,"alt":6310},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002Fdsh-buzz-reply.webp","kind 40003イベントによる逐次インプレース編集でストリーミング応答を再現するフロー図",[456,6312,6313],{},[459,6314,6315],{},[6316,6317,6318,6319,6321,6322,6324],"em",{},"Buzzブリッジはまずプレースホルダーとなる",[644,6320,6155],{},"イベントを発行し、エージェントの思考出力に伴ってレートリミットされた",[644,6323,6179],{},"インプレース編集イベントで段階的にメッセージを書き換えます。そしてエージェントの推論完了時に最終版を確定します。これはTelegramやDiscordブリッジで採用されている実績ある設計パターンです。",[548,6326,6328],{"id":6327},"チャットコマンドを通じたdeepseek-harnessワークスペースの連動","チャットコマンドを通じたDeepSeek Harnessワークスペースの連動",[429,6330,6331,6332,6335,6336,6339],{},"DSH Web UIにおける「ワークスペース」機能は、内部の",[644,6333,6334],{},"workspaceRegistry","サービス（",[644,6337,6338],{},"@deepseek-ai\u002Fdsh-workspace","）によって制御されています：",[663,6341,6345],{"className":6342,"code":6343,"language":6344,"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",[644,6346,6347],{"__ignoreMap":424},[671,6348,6349,6352,6355,6358,6362,6365,6368,6370,6372,6375,6378,6380,6383],{"class":673,"line":674},[671,6350,6351],{"class":1271},"const",[671,6353,6354],{"class":2001}," existing ",[671,6356,6357],{"class":681},"=",[671,6359,6361],{"class":6360},"s7zQu"," await",[671,6363,6364],{"class":2001}," ctx",[671,6366,6367],{"class":681},".",[671,6369,6334],{"class":2001},[671,6371,6367],{"class":681},[671,6373,6374],{"class":784},"resolveByPath",[671,6376,6377],{"class":2001},"(request",[671,6379,6367],{"class":681},[671,6381,6382],{"class":2001},"path)",[671,6384,6385],{"class":681},";\n",[429,6387,6388,6389,6392],{},"Buzzブリッジはチャットコマンド",[644,6390,6391],{},"\u002Fworkspace \u003Cフォルダパス>","を提供し、ローカルに実在するディレクトリをDSHへ登録できます。ゲートウェイ経由で作成された新規セッションはすべてこのフォルダに関連付けられ、Web UI上にも即座に反映されます。",[435,6394],{"src":6395,"alt":6396},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002Fdsh-buzz-workspace.webp","ゲートウェイ経由のチャットコマンドからDeepSeek Harnessワークスペースを登録する連携アーキテクチャ図",[429,6398,6399],{},"設計上の3つの重要ポイント：",[456,6401,6402,6412,6421],{},[459,6403,6404,6407,6408,6411],{},[443,6405,6406],{},"フォルダ切り替え＝新規セッション開始","：作業ディレクトリ（",[644,6409,6410],{},"cwd","）はセッション作成時にヘッダーへ固定記録されるため、途中で動的に変更することはできません。",[459,6413,6414,5951,6417,6420],{},[443,6415,6416],{},"フォルダの実在が必須",[644,6418,6419],{},"create","処理は存在しないパスの指定を即時エラーとして拒否します。",[459,6422,6423,6426,6427,6430],{},[443,6424,6425],{},"セキュリティ配慮","：すべてのセッションは",[443,6428,6429],{},"auto-approve","（自動承認）ポリシーで稼働するため、指定フォルダ配下のファイルに対して完全なアクセス権が付与されます。",[448,6432,6433],{"id":6433},"インストールと詳細設定のステップバイステップ手順",[592,6435,6436],{},[459,6437,6438],{},"ターミナルで以下のコマンドを実行します：",[663,6440,6442],{"className":665,"code":6441,"language":667,"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",[644,6443,6444,6464,6468,6473],{"__ignoreMap":424},[671,6445,6446,6449,6452,6455,6458,6461],{"class":673,"line":674},[671,6447,6448],{"class":677},"dsh",[671,6450,6451],{"class":685}," plugin",[671,6453,6454],{"class":685}," --profile",[671,6456,6457],{"class":685}," web",[671,6459,6460],{"class":685}," add",[671,6462,6463],{"class":685}," https:\u002F\u002Fgithub.com\u002FTech-Voyage-Dev\u002Fdsh-message-gateway.git\n",[671,6465,6466],{"class":673,"line":740},[671,6467,772],{"emptyLinePlaceholder":771},[671,6469,6470],{"class":673,"line":614},[671,6471,6472],{"class":736},"# Start DSH web\n",[671,6474,6475,6477],{"class":673,"line":775},[671,6476,6448],{"class":677},[671,6478,6479],{"class":685}," web\n",[592,6481,6482],{"start":740},[459,6483,6484,6485,6487],{},"ブラウザでDSH Web UIが開いたら、左側メニューの「",[443,6486,5939],{},"」アイコンをクリックします：",[429,6489,6490],{},[435,6491],{"alt":6492,"src":6493},"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",[592,6495,6496],{"start":614},[459,6497,6498,6499,6501],{},"左側リストから「",[443,6500,445],{},"」を選択します：",[429,6503,6504],{},[435,6505],{"alt":6506,"src":6507},"DeepSeek HarnessメッセージゲートウェイにおけるBuzzブリッジの設定管理画面","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002Fdsh-message-gateway-buzz-config-panel.webp",[592,6509,6510,6520,6530],{"start":775},[459,6511,3216,6512,6515,6516,6519],{},[443,6513,6514],{},"Generate keypair","」をクリックしてNostrキーペアを生成します。表示された公開鍵（",[644,6517,6518],{},"npub","）を安全な場所にコピーしてください。",[459,6521,3216,6522,6525,6526,6529],{},[443,6523,6524],{},"Relay URL","」および購読対象のチャンネルUUIDを指定する「",[443,6527,6528],{},"Channels","」を入力します。",[459,6531,3216,6532,6535],{},[443,6533,6534],{},"Save","」ボタンをクリックします。",[429,6537,6538,6539,6542,6543,6546,6547,6549],{},"保存を実行すると認証情報が記録され、",[443,6540,6541],{},"ブリッジが即時起動","します。秘密鍵（",[644,6544,6545],{},"nsec","）は最重要機密として扱われ、ローカルの",[644,6548,5914],{},"内にのみ安全に保存されます。",[548,6551,6553],{"id":6552},"buzz-nostrリレーへのエージェント公開鍵登録","Buzz Nostrリレーへのエージェント公開鍵登録",[429,6555,6556,6559,6560,6562],{},[443,6557,6558],{},"DSHアシスタントをリレーの正規メンバーとして追加します。"," 先ほど生成した公開鍵（",[644,6561,6518],{},"）を指定して実行します：",[663,6564,6566],{"className":665,"code":6565,"language":667,"meta":424,"style":424},"docker compose exec relay buzz-admin add-member --pubkey npub123123123\n",[644,6567,6568],{"__ignoreMap":424},[671,6569,6570,6572,6574,6576,6578,6580,6582,6584],{"class":673,"line":674},[671,6571,921],{"class":677},[671,6573,963],{"class":685},[671,6575,1681],{"class":685},[671,6577,1684],{"class":685},[671,6579,1687],{"class":685},[671,6581,1690],{"class":685},[671,6583,1693],{"class":685},[671,6585,6586],{"class":685}," npub123123123\n",[429,6588,6589,6592,6593,6595,6596,6599,6600,6602,6603,6606,6607,6610],{},[443,6590,6591],{},"アシスタントを特定のチャンネルへ招待します。"," リレーへ追加した段階では、まだ各チャンネル内での検索や発言はできません。",[644,6594,1822],{},"を使用してチャンネルへ追加する際、",[644,6597,6598],{},"--pubkey","引数には",[644,6601,6518],{},"ではなく",[443,6604,6605],{},"HEX形式","の公開鍵を指定する必要があります（",[644,6608,6609],{},"buzz-admin add-member","の実行結果にHEX値が出力されます）：",[663,6612,6614],{"className":665,"code":6613,"language":667,"meta":424,"style":424},"buzz channels add-member --channel \u003CCHANNEL_UUID> --pubkey \u003CAGENT_HEX> --role member\n",[644,6615,6616],{"__ignoreMap":424},[671,6617,6618,6620,6622,6624,6626,6628,6630,6632,6634,6636,6638,6641,6644,6646,6649],{"class":673,"line":674},[671,6619,2053],{"class":677},[671,6621,2056],{"class":685},[671,6623,1690],{"class":685},[671,6625,2107],{"class":685},[671,6627,2323],{"class":681},[671,6629,2326],{"class":685},[671,6631,2329],{"class":2001},[671,6633,2005],{"class":681},[671,6635,1693],{"class":685},[671,6637,2323],{"class":681},[671,6639,6640],{"class":685},"AGENT_HE",[671,6642,6643],{"class":2001},"X",[671,6645,2005],{"class":681},[671,6647,6648],{"class":685}," --role",[671,6650,6651],{"class":685}," member\n",[575,6653],{"description":6654,"image":2667,"image-alt":2668,"label":6655,"min-read":3870,"title":6656,"to":6657},"Nostrチャンネル、メンバーキー、AIエージェントの権限を管理するためのbuzz-cliのインストールと設定手順を解説します。","CLIガイド","buzz-cliのインストールと使用方法","\u002Farticle\u002Fself-hosting-buzz-as-the-workspace-where-ai-agents-become-colleagues#install-buzz-cli",[429,6659,6660,6662],{},[644,6661,1822],{},"を使用して、Nostrリレー上のDSHアシスタントの表示名を分かりやすい名前に更新します：",[429,6664,6665],{},[435,6666],{"alt":6667,"src":6668},"buzz-cliを使用してNostrリレー上のDSHアシスタント表示名を更新する様子","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002Fdsh-assistant-buzz-cli-profile-update.webp",[429,6670,6671,6672,6675],{},"DSHアシスタントへ",[443,6673,6674],{},"Wave","（BuzzのDM挨拶アクション）を送信します。アシスタントから応答が返れば接続成功です：",[429,6677,6678],{},[435,6679],{"alt":6680,"src":6681},"Buzz内でDSHアシスタントにWaveメッセージをDM送信して接続テストを行う様子","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002Fdsh-buzz-dm-wave-greeting-reply.webp",[429,6683,6684],{},[6316,6685,6686],{},"DSHアシスタントへDMとしてWaveを送信 — ブリッジが正常に応答している様子。",[548,6688,6690,6693],{"id":6689},"workspaceによるローカルフォルダ連携の有効化",[644,6691,6692],{},"\u002Fworkspace","によるローカルフォルダ連携の有効化",[429,6695,6696,6697,6700,6701,6704,6705,6707],{},"デフォルトではセキュリティ保護のため",[644,6698,6699],{},"allowWorkspace","設定が",[644,6702,6703],{},"false","になっているため、初回実行時の",[644,6706,6692],{},"コマンドは拒絶されます：",[429,6709,6710],{},[435,6711],{"alt":6712,"src":6713},"allowWorkspaceが無効な状態で\u002Fworkspaceコマンドを実行した際のエラー通知画面","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002Fdsh-buzz-workspace-command-rejected-error.webp",[429,6715,6716,6719,6720,6722],{},[644,6717,6718],{},"~\u002F.dsh\u002Fprofiles\u002Fweb\u002Fcordis.patch.yml","を編集して機能を有効化し、",[644,6721,5996],{},"を再起動します：",[663,6724,6726],{"className":1156,"code":6725,"language":1158,"meta":424,"style":424},"- id: ui-message-gateway\n  config:\n    allowWorkspace: true\n",[644,6727,6728,6741,6748],{"__ignoreMap":424},[671,6729,6730,6733,6736,6738],{"class":673,"line":674},[671,6731,6732],{"class":681},"-",[671,6734,6735],{"class":1249}," id",[671,6737,1268],{"class":681},[671,6739,6740],{"class":685}," ui-message-gateway\n",[671,6742,6743,6746],{"class":673,"line":740},[671,6744,6745],{"class":1249},"  config",[671,6747,1253],{"class":681},[671,6749,6750,6753,6755],{"class":673,"line":614},[671,6751,6752],{"class":1249},"    allowWorkspace",[671,6754,1268],{"class":681},[671,6756,2221],{"class":6757},"sfNiH",[429,6759,6760],{},"再起動後の画面：",[429,6762,6763],{},[435,6764],{"alt":6765,"src":6766},"Buzz内で\u002Fworkspaceコマンドを実行しワークスペース登録が成功した確認画面","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002Fdsh-buzz-workspace-command-success-confirmation.webp",[429,6768,6769,6770,6773],{},"重要な注意点：この指定は、ワークスペースフォルダ（スクリーンショット内の",[644,6771,6772],{},"TechVoyage","）がデフォルトのユーザーホーム配下に存在することを前提としています。それ以外の階層を指定する場合はフルパスで入力してください。Buzz経由で登録されたセッションは、DeepSeek Harness Web UI上にも連動して表示されます。",[429,6775,6776],{},[435,6777],{"alt":6778,"src":6779},"Buzzから自動同期されDeepSeek Harness Web UI上に表示された作業セッション","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002Fdsh-web-ui-synced-workspace-session.webp",[548,6781,6783],{"id":6782},"buzz上で利用可能なコマンド一覧","Buzz上で利用可能なコマンド一覧",[429,6785,6786],{},"他プラットフォームで利用可能な主要コマンドは、Buzz環境でも完全に対応しています：",[6014,6788,6789,6799],{},[6017,6790,6791],{},[6020,6792,6793,6796],{},[6023,6794,6795],{},"コマンド",[6023,6797,6798],{},"機能概要",[6032,6800,6801,6811,6821,6831,6841,6851,6861,6871,6881,6901,6921],{},[6020,6802,6803,6808],{},[6037,6804,6805],{},[644,6806,6807],{},"\u002Fworkspace \u003Cfolder>",[6037,6809,6810],{},"既存のフォルダをチャットの作業スペースとして登録（設定ファイルでの事前有効化が必要）",[6020,6812,6813,6818],{},[6037,6814,6815],{},[644,6816,6817],{},"\u002Fhelp",[6037,6819,6820],{},"利用可能なコマンド一覧を表示",[6020,6822,6823,6828],{},[6037,6824,6825],{},[644,6826,6827],{},"\u002Ftime",[6037,6829,6830],{},"現在のサーバー時刻を表示",[6020,6832,6833,6838],{},[6037,6834,6835],{},[644,6836,6837],{},"\u002Fnew",[6037,6839,6840],{},"新しいクリーンなセッションを開始",[6020,6842,6843,6848],{},[6037,6844,6845],{},[644,6846,6847],{},"\u002Fclear",[6037,6849,6850],{},"現在の会話履歴をクリア",[6020,6852,6853,6858],{},[6037,6854,6855],{},[644,6856,6857],{},"\u002Fstatus",[6037,6859,6860],{},"現在のブリッジ接続ステータスを表示",[6020,6862,6863,6868],{},[6037,6864,6865],{},[644,6866,6867],{},"\u002Fstats",[6037,6869,6870],{},"チャット数および全プラットフォームのブリッジ稼働状態を表示（Buzzを含む）",[6020,6872,6873,6878],{},[6037,6874,6875],{},[644,6876,6877],{},"\u002Fcommands",[6037,6879,6880],{},"全コマンドの詳細な説明を表示",[6020,6882,6883,6888],{},[6037,6884,6885],{},[644,6886,6887],{},"@path\u002Fto\u002Ffile",[6037,6889,6890,6891,1078,6893,6896,6897,6900],{},"Webの@メンションと同様に機能：モデルがワークスペース相対パスでファイルを読み込み。単体の",[644,6892,6248],{},[644,6894,6895],{},"@prefix","、または",[644,6898,6899],{},"\u002Ffiles \u003Cprefix>","で一致する候補を一覧表示",[6020,6902,6903,6908],{},[6037,6904,6905],{},[644,6906,6907],{},"\u002Fmodel",[6037,6909,6910,6913,6914,6916,6917,6920],{},[644,6911,6912],{},"[provider model effort]"," — 稼働中のLLMカタログと検証の上、モデルおよび推論レベルを変更。",[644,6915,6907],{},"単体で選択肢一覧、",[644,6918,6919],{},"\u002Fmodel reset","で初期設定にリセット",[6020,6922,6923,6928],{},[6037,6924,6925],{},[644,6926,6927],{},"\u002Feffort",[6037,6929,6930,6933,6934,6937],{},[644,6931,6932],{},"\u003Cid>"," モデルの推論エフォート値のみを調整。",[644,6935,6936],{},"\u002Feffort reset","でデフォルト値に戻す",[548,6939,6940],{"id":6940},"セキュリティ設計の要点",[456,6942,6943,6955,6968],{},[459,6944,6945,5951,6948,6950,6951,6954],{},[443,6946,6947],{},"nsec（秘密鍵）の厳格管理",[644,6949,5914],{},"内でのみ保管（パーミッション0600、アトミック書き込み）。",[644,6952,6953],{},"\u002Fgateway\u002Flist","などのAPIやログに出力されることは一切ありません。",[459,6956,6957,6960,6961,3629,6964,6967],{},[443,6958,6959],{},"暗号検証の徹底","：受信したすべてのイベントは、エージェントへ渡る前に",[443,6962,6963],{},"署名検証",[644,6965,6966],{},"verifyEvent","）、重複排除、自己発信フィルター、メンション検証を通過します。",[459,6969,6970,6973,6974,6977],{},[443,6971,6972],{},"ワークスペース登録の二重防御","：ゲートウェイセッションが自動承認で動作するため、誤ったフォルダ公開を防ぐ目的で明示的な設定有効化（",[644,6975,6976],{},"allowWorkspace: true","）を必須としています。",[448,6979,6981],{"id":6980},"まとめbuzzによる分散型aiコラボレーションの実現","まとめ：Buzzによる分散型AIコラボレーションの実現",[429,6983,6984,6986],{},[644,6985,5874],{},"にBuzzを追加する上での最大の技術的挑戦は、Nostrプロトコルが要求する規約の厳密なハンドリングにありました。既存のプラグイン設計がセッション管理やコマンドルーティングを美しく抽象化していたため、イベントの送受信と逐次編集ストリーミングが確立されてからは、極めてスムーズかつ堅牢に稼働させることができました。",[448,6988,6989],{"id":4366},"参考リンク：",[456,6991,6992,7000,7008],{},[459,6993,6994,6999],{},[570,6995,6998],{"href":6996,"rel":6997},"https:\u002F\u002Fgithub.com\u002Fa792883583\u002Fdsh-message-gateway\u002Fblob\u002Fmain\u002Fdocs\u002Farchitecture.md",[1645],"dsh-message-gateway architecture guide"," — アーキテクチャガイド、拡張レシピ、セキュリティノート",[459,7001,7002,7007],{},[570,7003,7006],{"href":7004,"rel":7005},"https:\u002F\u002Fgithub.com\u002Fnbd-wtf\u002Fnostr-tools",[1645],"nostr-tools"," — 内部で使用されている主要Nostrライブラリ",[459,7009,7010,7015],{},[570,7011,7014],{"href":7012,"rel":7013},"https:\u002F\u002Fgithub.com\u002Fbytedance\u002Fdeer-flow\u002Fblob\u002Fmain\u002Fbackend\u002Fdocs\u002FIM_CHANNEL_CONNECTIONS.md",[1645],"deer-flow IM channel connections"," — インスタントメッセージング接続パターンの設計資料",[2628,7017,7018],{},"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":740,"depth":614,"links":7020},[7021,7022,7026,7033,7034],{"id":5894,"depth":740,"text":5894},{"id":6004,"depth":740,"text":6005,"children":7023},[7024,7025],{"id":6298,"depth":614,"text":6299},{"id":6327,"depth":614,"text":6328},{"id":6433,"depth":740,"text":6433,"children":7027},[7028,7029,7031,7032],{"id":6552,"depth":614,"text":6553},{"id":6689,"depth":614,"text":7030},"\u002Fworkspaceによるローカルフォルダ連携の有効化",{"id":6782,"depth":614,"text":6783},{"id":6940,"depth":614,"text":6940},{"id":6980,"depth":740,"text":6981},{"id":4366,"depth":740,"text":6989},[2663,2662,2053,7036],"deepseek-harness","2026-09-30","DeepSeek HarnessをNostrプロトコル経由でBlockのAI協働ワークスペースBuzzに接続する詳細手順を解説。NIP-42認証やWebSocket接続、kind 40003による逐次編集ストリーミング、チャンネル単位の自律型エージェント管理、ローカル作業環境コマンド連携までを完全網羅。","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002FJA-Bringing-Buzz-to-DeepSeek-Harness.webp","深みのあるインディゴとアンバーのアクセントが効いたプレミアムな16:9のテックカード。DeepSeek HarnessをNostrリレーブリッジ経由でBlock Buzzに接続する方法を表現し、洗練されたガラスモーフ調パネルの中央にタイポグラフィを配置。",{"schemaOrg":7042,"robots":2692,"sitemap":7064},[7043,7044],{"@type":2672,"headline":5858,"description":7038,"image":7039},{"@type":2674,"name":5858,"description":7038,"image":7039,"step":7045},[7046,7049,7052,7055,7058,7061],{"@type":2677,"name":7047,"text":7048},"フェーズ1：ゲートウェイプラグインの導入","dsh-message-gatewayプラグインをインストールしてdsh webを起動します。",{"@type":2677,"name":7050,"text":7051},"フェーズ2：Message platforms設定の開始","DSH Web UIを開き、サイドバーからMessage platforms設定へ移動します。",{"@type":2677,"name":7053,"text":7054},"フェーズ3：Buzzブリッジの接続設定","Nostrキーペアを生成し、Relay URLと購読チャンネルを入力します。",{"@type":2677,"name":7056,"text":7057},"フェーズ4：Nostrリレーへのエージェント登録","buzz-adminを使用してDSHアシスタントをBuzzリレーのメンバーとして追加します。",{"@type":2677,"name":7059,"text":7060},"フェーズ5：特定チャンネルへの参加","buzz-cliを使用してHEX形式の公開鍵をチャンネルに追加します。",{"@type":2677,"name":7062,"text":7063},"フェーズ6：ローカル作業フォルダ連携の有効化","cordis.patch.ymlでallowWorkspaceを有効化し、フォルダ連携を許可します。",{"lastmod":7037},{"title":7066,"description":7038,"ogTitle":5858,"ogDescription":7038,"twitterTitle":5858,"twitterDescription":7038},"DeepSeek Harness Buzzプラグイン導入：Nostrプロトコル中継リレー接続の構築手順","ja\u002Farticle\u002Fbringing-buzz-to-deepseek-harness",[6011,445,2699,7069,5874],"AIエージェント","G3P6ZGHDF8ind6nFnnP4iRMS71Dlm2AfulrpNfUFCJE",{"id":2708,"title":2709,"author":2703,"body":2710,"category":4435,"date":4437,"description":4438,"extension":2666,"image":4439,"imageAlt":4440,"isPublished":771,"meta":4441,"minRead":958,"navigation":771,"path":379,"seo":4448,"stem":4449,"tags":4450,"updatedAt":2694,"__hash__":4453},{"id":7073,"title":7074,"author":424,"body":7075,"category":7675,"date":7676,"description":7677,"extension":2666,"image":7678,"imageAlt":7679,"isPublished":771,"meta":7680,"minRead":740,"navigation":771,"path":367,"seo":7684,"stem":7686,"tags":7687,"updatedAt":2703,"__hash__":7690},"article\u002Fja\u002Farticle\u002Fhow-ai-agent-skills-replace-nuxt-app-scaffolding-scripts.md","Nuxtアプリの環境構築・初期化を自動化：AIエージェントのスキルが従来のシェルスクリプトに代わる理由",{"type":426,"value":7076,"toc":7668},[7077,7087,7090,7093,7096,7192,7195,7238,7241,7245,7252,7259,7262,7298,7302,7313,7486,7490,7573,7577,7586,7606,7613,7628,7639,7642,7648,7651,7657,7665],[429,7078,7079,7080,1078,7083,7086],{},"Nuxtフレームワークを使って新しいアプリケーションの開発を始めるとき、モジュールのインストールや、",[644,7081,7082],{},"nuxt.config.ts",[644,7084,7085],{},"wrangler.jsonc","などの設定ファイルのセットアップといった、退屈で煩雑な手順を踏む必要があります。シェルスクリプトを使えばこのプロセスを自動化できますが、プロジェクトの要件や構成のバリエーションが増えるにつれて、スクリプトによる対応はすぐに限界を迎えます。",[429,7088,7089],{},"そこで私たちは、従来の「スクリプト」によるアプローチを見直し、AIエージェントの**「スキル（Agent Skill）」**へと置き換える検証を行いました。",[448,7091,7092],{"id":7092},"従来のシェルスクリプトが得意なこと",[429,7094,7095],{},"スクリプトは、あらかじめ決定された固定の処理手順を、コード内に直接ハードコードされたロジックに従って順番に実行することに長けています。",[663,7097,7099],{"className":665,"code":7098,"language":667,"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",[644,7100,7101,7106,7113,7117,7156,7160,7170,7174,7183],{"__ignoreMap":424},[671,7102,7103],{"class":673,"line":674},[671,7104,7105],{"class":736},"#!\u002Fusr\u002Fbin\u002Fenv bash\n",[671,7107,7108,7111],{"class":673,"line":740},[671,7109,7110],{"class":784},"set",[671,7112,1619],{"class":685},[671,7114,7115],{"class":673,"line":614},[671,7116,772],{"emptyLinePlaceholder":771},[671,7118,7119,7121,7124,7127,7129,7133,7135,7138,7141,7144,7147,7150,7153],{"class":673,"line":775},[671,7120,3964],{"class":677},[671,7122,7123],{"class":685}," nuxi@latest",[671,7125,7126],{"class":685}," init",[671,7128,682],{"class":681},[671,7130,7132],{"class":7131},"sHdIc","$1",[671,7134,689],{"class":681},[671,7136,7137],{"class":685}," --template",[671,7139,7140],{"class":685}," minimal",[671,7142,7143],{"class":685}," --packageManager",[671,7145,7146],{"class":685}," pnpm",[671,7148,7149],{"class":685}," --no-gitInit",[671,7151,7152],{"class":685}," -M",[671,7154,7155],{"class":685}," @nuxt\u002Fui,@nuxthub\u002Fcore,@vueuse\u002Fnuxt\n",[671,7157,7158],{"class":673,"line":781},[671,7159,772],{"emptyLinePlaceholder":771},[671,7161,7162,7164,7166,7168],{"class":673,"line":826},[671,7163,995],{"class":784},[671,7165,682],{"class":681},[671,7167,7132],{"class":7131},[671,7169,700],{"class":681},[671,7171,7172],{"class":673,"line":831},[671,7173,772],{"emptyLinePlaceholder":771},[671,7175,7176,7178,7181],{"class":673,"line":837},[671,7177,1003],{"class":677},[671,7179,7180],{"class":685}," ~\u002Ftemplates\u002Fnuxt.config.ts",[671,7182,1304],{"class":685},[671,7184,7185,7187,7190],{"class":673,"line":849},[671,7186,1003],{"class":677},[671,7188,7189],{"class":685}," ~\u002Ftemplates\u002Fwrangler.jsonc",[671,7191,1304],{"class":685},[429,7193,7194],{},"しかし、このスクリプトは以下のような課題に直面すると、途端に機能しなくなります。",[456,7196,7197,7211,7228],{},[459,7198,7199,7202,7203,7206,7207,7210],{},[443,7200,7201],{},"固定されたデフォルト設定。"," 上記のスクリプトでは UIモジュールとして ",[644,7204,7205],{},"Nuxt UI"," がハードコードされています。もし ",[644,7208,7209],{},"Ant Design UI"," モジュールを使いたい場合はどうすればよいでしょうか？モジュールの選択肢が増えるたびに、ユーザーが指定しなければならないコマンド引数は増え続けます。",[459,7212,7213,7216,7217,7220,7221,4651,7224,7227],{},[443,7214,7215],{},"ユーザーの「意図」を読み取れない。"," 「ブログを作りたい」という要望には ",[644,7218,7219],{},"@nuxt\u002Fcontent"," が必要ですが、「ニュースレター機能付きのWebサイトを作りたい」という要望には ",[644,7222,7223],{},"Cloudflare D1",[644,7225,7226],{},"Drizzle"," が必要です。スクリプト単体ではこの要件の違いを自律的に判断できず、構成のパリエーションごとに個別のスクリプトを作成しなければなりません。",[459,7229,7230,7233,7234,7237],{},[443,7231,7232],{},"気づかないうちに風化・形骸化する。"," Nuxtなどのフレームワークは、メジャーアップデートの際に設計 convention が大きく変更されます。たとえば、Nuxt 4 ではソースディレクトリが ",[644,7235,7236],{},"app\u002F"," に変更されました。Nuxt 3 向けに書かれたスクリプトをそのまま使い続けると、誤ったディレクトリ構造で静かにスキャフォールディングが実行され、エラーを引き起こすまでユーザーは問題に気づきません。",[429,7239,7240],{},"**アプリケーションの初期構築（App Scaffolding）**は、「単純な処理の実行」ではなく「高度な意思決定」が求められる課題です。そのため、考慮すべき決定事項が増えれば増やすほど、スクリプトによる自動化はスケールしなくなります。",[448,7242,7244],{"id":7243},"なぜ従来のスクリプトではなくaiエージェントスキルを使うのか","なぜ従来のスクリプトではなく「AIエージェントスキル」を使うのか？",[429,7246,7247,7248,7251],{},"エージェントスキル（Agent Skill）とは、単に実行されるプログラムのコードではなく、**「AIエージェントが動作するために従う知識の体系」**です。スキルは ",[644,7249,7250],{},"SKILL.md"," という設計書ファイルを中心に構成され、タスクの実行に必要な関連リファレンスドキュメント、テンプレート、および実行スクリプトなどを柔軟に同梱できます。",[429,7253,7254,7255,7258],{},"エージェントスキルの具体的な仕組みについては、解説記事 ",[570,7256,7257],{"href":351},"AIエージェントのスキルとは？その基本概念から作成方法、再利用可能なワークフローの構築までを徹底解説"," で詳しく紹介しています。",[429,7260,7261],{},"AIエージェントのスキルは、シェルスクリプトとしての確実な実行力を維持しつつ、スクリプトにはない「自律的で合理的な判断力」をプロセスに追加してくれます。",[456,7263,7264,7267,7277,7292,7295],{},[459,7265,7266],{},"ユーザーの曖昧な指示（自然言語）から意図を推測し、データベースが必要かどうかを賢く判断します。",[459,7268,7269,7270,1078,7273,7276],{},"指定されたオプションリストから、本当に必要なオプションモジュールだけをインテリジェントに選択・導入します（例：",[644,7271,7272],{},"Nuxt Content",[644,7274,7275],{},"i18n","、分析ツールなどは、ユーザーの要件に応じてオプトインで追加されます）。",[459,7278,7279,7280,7283,7284,7287,7288,7291],{},"最新の ",[644,7281,7282],{},"Nuxt"," フレームワーク、Cloudflare 連携用の ",[644,7285,7286],{},"NuxtHub","、およびデプロイ用の ",[644,7289,7290],{},"Wrangler"," など、目まぐるしく変化するエコシステムの最新仕様に自律的に適応します。",[459,7293,7294],{},"実行途中でエラーが発生した場合、エージェント自身でエラー原因を分析して自己修復・リトライを試みます。",[459,7296,7297],{},"プロジェクトの構築完了前に、事前に定義されたチェックリストに沿って動作確認と品質チェックを自律的に実施します。",[448,7299,7301],{"id":7300},"nuxt-cloudflare-スキャフォールディングスキルの裏側","Nuxt & Cloudflare スキャフォールディングスキルの裏側",[429,7303,7304,7305,7312],{},"私たちが作成した ",[570,7306,7309],{"href":7307,"rel":7308},"https:\u002F\u002Fgithub.com\u002FTech-Voyage-Dev\u002Fscaffold-nuxt-cloudflare-app-skill",[1645],[644,7310,7311],{},"scaffold-nuxt-cloudflare-app-skill"," は、以下のステップに沿って、本番環境を見据えた高品質な初期構築を自律的に実行します。",[592,7314,7315,7346,7366,7391,7421,7460,7467],{},[459,7316,7317,1253,7320],{},[443,7318,7319],{},"曖昧な要件の具体化",[456,7321,7322,7330,7336],{},[459,7323,7324,7325,3633,7327,6167],{},"UIキットの選択（デフォルトは ",[443,7326,7205],{},[443,7328,7329],{},"Antdv Next",[459,7331,7332,7333,7335],{},"データベースの要否（例：",[443,7334,7223],{}," の有無）",[459,7337,7338,7339,7341,7342,7345],{},"CMS用の ",[644,7340,7219],{}," や多言語化用の ",[644,7343,7344],{},"@nuxtjs\u002Fi18n"," などの追加モジュールの要否",[459,7347,7348,3932,7351,7354,7355,7357,7358,7361,7362,7365],{},[443,7349,7350],{},"ベースアプリケーションの構築",[644,7352,7353],{},"pnpm dlx nuxi@latest init"," を実行して、最新バージョンの Nuxt フレームワークを ",[644,7356,5339],{}," パッケージマネージャー構成で初期化します。さらに、Cloudflare のビルド環境で ",[644,7359,7360],{},"better-sqlite3"," や ",[644,7363,7364],{},"sharp"," などのネイティブライブラリが正常にビルドできるよう、環境変数や設定を適切に構成します。",[459,7367,7368,3932,7371,7374,7375,1078,7378,1078,7381,1078,7384,1078,7387,7390],{},[443,7369,7370],{},"意思決定マトリクスによるモジュール導入",[644,7372,7373],{},"@nuxt\u002Fui"," \u002F ",[644,7376,7377],{},"@antdv-next\u002Fnuxt",[644,7379,7380],{},"@nuxt\u002Fimage",[644,7382,7383],{},"@nuxtjs\u002Fseo",[644,7385,7386],{},"@nuxthub\u002Fcore",[644,7388,7389],{},"@vueuse\u002Fnuxt"," などの必須・推奨モジュールに加え、ユーザーの要望に応じて Drizzle \u002F D1、Nuxt Content、i18n を条件分岐でインストールします。",[459,7392,7393,1253,7396],{},[443,7394,7395],{},"最適なディレクトリ構造の展開",[456,7397,7398,7403,7408,7413,7418],{},[459,7399,7400,7402],{},[644,7401,7236],{}," （Nuxt 4 準拠）",[459,7404,7405],{},[644,7406,7407],{},"server\u002F",[459,7409,7410],{},[644,7411,7412],{},"shared\u002F",[459,7414,7415],{},[644,7416,7417],{},"tests\u002F",[459,7419,7420],{},"ルート直下の各種設定ファイル",[459,7422,7423,1253,7428],{},[443,7424,7425,7427],{},[644,7426,7082],{}," の詳細設定",[456,7429,7430,7440,7447,7454],{},[459,7431,7432,7433,7361,7436,7439],{},"SEO向上のための ",[644,7434,7435],{},"site.url",[644,7437,7438],{},"site.name"," の設定",[459,7441,7442,7443,7446],{},"Cloudflare バインディング用の NuxtHub ",[644,7444,7445],{},"hub"," ブロックの記述",[459,7448,7449,7450,7453],{},"ルーティングとキャッシュの制御を行う ",[644,7451,7452],{},"routeRules"," の生成",[459,7455,7279,7456,7459],{},[644,7457,7458],{},"compatibilityDate"," の指定",[459,7461,7462],{},[443,7463,7464,7466],{},[644,7465,7085],{}," の自動生成とバインディング",[459,7468,7469,3932,7472,4651,7475,7478,7479,4916,7482,7485],{},[443,7470,7471],{},"開発環境の堅牢化とテスト",[644,7473,7474],{},"Vitest",[644,7476,7477],{},"ESLint"," をセットアップし、最後に自律的に ",[644,7480,7481],{},"pnpm install",[644,7483,7484],{},"pnpm dev"," を実行して動作確認を行います。すべての正常動作が確認された段階で、初めて初期構築作業の完了を宣言します。",[448,7487,7489],{"id":7488},"シェルスクリプト-vs-aiエージェントスキル機能対比","シェルスクリプト vs AIエージェントスキル：機能対比",[6014,7491,7492,7505],{},[6017,7493,7494],{},[6020,7495,7496,7499,7502],{},[6023,7497,7498],{},"比較項目",[6023,7500,7501],{},"シェルスクリプト",[6023,7503,7504],{},"エージェントスキル",[6032,7506,7507,7518,7529,7540,7551,7562],{},[6020,7508,7509,7512,7515],{},[6037,7510,7511],{},"ユーザーの意図の理解",[6037,7513,7514],{},"❌ 固定された挙動のみ",[6037,7516,7517],{},"✅ 要件に応じて柔軟に適応",[6020,7519,7520,7523,7526],{},[6037,7521,7522],{},"柔軟な意思決定",[6037,7524,7525],{},"❌ コマンド引数による事前定義のみ",[6037,7527,7528],{},"✅ 実行時に状況から自律判断",[6020,7530,7531,7534,7537],{},[6037,7532,7533],{},"フレームワークの更新",[6037,7535,7536],{},"❌ 手動でコードを書き換える必要あり",[6037,7538,7539],{},"✅ 現在の最新エコシステムを検証し適応",[6020,7541,7542,7545,7548],{},[6037,7543,7544],{},"エラー発生時の復旧",[6037,7546,7547],{},"❌ 処理がそこで停止する",[6037,7549,7550],{},"✅ エラー原因を特定し自律的に自己修復",[6020,7552,7553,7556,7559],{},[6037,7554,7555],{},"成果物の品質検証",[6037,7557,7558],{},"❌ チェック機能なし",[6037,7560,7561],{},"✅ 最終チェックリストによる自動テスト",[6020,7563,7564,7567,7570],{},[6037,7565,7566],{},"メンテナンスコスト",[6037,7568,7569],{},"❌ 引数や分岐ロジックの肥大化",[6037,7571,7572],{},"✅ マークダウン（設計書）の修正だけで完結",[448,7574,7576],{"id":7575},"npx-skills-cli-を使った-aiエージェントスキルのインストール方法","npx skills CLI を使った AIエージェントスキルのインストール方法",[429,7578,7579,7580,7585],{},"エージェントスキルの導入は、オープンソースの ",[570,7581,7584],{"href":7582,"rel":7583},"https:\u002F\u002Fgithub.com\u002Fvercel-labs\u002Fskills",[1645],"skills CLI"," を使うことで、たった1つのコマンドで完了します。",[663,7587,7589],{"className":665,"code":7588,"language":667,"meta":424,"style":424},"npx skills add https:\u002F\u002Fgithub.com\u002FTech-Voyage-Dev\u002Fscaffold-nuxt-cloudflare-app-skill.git -g\n",[644,7590,7591],{"__ignoreMap":424},[671,7592,7593,7595,7598,7600,7603],{"class":673,"line":674},[671,7594,3964],{"class":677},[671,7596,7597],{"class":685}," skills",[671,7599,6460],{"class":685},[671,7601,7602],{"class":685}," https:\u002F\u002Fgithub.com\u002FTech-Voyage-Dev\u002Fscaffold-nuxt-cloudflare-app-skill.git",[671,7604,7605],{"class":685}," -g\n",[429,7607,7608,7609],{},"このコマンドを実行すると、CLI がリポジトリを自動的にクローンし、検出されたスキルを現在あなたの環境に導入されているどのエージェントに紐付けるかを尋ねてきます。\n",[435,7610],{"alt":7611,"src":7612},"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,7614,7615,7616,7619,7620,7623,7624],{},"今回は、推奨されるインストール方法である ",[443,7617,7618],{},"Symlink（シンボリックリンク）"," を選択します。これにより、スキルは ",[644,7621,7622],{},"~\u002F.agents\u002Fskills"," に一度だけダウンロードされ、選択したすべてのエージェントがその同一のオリジナルファイルを参照するようになります。\n",[435,7625],{"alt":7626,"src":7627},"シンボリックリンク（Symlink）を利用して、~\u002F.agents\u002Fskills に一度だけスキルをインストールするセットアップ完了画面","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FHow%20AI%20Agent%20Skills%20Replace%20Nuxt%20App%20Scaffolding%20Scripts\u002Fnpx-skills-installation-summary-details.webp",[456,7629,7630],{},[459,7631,7632],{},[6316,7633,7634,7635,7638],{},"複数の異なるAIエージェントにスキルを一元管理して配布する手法の詳細は、解説記事 ",[570,7636,7637],{"href":359},"npx skillsを使ってAIエージェントのスキルフラグメンテーション（機能の断片化）を解消する方法"," をご参照ください。",[429,7640,7641],{},"インストール完了後、Claude Code を起動すると、新しいコマンドとして認識されていることが確認できます。",[429,7643,7644],{},[435,7645],{"alt":7646,"src":7647},"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,7649,7650],{},"あとは、普段の自然言語で指示を出すだけで、完璧な環境が数秒で構築されます。",[7652,7653,7654],"blockquote",{},[429,7655,7656],{},"\"Scaffold a new Nuxt app deployed to Cloudflare Workers — Nuxt UI, a blog section, and a D1 database\"\n（Cloudflare Workers にデプロイ可能な Nuxt アプリの雛形を作って。UI は Nuxt UI で、ブログセクションと D1 データベースも含めてほしい）",[429,7658,7659,7660,7664],{},"このスキャフォールディングスキルはオープンソースとして公開されています。ぜひ ",[570,7661,7663],{"href":7307,"rel":7662},[1645],"GitHub リポジトリ"," をチェックして、その劇的な効率化を体験してみてください。",[2628,7666,7667],{},"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":740,"depth":614,"links":7669},[7670,7671,7672,7673,7674],{"id":7092,"depth":740,"text":7092},{"id":7243,"depth":740,"text":7244},{"id":7300,"depth":740,"text":7301},{"id":7488,"depth":740,"text":7489},{"id":7575,"depth":740,"text":7576},[2663],"2026-08-25","Cloudflare Workers上にNuxtアプリを自動構築する方法を徹底解説。従来の壊れやすいシェルスクリプトを、開発者の意図を組んで柔軟に判断・動作するインテリジェントなAIエージェントのスキルに置き換えるメリットや、npx skillsコマンドを用いた実用的なセットアップ手順を紹介します。","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FHow%20AI%20Agent%20Skills%20Replace%20Nuxt%20App%20Scaffolding%20Scripts\u002FJA-How-AI-Agent-Skills-Replace-Nuxt-App-Scaffolding-Scripts.webp","CloudflareでのNuxt環境構築：シェルスクリプトからAIエージェントスキルへ移行するメリット。スクリプトとAIスキルの徹底比較。",{"schemaOrg":7681,"robots":2692,"sitemap":7683},[7682],{"@type":2672,"headline":7074,"description":7677,"image":7678},{"lastmod":7676},{"title":7685,"description":7677,"ogTitle":7074,"ogDescription":7677,"twitterTitle":7074,"twitterDescription":7677},"CloudflareでのNuxt環境構築：シェルスクリプトからAIエージェントスキルへ移行するメリット","ja\u002Farticle\u002Fhow-ai-agent-skills-replace-nuxt-app-scaffolding-scripts",[7282,2702,7688,7689],"AI Agent","Scaffolding","7nQfGY7WVvKS7mUnoFrtHe97RJD_xMp8x7o_dAtuTuI",1792489994864]