[{"data":1,"prerenderedAt":7794},["ShallowReactive",2],{"published-article-paths":3,"search-navigation":348,"\u002Fpt\u002Farticle\u002Fself-hosting-buzz-as-the-workspace-where-ai-agents-become-colleagues":421,"\u002Fpt\u002Farticle\u002Fself-hosting-buzz-as-the-workspace-where-ai-agents-become-colleagues-surround":2707},[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":2663,"date":2666,"description":2667,"extension":2668,"image":2669,"imageAlt":2670,"isPublished":773,"meta":2671,"minRead":929,"navigation":773,"path":229,"seo":2697,"stem":2699,"tags":2700,"updatedAt":2705,"__hash__":2706},"article\u002Fpt\u002Farticle\u002Fself-hosting-buzz-as-the-workspace-where-ai-agents-become-colleagues.md","Como auto-hospedar o Buzz do Block: Espaço para agentes de IA","",{"type":426,"value":427,"toc":2633},"minimark",[428,432,439,447,452,455,495,499,505,543,547,552,566,574,582,586,591,608,614,664,703,707,716,722,726,729,969,973,1019,1026,1033,1041,1093,1099,1127,1131,1135,1162,1192,1197,1239,1247,1532,1536,1582,1587,1594,1599,1603,1627,1630,1636,1639,1643,1652,1658,1661,1667,1670,1699,1705,1711,1714,1720,1724,1727,1730,1733,1739,1742,1748,1754,1760,1765,1769,1780,1787,1793,1796,1802,1806,1813,1819,1826,1830,1836,1900,1913,1968,1971,2043,2046,2062,2068,2072,2118,2124,2127,2133,2136,2142,2146,2162,2178,2184,2282,2285,2291,2302,2351,2357,2363,2375,2391,2394,2400,2404,2411,2433,2442,2540,2551,2557,2564,2570,2573,2579,2582,2588,2592,2595,2599,2629],[429,430,431],"p",{},"A fragmentação de contexto é um obstáculo frustrante ao trabalhar com múltiplos agentes de IA. Com conversas dispersas em diferentes ferramentas, você acaba agindo como um roteador humano ao copiar conversas do Claude Code para colar no Gemini CLI, depois copiando do Gemini CLI para colar no Hermes Agent. Essa fricção aumenta quando colegas humanos estão na mesma equipe.",[429,433,434],{},[435,436],"img",{"alt":437,"src":438},"A interface de usuário do espaço de trabalho colaborativo Buzz mostrando canais de chat e agentes de IA ativos","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],{},"O ",[443,444,445],"strong",{},"Buzz",", um espaço de trabalho colaborativo de código aberto, reúne equipes humanas e agentes de IA em um ambiente único e unificado. Aqui, colegas humanos e agentes de IA compartilham o mesmo histórico de tarefas e projetos, transferindo o trabalho entre si de forma integrada.",[448,449,451],"h2",{"id":450},"o-que-é-o-buzz-do-block-o-espaço-de-trabalho-colaborativo-para-agentes-de-ia","O que é o Buzz do Block? O espaço de trabalho colaborativo para agentes de IA",[429,453,454],{},"O Buzz é um espaço de trabalho colaborativo de código aberto da Block (empresa de Jack Dorsey) onde humanos e agentes de IA compartilham os mesmos canais e projetos. Ele oferece os seguintes recursos principais:",[456,457,458,465,471,477,483,489],"ul",{},[459,460,461,464],"li",{},[443,462,463],{},"Contexto compartilhado:"," Os canais são onde os humanos e agentes colaboram entre si. Todo o histórico de conversas e projetos está contido no canal.",[459,466,467,470],{},[443,468,469],{},"Comunicação agente a agente:"," Os agentes podem se comunicar entre si, mesmo em máquinas diferentes. Um agente pode mencionar outro usando @ para transferir trabalho ou verificar o código.",[459,472,473,476],{},[443,474,475],{},"Ativação baseada em menção:"," Os agentes só agem quando mencionados com @, caso contrário, permanecem silenciosos. Quando mencionado, um agente lê o contexto relevante no canal e começa a trabalhar.",[459,478,479,482],{},[443,480,481],{},"Sistema de identidade unificado:"," Humanos e agentes usam o mesmo sistema de identidade, autenticado por meio de chaves criptográficas.",[459,484,485,488],{},[443,486,487],{},"Comandos delegados:"," Você pode conceder a colegas humanos permissão para comandar seus agentes, permitindo que toda a equipe instrua e aproveite os assistentes digitais uns dos outros.",[459,490,491,494],{},[443,492,493],{},"Servidores auto-hospedados:"," Como você hospeda o servidor, seus dados permanecem totalmente sob seu controle. Você escolhe quem entra e define suas próprias regras operacionais.",[448,496,498],{"id":497},"a-arquitetura-criptográfica-baseada-em-nostr-do-buzz","A arquitetura criptográfica baseada em Nostr do Buzz",[429,500,501],{},[435,502],{"alt":503,"src":504},"Diagrama arquitetônico criptográfico baseado em Nostr do espaço de trabalho de colaboração 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],{},"O relay Nostr atua como o servidor:"," Mensagens, fluxos de trabalho, repositórios e outros eventos são assinados criptograficamente, verificados e armazenados em um servidor relay Nostr. O protocolo Nostr suporta nativamente a comunicação por meio de WebSockets e APIs REST.",[459,514,515,518],{},[443,516,517],{},"Identidade criptográfica unificada:"," Tanto os humanos quanto os agentes se autenticam usando suas próprias chaves criptográficas. Essa identidade permanece no lado do cliente e nunca é armazenada no servidor.",[459,520,521,524],{},[443,522,523],{},"Membro agente de primeira classe:"," Cada agente possui sua própria identidade, associações de canais e trilha de auditoria. Os agentes se conectam ao espaço de trabalho usando o Protocolo de Comunicação do Agente (ACP).",[459,526,527,530],{},[443,528,529],{},"Repositórios Git descentralizados:"," Os repositórios de código são armazenados em armazenamento de objetos compatível com S3, enquanto tarefas, pull requests e revisões de código são rastreados no log de eventos Nostr. Consequentemente, um repositório Git do Buzz é hospedado no relay Nostr em vez do GitHub.",[459,532,533,536],{},[443,534,535],{},"O aplicativo Buzz é um cliente Nostr:"," O Buzz é separado do relay Nostr; é um aplicativo cliente para desktop\u002Fdispositivos móveis que se conecta à URL do relay.",[459,538,539,542],{},[443,540,541],{},"Pilha de infraestrutura:"," Um banco de dados PostgreSQL gerencia o armazenamento de eventos e a busca em texto completo, o Redis gerencia o envio\u002Frecebimento de mensagens (pub\u002Fsub), e o MinIO compatível com S3 é usado para armazenamento de mídia.",[448,544,546],{"id":545},"como-auto-hospedar-o-relay-buzz-do-block-em-um-vps-linux","Como auto-hospedar o relay Buzz do Block em um VPS Linux",[548,549,551],"h3",{"id":550},"_0-pré-requisitos","0. Pré-requisitos",[456,553,554,557,560,563],{},[459,555,556],{},"Um VPS Linux",[459,558,559],{},"Um domínio que aponte para o seu servidor",[459,561,562],{},"Docker e o plugin Docker Compose",[459,564,565],{},"Conta da Cloudflare (plano gratuito)",[429,567,568,569,573],{},"Neste guia, executaremos o relay Nostr em um VPS Ubuntu por trás de uma rede privada ",[570,571,572],"a",{"href":363},"Expor o Hermes Agent em rede privada com Cloudflare WARP",". A pilha de recursos consiste em quatro serviços no Docker Compose — relay, PostgreSQL, Redis e MinIO — além do Caddy para HTTPS.",[575,576],"article-card",{"description":577,"image":578,"image-alt":579,"label":580,"min-read":581,"title":572,"to":363},"Aprenda a expor e acessar o seu Hermes Agent com segurança globalmente usando Cloudflare WARP e Zero Trust sem abrir portas de entrada no firewall.","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FExposing%20Hermes%20Agent%20to%20Private%20Network%20Using%20Cloudflare%20WARP\u002FPT-Exposing-Hermes-Agent-to-Private-Network-Using-Cloudflare-WARP.webp","Exposição segura do Hermes Agent a uma rede privada usando Cloudflare Zero Trust e túnel WARP","Guia relacionado","8",[548,583,585],{"id":584},"_1-dns-da-cloudflare-e-api-token","1. DNS da Cloudflare e API Token",[587,588,590],"h4",{"id":589},"criar-um-api-token-da-cloudflare","Criar um API Token da Cloudflare",[592,593,594,601],"ol",{},[459,595,596,597,600],{},"Clique no botão ",[443,598,599],{},"Profile"," no canto superior direito no menu suspenso do ícone do usuário.",[459,602,603,604,607],{},"Clique em ",[443,605,606],{},"API Tokens",".",[429,609,610],{},[435,611],{"alt":612,"src":613},"Página de perfil do usuário da Cloudflare mostrando o menu de criação de tokens de API","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf-Hosting%20Buzz%20As%20The%20Workspace%20Where%20AI%20Agents%20Become%20Colleagues\u002Fcloudflare-profile-api-tokens.webp",[592,615,617,622,628,649,654,658,661],{"start":616},3,[459,618,603,619,607],{},[443,620,621],{},"Create Token",[459,623,624,625,607],{},"Use o modelo ",[443,626,627],{},"Edit zone DNS",[459,629,630,631],{},"Configure o modelo da seguinte maneira:\n",[456,632,633,639],{},[459,634,635,638],{},[443,636,637],{},"Permissions",": Zone — DNS — Edit",[459,640,641,644,645],{},[443,642,643],{},"Zone Resources",": Include — Specific zone — ",[646,647,648],"code",{},"example.com",[459,650,603,651,607],{},[443,652,653],{},"Continue to summary",[459,655,603,656,607],{},[443,657,621],{},[459,659,660],{},"Copie o token gerado, pois ele não será exibido novamente após fechar a página.",[459,662,663],{},"Teste o token gerado no seu terminal para se certificar de que funciona corretamente:",[665,666,670],"pre",{"className":667,"code":668,"language":669,"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",[646,671,672],{"__ignoreMap":424},[673,674,677,681,685,689,692,695,697,700],"span",{"class":675,"line":676},"line",1,[673,678,680],{"class":679},"sBMFI","curl",[673,682,684],{"class":683},"sMK4o"," \"",[673,686,688],{"class":687},"sfazB","https:\u002F\u002Fapi.cloudflare.com\u002Fclient\u002Fv4\u002Fuser\u002Ftokens\u002Fverify",[673,690,691],{"class":683},"\"",[673,693,694],{"class":687}," -H",[673,696,684],{"class":683},[673,698,699],{"class":687},"Authorization: Bearer YOUR_TOKEN_HERE",[673,701,702],{"class":683},"\"\n",[587,704,706],{"id":705},"registros-dns","Registros DNS",[456,708,709],{},[459,710,711,712,715],{},"Crie um registro A e configure-o como ",[443,713,714],{},"Apenas DNS"," (DNS only).",[429,717,718],{},[435,719],{"alt":720,"src":721},"Configurando um registro DNS A para o domínio do Buzz no painel da Cloudflare com status de proxy configurado como apenas DNS","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf-Hosting%20Buzz%20As%20The%20Workspace%20Where%20AI%20Agents%20Become%20Colleagues\u002Fcloudflare-dns-a-record-configuration.webp",[548,723,725],{"id":724},"_2-instalar-o-docker-no-ubuntu","2. Instalar o Docker no Ubuntu",[429,727,728],{},"Execute os seguintes comandos para instalar o Docker no Ubuntu:",[665,730,732],{"className":667,"code":731,"language":669,"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",[646,733,734,740,769,775,781,826,831,837,849,854,860,882,887,893,907,912,918,927,932,947,952,958],{"__ignoreMap":424},[673,735,736],{"class":675,"line":676},[673,737,739],{"class":738},"sHwdD","# Add Docker's official GPG key and set up the Docker repository\n",[673,741,743,745,748,751,754,757,760,763,766],{"class":675,"line":742},2,[673,744,680],{"class":679},[673,746,747],{"class":687}," -fsSL",[673,749,750],{"class":687}," https:\u002F\u002Fdownload.docker.com\u002Flinux\u002Fubuntu\u002Fgpg",[673,752,753],{"class":683}," |",[673,755,756],{"class":679}," sudo",[673,758,759],{"class":687}," gpg",[673,761,762],{"class":687}," --dearmor",[673,764,765],{"class":687}," -o",[673,767,768],{"class":687}," \u002Fusr\u002Fshare\u002Fkeyrings\u002Fdocker-archive-keyring.gpg\n",[673,770,771],{"class":675,"line":616},[673,772,774],{"emptyLinePlaceholder":773},true,"\n",[673,776,778],{"class":675,"line":777},4,[673,779,780],{"class":738},"# Add the official Docker repository\n",[673,782,784,788,790,793,796,799,802,805,808,810,812,814,817,820,823],{"class":675,"line":783},5,[673,785,787],{"class":786},"s2Zo4","echo",[673,789,684],{"class":683},[673,791,792],{"class":687},"deb [arch=amd64 signed-by=\u002Fusr\u002Fshare\u002Fkeyrings\u002Fdocker-archive-keyring.gpg] https:\u002F\u002Fdownload.docker.com\u002Flinux\u002Fubuntu ",[673,794,795],{"class":683},"$(",[673,797,798],{"class":679},"lsb_release",[673,800,801],{"class":687}," -cs",[673,803,804],{"class":683},")",[673,806,807],{"class":687}," stable",[673,809,691],{"class":683},[673,811,753],{"class":683},[673,813,756],{"class":679},[673,815,816],{"class":687}," tee",[673,818,819],{"class":687}," \u002Fetc\u002Fapt\u002Fsources.list.d\u002Fdocker.list",[673,821,822],{"class":683}," >",[673,824,825],{"class":687}," \u002Fdev\u002Fnull\n",[673,827,829],{"class":675,"line":828},6,[673,830,774],{"emptyLinePlaceholder":773},[673,832,834],{"class":675,"line":833},7,[673,835,836],{"class":738},"# Update package list\n",[673,838,840,843,846],{"class":675,"line":839},8,[673,841,842],{"class":679},"sudo",[673,844,845],{"class":687}," apt",[673,847,848],{"class":687}," update\n",[673,850,852],{"class":675,"line":851},9,[673,853,774],{"emptyLinePlaceholder":773},[673,855,857],{"class":675,"line":856},10,[673,858,859],{"class":738},"# Install Docker Engine, Docker Community Edition, and containerd runtime\n",[673,861,863,865,867,870,873,876,879],{"class":675,"line":862},11,[673,864,842],{"class":679},[673,866,845],{"class":687},[673,868,869],{"class":687}," install",[673,871,872],{"class":687}," docker-ce",[673,874,875],{"class":687}," docker-ce-cli",[673,877,878],{"class":687}," containerd.io",[673,880,881],{"class":687}," -y\n",[673,883,885],{"class":675,"line":884},12,[673,886,774],{"emptyLinePlaceholder":773},[673,888,890],{"class":675,"line":889},13,[673,891,892],{"class":738},"# Start automatically when the system boots\n",[673,894,896,898,901,904],{"class":675,"line":895},14,[673,897,842],{"class":679},[673,899,900],{"class":687}," systemctl",[673,902,903],{"class":687}," enable",[673,905,906],{"class":687}," docker\n",[673,908,910],{"class":675,"line":909},15,[673,911,774],{"emptyLinePlaceholder":773},[673,913,915],{"class":675,"line":914},16,[673,916,917],{"class":738},"# Verify docker is installed\n",[673,919,921,924],{"class":675,"line":920},17,[673,922,923],{"class":679},"docker",[673,925,926],{"class":687}," --version\n",[673,928,930],{"class":675,"line":929},18,[673,931,774],{"emptyLinePlaceholder":773},[673,933,935,937,939,941,944],{"class":675,"line":934},19,[673,936,842],{"class":679},[673,938,845],{"class":687},[673,940,869],{"class":687},[673,942,943],{"class":687}," -y",[673,945,946],{"class":687}," docker-compose-plugin\n",[673,948,950],{"class":675,"line":949},20,[673,951,774],{"emptyLinePlaceholder":773},[673,953,955],{"class":675,"line":954},21,[673,956,957],{"class":738},"# Verify the compose plugin is installed\n",[673,959,961,963,966],{"class":675,"line":960},22,[673,962,923],{"class":679},[673,964,965],{"class":687}," compose",[673,967,968],{"class":687}," version\n",[548,970,972],{"id":971},"_3-clonar-e-configurar","3. Clonar e configurar",[665,974,976],{"className":667,"code":975,"language":669,"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",[646,977,978,989,993,1001,1012],{"__ignoreMap":424},[673,979,980,983,986],{"class":675,"line":676},[673,981,982],{"class":679},"git",[673,984,985],{"class":687}," clone",[673,987,988],{"class":687}," https:\u002F\u002Fgithub.com\u002Fblock\u002Fbuzz.git\n",[673,990,991],{"class":675,"line":742},[673,992,774],{"emptyLinePlaceholder":773},[673,994,995,998],{"class":675,"line":616},[673,996,997],{"class":786},"cd",[673,999,1000],{"class":687}," buzz\u002Fdeploy\u002Fcompose\n",[673,1002,1003,1006,1009],{"class":675,"line":777},[673,1004,1005],{"class":679},"cp",[673,1007,1008],{"class":687}," .env.example",[673,1010,1011],{"class":687}," .env\n",[673,1013,1014,1017],{"class":675,"line":783},[673,1015,1016],{"class":679},"nano",[673,1018,1011],{"class":687},[429,1020,1021,1022,1025],{},"Modifique ",[646,1023,1024],{},".env"," em grupos:",[456,1027,1028],{},[459,1029,1030],{},[443,1031,1032],{},"Domínio:",[665,1034,1039],{"className":1035,"code":1037,"language":1038},[1036],"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",[646,1040,1037],{"__ignoreMap":424},[456,1042,1043,1053],{},[459,1044,1045,1048,1049,1052],{},[443,1046,1047],{},"Chave do proprietário:"," ",[646,1050,1051],{},"RELAY_OWNER_PUBKEY"," requer sua chave pública hexadecimal de 64 caracteres. Gere uma identidade no aplicativo de desktop primeiro ('Create a new identity key' → copie seu ID público, que está no formato npub), depois converta-o para hexadecimal.",[459,1054,1055,1058],{},[443,1056,1057],{},"Segredos (Secrets):",[456,1059,1060,1072,1087],{},[459,1061,1062,1063,1067,1068,1071],{},"Gere segredos usando esta ",[570,1064,1066],{"href":1065},"\u002Fpt\u002Ftools\u002Fsecret-key-hex","ferramenta online"," ou com ",[646,1069,1070],{},"openssl rand -hex 32"," (execute sete vezes)",[459,1073,1074,1075,1078,1079,1082,1083,1086],{},"Substitua cada marcador ",[646,1076,1077],{},"CHANGE_ME",": ",[646,1080,1081],{},"BUZZ_RELAY_PRIVATE_KEY",", ",[646,1084,1085],{},"BUZZ_GIT_HOOK_HMAC_SECRET",", as senhas do Postgres\u002FRedis\u002FTypesense e as chaves secretas\u002Facesso do S3.",[459,1088,1089,1090,607],{},"Marcadores restantes são a causa mais comum de loops de reinicialização de contêineres; verifique os seus com ",[646,1091,1092],{},"grep CHANGE_ME .env",[665,1094,1097],{"className":1095,"code":1096,"language":1038},[1036],"    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",[646,1098,1096],{"__ignoreMap":424},[456,1100,1101],{},[459,1102,1103,1106],{},[443,1104,1105],{},"Outros:",[456,1107,1108,1115],{},[459,1109,1110,1111,1114],{},"Adicione ",[646,1112,1113],{},"CLOUDFLARE_API_TOKEN"," como uma variável de ambiente e atribua o token de API gerado anteriormente. Isso é obrigatório para o Caddy.",[459,1116,1117,1118,1082,1120,1123,1124,607],{},"Buzz é fornecido com padrões abertos — qualquer pessoa que conheça a URL do seu relay pode se autenticar e participar. Defina ",[646,1119,1051],{},[646,1121,1122],{},"BUZZ_REQUIRE_RELAY_MEMBERSHIP=true"," e ",[646,1125,1126],{},"BUZZ_REQUIRE_AUTH_TOKEN=true",[548,1128,1130],{"id":1129},"_4-habilitar-https-com-caddy","4. Habilitar HTTPS com Caddy",[587,1132,1134],{"id":1133},"construir-uma-imagem-personalizada-do-caddy-com-o-módulo-dns-da-cloudflare","Construir uma imagem personalizada do Caddy com o módulo DNS da Cloudflare",[456,1136,1137,1148,1159],{},[459,1138,1139,1140,1143,1144,1147],{},"Configuramos o DNS-01 com a Cloudflare para o Caddy. DNS-01 funciona fazendo com que o plug-in grave um registro TXT ",[646,1141,1142],{},"_acme-challenge.buzz.pafor.me"," no ",[443,1145,1146],{},"DNS público",";",[459,1149,1150,1151,1154,1155,1158],{},"Let's Encrypt então consulta o registro na internet pública para verificar o controle do domínio. Isso significa que ",[646,1152,1153],{},"pafor.me"," deve ser uma zona pública em sua conta da Cloudflare — não apenas um nome de host privado que existe apenas no DNS privado do Zero Trust \u002F WARP. Se o ",[646,1156,1157],{},"buzz.pafor.me"," for resolvido apenas de forma privada e não houver uma zona pública, o DNS-01 falhará, exigindo uma abordagem diferente.",[459,1160,1161],{},"Adicione o seguinte ao Caddyfile:",[665,1163,1167],{"className":1164,"code":1165,"language":1166,"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",[646,1168,1169,1174,1188],{"__ignoreMap":424},[673,1170,1171],{"class":675,"line":676},[673,1172,1173],{"class":683},"{\n",[673,1175,1176,1179,1182,1185],{"class":675,"line":742},[673,1177,1178],{"class":687},"  acme_dns cloudflare",[673,1180,1181],{"class":683}," {",[673,1183,1184],{"class":687},"env.CLOUDFLARE_API_TOKEN",[673,1186,1187],{"class":683},"}\n",[673,1189,1190],{"class":675,"line":616},[673,1191,1187],{"class":683},[456,1193,1194],{},[459,1195,1196],{},"Crie um Dockerfile.caddy com o seguinte conteúdo, que é exigido pelo compose.caddy.yml:",[665,1198,1200],{"className":1164,"code":1199,"language":1166,"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",[646,1201,1202,1207,1211,1216,1221,1225,1230,1234],{"__ignoreMap":424},[673,1203,1204],{"class":675,"line":676},[673,1205,1206],{"class":687},"FROM caddy:2-builder AS builder\n",[673,1208,1209],{"class":675,"line":742},[673,1210,774],{"emptyLinePlaceholder":773},[673,1212,1213],{"class":675,"line":616},[673,1214,1215],{"class":687},"RUN xcaddy build \\\n",[673,1217,1218],{"class":675,"line":777},[673,1219,1220],{"class":687},"    --with github.com\u002Fcaddy-dns\u002Fcloudflare\n",[673,1222,1223],{"class":675,"line":783},[673,1224,774],{"emptyLinePlaceholder":773},[673,1226,1227],{"class":675,"line":828},[673,1228,1229],{"class":687},"FROM caddy:2-alpine\n",[673,1231,1232],{"class":675,"line":833},[673,1233,774],{"emptyLinePlaceholder":773},[673,1235,1236],{"class":675,"line":839},[673,1237,1238],{"class":687},"COPY --from=builder \u002Fusr\u002Fbin\u002Fcaddy \u002Fusr\u002Fbin\u002Fcaddy\n",[456,1240,1241],{},[459,1242,1021,1243,1246],{},[646,1244,1245],{},"compose.caddy.yml"," para usar a imagem com o módulo da Cloudflare e passar o token de API da Cloudflare:",[665,1248,1250],{"className":1164,"code":1249,"language":1166,"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",[646,1251,1252,1261,1268,1283,1287,1294,1301,1312,1322,1332,1339,1346,1356,1363,1373,1383,1389,1401,1412,1419,1426,1433,1440,1451,1459,1467,1472,1480,1488,1496,1507,1515,1522],{"__ignoreMap":424},[673,1253,1254,1258],{"class":675,"line":676},[673,1255,1257],{"class":1256},"swJcz","services",[673,1259,1260],{"class":683},":\n",[673,1262,1263,1266],{"class":675,"line":742},[673,1264,1265],{"class":1256},"  relay",[673,1267,1260],{"class":683},[673,1269,1270,1273,1276,1280],{"class":675,"line":616},[673,1271,1272],{"class":1256},"    ports",[673,1274,1275],{"class":683},":",[673,1277,1279],{"class":1278},"spNyl"," !reset",[673,1281,1282],{"class":683}," []\n",[673,1284,1285],{"class":675,"line":777},[673,1286,774],{"emptyLinePlaceholder":773},[673,1288,1289,1292],{"class":675,"line":783},[673,1290,1291],{"class":1256},"  caddy",[673,1293,1260],{"class":683},[673,1295,1296,1299],{"class":675,"line":828},[673,1297,1298],{"class":1256},"    build",[673,1300,1260],{"class":683},[673,1302,1303,1306,1308],{"class":675,"line":833},[673,1304,1305],{"class":1256},"      context",[673,1307,1275],{"class":683},[673,1309,1311],{"class":1310},"sbssI"," .\n",[673,1313,1314,1317,1319],{"class":675,"line":839},[673,1315,1316],{"class":1256},"      dockerfile",[673,1318,1275],{"class":683},[673,1320,1321],{"class":687}," Dockerfile.caddy\n",[673,1323,1324,1327,1329],{"class":675,"line":851},[673,1325,1326],{"class":1256},"    image",[673,1328,1275],{"class":683},[673,1330,1331],{"class":687}," buzz-caddy:cloudflare\n",[673,1333,1334,1337],{"class":675,"line":856},[673,1335,1336],{"class":1256},"    depends_on",[673,1338,1260],{"class":683},[673,1340,1341,1344],{"class":675,"line":862},[673,1342,1343],{"class":1256},"      relay",[673,1345,1260],{"class":683},[673,1347,1348,1351,1353],{"class":675,"line":884},[673,1349,1350],{"class":1256},"        condition",[673,1352,1275],{"class":683},[673,1354,1355],{"class":687}," service_healthy\n",[673,1357,1358,1361],{"class":675,"line":889},[673,1359,1360],{"class":1256},"    environment",[673,1362,1260],{"class":683},[673,1364,1365,1368,1370],{"class":675,"line":895},[673,1366,1367],{"class":1256},"      BUZZ_DOMAIN",[673,1369,1275],{"class":683},[673,1371,1372],{"class":687}," ${BUZZ_DOMAIN:?set BUZZ_DOMAIN}\n",[673,1374,1375,1378,1380],{"class":675,"line":909},[673,1376,1377],{"class":1256},"      CLOUDFLARE_API_TOKEN",[673,1379,1275],{"class":683},[673,1381,1382],{"class":687}," ${CLOUDFLARE_API_TOKEN:?set CLOUDFLARE_API_TOKEN}\n",[673,1384,1385,1387],{"class":675,"line":914},[673,1386,1272],{"class":1256},[673,1388,1260],{"class":683},[673,1390,1391,1394,1396,1399],{"class":675,"line":920},[673,1392,1393],{"class":683},"      -",[673,1395,684],{"class":683},[673,1397,1398],{"class":687},"${CADDY_HTTP_PORT:-80}:80",[673,1400,702],{"class":683},[673,1402,1403,1405,1407,1410],{"class":675,"line":929},[673,1404,1393],{"class":683},[673,1406,684],{"class":683},[673,1408,1409],{"class":687},"${CADDY_HTTPS_PORT:-443}:443",[673,1411,702],{"class":683},[673,1413,1414,1417],{"class":675,"line":934},[673,1415,1416],{"class":1256},"    volumes",[673,1418,1260],{"class":683},[673,1420,1421,1423],{"class":675,"line":949},[673,1422,1393],{"class":683},[673,1424,1425],{"class":687}," .\u002FCaddyfile:\u002Fetc\u002Fcaddy\u002FCaddyfile:ro\n",[673,1427,1428,1430],{"class":675,"line":954},[673,1429,1393],{"class":683},[673,1431,1432],{"class":687}," buzz-caddy-data:\u002Fdata\n",[673,1434,1435,1437],{"class":675,"line":960},[673,1436,1393],{"class":683},[673,1438,1439],{"class":687}," buzz-caddy-config:\u002Fconfig\n",[673,1441,1443,1446,1448],{"class":675,"line":1442},23,[673,1444,1445],{"class":1256},"    restart",[673,1447,1275],{"class":683},[673,1449,1450],{"class":687}," unless-stopped\n",[673,1452,1454,1457],{"class":675,"line":1453},24,[673,1455,1456],{"class":1256},"    networks",[673,1458,1260],{"class":683},[673,1460,1462,1464],{"class":675,"line":1461},25,[673,1463,1393],{"class":683},[673,1465,1466],{"class":687}," buzz-net\n",[673,1468,1470],{"class":675,"line":1469},26,[673,1471,774],{"emptyLinePlaceholder":773},[673,1473,1475,1478],{"class":675,"line":1474},27,[673,1476,1477],{"class":1256},"volumes",[673,1479,1260],{"class":683},[673,1481,1483,1486],{"class":675,"line":1482},28,[673,1484,1485],{"class":1256},"  buzz-caddy-data",[673,1487,1260],{"class":683},[673,1489,1491,1494],{"class":675,"line":1490},29,[673,1492,1493],{"class":1256},"    labels",[673,1495,1260],{"class":683},[673,1497,1499,1502,1504],{"class":675,"line":1498},30,[673,1500,1501],{"class":1256},"      com.buzz.volume",[673,1503,1275],{"class":683},[673,1505,1506],{"class":687}," caddy-data\n",[673,1508,1510,1513],{"class":675,"line":1509},31,[673,1511,1512],{"class":1256},"  buzz-caddy-config",[673,1514,1260],{"class":683},[673,1516,1518,1520],{"class":675,"line":1517},32,[673,1519,1493],{"class":1256},[673,1521,1260],{"class":683},[673,1523,1525,1527,1529],{"class":675,"line":1524},33,[673,1526,1501],{"class":1256},[673,1528,1275],{"class":683},[673,1530,1531],{"class":687}," caddy-config\n",[587,1533,1535],{"id":1534},"iniciar-os-contêineres-docker","Iniciar os contêineres Docker",[665,1537,1539],{"className":667,"code":1538,"language":669,"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",[646,1540,1541,1564,1568,1573],{"__ignoreMap":424},[673,1542,1543,1545,1547,1550,1553,1555,1558,1561],{"class":675,"line":676},[673,1544,923],{"class":679},[673,1546,965],{"class":687},[673,1548,1549],{"class":687}," -f",[673,1551,1552],{"class":687}," compose.yml",[673,1554,1549],{"class":687},[673,1556,1557],{"class":687}," compose.caddy.yml",[673,1559,1560],{"class":687}," up",[673,1562,1563],{"class":687}," -d\n",[673,1565,1566],{"class":675,"line":742},[673,1567,774],{"emptyLinePlaceholder":773},[673,1569,1570],{"class":675,"line":616},[673,1571,1572],{"class":738},"#Check the Docker status\n",[673,1574,1575,1577,1579],{"class":675,"line":777},[673,1576,923],{"class":679},[673,1578,965],{"class":687},[673,1580,1581],{"class":687}," ps\n",[435,1583],{"src":1584,"alt":1585,"style":1586},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf-Hosting%20Buzz%20As%20The%20Workspace%20Where%20AI%20Agents%20Become%20Colleagues\u002Fdocker-compose-ps-status-terminal.webp","Janela de terminal exibindo contêineres em execução para os serviços do Buzz via docker compose ps","max-width: 700px; width: 100%; height: auto;",[429,1588,1589,1590,1593],{},"Abra o seu navegador e navegue até ",[646,1591,1592],{},"http:\u002F\u002Fbuzz.pafor.me"," para verificar se o relay está funcionando.",[435,1595],{"src":1596,"alt":1597,"style":1598},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf-Hosting%20Buzz%20As%20The%20Workspace%20Where%20AI%20Agents%20Become%20Colleagues\u002Fbuzz-relay-running-browser-verification.webp","Verificação no navegador mostrando resposta bem-sucedida do relay auto-hospedado do Buzz do Block","max-width: 500px; width: 100%; height: auto;",[548,1600,1602],{"id":1601},"passo-5-backups-desde-o-primeiro-dia","Passo 5: Backups desde o primeiro dia",[665,1604,1606],{"className":667,"code":1605,"language":669,"meta":424,"style":424},"mkdir -p \u002Fbuzz_backups\ncrontab -e\n",[646,1607,1608,1619],{"__ignoreMap":424},[673,1609,1610,1613,1616],{"class":675,"line":676},[673,1611,1612],{"class":679},"mkdir",[673,1614,1615],{"class":687}," -p",[673,1617,1618],{"class":687}," \u002Fbuzz_backups\n",[673,1620,1621,1624],{"class":675,"line":742},[673,1622,1623],{"class":679},"crontab",[673,1625,1626],{"class":687}," -e\n",[429,1628,1629],{},"Adicione um trabalho cron de backup noturno do banco de dados:",[665,1631,1634],{"className":1632,"code":1633,"language":1038},[1036],"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",[646,1635,1633],{"__ignoreMap":424},[429,1637,1638],{},"Nota: Trate BUZZ_RELAY_PRIVATE_KEY como permanente. Os eventos assinados por ela falharão na verificação se a chave for alterada; um banco de dados restaurado emparejado com uma nova chave não será tratado como o mesmo relay.",[448,1640,1642],{"id":1641},"configurando-o-cliente-desktop-buzz-e-as-identidades-nostr","Configurando o cliente desktop Buzz e as identidades Nostr",[429,1644,1645,1646,1651],{},"Baixe o aplicativo desktop do Buzz em ",[570,1647,1648],{"href":1648,"rel":1649},"https:\u002F\u002Fgithub.com\u002Fblock\u002Fbuzz\u002Freleases",[1650],"nofollow"," e inicie-o. Preencha as informações do perfil até chegar à página \"Join or create a community\".",[429,1653,1654],{},[435,1655],{"alt":1656,"src":1657},"Tela de configuração inicial do cliente desktop Buzz para participar ou criar uma comunidade","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf-Hosting%20Buzz%20As%20The%20Workspace%20Where%20AI%20Agents%20Become%20Colleagues\u002Fbuzz-desktop-client-setup-community.webp",[429,1659,1660],{},"Clique em \"Join a community\" e copie a sua chave pública.",[429,1662,1663],{},[435,1664],{"alt":1665,"src":1666},"Exibição do cliente Buzz mostrando a identidade da chave pública antes de participar da comunidade","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,1668,1669],{},"Execute o seguinte comando no VPS para se adicionar como o primeiro membro:",[665,1671,1673],{"className":667,"code":1672,"language":669,"meta":424,"style":424},"docker compose exec relay buzz-admin add-member --pubkey npub1yourkeyhere\n",[646,1674,1675],{"__ignoreMap":424},[673,1676,1677,1679,1681,1684,1687,1690,1693,1696],{"class":675,"line":676},[673,1678,923],{"class":679},[673,1680,965],{"class":687},[673,1682,1683],{"class":687}," exec",[673,1685,1686],{"class":687}," relay",[673,1688,1689],{"class":687}," buzz-admin",[673,1691,1692],{"class":687}," add-member",[673,1694,1695],{"class":687}," --pubkey",[673,1697,1698],{"class":687}," npub1yourkeyhere\n",[429,1700,1110,1701,1704],{},[646,1702,1703],{},"wss:\u002F\u002Fbuzz.pafor.me"," como a URL da comunidade e clique em \"Next\".",[429,1706,1707],{},[435,1708],{"alt":1709,"src":1710},"Inserindo a URL do relay da comunidade auto-hospedada no aplicativo desktop Buzz","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,1712,1713],{},"Digite um nome e clique no botão Next.",[429,1715,1716],{},[435,1717],{"alt":1718,"src":1719},"Tela de configuração de perfil no aplicativo Buzz para inserir o nome de exibição","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,1721,1723],{"id":1722},"canais-channels-e-agentes","Canais (Channels) e Agentes",[429,1725,1726],{},"Canais são grupos de tarefas ou projetos. Crie um canal por tarefa ou projeto e inclua os humanos e agentes.",[429,1728,1729],{},"Tudo dentro de um canal é compartilhado automaticamente, eliminando a necessidade de instruir cada membro individualmente. Cada agente pode ser mencionado usando @ e lê as mensagens relevantes. Além disso, os agentes podem se mencionar usando @ entre si.",[429,1731,1732],{},"Vamos enviar uma mensagem direta (DM) para um agente pré-configurado",[429,1734,1735],{},[435,1736],{"alt":1737,"src":1738},"Enviando mensagem direta para um agente de IA no cliente desktop colaborativo Buzz","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf-Hosting%20Buzz%20As%20The%20Workspace%20Where%20AI%20Agents%20Become%20Colleagues\u002Fbuzz-desktop-client-dm-agent.webp",[429,1740,1741],{},"Vamos criar um canal e adicionar alguns agentes a ele",[429,1743,1744],{},[435,1745],{"alt":1746,"src":1747},"Criando um novo canal de tarefa ou projeto no aplicativo desktop 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,1749,1750],{},[435,1751],{"alt":1752,"src":1753},"Adicionando membro humano e agentes de IA ao canal recém-criado","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,1755,1756],{},[435,1757],{"alt":1758,"src":1759},"Visualização do canal ativo exibindo histórico de chat consolidado e tarefas do projeto","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf-Hosting%20Buzz%20As%20The%20Workspace%20Where%20AI%20Agents%20Become%20Colleagues\u002Fbuzz-desktop-client-channel-view.webp",[435,1761],{"src":1762,"alt":1763,"style":1764},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf-Hosting%20Buzz%20As%20The%20Workspace%20Where%20AI%20Agents%20Become%20Colleagues\u002Fbuzz-desktop-client-channel-active-agents.webp","Visualização detalhada dos agentes de IA ativos integrados no canal do projeto colaborativo","max-width: 367px; width: 100%; height: auto;",[548,1766,1768],{"id":1767},"habilitar-runtimes-de-agentes","Habilitar runtimes de agentes",[429,1770,1771,1772,1775,1776,1779],{},"Os runtimes predefinidos dependem da descoberta automática que detecta os binários de inicialização (como ",[646,1773,1774],{},"hermes-acp",") em diretórios padrão como ",[646,1777,1778],{},"~\u002F.local\u002Fbin",". Se uma ferramenta foi instalada em um local não padrão, o Buzz não poderá resolvê-la.",[429,1781,1782,1783,1786],{},"Para o Kimi Code, o ID do agente é kimi, e o Buzz procura o seu binario em ",[646,1784,1785],{},"~\u002F.local\u002Fbin\u002Fkimi",". Um link simbólico resolve o problema:",[665,1788,1791],{"className":1789,"code":1790,"language":1038},[1036],"ln -s kimi-cli \u002FUsers\u002F\u003Cuser>\u002F.local\u002Fbin\u002Fkimi\n",[646,1792,1790],{"__ignoreMap":424},[429,1794,1795],{},"O Kimi Code agora aparece em runtimes de agentes.",[429,1797,1798],{},[435,1799],{"alt":1800,"src":1801},"Configurações do aplicativo Buzz exibindo runtimes de agentes de IA configurados, incluindo Kimi","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf-Hosting%20Buzz%20As%20The%20Workspace%20Where%20AI%20Agents%20Become%20Colleagues\u002Fbuzz-settings-agent-runtimes-list.webp",[548,1803,1805],{"id":1804},"projetos-e-repositórios","Projetos e Repositórios",[429,1807,1808,1809,1812],{},"Primeiro, ative o recurso '",[443,1810,1811],{},"Projects","' em Settings → Experiments:",[429,1814,1815],{},[435,1816],{"alt":1817,"src":1818},"Habilitando o recurso experimental Projects na guia de configurações do Buzz","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf-Hosting%20Buzz%20As%20The%20Workspace%20Where%20AI%20Agents%20Become%20Colleagues\u002Fbuzz-settings-experiments-projects.webp",[429,1820,1821,1822,1825],{},"Atualmente, um projeto deve ser criado usando o ",[646,1823,1824],{},"buzz-cli"," (embora a criação direta de projetos a partir da interface do usuário esteja planejada para uma versão futura).",[587,1827,1829],{"id":1828},"instalar-buzz-cli","Instalar buzz-cli",[429,1831,1832,1833,1835],{},"Execute os seguintes comandos para instalar o ",[646,1834,1824],{}," no VPS:",[665,1837,1839],{"className":667,"code":1838,"language":669,"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",[646,1840,1841,1852,1859,1872],{"__ignoreMap":424},[673,1842,1843,1845,1847,1849],{"class":675,"line":676},[673,1844,842],{"class":679},[673,1846,845],{"class":687},[673,1848,869],{"class":687},[673,1850,1851],{"class":687}," cargo\n",[673,1853,1854,1856],{"class":675,"line":742},[673,1855,997],{"class":786},[673,1857,1858],{"class":687}," ~\u002Fbuzz\n",[673,1860,1861,1864,1866,1869],{"class":675,"line":616},[673,1862,1863],{"class":679},"cargo",[673,1865,869],{"class":687},[673,1867,1868],{"class":687}," --path",[673,1870,1871],{"class":687}," crates\u002Fbuzz-cli\n",[673,1873,1874,1876,1879,1882,1885,1888,1891,1894,1897],{"class":675,"line":777},[673,1875,787],{"class":786},[673,1877,1878],{"class":683}," '",[673,1880,1881],{"class":687},"export PATH=\"$HOME\u002F.cargo\u002Fbin:$PATH\"",[673,1883,1884],{"class":683},"'",[673,1886,1887],{"class":683}," >>",[673,1889,1890],{"class":687}," ~\u002F.bashrc",[673,1892,1893],{"class":683}," &&",[673,1895,1896],{"class":786}," source",[673,1898,1899],{"class":687}," ~\u002F.bashrc\n",[429,1901,1902,1903,1906,1907,1909,1910,1912],{},"Gere um par de chaves privada e pública usando a ",[570,1904,1066],{"href":1905},"\u002Fpt\u002Ftools\u002Fnostr-key-generator"," ou o ",[646,1908,1824],{},". Este par constitui a identidade do ",[646,1911,1824],{}," no relay Nostr.",[665,1914,1916],{"className":667,"code":1915,"language":669,"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",[646,1917,1918,1940,1944,1949],{"__ignoreMap":424},[673,1919,1920,1922,1925,1928,1931,1934,1937],{"class":675,"line":676},[673,1921,923],{"class":679},[673,1923,1924],{"class":687}," run",[673,1926,1927],{"class":687}," --rm",[673,1929,1930],{"class":687}," --entrypoint",[673,1932,1933],{"class":687}," \u002Fusr\u002Flocal\u002Fbin\u002Fbuzz-admin",[673,1935,1936],{"class":687}," ghcr.io\u002Fblock\u002Fbuzz:main",[673,1938,1939],{"class":687}," generate-key\n",[673,1941,1942],{"class":675,"line":742},[673,1943,774],{"emptyLinePlaceholder":773},[673,1945,1946],{"class":675,"line":616},[673,1947,1948],{"class":738},"# Use the generated Public Key\n",[673,1950,1951,1953,1955,1957,1959,1961,1963,1965],{"class":675,"line":777},[673,1952,923],{"class":679},[673,1954,965],{"class":687},[673,1956,1683],{"class":687},[673,1958,1686],{"class":687},[673,1960,1689],{"class":687},[673,1962,1692],{"class":687},[673,1964,1695],{"class":687},[673,1966,1967],{"class":687}," generated_Public_key\n",[429,1969,1970],{},"Configurar a CLI:",[665,1972,1974],{"className":667,"code":1973,"language":669,"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",[646,1975,1976,1981,2014,2018],{"__ignoreMap":424},[673,1977,1978],{"class":675,"line":676},[673,1979,1980],{"class":738},"# Copy the Secret key as the BUZZ_PRIVATE_KEY\n",[673,1982,1983,1985,1987,1990,1992,1995,1998,2001,2004,2008,2011],{"class":675,"line":742},[673,1984,787],{"class":786},[673,1986,1878],{"class":683},[673,1988,1989],{"class":687},"export BUZZ_PRIVATE_KEY=\"nsec1...\"",[673,1991,1884],{"class":683},[673,1993,1994],{"class":683},"  >>",[673,1996,1997],{"class":687}," \u002Fhome\u002F",[673,1999,2000],{"class":683},"\u003C",[673,2002,2003],{"class":687},"use",[673,2005,2007],{"class":2006},"sTEyZ","r",[673,2009,2010],{"class":683},">",[673,2012,2013],{"class":687},"\u002F.bashrc\n",[673,2015,2016],{"class":675,"line":616},[673,2017,774],{"emptyLinePlaceholder":773},[673,2019,2020,2022,2024,2027,2029,2031,2033,2035,2037,2039,2041],{"class":675,"line":777},[673,2021,787],{"class":786},[673,2023,1878],{"class":683},[673,2025,2026],{"class":687},"export BUZZ_RELAY_URL=\"wss:\u002F\u002Fbuzz.pafor.me\"",[673,2028,1884],{"class":683},[673,2030,1994],{"class":683},[673,2032,1997],{"class":687},[673,2034,2000],{"class":683},[673,2036,2003],{"class":687},[673,2038,2007],{"class":2006},[673,2040,2010],{"class":683},[673,2042,2013],{"class":687},[429,2044,2045],{},"Execute o seguinte comando para verificar se o buzz-cli está configurado corretamente:",[665,2047,2049],{"className":667,"code":2048,"language":669,"meta":424,"style":424},"buzz channels list\n",[646,2050,2051],{"__ignoreMap":424},[673,2052,2053,2056,2059],{"class":675,"line":676},[673,2054,2055],{"class":679},"buzz",[673,2057,2058],{"class":687}," channels",[673,2060,2061],{"class":687}," list\n",[429,2063,2064],{},[435,2065],{"alt":2066,"src":2067},"Execução de comando no terminal verificando a configuração do buzz-cli ao listar canais ativos","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf-Hosting%20Buzz%20As%20The%20Workspace%20Where%20AI%20Agents%20Become%20Colleagues\u002Fbuzz-cli-channels-list-terminal.webp",[587,2069,2071],{"id":2070},"criar-um-projeto-com-o-buzz-cli","Criar um projeto com o buzz-cli",[665,2073,2075],{"className":667,"code":2074,"language":669,"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",[646,2076,2077,2082],{"__ignoreMap":424},[673,2078,2079],{"class":675,"line":676},[673,2080,2081],{"class":738},"# --channel refers to the UUID of the channel\n",[673,2083,2084,2086,2089,2092,2095,2098,2101,2103,2106,2108,2111,2113,2116],{"class":675,"line":742},[673,2085,2055],{"class":679},[673,2087,2088],{"class":687}," repos",[673,2090,2091],{"class":687}," create",[673,2093,2094],{"class":687}," --id",[673,2096,2097],{"class":687}," TestKOA",[673,2099,2100],{"class":687}," --name",[673,2102,1878],{"class":683},[673,2104,2105],{"class":687},"Display Name",[673,2107,1884],{"class":683},[673,2109,2110],{"class":687}," --channel",[673,2112,684],{"class":683},[673,2114,2115],{"class":687},"bd92b3d1-8fac-441c-a9ac-2b2f3aac5c5b",[673,2117,702],{"class":683},[429,2119,2120,2121,2123],{},"Um projeto só pode ser removido por seu proprietário. Como o projeto \"Display Name\" foi criado pelo ",[646,2122,1824],{},", que carece de um comando de remoção, ele não pode ser excluído dessa maneira.",[429,2125,2126],{},"Consulte o aplicativo desktop Buzz para verificar se o projeto foi criado.",[429,2128,2129],{},[435,2130],{"alt":2131,"src":2132},"Visualização de projetos do aplicativo Buzz confirmando a criação bem-sucedida do projeto","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf-Hosting%20Buzz%20As%20The%20Workspace%20Where%20AI%20Agents%20Become%20Colleagues\u002Fbuzz-desktop-client-project-view.webp",[429,2134,2135],{},"Assim que um projeto estiver disponível em Projects, mais projetos poderão ser adicionados usando o botão \"+\" no canto superior direito.",[429,2137,2138],{},[435,2139],{"alt":2140,"src":2141},"Adicionando novos projetos de desenvolvedor usando o ícone de adição no cliente 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,2143,2145],{"id":2144},"vincular-repositórios-git-existentes","Vincular repositórios Git existentes",[429,2147,2148,2149,2152,2153,2156,2157,1275],{},"Instale o ",[646,2150,2151],{},"git-credential-nostr"," na máquina onde os repositórios git estão instalados. Ele requer o ",[443,2154,2155],{},"git 2.46+"," e a toolchain Rust. Consulte este ",[570,2158,2161],{"href":2159,"rel":2160},"https:\u002F\u002Fgithub.com\u002Fblock\u002Fbuzz\u002Ftree\u002Fmain\u002Fcrates\u002Fgit-credential-nostr",[1650],"Readme",[665,2163,2165],{"className":667,"code":2164,"language":669,"meta":424,"style":424},"cargo install --path crates\u002Fgit-credential-nostr\n",[646,2166,2167],{"__ignoreMap":424},[673,2168,2169,2171,2173,2175],{"class":675,"line":676},[673,2170,1863],{"class":679},[673,2172,869],{"class":687},[673,2174,1868],{"class":687},[673,2176,2177],{"class":687}," crates\u002Fgit-credential-nostr\n",[429,2179,2180,2181,2183],{},"Configure o ",[646,2182,2151],{}," para autorização do relay Buzz:",[665,2185,2187],{"className":667,"code":2186,"language":669,"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",[646,2188,2189,2194,2210,2224,2228,2233,2242,2269],{"__ignoreMap":424},[673,2190,2191],{"class":675,"line":676},[673,2192,2193],{"class":738},"# 1. Register the helper and enable per-path credentials.\n",[673,2195,2196,2198,2201,2204,2207],{"class":675,"line":742},[673,2197,982],{"class":679},[673,2199,2200],{"class":687}," config",[673,2202,2203],{"class":687}," --global",[673,2205,2206],{"class":687}," credential.helper",[673,2208,2209],{"class":687}," nostr\n",[673,2211,2212,2214,2216,2218,2221],{"class":675,"line":616},[673,2213,982],{"class":679},[673,2215,2200],{"class":687},[673,2217,2203],{"class":687},[673,2219,2220],{"class":687}," credential.useHttpPath",[673,2222,2223],{"class":683}," true\n",[673,2225,2226],{"class":675,"line":777},[673,2227,774],{"emptyLinePlaceholder":773},[673,2229,2230],{"class":675,"line":783},[673,2231,2232],{"class":738},"# 2. Store your nsec in a key file (must be 0600). Replace \"nsec1...\" with your private key\n",[673,2234,2235,2237,2239],{"class":675,"line":828},[673,2236,1612],{"class":679},[673,2238,1615],{"class":687},[673,2240,2241],{"class":687}," ~\u002F.nostr\n",[673,2243,2244,2246,2248,2251,2253,2255,2258,2260,2263,2266],{"class":675,"line":833},[673,2245,787],{"class":786},[673,2247,684],{"class":683},[673,2249,2250],{"class":687},"nsec1...",[673,2252,691],{"class":683},[673,2254,822],{"class":683},[673,2256,2257],{"class":687}," ~\u002F.nostr\u002Fkey",[673,2259,1893],{"class":683},[673,2261,2262],{"class":679}," chmod",[673,2264,2265],{"class":1310}," 600",[673,2267,2268],{"class":687}," ~\u002F.nostr\u002Fkey\n",[673,2270,2271,2273,2275,2277,2280],{"class":675,"line":839},[673,2272,982],{"class":679},[673,2274,2200],{"class":687},[673,2276,2203],{"class":687},[673,2278,2279],{"class":687}," nostr.keyfile",[673,2281,2268],{"class":687},[429,2283,2284],{},"Crie um repositório no relay Buzz:",[665,2286,2289],{"className":2287,"code":2288,"language":1038},[1036],"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",[646,2290,2288],{"__ignoreMap":424},[429,2292,2293,2294,2297,2298,2301],{},"No seu primeiro ",[646,2295,2296],{},"git push",", você encontrará um erro ",[646,2299,2300],{},"remote: missing Authorization header",". Para resolver isso, você precisa vincular o ID do repositório a um canal Buzz, pois a associação ao canal dita as permissões de gravação do Git (ACLs):",[665,2303,2305],{"className":667,"code":2304,"language":669,"meta":424,"style":424},"buzz repos bind --id koa-email-routing --channel \u003CCHANNEL_UUID>\n\n# push the code again\ngit push\n",[646,2306,2307,2335,2339,2344],{"__ignoreMap":424},[673,2308,2309,2311,2313,2316,2318,2321,2323,2326,2329,2332],{"class":675,"line":676},[673,2310,2055],{"class":679},[673,2312,2088],{"class":687},[673,2314,2315],{"class":687}," bind",[673,2317,2094],{"class":687},[673,2319,2320],{"class":687}," koa-email-routing",[673,2322,2110],{"class":687},[673,2324,2325],{"class":683}," \u003C",[673,2327,2328],{"class":687},"CHANNEL_UUI",[673,2330,2331],{"class":2006},"D",[673,2333,2334],{"class":683},">\n",[673,2336,2337],{"class":675,"line":742},[673,2338,774],{"emptyLinePlaceholder":773},[673,2340,2341],{"class":675,"line":616},[673,2342,2343],{"class":738},"# push the code again\n",[673,2345,2346,2348],{"class":675,"line":777},[673,2347,982],{"class":679},[673,2349,2350],{"class":687}," push\n",[429,2352,2353,2354,2356],{},"A verificação do projeto no aplicativo Buzz desktop mostra o seguinte, porque o aplicativo precisa do ",[443,2355,2155],{}," — iniciar o aplicativo diretamente pode carregar uma versão mais antiga do Git:",[429,2358,2359],{},[435,2360],{"alt":2361,"src":2362},"O cliente Buzz exibindo erro de carregamento do Git devido a versão local do Git desatualizada inferior a 2.46","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,2364,2365,2366,2369,2370,607],{},"Exporte o PATH por meio de ",[646,2367,2368],{},"launchctl setenv PATH \"\u002Fopt\u002Fhomebrew\u002Fbin:\u002Fusr\u002Flocal\u002Fbin:\u002Fusr\u002Fbin:\u002Fbin:\u002Fusr\u002Fsbin:\u002Fsbin\""," no perfil do shell e inicie o aplicativo Buzz no shell. Consulte este ",[570,2371,2374],{"href":2372,"rel":2373},"https:\u002F\u002Fgithub.com\u002Fblock\u002Fbuzz\u002Fissues\u002F5348",[1650],"problema",[665,2376,2378],{"className":667,"code":2377,"language":669,"meta":424,"style":424},"open -a Buzz\n",[646,2379,2380],{"__ignoreMap":424},[673,2381,2382,2385,2388],{"class":675,"line":676},[673,2383,2384],{"class":679},"open",[673,2386,2387],{"class":687}," -a",[673,2389,2390],{"class":687}," Buzz\n",[429,2392,2393],{},"Consulte novamente os Projetos no aplicativo Buzz, os detalhes do repositório agora estão carregados.",[429,2395,2396],{},[435,2397],{"alt":2398,"src":2399},"Interface de desktop do Buzz com detalhes do repositório Git e logs de commit carregados com sucesso","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,2401,2403],{"id":2402},"sincronizando-agentes-de-ia-com-o-buzz-mobile-app-via-código-qr","Sincronizando agentes de IA com o Buzz Mobile App via código QR",[429,2405,2406,2407,2410],{},"O emparelhamento do aplicativo móvel Buzz só aceita o protocolo HTTPS e o ",[646,2408,2409],{},"buzz-pair-relay"," não é iniciado por padrão no VPS.",[665,2412,2414],{"className":667,"code":2413,"language":669,"meta":424,"style":424},"cd ~\u002Fbuzz\ncargo install --path crates\u002Fbuzz-pair-relay\n",[646,2415,2416,2422],{"__ignoreMap":424},[673,2417,2418,2420],{"class":675,"line":676},[673,2419,997],{"class":786},[673,2421,1858],{"class":687},[673,2423,2424,2426,2428,2430],{"class":675,"line":742},[673,2425,1863],{"class":679},[673,2427,869],{"class":687},[673,2429,1868],{"class":687},[673,2431,2432],{"class":687}," crates\u002Fbuzz-pair-relay\n",[429,2434,2435,2436,2439,2440,1275],{},"Adicione o seguinte ao ",[646,2437,2438],{},"compose.yml"," para iniciar o serviço ",[646,2441,2409],{},[665,2443,2445],{"className":1164,"code":2444,"language":1166,"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",[646,2446,2447,2454,2463,2483,2489,2499,2505,2516,2524,2530],{"__ignoreMap":424},[673,2448,2449,2452],{"class":675,"line":676},[673,2450,2451],{"class":1256},"  pair",[673,2453,1260],{"class":683},[673,2455,2456,2458,2460],{"class":675,"line":742},[673,2457,1326],{"class":1256},[673,2459,1275],{"class":683},[673,2461,2462],{"class":687}," ${BUZZ_IMAGE:-ghcr.io\u002Fblock\u002Fbuzz:main}\n",[673,2464,2465,2468,2470,2473,2475,2478,2480],{"class":675,"line":616},[673,2466,2467],{"class":1256},"    entrypoint",[673,2469,1275],{"class":683},[673,2471,2472],{"class":683}," [",[673,2474,691],{"class":683},[673,2476,2477],{"class":687},"\u002Fusr\u002Flocal\u002Fbin\u002Fbuzz-pair-relay",[673,2479,691],{"class":683},[673,2481,2482],{"class":683},"]\n",[673,2484,2485,2487],{"class":675,"line":777},[673,2486,1360],{"class":1256},[673,2488,1260],{"class":683},[673,2490,2491,2494,2496],{"class":675,"line":783},[673,2492,2493],{"class":1256},"      BUZZ_PAIR_RELAY_BIND_ADDR",[673,2495,1275],{"class":683},[673,2497,2498],{"class":687}," 0.0.0.0:5000\n",[673,2500,2501,2503],{"class":675,"line":828},[673,2502,1272],{"class":1256},[673,2504,1260],{"class":683},[673,2506,2507,2509,2511,2514],{"class":675,"line":833},[673,2508,1393],{"class":683},[673,2510,684],{"class":683},[673,2512,2513],{"class":687},"${BUZZ_PAIR_RELAY_PORT:-5000}:5000",[673,2515,702],{"class":683},[673,2517,2518,2520,2522],{"class":675,"line":839},[673,2519,1445],{"class":1256},[673,2521,1275],{"class":683},[673,2523,1450],{"class":687},[673,2525,2526,2528],{"class":675,"line":851},[673,2527,1456],{"class":1256},[673,2529,1260],{"class":683},[673,2531,2532,2535,2538],{"class":675,"line":856},[673,2533,2534],{"class":683},"      [",[673,2536,2537],{"class":687},"buzz-net",[673,2539,2482],{"class":683},[429,2541,1110,2542,1123,2545,2548,2549,1275],{},[646,2543,2544],{},"BUZZ_PAIRING_RELAY_URL",[646,2546,2547],{},"BUZZ_PAIR_RELAY_PORT"," ao arquivo ",[646,2550,1024],{},[665,2552,2555],{"className":2553,"code":2554,"language":1038},[1036],"BUZZ_PAIRING_RELAY_URL=wss:\u002F\u002Fbuzz.pafor.me\u002Fpair\nBUZZ_PAIR_RELAY_PORT=5000\n",[646,2556,2554],{"__ignoreMap":424},[429,2558,2559,2560,2563],{},"Vá para '",[443,2561,2562],{},"Mobile","' nas configurações da versão desktop do Buzz:",[429,2565,2566],{},[435,2567],{"alt":2568,"src":2569},"Caixa de diálogo de configurações no aplicativo Buzz mostrando a guia de configuração de dispositivos móveis","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],{},"Clique em \"Start pairing\" — um código QR é gerado; escaneie esse código QR com o aplicativo Buzz no dispositivo móvel. Ele será emparelhado depois que você clicar em \"Code Match\".",[429,2574,2575],{},[435,2576],{"alt":2577,"src":2578},"Gerando código QR de emparelhamento seguro no cliente de desktop para sincronização móvel do Buzz","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],{},"Os agentes no aplicativo móvel Buzz só estão disponíveis se estiverem sendo executados no aplicativo de dektop Buzz. O computador desktop deve estar ligado para que os agentes funcionem.",[429,2583,2584],{},[435,2585],{"alt":2586,"src":2587},"Interface do aplicativo móvel do Buzz apresentando os agentes de IA ativos sincronizados","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,2591],{"id":2590},"considerações-finais","Considerações Finais",[429,2593,2594],{},"Embora o Buzz ainda esteja em estágio muito inicial para ambientes de produção em larga escala, apresentando vários bugs e limitações de interface de usuário, é uma experiência empolgante para pequenas equipes e desenvolvedores individuais. Ele oferece uma prévia de como é realmente um espaço de trabalho colaborativo focado primeiramente em IA.",[448,2596,2598],{"id":2597},"referências","Referências",[456,2600,2601,2608,2615,2622],{},[459,2602,2603],{},[570,2604,2607],{"href":2605,"rel":2606},"https:\u002F\u002Fgithub.com\u002Fblock\u002Fbuzz",[1650],"Buzz releases",[459,2609,2610],{},[570,2611,2614],{"href":2612,"rel":2613},"https:\u002F\u002Fblock.xyz\u002Finside\u002Fintroducing-buzz-where-humans-and-agents-work-together",[1650],"Introducing Buzz",[459,2616,2617],{},[570,2618,2621],{"href":2619,"rel":2620},"https:\u002F\u002Fwww.hostinger.com\u002Ftutorials\u002Fwhat-is-buzz",[1650],"What is buzz",[459,2623,2624],{},[570,2625,2628],{"href":2626,"rel":2627},"https:\u002F\u002Fmiget.com\u002Fblog\u002Fhow-to-self-host-buzz",[1650],"How to self-host Buzz (Miget)",[2630,2631,2632],"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":742,"depth":616,"links":2634},[2635,2636,2637,2651,2660,2661,2662],{"id":450,"depth":742,"text":451},{"id":497,"depth":742,"text":498},{"id":545,"depth":742,"text":546,"children":2638},[2639,2640,2644,2645,2646,2650],{"id":550,"depth":616,"text":551},{"id":584,"depth":616,"text":585,"children":2641},[2642,2643],{"id":589,"depth":777,"text":590},{"id":705,"depth":777,"text":706},{"id":724,"depth":616,"text":725},{"id":971,"depth":616,"text":972},{"id":1129,"depth":616,"text":1130,"children":2647},[2648,2649],{"id":1133,"depth":777,"text":1134},{"id":1534,"depth":777,"text":1535},{"id":1601,"depth":616,"text":1602},{"id":1641,"depth":742,"text":1642,"children":2652},[2653,2654,2655],{"id":1722,"depth":616,"text":1723},{"id":1767,"depth":616,"text":1768},{"id":1804,"depth":616,"text":1805,"children":2656},[2657,2658,2659],{"id":1828,"depth":777,"text":1829},{"id":2070,"depth":777,"text":2071},{"id":2144,"depth":777,"text":2145},{"id":2402,"depth":742,"text":2403},{"id":2590,"depth":742,"text":2591},{"id":2597,"depth":742,"text":2598},[2664,2665,2055],"collaboration","ai-agents","2026-09-08","Aprenda a auto-hospedar o relay Buzz da Block em um VPS Linux com Cloudflare. Crie um espaço de trabalho seguro baseado em Nostr para humanos e agentes IA.","md","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf-Hosting%20Buzz%20As%20The%20Workspace%20Where%20AI%20Agents%20Become%20Colleagues\u002FPT-Self-Hosting-Buzz-As-The-Workspace-Where-AI-Agents-Become-Colleagues.webp","Um cartão tecnológico premium de 16:9 com detalhes em azul profundo e laranja ilustrando como auto-hospedar o relay Buzz do Block em um VPS Ubuntu, apresentando um painel glassmorphic limpo com tipografia centrada.",{"schemaOrg":2672,"robots":2694,"sitemap":2695},[2673,2675],{"@type":2674,"headline":423,"description":2667,"image":2669},"TechArticle",{"@type":2676,"name":423,"description":2667,"image":2669,"step":2677},"HowTo",[2678,2682,2685,2688,2691],{"@type":2679,"name":2680,"text":2681},"HowToStep","Fase 1: Configuração da Cloudflare","Criar um token de API da Cloudflare e configurar as definições de DNS.",{"@type":2679,"name":2683,"text":2684},"Fase 2: Instalar o Docker","Configurar e instalar o Docker Engine no VPS Ubuntu.",{"@type":2679,"name":2686,"text":2687},"Fase 3: Clonar e configurar","Clonar o repositório e configurar as variáveis do compose.",{"@type":2679,"name":2689,"text":2690},"Fase 4: Integração do Caddy","Compilar um Caddy personalizado com o módulo de desafio DNS da Cloudflare.",{"@type":2679,"name":2692,"text":2693},"Fase 5: Backup automatizado","Configurar uma tarefa cron para fazer backup automático do PostgreSQL.","index, follow",{"lastmod":2696},"2026-09-03",{"title":2698,"description":2667,"ogTitle":423,"ogDescription":2667,"twitterTitle":423,"twitterDescription":2667},"Como instalar e auto-hospedar o relay Buzz em VPS Ubuntu","pt\u002Farticle\u002Fself-hosting-buzz-as-the-workspace-where-ai-agents-become-colleagues",[2701,2702,445,2703,2704],"Nostr","Docker","Caddy","Cloudflare",null,"d81fxoKo6iAaIp8OwbrHCSaUSob7w9HyKP0oH38Exq0",{"surround":2708,"related":6018},[2709,4610],{"id":2710,"title":2711,"author":2705,"body":2712,"category":4592,"date":4594,"description":4595,"extension":2668,"image":4596,"imageAlt":4597,"isPublished":773,"meta":4598,"minRead":1461,"navigation":773,"path":227,"seo":4605,"stem":4606,"tags":4607,"updatedAt":2696,"__hash__":4609},"article\u002Fpt\u002Farticle\u002Fself-hosted-travel-planner-trek.md","Aloje os seus itinerários de viagem com TREK e Docker",{"type":426,"value":2713,"toc":4551},[2714,2717,2720,2723,2727,2731,2873,2877,2883,2902,2905,2909,3013,3024,3027,3032,3035,3046,3051,3055,3058,3061,3101,3105,3108,3142,3145,3185,3188,3192,3203,3207,3214,3218,3221,3314,3318,3324,3328,3335,3339,3342,3360,3370,3374,3377,3387,3391,3395,3404,3408,3412,3415,3419,3423,3426,3431,3434,3439,3445,3449,3453,3456,3460,3474,3479,3485,3490,3494,3497,3502,3507,3510,3517,3521,3524,3527,3537,3544,3549,3555,3560,3564,3569,3574,3577,3582,3586,3592,3596,3601,3605,3608,3611,3616,3621,3626,3630,3637,3642,3647,3652,3657,3661,3666,3671,3677,3681,3684,3688,3694,3699,3704,3710,3715,3720,3725,3739,3743,3748,3769,3774,3777,3781,3784,3789,3792,3840,3844,3851,3857,3862,3868,3873,3879,3884,3890,3893,3898,3904,3909,3915,3919,3925,3930,3935,3939,3943,3946,3950,3953,3960,3964,3971,3975,3987,3992,3996,4000,4010,4019,4024,4031,4036,4043,4047,4050,4214,4220,4224,4227,4232,4235,4241,4245,4252,4256,4259,4264,4271,4276,4280,4290,4361,4377,4380,4385,4389,4393,4403,4480,4490,4493,4497,4501,4504,4507,4510,4513,4522,4525,4548],[429,2715,2716],{},"A parte mais cansativa do planejamento de uma viagem é que os PDFs de reservas de voo, as confirmações de hotéis, as conversas com os companheiros de viagem e as listas de locais a visitar ficam dispersos em múltiplos lugares. Quando chega a altura de calcular as despesas totais e dividir as contas, é necessário um esforço tremendo para analisar todo esse histórico de dados.",[429,2718,2719],{},"O TREK é um planejador de viagens de código aberto que pode ser autohospedado, integrando o seu itinerário, as suas reservas, o seu orçamento e as listas de bagagem num único local. O seu servidor MCP integrado permite que agentes de IA (como o Claude Desktop) manipulem diretamente os dados das suas viagens.",[429,2721,2722],{},"Este guia irá acompanhá-lo passo a passo, desde a implantação até à gestão completa de uma viagem real do início ao fim.",[548,2724,2726],{"id":2725},"_1-como-implantar-o-planejador-de-viagens-trek-com-docker","1. Como implantar o planejador de viagens TREK com Docker",[587,2728,2730],{"id":2729},"instalar-o-docker-num-vps-ubuntu","Instalar o Docker num VPS Ubuntu",[665,2732,2734],{"className":667,"code":2733,"language":669,"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",[646,2735,2736,2740,2760,2764,2768,2800,2804,2808,2816,2820,2824,2840,2844,2848,2854,2858,2863],{"__ignoreMap":424},[673,2737,2738],{"class":675,"line":676},[673,2739,739],{"class":738},[673,2741,2742,2744,2746,2748,2750,2752,2754,2756,2758],{"class":675,"line":742},[673,2743,680],{"class":679},[673,2745,747],{"class":687},[673,2747,750],{"class":687},[673,2749,753],{"class":683},[673,2751,756],{"class":679},[673,2753,759],{"class":687},[673,2755,762],{"class":687},[673,2757,765],{"class":687},[673,2759,768],{"class":687},[673,2761,2762],{"class":675,"line":616},[673,2763,774],{"emptyLinePlaceholder":773},[673,2765,2766],{"class":675,"line":777},[673,2767,780],{"class":738},[673,2769,2770,2772,2774,2776,2778,2780,2782,2784,2786,2788,2790,2792,2794,2796,2798],{"class":675,"line":783},[673,2771,787],{"class":786},[673,2773,684],{"class":683},[673,2775,792],{"class":687},[673,2777,795],{"class":683},[673,2779,798],{"class":679},[673,2781,801],{"class":687},[673,2783,804],{"class":683},[673,2785,807],{"class":687},[673,2787,691],{"class":683},[673,2789,753],{"class":683},[673,2791,756],{"class":679},[673,2793,816],{"class":687},[673,2795,819],{"class":687},[673,2797,822],{"class":683},[673,2799,825],{"class":687},[673,2801,2802],{"class":675,"line":828},[673,2803,774],{"emptyLinePlaceholder":773},[673,2805,2806],{"class":675,"line":833},[673,2807,836],{"class":738},[673,2809,2810,2812,2814],{"class":675,"line":839},[673,2811,842],{"class":679},[673,2813,845],{"class":687},[673,2815,848],{"class":687},[673,2817,2818],{"class":675,"line":851},[673,2819,774],{"emptyLinePlaceholder":773},[673,2821,2822],{"class":675,"line":856},[673,2823,859],{"class":738},[673,2825,2826,2828,2830,2832,2834,2836,2838],{"class":675,"line":862},[673,2827,842],{"class":679},[673,2829,845],{"class":687},[673,2831,869],{"class":687},[673,2833,872],{"class":687},[673,2835,875],{"class":687},[673,2837,878],{"class":687},[673,2839,881],{"class":687},[673,2841,2842],{"class":675,"line":884},[673,2843,774],{"emptyLinePlaceholder":773},[673,2845,2846],{"class":675,"line":889},[673,2847,917],{"class":738},[673,2849,2850,2852],{"class":675,"line":895},[673,2851,923],{"class":679},[673,2853,926],{"class":687},[673,2855,2856],{"class":675,"line":909},[673,2857,774],{"emptyLinePlaceholder":773},[673,2859,2860],{"class":675,"line":914},[673,2861,2862],{"class":738},"# Starts automatically when your system boots\n",[673,2864,2865,2867,2869,2871],{"class":675,"line":920},[673,2866,842],{"class":679},[673,2868,900],{"class":687},[673,2870,903],{"class":687},[673,2872,906],{"class":687},[587,2874,2876],{"id":2875},"gerar-a-chave-de-criptografia","Gerar a chave de criptografia",[429,2878,2879,2880,2882],{},"O TREK utiliza uma chave para criptografar dados confidenciais. Utilize o comando seguinte ou esta ",[570,2881,1066],{"href":1065}," para gerar a sua chave de criptografia:",[665,2884,2886],{"className":667,"code":2885,"language":669,"meta":424,"style":424},"openssl rand -hex 32\n",[646,2887,2888],{"__ignoreMap":424},[673,2889,2890,2893,2896,2899],{"class":675,"line":676},[673,2891,2892],{"class":679},"openssl",[673,2894,2895],{"class":687}," rand",[673,2897,2898],{"class":687}," -hex",[673,2900,2901],{"class":1310}," 32\n",[429,2903,2904],{},"Guarde-a num local seguro; perdê-la significa perder o acesso aos dados criptografados.",[587,2906,2908],{"id":2907},"iniciar-o-contêiner","Iniciar o contêiner",[665,2910,2912],{"className":667,"code":2911,"language":669,"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",[646,2913,2914,2926,2936,2946,2963,2979,2989,2998,3008],{"__ignoreMap":424},[673,2915,2916,2918,2920,2923],{"class":675,"line":676},[673,2917,923],{"class":679},[673,2919,1924],{"class":687},[673,2921,2922],{"class":687}," -d",[673,2924,2925],{"class":2006}," \\\n",[673,2927,2928,2931,2934],{"class":675,"line":742},[673,2929,2930],{"class":687},"  --name",[673,2932,2933],{"class":687}," trek",[673,2935,2925],{"class":2006},[673,2937,2938,2941,2944],{"class":675,"line":616},[673,2939,2940],{"class":687},"  -p",[673,2942,2943],{"class":687}," 3000:3000",[673,2945,2925],{"class":2006},[673,2947,2948,2951,2954,2956,2959,2961],{"class":675,"line":777},[673,2949,2950],{"class":687},"  -e",[673,2952,2953],{"class":687}," ENCRYPTION_KEY=",[673,2955,691],{"class":683},[673,2957,2958],{"class":687},"\u003Cgenerated_key>",[673,2960,691],{"class":683},[673,2962,2925],{"class":2006},[673,2964,2965,2967,2970,2972,2975,2977],{"class":675,"line":783},[673,2966,2950],{"class":687},[673,2968,2969],{"class":687}," APP_URL=",[673,2971,691],{"class":683},[673,2973,2974],{"class":687},"https:\u002F\u002Ftrek.pafor.me",[673,2976,691],{"class":683},[673,2978,2925],{"class":2006},[673,2980,2981,2984,2987],{"class":675,"line":828},[673,2982,2983],{"class":687},"  -v",[673,2985,2986],{"class":687}," .\u002Fdata:\u002Fapp\u002Fdata",[673,2988,2925],{"class":2006},[673,2990,2991,2993,2996],{"class":675,"line":833},[673,2992,2983],{"class":687},[673,2994,2995],{"class":687}," .\u002Fuploads:\u002Fapp\u002Fuploads",[673,2997,2925],{"class":2006},[673,2999,3000,3003,3006],{"class":675,"line":839},[673,3001,3002],{"class":687},"  --restart",[673,3004,3005],{"class":687}," unless-stopped",[673,3007,2925],{"class":2006},[673,3009,3010],{"class":675,"line":851},[673,3011,3012],{"class":687},"  mauriceboe\u002Ftrek:latest\n",[456,3014,3015],{},[459,3016,3017,3023],{},[443,3018,3019,3022],{},[646,3020,3021],{},"APP_URL"," deve estar definido corretamente"," — o fluxo de descoberta OAuth do servidor MCP depende disso. Defina o seu endereço HTTPS público final desde o início.",[429,3025,3026],{},"A primeira execução demorará um pouco para descarregar a imagem:",[435,3028],{"src":3029,"alt":3030,"style":3031},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-docker-pull-image.webp","Logs de pull e run do Docker para o TREK","max-width: 215px; width:100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[429,3033,3034],{},"Verifique se está em execução:",[665,3036,3038],{"className":667,"code":3037,"language":669,"meta":424,"style":424},"docker ps\n",[646,3039,3040],{"__ignoreMap":424},[673,3041,3042,3044],{"class":675,"line":676},[673,3043,923],{"class":679},[673,3045,1581],{"class":687},[435,3047],{"src":3048,"alt":3049,"style":3050},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-docker-ps-status.webp","Verificando o status do container em execução via docker ps","max-width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[548,3052,3054],{"id":3053},"_2-configurar-o-encaminhamento-de-domínio-e-ssl-com-o-proxy-reverso-caddy","2. Configurar o encaminhamento de domínio e SSL com o proxy reverso Caddy",[429,3056,3057],{},"O protocolo HTTPS é obrigatório para as chaves de acesso (passkeys) e OAuth para MCP. O nome de domínio é alojado na Cloudflare, que oferece um certificado SSL gratuito e proteção DDoS.",[429,3059,3060],{},"O Caddy é configurado como o servidor de proxy reverso seguro apontando para a porta 3000. Eis um exemplo de Caddyfile:",[665,3062,3066],{"className":3063,"code":3064,"language":3065,"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",[646,3067,3068,3082,3087,3097],{"__ignoreMap":424},[673,3069,3070,3073,3076,3079],{"class":675,"line":676},[673,3071,3072],{"class":683},"{",[673,3074,3075],{"class":2006},"$TREK_DOMAIN",[673,3077,3078],{"class":683},"}",[673,3080,3081],{"class":683}," {\n",[673,3083,3084],{"class":675,"line":742},[673,3085,3086],{"class":2006},"  encode zstd gzip\n",[673,3088,3089,3092,3094],{"class":675,"line":616},[673,3090,3091],{"class":2006},"  reverse_proxy host.docker.internal",[673,3093,1275],{"class":683},[673,3095,3096],{"class":1310},"3000\n",[673,3098,3099],{"class":675,"line":777},[673,3100,1187],{"class":683},[548,3102,3104],{"id":3103},"_3-configuração-inicial-e-criação-do-administrador-seguro","3. Configuração inicial e criação do administrador seguro",[429,3106,3107],{},"Existem duas formas de criar a conta de administrador:",[456,3109,3110,3121],{},[459,3111,3112,3120],{},[443,3113,3114,1123,3117],{},[646,3115,3116],{},"ADMIN_EMAIL",[646,3118,3119],{},"ADMIN_PASSWORD"," são definidos como variáveis de ambiente; esses valores são usados diretamente.",[459,3122,3123],{},[443,3124,3125,3126,3129,3130,3133,3134,3137,3138,3141],{},"O TREK cria o e-mail ",[646,3127,3128],{},"admin@trek.local",", o nome de utilizador ",[646,3131,3132],{},"admin"," e uma ",[646,3135,3136],{},"senha gerada aleatoriamente que é impressa nos logs do contêiner",". Execute ",[646,3139,3140],{},"docker logs trek"," para recuperá-la.",[429,3143,3144],{},"Se não conseguir encontrar a senha nos logs, redefina-a com o comando:",[665,3146,3148],{"className":667,"code":3147,"language":669,"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",[646,3149,3150],{"__ignoreMap":424},[673,3151,3152,3154,3156,3159,3162,3165,3167,3170,3172,3175,3177,3179,3182],{"class":675,"line":676},[673,3153,923],{"class":679},[673,3155,1683],{"class":687},[673,3157,3158],{"class":687}," -it",[673,3160,3161],{"class":687}," -e",[673,3163,3164],{"class":687}," RESET_ADMIN_EMAIL=admin@trek.local",[673,3166,3161],{"class":687},[673,3168,3169],{"class":687}," RESET_ADMIN_PASSWORD=",[673,3171,1884],{"class":683},[673,3173,3174],{"class":687},"YourNewPassword",[673,3176,1884],{"class":683},[673,3178,2933],{"class":687},[673,3180,3181],{"class":687}," node",[673,3183,3184],{"class":687}," server\u002Freset-admin.js\n",[429,3186,3187],{},"Será solicitado que altere a senha no primeiro login.",[435,3189],{"src":3190,"alt":3191,"style":3050},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-initial-login-password-prompt.webp","Prompt de login inicial e redefinição de senha do administrador",[429,3193,603,3194,3197,3198],{},[443,3195,3196],{},"Admin"," e atualize o endereço de e-mail:",[435,3199],{"src":3200,"alt":3201,"style":3202},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-admin-email-update-panel.webp","Configurando e-mail personalizado nas configurações de administrador do TREK","max-width: 700px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[587,3204,3206],{"id":3205},"_31-cópias-de-segurança-backups","3.1 Cópias de segurança (Backups)",[429,3208,3209,3210],{},"Configure as cópias de segurança automáticas com uma política de retenção no painel de administração:\n",[435,3211],{"src":3212,"alt":3213,"style":3050},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-admin-backup-retention-policy.webp","Configurando agendamentos de backup automáticos e regras de retenção",[587,3215,3217],{"id":3216},"_32-armazenar-ficheiros-carregados-no-cloudflare-r2","3.2 Armazenar ficheiros carregados no Cloudflare R2",[429,3219,3220],{},"Armazenar ficheiros carregados, fotos e backups no Cloudflare R2 mantém o disco do VPS limpo e leve. O TREK suporta backends compatíveis com S3, e o Cloudflare R2 encaixa-se perfeitamente nisto.",[592,3222,3223,3229,3242,3252,3263,3277,3288,3303],{},[459,3224,3225,3226,607],{},"Crie um bucket R2 chamado ",[646,3227,3228],{},"trek",[459,3230,3231,3232,3235,3236,3237],{},"Na secção ",[443,3233,3234],{},"Account Details",", encontre o ID da sua conta:","\n  ",[435,3238],{"src":3239,"alt":3240,"style":3241},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Fcloudflare-r2-account-details-id.webp","Localizando o ID da conta Cloudflare no portal","max-width: 325px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[459,3243,603,3244,1275,3236,3247],{},[443,3245,3246],{},"Manage API Tokens",[435,3248],{"src":3249,"alt":3250,"style":3251},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Fcloudflare-r2-manage-api-tokens-button.webp","Tela de gerenciamento de tokens de API no portal Cloudflare","max-width: 282px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[459,3253,603,3254,3257,3236,3258],{},[443,3255,3256],{},"Create Account API token"," com permissões de leitura\u002Fescrita para o bucket:",[435,3259],{"src":3260,"alt":3261,"style":3262},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Fcloudflare-r2-create-token-permissions.webp","Criando token de acesso R2 com permissões de leitura e escrita","max-width: 360px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[459,3264,603,3265,3268,3269,1275,3236,3272],{},[443,3266,3267],{},"Storage"," no painel de ",[443,3270,3271],{},"ADMINISTRATION",[435,3273],{"src":3274,"alt":3275,"style":3276},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-administration-storage-menu.webp","Navegando para as configurações de armazenamento no painel de controle do TREK","max-width: 539px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[459,3278,596,3279,3282,3236,3283],{},[443,3280,3281],{},"Add Backend"," e preencha o endpoint, o bucket e as credenciais:",[435,3284],{"src":3285,"alt":3286,"style":3287},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-add-storage-backend-credentials.webp","Configurando o backend de armazenamento Cloudflare R2 compatível com S3","max-width: 445px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[459,3289,603,3290,3293,3294,3297,3236,3298],{},[443,3291,3292],{},"Apply"," e depois no botão ",[443,3295,3296],{},"Test",". Deverá ver a mensagem \"Connection OK\":",[435,3299],{"src":3300,"alt":3301,"style":3302},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-test-storage-backend-connection-ok.webp","Teste de conexão de armazenamento bem-sucedido exibindo Connection OK","max-width: 677px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[459,3304,3305,3306,1275,3236,3309],{},"Altere todas as categorias de armazenamento para Cloudflare R2 e clique em ",[443,3307,3308],{},"Save changes",[435,3310],{"src":3311,"alt":3312,"style":3313},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-switch-storage-categories-r2.webp","Roteando todas as categorias de armazenamento de arquivos para o Cloudflare R2","max-width: 653px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[587,3315,3317],{"id":3316},"_33-login-com-chaves-de-acesso-passkeys","3.3 Login com chaves de acesso (Passkeys)",[429,3319,3320,3321,1275],{},"O TREK suporta chaves de acesso, autenticação de dois fatores (2FA) e autenticação única (SSO) via OIDC. Para chaves de acesso, introduza o seu nome de domínio e as origens permitidas (allowed origins) nas definições e clique em ",[443,3322,3323],{},"Save",[435,3325],{"src":3326,"alt":3327,"style":3050},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-passkey-allowed-origins-settings.webp","Registrando origens permitidas para autenticação segura com Passkey",[429,3329,3330,3331,3334],{},"Sem configurar as ",[443,3332,3333],{},"allowed origins",", o registo da chave de acesso falhará.",[587,3336,3338],{"id":3337},"_34-chave-de-api-do-google-maps","3.4 Chave de API do Google Maps",[429,3340,3341],{},"Uma chave do Google Maps enriquece a pesquisa de locais com classificações, horários de funcionamento e fotos. O TREK reverte automaticamente para o OpenStreetMap caso não seja inserida nenhuma chave, contudo as classificações e fotos não estarão disponíveis.",[429,3343,3344,3345,3350,3351,3354,3355],{},"Siga este ",[570,3346,3349],{"href":3347,"rel":3348},"https:\u002F\u002Fmapsplatform.google.com\u002Fmaps-demo-key\u002F",[1650],"link"," e clique em ",[443,3352,3353],{},"Get demo key"," para solicitar uma:                                                  ",[435,3356],{"src":3357,"alt":3358,"style":3359},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Fgoogle-maps-get-demo-api-key.webp","Solicitando chave de API do Google Maps Platform","max-width: 176px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[429,3361,3362,3363,3365,3366],{},"Cole a chave nas definições e clique em ",[443,3364,3296],{}," para confirmar a ligação:\n",[435,3367],{"src":3368,"alt":3369,"style":3050},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-google-maps-key-test-connection.webp","Verificando a conectividade da chave de API do Google Maps nas configurações",[587,3371,3373],{"id":3372},"_35-integração-de-ia","3.5 Integração de IA",[429,3375,3376],{},"O modelo de IA é utilizado para recuperar e estruturar e-mails de confirmação e PDFs de reserva em dados de reserva estruturados.",[429,3378,603,3379,3382,3383,3386],{},[443,3380,3381],{},"Addons"," no menu esquerdo e ative ",[443,3384,3385],{},"AI Parsing",". Selecione \"OpenAI\" (ou outro fornecedor compatível) e preencha as informações do mesmo:",[435,3388],{"src":3389,"alt":3390,"style":3050},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-addons-enable-ai-parsing-openai.webp","Ativando o addon de parsing de IA com integração com a OpenAI",[587,3392,3394],{"id":3393},"_36-acesso-mcp","3.6 Acesso MCP",[429,3396,3397,3398,3400,3401,1275],{},"Sob ",[443,3399,3381],{},", ative o ",[443,3402,3403],{},"MCP",[435,3405],{"src":3406,"alt":3407,"style":3050},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-addons-enable-mcp.webp","Ativando o addon do servidor MCP do Model Context Protocol",[587,3409,3411],{"id":3410},"_37-plugins","3.7 Plugins",[429,3413,3414],{},"Os seguintes plugins são recomendados e vale a pena ativá-los:",[435,3416],{"src":3417,"alt":3418,"style":3050},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-recommended-addons-plugins-activation.webp","Lista de plugins e addons recomendados ativos",[587,3420,3422],{"id":3421},"_38-criar-o-seu-utilizador-para-o-dia-a-dia","3.8 Criar o seu utilizador para o dia a dia",[429,3424,3425],{},"Planeie as viagens como um utilizador normal, não como administrador. Crie um utilizador regular e inicie sessão com ele:",[435,3427],{"src":3428,"alt":3429,"style":3430},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-create-regular-user-form.webp","Criando uma conta de usuário comum no painel do TREK","max-width: 420px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[429,3432,3433],{},"Depois de iniciar sessão, adicione uma chave de acesso ou configure a autenticação de dois fatores (2FA) para reforçar a segurança da conta:",[435,3435],{"src":3436,"alt":3437,"style":3438},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-user-security-passkey-2fa-setup.webp","Configurando as configurações de segurança do usuário com Passkeys e 2FA","max-width: 381px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[429,3440,603,3441,3444],{},[443,3442,3443],{},"+ Add a passkey",", introduza a senha atual e confirme:",[435,3446],{"src":3447,"alt":3448,"style":3050},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-add-passkey-confirm-password.webp","Confirmando a senha para registrar um novo Passkey físico",[548,3450,3452],{"id":3451},"_4-testar-a-implantação-importar-dados-de-viagens-passadas","4. Testar a implantação: importar dados de viagens passadas",[429,3454,3455],{},"Uma excelente forma de explorar o TREK é registar o seu histórico de viagens.",[587,3457,3459],{"id":3458},"_41-criar-a-viagem","4.1 Criar a viagem",[429,3461,603,3462,3465,3466,3469,3470,3473],{},[443,3463,3464],{},"+ New Trip"," e configure a data de início (",[443,3467,3468],{},"Start Date",") e data de fim (",[443,3471,3472],{},"End Date",") com as datas passadas do seu passeio:",[435,3475],{"src":3476,"alt":3477,"style":3478},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-create-new-trip-details.webp","Criando uma nova viagem com intervalos de datas personalizados","max-width: 334px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[429,3480,3481,3482,1275],{},"Adicione uma foto de capa (arraste uma ou cole do seu área de transferência) e clique em ",[443,3483,3484],{},"Create New Trip",[435,3486],{"src":3487,"alt":3488,"style":3489},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-trip-cover-image-upload.webp","Configurando uma imagem de capa de viagem de alta qualidade","max-width: 608px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[587,3491,3493],{"id":3492},"_42-importar-as-reservas","4.2 Importar as reservas",[429,3495,3496],{},"Arraste e solte todos os ficheiros de voos, comboios e outros meios de transporte:",[435,3498],{"src":3499,"alt":3500,"style":3501},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-import-travel-booking-files.webp","Área de arrastar e soltar para importar PDFs de viagem e reservas","max-width: 570px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[435,3503],{"src":3504,"alt":3505,"style":3506},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-import-booking-pdf-processing-status.webp","Janela de processamento de reserva enviada exibindo a extração","max-width: 377px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[429,3508,3509],{},"Com o modelo de IA ativado, os PDFs de confirmação de reservas são analisados e estruturados automaticamente.",[429,3511,3512,3513,3516],{},"Reveja o resultado do processamento e clique em ",[443,3514,3515],{},"Add"," para registar os detalhes da reserva:",[435,3518],{"src":3519,"alt":3520,"style":3050},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-review-parsed-booking-details.webp","Revisando os detalhes de reserva estruturados extraídos pela IA",[429,3522,3523],{},"Se uma reserva estiver apenas num e-mail, exporte o e-mail como PDF e carregue-o — aplica-se o mesmo fluxo de extração por IA.",[429,3525,3526],{},"As capturas de ecrã seguintes mostram como as reservas são apresentadas:",[429,3528,3529,3533],{},[435,3530],{"src":3531,"alt":3532,"style":3050},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-trip-bookings-timeline-view.webp","Exibição de linha do tempo abrangente das reservas de viagem",[435,3534],{"src":3535,"alt":3536,"style":3050},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-booking-confirmation-details.webp","Visualização detalhada de uma reserva de transporte confirmada",[429,3538,3539,3540,3543],{},"Na página ",[443,3541,3542],{},"Plan",", todos os alojamentos serão indicados no mapa:",[435,3545],{"src":3546,"alt":3547,"style":3548},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-plan-accommodations-map-display.webp","Mapa interativo plotando todas as acomodações de hotel","max-width: 546px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[429,3550,603,3551,3554],{},[443,3552,3553],{},"Atlas"," na barra de menu superior para aceder à lista (e mapa) de todos os países que já visitou:",[435,3556],{"src":3557,"alt":3558,"style":3559},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-atlas-countries-visited-summary.webp","Visão geral do histórico de viagens no rastreador pessoal do Atlas","max-width: 407px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[587,3561,3563],{"id":3562},"_43-adicionar-companheiros-de-viagem","4.3 Adicionar companheiros de viagem",[429,3565,596,3566,1275],{},[443,3567,3568],{},"Share",[435,3570],{"src":3571,"alt":3572,"style":3573},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-trip-share-options-button.webp","Abrindo o diálogo de compartilhamento de viagem no TREK","max-width: 224px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[429,3575,3576],{},"Na parte inferior de la janela, é possível adicionar convidados:",[435,3578],{"src":3579,"alt":3580,"style":3581},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-trip-add-companions-guests.webp","Adicionando companheiros de viagem e convidados personalizados","max-width: 635px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[587,3583,3585],{"id":3584},"_44-registar-as-despesas","4.4 Registar as despesas",[429,3587,603,3588,3591],{},[443,3589,3590],{},"Add expense"," para registar despesas adicionais que não sejam reservas, tais como seguro de saúde, transporte local ou cartões SIM:",[435,3593],{"src":3594,"alt":3595,"style":3050},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-add-custom-expense-form.webp","Inserindo dados detalhados de gastos no formulário de despesas",[435,3597],{"src":3598,"alt":3599,"style":3600},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-expenses-list-billing-split.webp","Divisão de despesas e livro de rastreamento de custos","max-width: 526px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[587,3602,3604],{"id":3603},"_45-segmentos-da-viagem","4.5 Segmentos da viagem",[429,3606,3607],{},"Esta funcionalidade requer que o plugin Trip Segment esteja instalado.",[429,3609,3610],{},"As viagens longas são divididas de forma elegante em segmentos, cada etapa exibindo as suas próprias reservas, pontos turísticos e custos:",[435,3612],{"src":3613,"alt":3614,"style":3615},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-trip-segments-overview-display.webp","Desmembrando um itinerário complexo em segmentos de viagem","max-width: 465px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[435,3617],{"src":3618,"alt":3619,"style":3620},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-trip-segment-itinerary-details.webp","Segmento de viagem ativo exibindo locais e programações","max-width: 596px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[435,3622],{"src":3623,"alt":3624,"style":3625},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-trip-segments-interactive-map.webp","Mapeando diferentes trechos da viagem na linha do tempo","max-width: 605px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[587,3627,3629],{"id":3628},"_46-criar-um-diário-de-viagem-journey-e-consultar-o-seu-atlas","4.6 Criar um diário de viagem (Journey) e consultar o seu atlas",[429,3631,3632,3633,3636],{},"Agrupe as suas viagens num ",[443,3634,3635],{},"Journey"," (diário de rota) e escreva relatos para partilhar as aventuras com os seus amigos:",[435,3638],{"src":3639,"alt":3640,"style":3641},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-create-new-journey-group.webp","Consolidando várias viagens em uma jornada visual (Journey)","max-width: 441px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[435,3643],{"src":3644,"alt":3645,"style":3646},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-journey-timeline-story-writing.webp","Escrevendo histórias visuais no painel de jornada","max-width: 443px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[435,3648],{"src":3649,"alt":3650,"style":3651},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-journey-gallery-media-grid.webp","Coleção de mídias e grade de galeria dentro de uma jornada","max-width: 440px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[435,3653],{"src":3654,"alt":3655,"style":3656},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-journey-public-share-link.webp","Gerando links públicos de compartilhamento para jornadas colaborativas","max-width: 532px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[548,3658,3660],{"id":3659},"_5-desenhar-itinerários-personalizados-e-listas-de-bagagem","5. Desenhar itinerários personalizados e listas de bagagem",[429,3662,603,3663,3665],{},[443,3664,3464],{},", introduza um nome e configure as datas:",[435,3667],{"src":3668,"alt":3669,"style":3670},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-planning-new-trip-setup.webp","Caixa de diálogo inicial para criar uma viagem sem data","max-width: 432px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[429,3672,3673,3676],{},[443,3674,3675],{},"Se ainda não definiu as datas do seu roteiro, deixe ambos os campos em branco."," Irá surgir um campo indicando o \"número de dias\" (até 365). Planeie primeiro, defina as datas mais tarde.",[587,3678,3680],{"id":3679},"_51-adicionar-locais","5.1 Adicionar locais",[429,3682,3683],{},"Este costuma ser o passo mais moroso de qualquer planeamento de viagem, e o TREK tem várias formas de acelerá-lo:",[435,3685],{"src":3686,"alt":3687,"style":3050},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-add-places-methods-overview.webp","Métodos multicanais para adicionar novos locais aos itinerários",[429,3689,3690,3693],{},[443,3691,3692],{},"1. Clique com o botão direito no mapa"," para criar um local nessa posição exata (o endereço é geocodificado de forma reversa automaticamente):",[435,3695],{"src":3696,"alt":3697,"style":3698},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-right-click-map-location.webp","Clicando com o botão direito no mapa para fixar localizações","max-width: 632px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[435,3700],{"src":3701,"alt":3702,"style":3703},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-right-click-reverse-geocode-address.webp","Geocodificação reversa automática das coordenadas selecionadas no mapa","max-width: 628px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[429,3705,3706,3709],{},[443,3707,3708],{},"2. Clique em + Add Place\u002FActivity"," e pesquise por nome:",[435,3711],{"src":3712,"alt":3713,"style":3714},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-search-place-by-name-input.webp","Buscando locais do mundo real usando entradas de texto","max-width: 642px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[435,3716],{"src":3717,"alt":3718,"style":3719},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-select-place-search-results-list.webp","Exibindo resultados de busca de locais com sobreposição de endereços","max-width: 594px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[435,3721],{"src":3722,"alt":3723,"style":3724},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-place-details-rich-info-card.webp","Cartão de informações abrangente do local com avaliações e notas","max-width: 568px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[429,3726,3727,3730,3731,3734,3735,3738],{},[443,3728,3729],{},"3. Cole um URL do Google Maps"," (",[646,3732,3733],{},"maps.app.goo.gl\u002F…"," ou ",[646,3736,3737],{},"maps.google.com\u002F…",") no campo de pesquisa. O TREK extrairá o nome, o endereço e as coordenadas automaticamente:",[435,3740],{"src":3741,"alt":3742,"style":3302},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-paste-google-maps-share-link.webp","Extraindo localizações diretamente de links de compartilhamento copiados do Google Maps",[435,3744],{"src":3745,"alt":3746,"style":3747},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-google-maps-parsed-location.webp","Extração de coordenadas bem-sucedida a partir de URL do Maps","max-width: 543px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[429,3749,3750,3753,3754,3757,3758,1123,3761,3764,3765,3768],{},[443,3751,3752],{},"4. Importação em lote"," — o caminho mais simples. Se já tem uma lista de locais pendentes no Google Maps, exporte-a como ",[646,3755,3756],{},".gpx"," (os formatos ",[646,3759,3760],{},".kml",[646,3762,3763],{},".kmz"," também funcionam) e clique em ",[443,3766,3767],{},"Import file"," no painel direito para carregar tudo de uma só vez:",[435,3770],{"src":3771,"alt":3772,"style":3773},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-bulk-import-places-gpx-file.webp","Realizando importações em lote de locais usando arquivos GPX ou KML","max-width: 389px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[429,3775,3776],{},"Adicione primeiro todos os pontos de interesse, independentemente de caberem ou não na agenda. Pode distribuí-los por dias específicos mais tarde.",[587,3778,3780],{"id":3779},"_52-planos-diários-e-notas","5.2 Planos diários e notas",[429,3782,3783],{},"O plano diário organiza os locais por dias sequenciais. É uma lista desdobrável por cada dia, e tudo funciona com o recurso de arrastar e soltar:",[435,3785],{"src":3786,"alt":3787,"style":3788},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-day-plan-drag-drop-ordering.webp","Personalizando rotas diárias com ações de arrastar e soltar","max-width: 496px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[429,3790,3791],{},"Os detalhes essenciais que fazem a diferença:",[456,3793,3794,3804,3814,3824],{},[459,3795,3796,3799,3800],{},[443,3797,3798],{},"Transporte entre paragens",": o ícone de autocarro no canto superior esquerdo de um dia adiciona transportes intermédios (comboios, autocarros ou voos dentro do mesmo dia):\n",[435,3801],{"src":3802,"alt":3803,"style":3050},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-day-plan-commuting-transport-button.webp","Registrando o transporte de deslocamento entre os segmentos do dia",[459,3805,3806,3809,3810],{},[443,3807,3808],{},"Notas do diárias",": o ícone de notas no canto inferior esquerdo adiciona notas identificadas com emojis — \"arranque matinal hoje\", \"este museu necessita de reserva prévia\":\n",[435,3811],{"src":3812,"alt":3813,"style":3050},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-day-plan-icon-tagged-notes-button.webp","Adicionando notas personalizadas com ícones visíveis aos dias",[459,3815,3816,3819,3820],{},[443,3817,3818],{},"Horários definidos",": arraste um local do painel direito para um dia e atribua-lhe uma hora. Os locais com horário definido são ligados automaticamente no mapa:\n",[435,3821],{"src":3822,"alt":3823,"style":3050},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-day-plan-timed-places-routing.webp","Rotas de trânsito calculadas automaticamente entre locais com horário definido",[459,3825,3826,3827,3832,3833,3836,3837,607],{},"Consulte a ",[570,3828,3831],{"href":3829,"rel":3830},"https:\u002F\u002Fgithub.com\u002Fliketrek\u002FTREK\u002Fwiki\u002FDay-Plans-and-Notes",[1650],"página wiki de Planos Diários e Notas"," para mais informações sobre ",[443,3834,3835],{},"Otimização de rotas"," e o ",[443,3838,3839],{},"Clima",[587,3841,3843],{"id":3842},"_53-coleções-listas-de-locais-reutilizáveis","5.3 Coleções: listas de locais reutilizáveis",[429,3845,3846,3847,3850],{},"As Coleções permitem aos utilizadores guardar listas de locais independentemente de qualquer viagem. Podem ser partilhadas com amigos e estarem preparadas para a próxima jornada. Os locais são ",[443,3848,3849],{},"copiados"," para as viagens, pelo que a edição de um ponto num itinerário nunca altera a sua coleção original e vice-versa.",[429,3852,603,3853,3856],{},[443,3854,3855],{},"Collections"," na barra de menu superior:",[435,3858],{"src":3859,"alt":3860,"style":3861},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-collections-dashboard-view.webp","Acessando coleções personalizadas do usuário para locais salvos","max-width: 495px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[429,3863,603,3864,3867],{},[443,3865,3866],{},"+ New list"," para criar uma nova:",[435,3869],{"src":3870,"alt":3871,"style":3872},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-collections-create-new-list.webp","Criando listas personalizadas nas coleções do usuário","max-width: 269px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[429,3874,603,3875,3878],{},[443,3876,3877],{},"+ Add a place"," e preencha os dados:",[435,3880],{"src":3881,"alt":3882,"style":3883},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-collections-add-place-manually-form.webp","Entrada manual de formulário para preencher listas de coleções personalizadas","max-width: 271px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[429,3885,3886,3889],{},[443,3887,3888],{},"Nota:"," a barra de pesquisa dentro da janela \"Add a place\" parece não funcionar, pelo que terá de inserir os detalhes manualmente.",[429,3891,3892],{},"Si as coordenadas geográficas dos locais estiverem disponíveis, estes aparecerão no mapa:",[435,3894],{"src":3895,"alt":3896,"style":3897},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-collections-map-places-display.webp","Visualizando locais das coleções personalizadas em um mapa interativo","max-width: 592px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[429,3899,3900,3901,1275],{},"Para organizar os locais com etiquetas (labels), clique no ícone da ",[443,3902,3903],{},"caixa de seleção",[435,3905],{"src":3906,"alt":3907,"style":3908},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-collections-select-places-tickbox.webp","Modo de seleção para etiquetagem em lote de locais salvos","max-width: 662px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[429,3910,3911,3912,1275],{},"Selecione os locais que pretende agrupar e clique em ",[443,3913,3914],{},"Assign label",[435,3916],{"src":3917,"alt":3918,"style":3747},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-collections-group-assign-label.webp","Atribuindo etiquetas descritivas aos locais selecionados",[429,3920,603,3921,3924],{},[443,3922,3923],{},"Manage labels"," para criar as etiquetas de antemão:",[435,3926],{"src":3927,"alt":3928,"style":3929},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-collections-manage-custom-labels.webp","Criação e gerenciamento de etiquetas personalizadas","max-width: 411px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[429,3931,3932,3933,1275],{},"Selecione uma etiqueta e clique em ",[443,3934,3914],{},[435,3936],{"src":3937,"alt":3938,"style":3559},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-collections-confirm-label-selection.webp","Aplicando etiquetas personalizadas a grupos de locais",[587,3940,3942],{"id":3941},"_54-custos-e-orçamento","5.4 Custos e orçamento",[429,3944,3945],{},"Podemos registar outras despesas para a viagem na página 'Costs'.",[435,3947],{"src":3948,"alt":3949,"style":3788},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-costs-budget-overall-expenses-list.webp","Tabela abrangente de despesas e livro de acerto de contas",[429,3951,3952],{},"Os pagamentos efetuados por companheiros de viagem podem ser adicionados e divididos nessa mesma página.",[429,3954,3955,3956,3959],{},"O painel de acertos executa um algoritmo voraz (greedy) para calcular o ",[443,3957,3958],{},"número mínimo de transferências"," necessárias para liquidar as despesas entre os membros.",[548,3961,3963],{"id":3962},"_6-aproveitar-o-model-context-protocol-mcp-para-planeamento-de-viagens-com-ia","6. Aproveitar o Model Context Protocol (MCP) para Planeamento de Viagens com IA",[429,3965,3966,3967,3970],{},"O TREK possui um ",[443,3968,3969],{},"servidor MCP (Model Context Protocol) integrado",", o que permite que agentes de IA leiam e editem diretamente os seus dados de viagem — com mais de 150 ferramentas e 30 recursos para itinerários, pontos de interesse, orçamentos, bagagem, reservas e colaboração.",[587,3972,3974],{"id":3973},"_61-cloudflare-zero-trust","6.1 Cloudflare Zero Trust",[429,3976,3977,3978,3981,3982,607],{},"Devido ao facto de o TREK correr atrás de uma rede ",[570,3979,3980],{"href":363},"Cloudflare Zero Trust",", terá de adicionar o seu domínio à lista de inclusão do Split Tunnels. Caso contrário, terá problemas com a autorização OAuth. Consulte este ticket do GitHub: ",[570,3983,3986],{"href":3984,"rel":3985},"https:\u002F\u002Fgithub.com\u002Fliketrek\u002FTREK\u002Fissues\u002F1463",[1650],"issue do github",[575,3988],{"description":3989,"image":578,"image-alt":3990,"label":580,"min-read":3991,"title":572,"to":363},"Aprenda a expor e acessar globalmente seu Hermes Agent de forma segura com o Cloudflare WARP e o Zero Trust, sem abrir portas de entrada em seu firewall.","Exposição segura do Hermes Agent em rede privada usando Cloudflare Zero Trust e túnel WARP","9",[435,3993],{"src":3994,"alt":3995,"style":3050},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Fcloudflare-zero-trust-split-tunnels-domain.webp","Adicionando domínios personalizados ao Split Tunnels do Cloudflare Warp",[587,3997,3999],{"id":3998},"_62-claude-desktop","6.2 Claude Desktop",[429,4001,603,4002,4005,4006],{},[443,4003,4004],{},"+ New Client"," para criar um novo cliente de agente de IA:\n",[435,4007],{"src":4008,"alt":4009,"style":3050},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-register-new-mcp-client.webp","Registrando um novo token de cliente personalizado nas configurações",[429,4011,4012,4013,3350,4016,1275],{},"Selecione o separador ",[443,4014,4015],{},"Claude Desktop",[443,4017,4018],{},"Register Client",[435,4020],{"src":4021,"alt":4022,"style":4023},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-mcp-claude-desktop-client-credentials.webp","Gerando credenciais de cliente para o Claude Desktop","max-width: 354px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[429,4025,4026,4027,4030],{},"É apresentado um ID de cliente e segredo de cliente. Guarde-os num local seguro. De seguida, clique em ",[443,4028,4029],{},"Client Configuration"," para mostrar as definições do MCP:",[435,4032],{"src":4033,"alt":4034,"style":4035},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-mcp-client-configuration-block.webp","Obtendo o bloco de configuração pré-formatado do servidor MCP","max-width: 508px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[429,4037,4038,4039,4042],{},"No Claude Desktop, clique em ",[443,4040,4041],{},"Edit Config"," para abrir o ficheiro local de configuração dos servidores MCP:",[435,4044],{"src":4045,"alt":4046,"style":3050},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Fclaude-desktop-mcp-config-json.webp","Editando o arquivo JSON de configuração local do MCP do Claude Desktop",[429,4048,4049],{},"Cole a configuração do TREK, substituindo os marcadores de posição pelas suas credenciais:",[665,4051,4053],{"className":3063,"code":4052,"language":3065,"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",[646,4054,4055,4069,4082,4104,4118,4130,4141,4152,4197,4202,4207],{"__ignoreMap":424},[673,4056,4057,4060,4063,4065,4067],{"class":675,"line":676},[673,4058,4059],{"class":683},"  \"",[673,4061,4062],{"class":687},"mcpServers",[673,4064,691],{"class":683},[673,4066,1078],{"class":2006},[673,4068,1173],{"class":683},[673,4070,4071,4074,4076,4078,4080],{"class":675,"line":742},[673,4072,4073],{"class":683},"    \"",[673,4075,3228],{"class":1278},[673,4077,691],{"class":683},[673,4079,1275],{"class":683},[673,4081,3081],{"class":683},[673,4083,4084,4087,4090,4092,4094,4096,4099,4101],{"class":675,"line":616},[673,4085,4086],{"class":683},"      \"",[673,4088,4089],{"class":679},"command",[673,4091,691],{"class":683},[673,4093,1275],{"class":683},[673,4095,684],{"class":683},[673,4097,4098],{"class":687},"npx",[673,4100,691],{"class":683},[673,4102,4103],{"class":683},",\n",[673,4105,4106,4108,4111,4113,4115],{"class":675,"line":777},[673,4107,4086],{"class":683},[673,4109,4110],{"class":679},"args",[673,4112,691],{"class":683},[673,4114,1275],{"class":683},[673,4116,4117],{"class":683}," [\n",[673,4119,4120,4123,4126,4128],{"class":675,"line":783},[673,4121,4122],{"class":683},"        \"",[673,4124,4125],{"class":687},"mcp-remote",[673,4127,691],{"class":683},[673,4129,4103],{"class":683},[673,4131,4132,4134,4137,4139],{"class":675,"line":828},[673,4133,4122],{"class":683},[673,4135,4136],{"class":687},"https:\u002F\u002Ftrek.pafor.me\u002Fmcp",[673,4138,691],{"class":683},[673,4140,4103],{"class":683},[673,4142,4143,4145,4148,4150],{"class":675,"line":833},[673,4144,4122],{"class":683},[673,4146,4147],{"class":687},"--static-oauth-client-info",[673,4149,691],{"class":683},[673,4151,4103],{"class":683},[673,4153,4154,4156,4158,4161,4164,4166,4168,4170,4173,4175,4177,4179,4182,4184,4186,4188,4191,4193,4195],{"class":675,"line":839},[673,4155,4122],{"class":683},[673,4157,3072],{"class":687},[673,4159,4160],{"class":2006},"\\\"",[673,4162,4163],{"class":687},"client_id",[673,4165,4160],{"class":2006},[673,4167,1078],{"class":687},[673,4169,4160],{"class":2006},[673,4171,4172],{"class":687},"\u003Cyour_client_id>",[673,4174,4160],{"class":2006},[673,4176,1082],{"class":687},[673,4178,4160],{"class":2006},[673,4180,4181],{"class":687},"client_secret",[673,4183,4160],{"class":2006},[673,4185,1078],{"class":687},[673,4187,4160],{"class":2006},[673,4189,4190],{"class":687},"\u003Cyour_client_secret>",[673,4192,4160],{"class":2006},[673,4194,3078],{"class":687},[673,4196,702],{"class":683},[673,4198,4199],{"class":675,"line":851},[673,4200,4201],{"class":683},"      ]\n",[673,4203,4204],{"class":675,"line":856},[673,4205,4206],{"class":683},"    }\n",[673,4208,4209,4212],{"class":675,"line":862},[673,4210,4211],{"class":683},"  }",[673,4213,4103],{"class":2006},[429,4215,4216,4217,1275],{},"Reinicie o Claude Desktop, e o servidor do TREK passará a ser exibido como ligado em ",[443,4218,4219],{},"Local MCP servers",[435,4221],{"src":4222,"alt":4223,"style":3050},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Fclaude-desktop-mcp-trek-server-connected.webp","Verificando o status de conexão ativa do TREK dentro da interface do Claude",[429,4225,4226],{},"Agora envie uma instrução (prompt):",[435,4228],{"src":4229,"alt":4230,"style":4231},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Fclaude-desktop-mcp-natural-language-prompt.webp","Instruindo o Claude em linguagem natural para manipular dados de viagem","max-width: 550px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[429,4233,4234],{},"Vamos adicionar uma despesa usando linguagem natural:",[665,4236,4239],{"className":4237,"code":4238,"language":1038,"meta":424},[1036],"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",[646,4240,4238],{"__ignoreMap":424},[435,4242],{"src":4243,"alt":4244,"style":3050},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Fclaude-desktop-mcp-add-expense-response.webp","Claude utilizando ferramentas para registrar uma despesa automaticamente",[429,4246,4247,4248,4251],{},"Ao verificar a página ",[443,4249,4250],{},"Costs",", a despesa surge criada com a indicação \"Ninguém pagou ainda\", uma vez que nenhum pagador foi mencionado na ordem:",[435,4253],{"src":4254,"alt":4255,"style":3202},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-costs-page-mcp-parsed-expense.webp","Confirmando a despesa de IA recém-analisada na visualização de custos",[429,4257,4258],{},"Adicionar elementos à lista de bagagem funciona exatamente da mesma maneira:",[435,4260],{"src":4261,"alt":4262,"style":4263},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Fclaude-desktop-mcp-add-packing-items.webp","Claude adicionando itens de bagagem usando instruções em linguagem natural","max-width: 631px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[429,4265,4266,4267,4270],{},"Atualize a página ",[443,4268,4269],{},"Packing List"," e verá os três elementos adicionados:",[435,4272],{"src":4273,"alt":4274,"style":4275},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Ftrek-packing-list-mcp-parsed-items.webp","Confirmando os itens de bagagem recém-analisados na página de lista de bagagem","max-width: 312px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[587,4277,4279],{"id":4278},"_63-gemini-cli-registo-dinâmico","6.3 Gemini CLI (registo dinâmico)",[429,4281,4282,4283,4286,4287,1275],{},"A Gemini CLI suporta ",[443,4284,4285],{},"registo dinâmico",", pelo que não necessita de um cliente pré-criado. Adicione isto a ",[646,4288,4289],{},".gemini\u002Fsettings.json",[665,4291,4293],{"className":3063,"code":4292,"language":3065,"meta":424,"style":424},"    \"trek\": {\n      \"httpUrl\": \"https:\u002F\u002Ftrek.pafor.me\u002Fmcp\",\n      \"oauth\": {\n        \"enabled\": true\n      }\n    }\n",[646,4294,4295,4307,4326,4339,4352,4357],{"__ignoreMap":424},[673,4296,4297,4299,4301,4303,4305],{"class":675,"line":676},[673,4298,4073],{"class":683},[673,4300,3228],{"class":687},[673,4302,691],{"class":683},[673,4304,1078],{"class":2006},[673,4306,1173],{"class":683},[673,4308,4309,4311,4314,4316,4318,4320,4322,4324],{"class":675,"line":742},[673,4310,4086],{"class":683},[673,4312,4313],{"class":1278},"httpUrl",[673,4315,691],{"class":683},[673,4317,1275],{"class":683},[673,4319,684],{"class":683},[673,4321,4136],{"class":687},[673,4323,691],{"class":683},[673,4325,4103],{"class":683},[673,4327,4328,4330,4333,4335,4337],{"class":675,"line":616},[673,4329,4086],{"class":683},[673,4331,4332],{"class":1278},"oauth",[673,4334,691],{"class":683},[673,4336,1275],{"class":683},[673,4338,3081],{"class":683},[673,4340,4341,4343,4346,4348,4350],{"class":675,"line":777},[673,4342,4122],{"class":683},[673,4344,4345],{"class":679},"enabled",[673,4347,691],{"class":683},[673,4349,1275],{"class":683},[673,4351,2223],{"class":683},[673,4353,4354],{"class":675,"line":783},[673,4355,4356],{"class":683},"      }\n",[673,4358,4359],{"class":675,"line":828},[673,4360,4206],{"class":683},[429,4362,4363,4364,4367,4368,4371,4372],{},"Execute ",[646,4365,4366],{},"gemini"," no terminal e clique em ",[443,4369,4370],{},"Approve"," quando a janela de autorização surgir:\n",[435,4373],{"src":4374,"alt":4375,"style":4376},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Fmcp-client-oauth-authorization-prompt.webp","Aprovando acesso OAuth para o servidor MCP do TREK","max-width: 488px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[429,4378,4379],{},"De seguida, comece com uma instrução simples:",[435,4381],{"src":4382,"alt":4383,"style":4384},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Fgemini-cli-mcp-prompt-itinerary.webp","Instruindo a CLI do Gemini para buscar itinerários de viagem","max-width: 415px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[435,4386],{"src":4387,"alt":4388,"style":3651},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Fgemini-cli-mcp-display-itinerary.webp","CLI do Gemini exibindo com sucesso informações estruturadas de viagem",[587,4390,4392],{"id":4391},"_64-kimi-cli-registo-dinâmico","6.4 Kimi CLI (registo dinâmico)",[429,4394,4395,4396,4399,4400,1275],{},"A mesma abordagem — adicione ao ficheiro ",[646,4397,4398],{},"mcp.json"," na pasta ",[646,4401,4402],{},"\u002FUsers\u002F\u003Cuser>\u002F.kimi\u002F",[665,4404,4406],{"className":3063,"code":4405,"language":3065,"meta":424,"style":424},"    \"trek\": {\n      \"type\": \"http\",\n      \"url\": \"https:\u002F\u002Ftrek.pafor.me\u002Fmcp\",\n      \"auth\": \"oauth\"\n    }\n",[646,4407,4408,4420,4440,4459,4476],{"__ignoreMap":424},[673,4409,4410,4412,4414,4416,4418],{"class":675,"line":676},[673,4411,4073],{"class":683},[673,4413,3228],{"class":687},[673,4415,691],{"class":683},[673,4417,1078],{"class":2006},[673,4419,1173],{"class":683},[673,4421,4422,4424,4427,4429,4431,4433,4436,4438],{"class":675,"line":742},[673,4423,4086],{"class":683},[673,4425,4426],{"class":1278},"type",[673,4428,691],{"class":683},[673,4430,1275],{"class":683},[673,4432,684],{"class":683},[673,4434,4435],{"class":687},"http",[673,4437,691],{"class":683},[673,4439,4103],{"class":683},[673,4441,4442,4444,4447,4449,4451,4453,4455,4457],{"class":675,"line":616},[673,4443,4086],{"class":683},[673,4445,4446],{"class":1278},"url",[673,4448,691],{"class":683},[673,4450,1275],{"class":683},[673,4452,684],{"class":683},[673,4454,4136],{"class":687},[673,4456,691],{"class":683},[673,4458,4103],{"class":683},[673,4460,4461,4463,4466,4468,4470,4472,4474],{"class":675,"line":777},[673,4462,4086],{"class":683},[673,4464,4465],{"class":1278},"auth",[673,4467,691],{"class":683},[673,4469,1275],{"class":683},[673,4471,684],{"class":683},[673,4473,4332],{"class":687},[673,4475,702],{"class":683},[673,4477,4478],{"class":675,"line":783},[673,4479,4206],{"class":683},[429,4481,4363,4482,4367,4485,1260,4487],{},[646,4483,4484],{},"kimi mcp auth trek",[443,4486,4370],{},[435,4488],{"src":4374,"alt":4375,"style":4489},"max-width: 453px; width: 100%; height: auto; border-radius: 8px; margin: 1.5rem auto; display: block;",[429,4491,4492],{},"Uma vez autorizado, as ferramentas disponíveis são listadas:",[435,4494],{"src":4495,"alt":4496,"style":3050},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002Fkimi-cli-mcp-authorized-tools-list.webp","CLI do Kimi exibindo as ferramentas disponíveis após autorização bem-sucedida",[548,4498,4500],{"id":4499},"_7-experiência-móvel","7. Experiência móvel",[429,4502,4503],{},"O TREK é uma PWA (progressive web app) em dispositivos móveis. Um service worker guarda em cache os mapas e os dados das APIs, para que o seu itinerário continue legível mesmo sem ligação à Internet. No entanto, as notificações push podem apresentar alguma latência em comparação com uma aplicação nativa.",[548,4505,4506],{"id":2590},"Considerações finais",[429,4508,4509],{},"Ligar agentes de IA através de MCP poupa grande parte do cansativo trabalho de inserção manual de reservas de voos e hotéis. Além disso, os agentes podem sugerir pontos de interesse com base nas datas e na época do ano em que viaja. Uma única conversa com um agente de IA pode cobrir todo o processo, desde a pesquisa e criação do itinerario até ao controlo de orçamento e à preparação da bagagem.",[429,4511,4512],{},"Há alguns pequenos pormenores técnicos por ajustar. Por exemplo, ao importar reservas a partir de ficheiros PDF, a moeda assume por omissão a moeda base da viagem em vez da moeda efetivamente paga. Além disso, ao criar uma nova lista em Coleções, qualquer imagem de capa associada durante a criação desaparece ao guardar, embora possa ser readicionada manualmente na edição posterior.",[429,4514,4515,4516,4521],{},"Existe uma ligeira barreira técnica, pois necessita de alojar o sistema no seu próprio servidor. O TREK foi concebido principalmente para pessoas que viajam com frequência e têm elevadas expectativas sobre a organização dos seus dados de viagem. Sugerimos que experimente a demonstração oficial em ",[570,4517,4520],{"href":4518,"rel":4519},"https:\u002F\u002Fdemo.liketrek.com\u002F",[1650],"demo.liketrek.com"," antes de equacionar o autohospedamento.",[548,4523,4524],{"id":2597},"Referências:",[456,4526,4527,4534,4541],{},[459,4528,4529],{},[570,4530,4533],{"href":4531,"rel":4532},"https:\u002F\u002Fgithub.com\u002Fliketrek\u002FTREK\u002Fwiki\u002FQuick-Start",[1650],"Início rápido do TREK",[459,4535,4536],{},[570,4537,4540],{"href":4538,"rel":4539},"https:\u002F\u002Fgithub.com\u002Fliketrek\u002FTREK\u002Fwiki\u002FTroubleshooting",[1650],"Resolução de problemas do TREK",[459,4542,4543],{},[570,4544,4547],{"href":4545,"rel":4546},"https:\u002F\u002Fgithub.com\u002Fliketrek\u002FTREK\u002Fwiki\u002FMCP-Scopes",[1650],"Escopos MCP do TREK",[2630,4549,4550],{},"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":742,"depth":616,"links":4552},[4553,4558,4559,4569,4577,4583,4589,4590,4591],{"id":2725,"depth":616,"text":2726,"children":4554},[4555,4556,4557],{"id":2729,"depth":777,"text":2730},{"id":2875,"depth":777,"text":2876},{"id":2907,"depth":777,"text":2908},{"id":3053,"depth":616,"text":3054},{"id":3103,"depth":616,"text":3104,"children":4560},[4561,4562,4563,4564,4565,4566,4567,4568],{"id":3205,"depth":777,"text":3206},{"id":3216,"depth":777,"text":3217},{"id":3316,"depth":777,"text":3317},{"id":3337,"depth":777,"text":3338},{"id":3372,"depth":777,"text":3373},{"id":3393,"depth":777,"text":3394},{"id":3410,"depth":777,"text":3411},{"id":3421,"depth":777,"text":3422},{"id":3451,"depth":616,"text":3452,"children":4570},[4571,4572,4573,4574,4575,4576],{"id":3458,"depth":777,"text":3459},{"id":3492,"depth":777,"text":3493},{"id":3562,"depth":777,"text":3563},{"id":3584,"depth":777,"text":3585},{"id":3603,"depth":777,"text":3604},{"id":3628,"depth":777,"text":3629},{"id":3659,"depth":616,"text":3660,"children":4578},[4579,4580,4581,4582],{"id":3679,"depth":777,"text":3680},{"id":3779,"depth":777,"text":3780},{"id":3842,"depth":777,"text":3843},{"id":3941,"depth":777,"text":3942},{"id":3962,"depth":616,"text":3963,"children":4584},[4585,4586,4587,4588],{"id":3973,"depth":777,"text":3974},{"id":3998,"depth":777,"text":3999},{"id":4278,"depth":777,"text":4279},{"id":4391,"depth":777,"text":4392},{"id":4499,"depth":616,"text":4500},{"id":2590,"depth":616,"text":4506},{"id":2597,"depth":616,"text":4524},[4593,2665],"travel","2026-09-01","Aprenda a implantar o TREK usando Docker, a protegê-lo com Cloudflare R2 e Caddy, e a usar agentes de IA via MCP para planejar todas as viagens sem esforço.","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSelf%20hosted%20travel%20planner%20TREK\u002FPT-Self-hosted-travel-planner-TREK.webp","Uma ilustração 3D minimalista e sofisticada do painel do planeador de viagens autohospedado TREK num fundo de pergaminho quente.",{"schemaOrg":4599,"robots":2694,"sitemap":4604},[4600,4601],{"@type":2676,"headline":2711,"description":4595},{"@type":4602,"headline":4603,"description":4595},"Article","Como alojar o TREK: O melhor planeador de viagens com IA",{"lastmod":4594},{"title":4603,"description":4595,"ogTitle":2711,"ogDescription":4595,"twitterTitle":2711,"twitterDescription":4595},"pt\u002Farticle\u002Fself-hosted-travel-planner-trek",[2702,4608,2703,2704,3403],"TREK","uBWL-fAL0Rz92WLnscPitCwqC44q4YSJbJuVmgQMof4",{"id":4611,"title":4612,"author":424,"body":4613,"category":5997,"date":5999,"description":6000,"extension":2668,"image":6001,"imageAlt":6002,"isPublished":773,"meta":6003,"minRead":909,"navigation":773,"path":239,"seo":6009,"stem":6011,"tags":6012,"updatedAt":2705,"__hash__":6017},"article\u002Fpt\u002Farticle\u002Fsync-obsidian-across-devices.md","Sincronizar cofres do Obsidian entre dispositivos",{"type":426,"value":4614,"toc":5975},[4615,4618,4623,4632,4641,4658,4663,4669,4673,4678,4692,4708,4711,4715,4719,4725,4730,4734,4739,4790,4796,4826,4830,4837,4844,4851,4903,4906,4921,4927,4939,4943,4947,4958,4963,4973,4995,5000,5013,5018,5024,5029,5044,5047,5051,5054,5059,5063,5068,5083,5087,5101,5111,5115,5120,5123,5132,5165,5169,5175,5303,5337,5342,5362,5373,5378,5382,5392,5464,5468,5474,5510,5639,5646,5652,5658,5664,5667,5673,5679,5693,5704,5711,5717,5724,5855,5861,5866,5869,5874,5877,5881,5886,5891,5897,5908,5918,5922,5933,5938,5944,5947,5949,5972],[429,4616,4617],{},"O Obsidian é uma aplicação de gestão de conhecimento que prioriza o armazenamento local (local-first). Cada nota é um ficheiro markdown no seu dispositivo e permanece inteiramente sob o seu controlo. No entanto, muitas vezes pretendemos ter o mesmo cofre (vault) no portátil, no telemóvel e noutros dispositivos, ou poder aceder-lhe remotamente através de um navegador web.",[435,4619],{"src":4620,"alt":4621,"style":4622},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fobsidian-multi-device-sync-illustration.webp","Ilustração do cofre do Obsidian sincronizado em vários dispositivos","max-width: 667px; width: 100%; height: auto;",[429,4624,4625,4626,4631],{},"Existem várias soluções de sincronização disponíveis para o Obsidian, mas todas elas implicam cedências no que toca à gestão de conflitos, encriptação ou soberania dos dados. O ",[570,4627,4630],{"href":4628,"rel":4629},"https:\u002F\u002Fgithub.com\u002Fhjinco\u002Fsynch",[1650],"Synch"," é uma aplicação de código aberto que sincroniza o seu cofre do Obsidian com encriptação de ponta a ponta e gestão automática de conflitos num servidor auto-hospedado.",[429,4633,4634,4635,4640],{},"Embora a abordagem local-first do Obsidian funcione perfeitamente na maior parte do tempo, podemos ainda necessitar de aceder ao nosso cofre remotamente através de um navegador web em certas ocasiões. O ",[570,4636,4639],{"href":4637,"rel":4638},"https:\u002F\u002Fgithub.com\u002FNystik-gh\u002Fignis",[1650],"Ignis"," é uma aplicação de código aberto que executa o Obsidian dentro de um navegador web num formato muito próximo do nativo, permitindo-lhe ler e editar o seu cofre a partir de qualquer lugar.",[429,4642,4643,4644,3836,4646,4648,4649,4652,4653,4657],{},"Neste guia, iremos configurar o ",[443,4645,4630],{},[443,4647,4639],{}," num ",[443,4650,4651],{},"VPS"," (Servidor Privado Virtual), alojando-os de forma segura dentro de uma rede privada ",[443,4654,4655],{},[570,4656,3980],{"href":363},", em vez de os expor à internet aberta.",[435,4659],{"src":4660,"alt":4661,"style":4662},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fobsidian-sync-cloudflare-zero-trust-architecture.webp","Diagrama de arquitetura da sincronização do Obsidian usando Cloudflare Zero Trust","max-width: 671px; width: 100%; height: auto;",[575,4664],{"description":4665,"image":4666,"image-alt":4667,"label":580,"min-read":581,"title":4668,"to":363},"Saiba como expor e aceder ao seu Hermes Agent globalmente de forma segura usando o Cloudflare WARP e Zero Trust sem abrir portas de entrada no firewall.","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","Exposição segura do Hermes Agent a uma rede privada usando o túnel Cloudflare Zero Trust e WARP","Como expor o Hermes Agent de forma privada com o Cloudflare WARP",[448,4670,4672],{"id":4671},"sincronização-segura-de-cofres-do-obsidian-com-o-synch","Sincronização segura de cofres do Obsidian com o Synch",[429,4674,441,4675,4677],{},[443,4676,4630],{}," oferece as seguintes funcionalidades:",[456,4679,4680,4683,4686,4689],{},[459,4681,4682],{},"Sincroniza o seu cofre assim que são detetadas alterações",[459,4684,4685],{},"Encripta os dados do cofre antes do carregamento",[459,4687,4688],{},"Permite a restauração a partir do histórico de versões",[459,4690,4691],{},"Inclui gestão automática de conflitos",[429,4693,441,4694,4696,4697,4700,4701,4704,4705,4707],{},[443,4695,4630],{}," gera uma ",[443,4698,4699],{},"chave de cofre"," aleatória de 32 bytes no seu dispositivo, que é utilizada para encriptar os dados do cofre. Quando cria um cofre remoto, escolhe uma ",[443,4702,4703],{},"palavra-passe do cofre","; esta palavra-passe é utilizada para proteger a ",[443,4706,4699],{},", permitindo que esta seja armazenada de forma segura no servidor e desbloqueada noutros dispositivos.",[429,4709,4710],{},"Note que a resolução de conflitos é gerida nos seus dispositivos de cliente e não no servidor. Se dois dispositivos editarem a mesma nota simultaneamente, o servidor mantém a versão que chegar primeiro e marca o outro dispositivo como desatualizado. O dispositivo desatualizado junta automaticamente a versão mais recente com as suas alterações locais antes de enviar a nota final combinada.",[548,4712,4714],{"id":4713},"configurar-o-synch-no-seu-vps","Configurar o Synch no seu VPS",[587,4716,4718],{"id":4717},"criar-um-nome-de-domínio","Criar um nome de domínio",[429,4720,4721,4722,4724],{},"Crie um registo A no Cloudflare e defina o estado do proxy para ",[443,4723,714],{}," (ignorando o CDN do Cloudflare).",[435,4726],{"src":4727,"alt":4728,"style":4729},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fcloudflare-dns-a-record-synch-server.webp","Configurando um registro A de DNS para o servidor Synch no Cloudflare","max-width: 538px; width: 100%; height: auto;",[587,4731,4733],{"id":4732},"instalar-o-synch-com-docker-no-ubuntu","Instalar o Synch com Docker no Ubuntu",[4735,4736,4738],"h5",{"id":4737},"clonar-o-repositório","Clonar o repositório",[665,4740,4742],{"className":667,"code":4741,"language":669,"meta":424,"style":424},"git clone https:\u002F\u002Fgithub.com\u002Fhjinco\u002Fsynch.git       \n        \n# Navegar para a pasta da API\ncd synch\u002Fapps\u002Fapi\n        \n# Copiar o ficheiro de ambiente de exemplo:\ncp .env.example .env\n",[646,4743,4744,4756,4761,4766,4773,4777,4782],{"__ignoreMap":424},[673,4745,4746,4748,4750,4753],{"class":675,"line":676},[673,4747,982],{"class":679},[673,4749,985],{"class":687},[673,4751,4752],{"class":687}," https:\u002F\u002Fgithub.com\u002Fhjinco\u002Fsynch.git",[673,4754,4755],{"class":2006},"       \n",[673,4757,4758],{"class":675,"line":742},[673,4759,4760],{"class":2006},"        \n",[673,4762,4763],{"class":675,"line":616},[673,4764,4765],{"class":738},"# Navegar para a pasta da API\n",[673,4767,4768,4770],{"class":675,"line":777},[673,4769,997],{"class":786},[673,4771,4772],{"class":687}," synch\u002Fapps\u002Fapi\n",[673,4774,4775],{"class":675,"line":783},[673,4776,4760],{"class":2006},[673,4778,4779],{"class":675,"line":828},[673,4780,4781],{"class":738},"# Copiar o ficheiro de ambiente de exemplo:\n",[673,4783,4784,4786,4788],{"class":675,"line":833},[673,4785,1005],{"class":679},[673,4787,1008],{"class":687},[673,4789,1011],{"class":687},[4735,4791,4793,4794],{"id":4792},"editar-os-valores-do-env","Editar os valores do ",[646,4795,1024],{},[456,4797,4798,4804,4820],{},[459,4799,4800,4803],{},[646,4801,4802],{},"PUBLIC_URL=synch.pafor.me",": Introduza o nome de domínio público do seu servidor Synch (o nome de domínio criado no passo anterior).",[459,4805,4806,1123,4809,4812,4813,4816,4817,4819],{},[646,4807,4808],{},"BETTER_AUTH_SECRET",[646,4810,4811],{},"SYNC_TOKEN_SECRET",": Gere chaves seguras utilizando esta ",[570,4814,4815],{"href":1065},"ferramenta online de chaves secretas"," ou executando ",[646,4818,1070],{}," duas vezes no seu terminal.",[459,4821,4822,4825],{},[646,4823,4824],{},"AUTH_ALLOWED_EMAILS",": Uma lista separada por vírgulas dos endereços de e-mail autorizados a registar-se e criar contas.",[4735,4827,4829],{"id":4828},"adicionar-o-domínio-ao-caddyfile","Adicionar o domínio ao Caddyfile",[429,4831,4832,4833,607],{},"Os detalhes sobre como o módulo DNS do Cloudflare é integrado com o Caddy e iniciado num contentor podem ser consultados no nosso ",[570,4834,4836],{"href":4835},"\u002Farticle\u002Fself-hosting-buzz-as-the-workspace-where-ai-agents-become-colleagues#_4-enable-https-with-caddy","artigo sobre a auto-hospedagem do Buzz",[575,4838],{"description":4839,"image":4840,"image-alt":4841,"label":4842,"min-read":4843,"title":423,"to":4835},"Saiba como configurar o Caddy para fornecer automaticamente certificados SSL\u002FTLS utilizando desafios DNS do Cloudflare em contentores Docker.","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","Configuração do Caddy com token de API do Cloudflare DNS para geração automática de certificados SSL\u002FTLS num espaço de trabalho auto-hospedado","Guia de auto-hospedagem","12",[429,4845,4846,4847,4850],{},"Inclua a diretiva ",[646,4848,4849],{},"SYNCH_DOMAIN"," no seu Caddyfile, apontando para a porta 8787 (a porta utilizada pelo contentor do Synch):",[665,4852,4854],{"className":3063,"code":4853,"language":3065,"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",[646,4855,4856,4860,4867,4871,4875,4886,4890,4899],{"__ignoreMap":424},[673,4857,4858],{"class":675,"line":676},[673,4859,1173],{"class":683},[673,4861,4862,4865],{"class":675,"line":742},[673,4863,4864],{"class":2006},"  acme_dns cloudflare {env.CLOUDFLARE_API_TOKEN",[673,4866,1187],{"class":683},[673,4868,4869],{"class":675,"line":616},[673,4870,1187],{"class":2006},[673,4872,4873],{"class":675,"line":777},[673,4874,774],{"emptyLinePlaceholder":773},[673,4876,4877,4879,4882,4884],{"class":675,"line":783},[673,4878,3072],{"class":683},[673,4880,4881],{"class":2006},"$SYNCH_DOMAIN",[673,4883,3078],{"class":683},[673,4885,3081],{"class":683},[673,4887,4888],{"class":675,"line":828},[673,4889,3086],{"class":2006},[673,4891,4892,4894,4896],{"class":675,"line":833},[673,4893,3091],{"class":2006},[673,4895,1275],{"class":683},[673,4897,4898],{"class":1310},"8787\n",[673,4900,4901],{"class":675,"line":839},[673,4902,1187],{"class":683},[429,4904,4905],{},"Inicie o contentor:",[665,4907,4909],{"className":667,"code":4908,"language":669,"meta":424,"style":424},"docker compose up -d\n",[646,4910,4911],{"__ignoreMap":424},[673,4912,4913,4915,4917,4919],{"class":675,"line":676},[673,4914,923],{"class":679},[673,4916,965],{"class":687},[673,4918,1560],{"class":687},[673,4920,1563],{"class":687},[429,4922,4923,4924,4926],{},"Execute o seguinte comando ",[646,4925,680],{}," para verificar a sua disponibilidade:",[665,4928,4930],{"className":667,"code":4929,"language":669,"meta":424,"style":424},"curl https:\u002F\u002Fsynch.pafor.me\u002Fhealth\n",[646,4931,4932],{"__ignoreMap":424},[673,4933,4934,4936],{"class":675,"line":676},[673,4935,680],{"class":679},[673,4937,4938],{"class":687}," https:\u002F\u002Fsynch.pafor.me\u002Fhealth\n",[548,4940,4942],{"id":4941},"ligar-o-obsidian-ao-seu-servidor-synch","Ligar o Obsidian ao seu servidor Synch",[587,4944,4946],{"id":4945},"instalar-o-plug-in-synch-no-obsidian","Instalar o plug-in Synch no Obsidian",[429,4948,4949,4950,4953,4954,4957],{},"Abra as Definições do Obsidian, navegue para ",[443,4951,4952],{},"Community plugins"," (Plug-ins da comunidade) e clique no botão ",[443,4955,4956],{},"'Browse'"," (Procurar):",[435,4959],{"src":4960,"alt":4961,"style":4962},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fobsidian-community-plugins-browse.webp","Explorando plugins da comunidade nas configurações do Obsidian","max-width: 523px; width: 100%; height: auto;",[429,4964,4965,4966,1260,4969],{},"Procure e instale ",[443,4967,4968],{},"'Synchrun'",[435,4970],{"src":4971,"alt":4972,"style":4729},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fobsidian-install-synchrun-plugin.webp","Instalando o plugin Synchrun no Obsidian",[429,4974,4975,4976,4978,4979,4982,4983,4986,4987,4990,4991,4994],{},"Assim que o ",[443,4977,4968],{}," estiver instalado, abra as definições do plug-in e ative ",[443,4980,4981],{},"'Use a self-hosted server'"," (Utilizar um servidor auto-hospedado). Em seguida, introduza ",[646,4984,4985],{},"https:\u002F\u002Fsynch.pafor.me"," no campo ",[443,4988,4989],{},"'Server URL'"," (URL do Servidor) e clique em ",[443,4992,4993],{},"'Save'"," (Guardar).",[435,4996],{"src":4997,"alt":4998,"style":4999},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fobsidian-synchrun-plugin-settings-self-hosted.webp","Configurando a URL do servidor auto-hospedado no Synchrun","max-width: 525px; width: 100%; height: auto;",[429,5001,596,5002,5005,5006,5009,5010,5012],{},[443,5003,5004],{},"'Sign in on this device'"," (Iniciar sessão neste dispositivo) sob ",[443,5007,5008],{},"'Account'"," (Conta). A seguir, registe-se para obter uma conta utilizando o endereço de e-mail especificado na sua lista ",[646,5011,4824],{},"; será então redirecionado para a seguinte página de autorização:",[435,5014],{"src":5015,"alt":5016,"style":5017},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fsynchrun-account-authorization-page.webp","Página de autorização de conta para o Synchrun","max-width: 494px; width: 100%; height: auto;",[429,5019,596,5020,5023],{},[443,5021,5022],{},"'Allow Obsidian sign-in'"," (Permitir início de sessão no Obsidian):",[435,5025],{"src":5026,"alt":5027,"style":5028},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fsynchrun-allow-obsidian-signin.webp","Permitindo o login do Obsidian para o Synch","max-width: 498px; width: 100%; height: auto;",[429,5030,596,5031,5034,5035,5038,5039],{},[443,5032,5033],{},"'Return to Obsidian'"," (Voltar ao Obsidian) e, em seguida, clique em ",[443,5036,5037],{},"'Create vault'"," (Criar cofre):\n",[435,5040],{"src":5041,"alt":5042,"style":5043},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fobsidian-synchrun-create-remote-vault.webp","Criando um novo cofre remoto no Synchrun","max-width: 496px; width: 100%; height: auto;",[429,5045,5046],{},"Introduza um nome e uma palavra-passe segura para criar o seu cofre remoto.",[435,5048],{"src":5049,"alt":5050,"style":1598},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fobsidian-synchrun-vault-password-setup.webp","Configurando uma senha segura para o cofre remoto do Obsidian",[429,5052,5053],{},"O processo de sincronização será iniciado de imediato e poderá demorar algum tempo, dependendo do tamanho do seu cofre. Uma vez concluído, será exibida a sua utilização total de armazenamento.",[435,5055],{"src":5056,"alt":5057,"style":5058},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fobsidian-synchrun-sync-completed-storage.webp","Sincronização concluída no Synchrun mostrando o armazenamento total utilizado","max-width: 508px; width: 100%; height: auto;",[448,5060,5062],{"id":5061},"acesso-ao-obsidian-no-navegador-com-o-ignis","Acesso ao Obsidian no navegador com o Ignis",[429,5064,441,5065,5067],{},[443,5066,4639],{}," substitui as APIs Electron do Obsidian por APIs Web, o que permite que o código JavaScript do Obsidian seja executado diretamente num navegador web normal. Todos os seus ficheiros markdown e anexos são guardados diretamente no sistema de ficheiros do servidor anfitrião.",[429,5069,5070,5071,5076,5077,5082],{},"Contudo, existem algumas limitações em comparação com a aplicação nativa de ambiente de trabalho do Obsidian. Algumas funcionalidades ou plug-ins que requerem APIs do Electron ou Node.js (que não têm equivalente direto num ambiente de navegador) não irão funcionar. Consulte os guias de ",[570,5072,5075],{"href":5073,"rel":5074},"https:\u002F\u002Fignis.thiefling.com\u002Fdocs\u002Fusing\u002Flimitations\u002F",[1650],"Limitações"," e de ",[570,5078,5081],{"href":5079,"rel":5080},"https:\u002F\u002Fignis.thiefling.com\u002Fdocs\u002Fusing\u002Fplugin-compatibility\u002F",[1650],"Compatibilidade de plug-ins"," do Ignis para obter listagens detalhadas de compatibilidade.",[548,5084,5086],{"id":5085},"configuração-do-ignis","Configuração do Ignis",[429,5088,5089,5090,5092,5093,5096,5097,5100],{},"Iremos instalar o ",[443,5091,4639],{}," no nosso VPS utilizando o Docker, montando-o na pasta local ",[646,5094,5095],{},".\u002Fvaults",". Este diretório do cofre será sincronizado utilizando a ",[443,5098,5099],{},"Synch CLI"," para descarregar as atualizações das notas a partir do cofre remoto que configurámos anteriormente.",[429,5102,5103,5104,5106,5107,607],{},"Como o ",[443,5105,4639],{}," não possui autenticação integrada, deve ser protegido por trás de uma rede privada ",[443,5108,5109],{},[570,5110,3980],{"href":363},[587,5112,5114],{"id":5113},"criar-registo-dns","Criar registo DNS",[435,5116],{"src":5117,"alt":5118,"style":5119},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fcloudflare-dns-a-record-ignis.webp","Configurando um registro A de DNS para o cliente web Ignis no Cloudflare","max-width: 552px; width: 100%; height: auto;",[587,5121,4829],{"id":5122},"adicionar-o-domínio-ao-caddyfile-1",[429,5124,1110,5125,5128,5129,1275],{},[646,5126,5127],{},"obsidian.pafor.me"," ao seu Caddyfile da mesma forma que ",[646,5130,5131],{},"synch.pafor.me",[665,5133,5135],{"className":3063,"code":5134,"language":3065,"meta":424,"style":424},"{$OBSIDIAN_DOMAIN} {\n  encode zstd gzip\n  reverse_proxy host.docker.internal:9898\n}\n",[646,5136,5137,5148,5152,5161],{"__ignoreMap":424},[673,5138,5139,5141,5144,5146],{"class":675,"line":676},[673,5140,3072],{"class":683},[673,5142,5143],{"class":2006},"$OBSIDIAN_DOMAIN",[673,5145,3078],{"class":683},[673,5147,3081],{"class":683},[673,5149,5150],{"class":675,"line":742},[673,5151,3086],{"class":2006},[673,5153,5154,5156,5158],{"class":675,"line":616},[673,5155,3091],{"class":2006},[673,5157,1275],{"class":683},[673,5159,5160],{"class":1310},"9898\n",[673,5162,5163],{"class":675,"line":777},[673,5164,1187],{"class":683},[587,5166,5168],{"id":5167},"iniciar-o-ignis-utilizando-o-docker","Iniciar o Ignis utilizando o Docker",[429,5170,5171,5172,1835],{},"Guarde o seguinte ficheiro docker compose yml como ",[646,5173,5174],{},"ignis-docker-compose.yml",[665,5176,5178],{"className":1164,"code":5177,"language":1166,"meta":424,"style":424},"services:\n  ignis:\n    image: nobbe\u002Fignis:latest\n    ports:\n      - \"9898:8080\"\n    environment:\n      # coincidir com o utilizador do seu host (executar: 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",[646,5179,5180,5186,5193,5202,5208,5219,5225,5230,5237,5244,5251,5257,5264,5271,5278,5286,5290,5296],{"__ignoreMap":424},[673,5181,5182,5184],{"class":675,"line":676},[673,5183,1257],{"class":1256},[673,5185,1260],{"class":683},[673,5187,5188,5191],{"class":675,"line":742},[673,5189,5190],{"class":1256},"  ignis",[673,5192,1260],{"class":683},[673,5194,5195,5197,5199],{"class":675,"line":616},[673,5196,1326],{"class":1256},[673,5198,1275],{"class":683},[673,5200,5201],{"class":687}," nobbe\u002Fignis:latest\n",[673,5203,5204,5206],{"class":675,"line":777},[673,5205,1272],{"class":1256},[673,5207,1260],{"class":683},[673,5209,5210,5212,5214,5217],{"class":675,"line":783},[673,5211,1393],{"class":683},[673,5213,684],{"class":683},[673,5215,5216],{"class":687},"9898:8080",[673,5218,702],{"class":683},[673,5220,5221,5223],{"class":675,"line":828},[673,5222,1360],{"class":1256},[673,5224,1260],{"class":683},[673,5226,5227],{"class":675,"line":833},[673,5228,5229],{"class":738},"      # coincidir com o utilizador do seu host (executar: id)\n",[673,5231,5232,5234],{"class":675,"line":839},[673,5233,1393],{"class":683},[673,5235,5236],{"class":687}," PUID=1000\n",[673,5238,5239,5241],{"class":675,"line":851},[673,5240,1393],{"class":683},[673,5242,5243],{"class":687}," PGID=1000\n",[673,5245,5246,5248],{"class":675,"line":856},[673,5247,1393],{"class":683},[673,5249,5250],{"class":687}," WS_ORIGINS=https:\u002F\u002Fobsidian.pafor.me\n",[673,5252,5253,5255],{"class":675,"line":862},[673,5254,1416],{"class":1256},[673,5256,1260],{"class":683},[673,5258,5259,5261],{"class":675,"line":884},[673,5260,1393],{"class":683},[673,5262,5263],{"class":687}," .\u002Fvaults:\u002Fvaults\n",[673,5265,5266,5268],{"class":675,"line":889},[673,5267,1393],{"class":683},[673,5269,5270],{"class":687}," .\u002Fdata:\u002Fapp\u002Fdata\n",[673,5272,5273,5275],{"class":675,"line":895},[673,5274,1393],{"class":683},[673,5276,5277],{"class":687}," obsidian-app:\u002Fapp\u002Fobsidian-app\n",[673,5279,5280,5282,5284],{"class":675,"line":909},[673,5281,1445],{"class":1256},[673,5283,1275],{"class":683},[673,5285,1450],{"class":687},[673,5287,5288],{"class":675,"line":914},[673,5289,774],{"emptyLinePlaceholder":773},[673,5291,5292,5294],{"class":675,"line":920},[673,5293,1477],{"class":1256},[673,5295,1260],{"class":683},[673,5297,5298,5301],{"class":675,"line":929},[673,5299,5300],{"class":1256},"  obsidian-app",[673,5302,1260],{"class":683},[456,5304,5305,5316,5330],{},[459,5306,5307,5308,5311,5312,5315],{},"Utilize a porta ",[646,5309,5310],{},"9898"," no host, visto que a ",[646,5313,5314],{},"8080"," é habitualmente utilizada por outros serviços.",[459,5317,5318,5319,5322,5323,3836,5326,5329],{},"Execute o comando ",[646,5320,5321],{},"id"," no seu VPS para verificar o ",[646,5324,5325],{},"UID",[646,5327,5328],{},"GID"," do utilizador do seu host para garantir as permissões corretas do sistema de ficheiros.",[459,5331,5332,5333,5336],{},"Defina ",[646,5334,5335],{},"WS_ORIGINS"," para permitir apenas ligações WebSocket originárias do seu nome de domínio específico.",[429,5338,5339,5340,1275],{},"Inicie o Docker do ",[443,5341,4639],{},[665,5343,5345],{"className":667,"code":5344,"language":669,"meta":424,"style":424},"docker compose -f ignis-docker-compose.yml up -d\n",[646,5346,5347],{"__ignoreMap":424},[673,5348,5349,5351,5353,5355,5358,5360],{"class":675,"line":676},[673,5350,923],{"class":679},[673,5352,965],{"class":687},[673,5354,1549],{"class":687},[673,5356,5357],{"class":687}," ignis-docker-compose.yml",[673,5359,1560],{"class":687},[673,5361,1563],{"class":687},[429,5363,5364,5365,5368,5369,5372],{},"Ao aceder ao seu domínio num navegador web, surgirá o ",[443,5366,5367],{},"'Vault Manager'"," (Gestor de Cofres). Estará vazio, uma vez que ainda não configurou nenhum cofre. Iremos configurar a ",[443,5370,5371],{},"'Synch CLI'"," na próxima secção para sincronizar os conteúdos do nosso cofre remoto.",[435,5374],{"src":5375,"alt":5376,"style":5377},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fignis-vault-manager-empty.webp","Interface vazia do Gerenciador de Cofres no cliente web Ignis","max-width: 466px; width: 100%; height: auto;",[587,5379,5381],{"id":5380},"questão-de-firewall","Questão de Firewall",[429,5383,5384,5385,5388,5389,1275],{},"Por predefinição, o Docker insere automaticamente as suas próprias regras DNAT e FORWARD, que encaminham o tráfego público diretamente para os contentores ativos. Isto contorna a cadeia ",[646,5386,5387],{},"INPUT"," padrão do Ubuntu UFW\u002Fiptables. Para bloquear o tráfego público externo e manter os contentores privados, adicione manualmente as seguintes regras ao ",[646,5390,5391],{},"iptables",[665,5393,5395],{"className":667,"code":5394,"language":669,"meta":424,"style":424},"# Bloquear todo o tráfego público externo\nsudo iptables -I DOCKER-USER -i ext_if -j DROP \n\n# Permitir tráfego apenas do IP privado do seu cliente Cloudflare WARP\nsudo iptables -I DOCKER-USER -i ext_if -s 100.96.0.10 -j ACCEPT\n",[646,5396,5397,5402,5430,5434,5439],{"__ignoreMap":424},[673,5398,5399],{"class":675,"line":676},[673,5400,5401],{"class":738},"# Bloquear todo o tráfego público externo\n",[673,5403,5404,5406,5409,5412,5415,5418,5421,5424,5427],{"class":675,"line":742},[673,5405,842],{"class":679},[673,5407,5408],{"class":687}," iptables",[673,5410,5411],{"class":687}," -I",[673,5413,5414],{"class":687}," DOCKER-USER",[673,5416,5417],{"class":687}," -i",[673,5419,5420],{"class":687}," ext_if",[673,5422,5423],{"class":687}," -j",[673,5425,5426],{"class":687}," DROP",[673,5428,5429],{"class":2006}," \n",[673,5431,5432],{"class":675,"line":616},[673,5433,774],{"emptyLinePlaceholder":773},[673,5435,5436],{"class":675,"line":777},[673,5437,5438],{"class":738},"# Permitir tráfego apenas do IP privado do seu cliente Cloudflare WARP\n",[673,5440,5441,5443,5445,5447,5449,5451,5453,5456,5459,5461],{"class":675,"line":783},[673,5442,842],{"class":679},[673,5444,5408],{"class":687},[673,5446,5411],{"class":687},[673,5448,5414],{"class":687},[673,5450,5417],{"class":687},[673,5452,5420],{"class":687},[673,5454,5455],{"class":687}," -s",[673,5457,5458],{"class":1310}," 100.96.0.10",[673,5460,5423],{"class":687},[673,5462,5463],{"class":687}," ACCEPT\n",[587,5465,5467],{"id":5466},"configuração-da-synch-cli","Configuração da Synch CLI",[429,5469,5470,5471,5473],{},"A ",[443,5472,5099],{}," é uma ferramenta sem interface gráfica (headless) que permite sincronizar o diretório de um cofre do Obsidian diretamente em servidores remotos, sem exigir a instalação da aplicação de ambiente de trabalho completa.",[429,5475,5476,5477,5479,5480,5483,5484,5487,5488,5491,5492,1082,5495,1123,5498,5501,5502,5505,5506,5509],{},"Compile a ",[443,5478,5099],{}," a partir do seu repositório ",[646,5481,5482],{},"synch"," clonado. A compilação requer o ",[443,5485,5486],{},"Node.js >= 22.5"," (pois a CLI depende do ",[646,5489,5490],{},"node:sqlite"," e de APIs globais do navegador como ",[646,5493,5494],{},"fetch",[646,5496,5497],{},"WebSocket",[646,5499,5500],{},"WebCrypto",") e o ",[443,5503,5504],{},"pnpm"," (dado que o repositório está estruturado como um espaço de trabalho de pnpm utilizando a versão ",[646,5507,5508],{},"10.33.0","):",[665,5511,5513],{"className":667,"code":5512,"language":669,"meta":424,"style":424},"# Verificar versões\nnode --version   # deve ser >= 22.5\npnpm --version\n\n# Na raiz do repositório\npnpm install\n\n# Compilar o pacote da CLI\npnpm -C apps\u002Fcli build\n\n# Após uma compilação bem-sucedida, terá o ficheiro `apps\u002Fcli\u002Fdist\u002Fsynch.js`. Torne-o executável e coloque-o no seu PATH\nchmod +x apps\u002Fcli\u002Fdist\u002Fsynch.js\nln -sf \"$PWD\u002Fapps\u002Fcli\u002Fdist\u002Fsynch.js\" \"$HOME\u002F.local\u002Fbin\u002Fsynch\"\n\n# Verificação\nsynch --help\n",[646,5514,5515,5520,5531,5537,5541,5546,5553,5557,5562,5575,5579,5584,5595,5623,5627,5632],{"__ignoreMap":424},[673,5516,5517],{"class":675,"line":676},[673,5518,5519],{"class":738},"# Verificar versões\n",[673,5521,5522,5525,5528],{"class":675,"line":742},[673,5523,5524],{"class":679},"node",[673,5526,5527],{"class":687}," --version",[673,5529,5530],{"class":738},"   # deve ser >= 22.5\n",[673,5532,5533,5535],{"class":675,"line":616},[673,5534,5504],{"class":679},[673,5536,926],{"class":687},[673,5538,5539],{"class":675,"line":777},[673,5540,774],{"emptyLinePlaceholder":773},[673,5542,5543],{"class":675,"line":783},[673,5544,5545],{"class":738},"# Na raiz do repositório\n",[673,5547,5548,5550],{"class":675,"line":828},[673,5549,5504],{"class":679},[673,5551,5552],{"class":687}," install\n",[673,5554,5555],{"class":675,"line":833},[673,5556,774],{"emptyLinePlaceholder":773},[673,5558,5559],{"class":675,"line":839},[673,5560,5561],{"class":738},"# Compilar o pacote da CLI\n",[673,5563,5564,5566,5569,5572],{"class":675,"line":851},[673,5565,5504],{"class":679},[673,5567,5568],{"class":687}," -C",[673,5570,5571],{"class":687}," apps\u002Fcli",[673,5573,5574],{"class":687}," build\n",[673,5576,5577],{"class":675,"line":856},[673,5578,774],{"emptyLinePlaceholder":773},[673,5580,5581],{"class":675,"line":862},[673,5582,5583],{"class":738},"# Após uma compilação bem-sucedida, terá o ficheiro `apps\u002Fcli\u002Fdist\u002Fsynch.js`. Torne-o executável e coloque-o no seu PATH\n",[673,5585,5586,5589,5592],{"class":675,"line":884},[673,5587,5588],{"class":679},"chmod",[673,5590,5591],{"class":687}," +x",[673,5593,5594],{"class":687}," apps\u002Fcli\u002Fdist\u002Fsynch.js\n",[673,5596,5597,5600,5603,5605,5608,5611,5613,5615,5618,5621],{"class":675,"line":889},[673,5598,5599],{"class":679},"ln",[673,5601,5602],{"class":687}," -sf",[673,5604,684],{"class":683},[673,5606,5607],{"class":2006},"$PWD",[673,5609,5610],{"class":687},"\u002Fapps\u002Fcli\u002Fdist\u002Fsynch.js",[673,5612,691],{"class":683},[673,5614,684],{"class":683},[673,5616,5617],{"class":2006},"$HOME",[673,5619,5620],{"class":687},"\u002F.local\u002Fbin\u002Fsynch",[673,5622,702],{"class":683},[673,5624,5625],{"class":675,"line":895},[673,5626,774],{"emptyLinePlaceholder":773},[673,5628,5629],{"class":675,"line":909},[673,5630,5631],{"class":738},"# Verificação\n",[673,5633,5634,5636],{"class":675,"line":914},[673,5635,5482],{"class":679},[673,5637,5638],{"class":687}," --help\n",[429,5640,5641,5642,5645],{},"Visto que a Synch CLI é executada no mesmo VPS que o seu cofre remoto do Synch, esta pode ligar-se diretamente ao servidor local da API. Se estiver a configurar um servidor diferente, execute ",[646,5643,5644],{},"synch login --api-url \u003Curl-da-api-synch-remota>"," para definir o seu endpoint de destino da API.",[429,5647,5648],{},[435,5649],{"alt":5650,"src":5651},"Executando o synch login com URL de API personalizada no terminal","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fsynch-login-api-url-terminal.webp",[429,5653,4363,5654,5657],{},[646,5655,5656],{},"synch login"," no seu terminal e receberá um URL de autenticação:",[429,5659,5660],{},[435,5661],{"alt":5662,"src":5663},"Saída do terminal mostrando a URL de autenticação para o Synch CLI","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fsynch-login-auth-url-terminal.webp",[429,5665,5666],{},"Inicie sessão através da página web utilizando o mesmo endereço de e-mail registado com o plug-in Synchrun do seu Obsidian desktop.",[429,5668,5669],{},[435,5670],{"alt":5671,"src":5672},"Login web bem-sucedido para autorização do Synch CLI","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fsynch-web-login-success.webp",[429,5674,4363,5675,5678],{},[646,5676,5677],{},"synch vault connect --vault ~\u002Fvaults\u002F\u003Cnome_do_cofre> --vault-id asadqe-7b29-4677-fsad-234asdafasd"," para ligar o seu diretório de cofre local no VPS ao cofre remoto.",[429,5680,5681,5682,5685,5686,5689,5690,5509],{},"O ID do cofre remoto pode ser encontrado nas definições do plug-in ",[443,5683,5684],{},"Synchrun",", clicando em ",[443,5687,5688],{},"'Manage remote vaults'"," (Gerir cofres remotos). Isto irá exibir uma página web com a lista dos seus cofres remotos, cada um identificado por um GUID exclusivo (por exemplo, ",[646,5691,5692],{},"123e4567-e89b-12d3-a456-426614174000",[429,5694,5695,5700],{},[435,5696],{"src":5697,"alt":5698,"style":5699},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fsynchrun-manage-remote-vaults.webp","Gerenciando cofres remotos no plugin Synchrun","max-width: 582px; width: 100%; height: auto;",[435,5701],{"alt":5702,"src":5703},"Localizando o ID exclusivo do cofre remoto no Synchrun","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fsynchrun-remote-vault-id.webp",[429,5705,5706,5707,5710],{},"Introduza a palavra-passe do seu cofre quando solicitado para estabelecer a ligação. Assim que estiver ligado, execute ",[646,5708,5709],{},"synch sync --vault ~\u002Fvaults\u002F\u003Cnome-do-cofre>"," para efetuar a sua sincronização inicial. Esta primeira execução poderá demorar algum tempo, dependendo do tamanho do seu cofre.",[429,5712,5713],{},[435,5714],{"alt":5715,"src":5716},"Progresso inicial de sincronização do cofre no Synch CLI","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fsynch-cli-initial-sync-progress.webp",[429,5718,5719,5720,5723],{},"Para automatizar este processo, configure e ative um serviço systemd para executar o ",[646,5721,5722],{},"synch watch"," continuamente, garantindo que as alterações sejam sincronizadas instantaneamente no arranque:",[665,5725,5727],{"className":667,"code":5726,"language":669,"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",[646,5728,5729,5744,5749,5754,5759,5764,5768,5773,5778,5783,5788,5793,5798,5803,5808,5813,5817,5822,5827,5832,5841],{"__ignoreMap":424},[673,5730,5731,5733,5735,5738,5741],{"class":675,"line":676},[673,5732,842],{"class":679},[673,5734,816],{"class":687},[673,5736,5737],{"class":687}," \u002Fetc\u002Fsystemd\u002Fsystem\u002Fsynch-watch.service",[673,5739,5740],{"class":683}," \u003C\u003C",[673,5742,5743],{"class":683},"'EOF'\n",[673,5745,5746],{"class":675,"line":742},[673,5747,5748],{"class":687},"[Unit]\n",[673,5750,5751],{"class":675,"line":616},[673,5752,5753],{"class":687},"Description=Synch vault watcher\n",[673,5755,5756],{"class":675,"line":777},[673,5757,5758],{"class":687},"After=network-online.target\n",[673,5760,5761],{"class":675,"line":783},[673,5762,5763],{"class":687},"Wants=network-online.target\n",[673,5765,5766],{"class":675,"line":828},[673,5767,774],{"emptyLinePlaceholder":773},[673,5769,5770],{"class":675,"line":833},[673,5771,5772],{"class":687},"[Service]\n",[673,5774,5775],{"class":675,"line":839},[673,5776,5777],{"class":687},"Type=simple\n",[673,5779,5780],{"class":675,"line":851},[673,5781,5782],{"class":687},"User=\u003Cusername>\n",[673,5784,5785],{"class":675,"line":856},[673,5786,5787],{"class":687},"ExecStart=\u002Fhome\u002F\u003Cusername>\u002F.local\u002Fbin\u002Fsynch watch --vault \u002Fhome\u002F\u003Cusername>\u002Fvaults\u002F\u003Cvault-name>\n",[673,5789,5790],{"class":675,"line":862},[673,5791,5792],{"class":687},"WorkingDirectory=\u002Fhome\u002F\u003Cusername>\u002Fvaults\n",[673,5794,5795],{"class":675,"line":884},[673,5796,5797],{"class":687},"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",[673,5799,5800],{"class":675,"line":889},[673,5801,5802],{"class":687},"Environment=\"HOME=\u002Fhome\u002F\u003Cusername>\"\n",[673,5804,5805],{"class":675,"line":895},[673,5806,5807],{"class":687},"Restart=always\n",[673,5809,5810],{"class":675,"line":909},[673,5811,5812],{"class":687},"RestartSec=5\n",[673,5814,5815],{"class":675,"line":914},[673,5816,774],{"emptyLinePlaceholder":773},[673,5818,5819],{"class":675,"line":920},[673,5820,5821],{"class":687},"[Install]\n",[673,5823,5824],{"class":675,"line":929},[673,5825,5826],{"class":687},"WantedBy=multi-user.target\n",[673,5828,5829],{"class":675,"line":934},[673,5830,5831],{"class":683},"EOF\n",[673,5833,5834,5836,5838],{"class":675,"line":949},[673,5835,842],{"class":679},[673,5837,900],{"class":687},[673,5839,5840],{"class":687}," daemon-reload\n",[673,5842,5843,5845,5847,5849,5852],{"class":675,"line":954},[673,5844,842],{"class":679},[673,5846,900],{"class":687},[673,5848,903],{"class":687},[673,5850,5851],{"class":687}," --now",[673,5853,5854],{"class":687}," synch-watch.service\n",[429,5856,5857,5858,5860],{},"Abra ",[646,5859,5127],{}," no seu navegador web. Irá constatar que a interface do utilizador e o layout são praticamente idênticos aos da aplicação de ambiente de trabalho:",[435,5862],{"src":5863,"alt":5864,"style":5865},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fignis-web-interface-desktop-view.webp","Interface web do Ignis exibindo o cofre do Obsidian no desktop","max-width: 593px; width: 100%; height: auto;",[429,5867,5868],{},"Clicar no ícone de definições revela que quase todas as configurações essenciais se mantêm intactas, embora seja necessário reinstalar os seus plug-ins da comunidade:",[435,5870],{"src":5871,"alt":5872,"style":5873},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fignis-settings-community-plugins.webp","Configurações de plugins da comunidade na interface web do Ignis","max-width: 597px; width: 100%; height: auto;",[429,5875,5876],{},"Para testar a configuração, pode adicionar uma nova nota através da interface web:",[435,5878],{"src":5879,"alt":5880,"style":5873},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fignis-create-new-note-web.webp","Criando uma nova nota markdown através da interface web do Ignis",[429,5882,5883,5884,607],{},"A nota é sincronizada imediatamente de volta para a sua aplicação de ambiente de trabalho do Obsidian. Note que as pastas vazias não aparecem no ",[443,5885,4639],{},[435,5887],{"src":5888,"alt":5889,"style":5890},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fobsidian-desktop-synced-note.webp","Nova nota criada e sincronizada com sucesso no aplicativo de desktop do Obsidian","max-width: 502px; width: 100%; height: auto;",[429,5892,5893,5894,5896],{},"Visualizar o ",[646,5895,5127],{}," num navegador web móvel:",[429,5898,5899,5904],{},[435,5900],{"src":5901,"alt":5902,"style":5903},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fignis-mobile-view-sidebar.webp","Navegação da barra lateral do cliente web Ignis em um dispositivo móvel","max-width: 269px; width: 100%; height: auto;",[435,5905],{"src":5906,"alt":5907,"style":5903},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002Fignis-mobile-view-editor.webp","Editor de notas markdown do cliente web Ignis em um dispositivo móvel",[429,5909,5910,5911,5913,5914,5917],{},"Quando elimina uma nota no ",[443,5912,4639],{},", esta é movida em segurança para a pasta ",[646,5915,5916],{},"~\u002Fvaults\u002F\u003Cnome-do-cofre>\u002F.trash"," do seu cofre local.",[448,5919,5921],{"id":5920},"considerações-finais-sobre-cofres-auto-hospedados","Considerações finais sobre cofres auto-hospedados",[429,5923,5924,5925,3836,5927,5929,5930,5932],{},"Juntos, o ",[443,5926,4630],{},[443,5928,4639],{}," disponibilizam o seu cofre principal do Obsidian de forma fluida em todos os seus dispositivos, inteiramente alojado numa infraestrutura sob o seu controlo direto. Posicionar estes serviços no interior de uma rede privada ",[443,5931,3980],{}," garante que as suas notas pessoais fiquem completamente protegidas da internet pública.",[429,5934,441,5935,5937],{},[443,5936,4639],{}," não se destina a substituir na totalidade a aplicação nativa de ambiente de trabalho do Obsidian. Em vez disso, atua como um cliente web leve e temporário para aceder e editar o seu cofre quando se encontra afastado do seu computador principal. Para a escrita diária e gestão detalhada do cofre, a aplicação nativa do Obsidian continua a ser a escolha mais confortável.",[429,5939,5940,5941,5943],{},"Como o Synch utiliza encriptação de ponta a ponta, a palavra-passe do seu cofre remoto tem de ser extremamente segura para proteger contra ataques de adivinhação por força bruta. É crítico que nunca perca esta palavra-passe — o servidor não armazena a ",[443,5942,4699],{}," desencriptada e, se a esquecer, os seus dados serão totalmente irrecuperáveis. Adicionalmente, certifique-se de que a sua instância de VPS, a par de quaisquer instantâneos ou cópias de segurança automatizadas, é devidamente mantida e mantida em segurança.",[429,5945,5946],{},"Embora o histórico de versões encriptado do Synch e as ferramentas de recuperação de ficheiros eliminados previnam a maioria das perdas acidentais, a manutenção de uma cópia de segurança independente e separada do seu cofre do Obsidian continua a ser fortemente recomendada.",[448,5948,2598],{"id":2597},[456,5950,5951,5958,5965],{},[459,5952,5953],{},[570,5954,5957],{"href":5955,"rel":5956},"https:\u002F\u002Fsynch.run\u002Fself-hosting-docker\u002F",[1650],"Implementação do Synch com Docker Compose",[459,5959,5960],{},[570,5961,5964],{"href":5962,"rel":5963},"https:\u002F\u002Fignis.thiefling.com\u002Fdocs\u002Fserver\u002Fdeploy\u002F",[1650],"Implementação do Ignis com Docker",[459,5966,5967],{},[570,5968,5971],{"href":5969,"rel":5970},"https:\u002F\u002Fsynch.run\u002Fblog\u002Fencryption-and-decryption\u002F",[1650],"Como funciona a encriptação de ponta a ponta no Synch?",[2630,5973,5974],{},"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":742,"depth":616,"links":5976},[5977,5986,5995,5996],{"id":4671,"depth":742,"text":4672,"children":5978},[5979,5983],{"id":4713,"depth":616,"text":4714,"children":5980},[5981,5982],{"id":4717,"depth":777,"text":4718},{"id":4732,"depth":777,"text":4733},{"id":4941,"depth":616,"text":4942,"children":5984},[5985],{"id":4945,"depth":777,"text":4946},{"id":5061,"depth":742,"text":5062,"children":5987},[5988],{"id":5085,"depth":616,"text":5086,"children":5989},[5990,5991,5992,5993,5994],{"id":5113,"depth":777,"text":5114},{"id":5122,"depth":777,"text":4829},{"id":5167,"depth":777,"text":5168},{"id":5380,"depth":777,"text":5381},{"id":5466,"depth":777,"text":5467},{"id":5920,"depth":742,"text":5921},{"id":2597,"depth":742,"text":2598},[5998],"productivity","2026-09-15","Sincronize cofres do Obsidian entre dispositivos e aceda às notas na web usando Synch e Ignis auto-hospedados com o Cloudflare Zero Trust de forma segura.","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FSync%20Obsidian%20Across%20Devices\u002FPT-Sync-Obsidian-Across-Devices.webp","Sincronização segura de cofres do Obsidian entre múltiplos dispositivos usando as ferramentas auto-hospedadas Synch e Ignis no Cloudflare Zero Trust",{"schemaOrg":6004,"robots":2694,"sitemap":6007},[6005,6006],{"@type":4602,"headline":4612,"description":6000,"image":6001},{"@type":2676,"name":4612,"description":6000,"image":6001},{"lastmod":6008},"2026-09-16",{"title":6010,"description":6000,"ogTitle":4612,"ogDescription":6000,"twitterTitle":4612,"twitterDescription":6000},"Sincronização segura do Obsidian com Synch e Ignis","pt\u002Farticle\u002Fsync-obsidian-across-devices",[6013,6014,6015,6016],"Self-hosting","Obsidian","Sync","Zero Trust","w9q-i3XBW-a7XzDtUq653w4_WENAorcI_0Z65GRHL2g",[6019,7219,7220],{"id":6020,"title":6021,"author":424,"body":6022,"category":7183,"date":7185,"description":7186,"extension":2668,"image":7187,"imageAlt":7188,"isPublished":773,"meta":7189,"minRead":862,"navigation":773,"path":355,"seo":7213,"stem":7215,"tags":7216,"updatedAt":2705,"__hash__":7218},"article\u002Fpt\u002Farticle\u002Fbringing-buzz-to-deepseek-harness.md","Conectar DeepSeek Harness ao Buzz: O Gateway de Nostr",{"type":426,"value":6023,"toc":7167},[6024,6030,6050,6053,6056,6060,6066,6108,6111,6168,6172,6178,6443,6446,6450,6454,6460,6464,6478,6482,6491,6536,6543,6547,6550,6582,6586,6591,6632,6640,6646,6654,6660,6690,6703,6707,6716,6740,6761,6802,6809,6814,6820,6827,6833,6838,6845,6859,6865,6874,6909,6912,6918,6925,6931,6935,6938,7088,7092,7126,7130,7136,7138,7164],[429,6025,6026],{},[435,6027],{"alt":6028,"src":6029},"Visão geral do gateway de mensagens DeepSeek Harness conectado a um canal do Block Buzz","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002Fdsh-buzz-nostr-gateway-overview.webp",[429,6031,6032,6033,6040,6041,6045,6046,607],{},"O plugin do DeepSeek Harness (DSH), ",[443,6034,6035],{},[570,6036,6039],{"href":6037,"rel":6038},"https:\u002F\u002Fgithub.com\u002Fa792883583\u002Fdsh-message-gateway",[1650],"dsh-message-gateway",", estende o assistente DeepSeek Harness a múltiplas plataformas de mensagens, como Discord, Telegram e WeChat. O repositório do plugin foi bifurcado e estendido para adicionar a plataforma ",[443,6042,6043],{},[570,6044,423],{"href":383}," à lista. O repositório bifurcado está disponível no GitHub em ",[570,6047,6048],{"href":6048,"rel":6049},"https:\u002F\u002Fgithub.com\u002FTech-Voyage-Dev\u002Fdsh-message-gateway",[1650],[575,6051],{"description":2667,"image":2669,"image-alt":2670,"label":6052,"min-read":4843,"title":423,"to":383},"Guia de pré-requisitos",[429,6054,6055],{},"O assistente DSH ingressa em um relay do Buzz como membro, recebe mensagens diretas (DMs) e mensagens de canal onde é @mencionado, e responde pelo mesmo pipeline de agentes por chat utilizado na interface Web.",[448,6057,6059],{"id":6058},"arquitetura-do-plugin-dsh-message-gateway","Arquitetura do plugin dsh-message-gateway",[429,6061,6062,6063,6065],{},"A arquitetura do plugin ",[443,6064,6039],{}," é dividida em duas camadas principais:",[456,6067,6068,6098],{},[459,6069,6070,6073,6074,6077,6078,6081,6082,6085,6086,6089,6090,6093,6094,6097],{},[443,6071,6072],{},"Host"," (Node): ",[646,6075,6076],{},"gateway-store"," (credenciais em ",[646,6079,6080],{},"~\u002F.dsh\u002Fgateway.json","), ",[646,6083,6084],{},"platforms.ts"," (definições de plataformas e testes de conexão), ",[646,6087,6088],{},"routes.ts"," (endpoints ",[646,6091,6092],{},"\u002Fgateway\u002F*",") e ",[646,6095,6096],{},"bridge-manager.ts"," (as pontes residentes: sessões de agentes independentes por chat e respostas em streaming).",[459,6099,6100,6103,6104,6107],{},[443,6101,6102],{},"Cliente"," (navegador): a página \"",[443,6105,6106],{},"Message platforms","\" na barra lateral, onde você salva credenciais, testa conexões e monitora o status do serviço.",[429,6109,6110],{},"Adicionar uma nova plataforma envolve as seguintes etapas:",[592,6112,6113,6130,6144],{},[459,6114,6115,6118,6119,6122,6123,6126,6127,607],{},[443,6116,6117],{},"Uma classe de ponte (bridge)",": implementando os métodos ",[646,6120,6121],{},"start\u002Fstop\u002Fstatus"," e o callback ",[646,6124,6125],{},"onText(text, frame)",", espelhando o padrão de ",[646,6128,6129],{},"wecom-bridge.ts",[459,6131,6132,6135,6136,6139,6140,6143],{},[443,6133,6134],{},"Integração no bridge-manager",": reaproveitar o pipeline existente por conversa (",[646,6137,6138],{},"ensureAgentForKey"," + ",[646,6141,6142],{},"pendingMap",") e conectar o coletor de respostas da plataforma.",[459,6145,6146,6149,6150,1123,6153,1078,6156,6159,6160,6163,6164,6167],{},[443,6147,6148],{},"Persistência e rotas",": em ",[646,6151,6152],{},"\u002Fgateway\u002Fsave",[646,6154,6155],{},"\u002Fgateway\u002Fdelete",[443,6157,6158],{},"salvar credenciais inicia a ponte, excluí-las a encerra"," — complementado por uma flag ",[646,6161,6162],{},"autoStartXxx"," para que o ",[646,6165,6166],{},"dsh web"," reconecte automaticamente no boot.",[448,6169,6171],{"id":6170},"implementação-da-ponte-do-buzz-protocolo-nostr-e-ciclo-de-vida-de-eventos","Implementação da ponte do Buzz: Protocolo Nostr e ciclo de vida de eventos",[429,6173,441,6174,6177],{},[443,6175,6176],{},"DeepSeek Harness"," foi utilizado para implementar a ponte do Buzz. A implementação atende rigorosamente às seguintes especificações do protocolo Nostr:",[6179,6180,6181,6207],"table",{},[6182,6183,6184],"thead",{},[6185,6186,6187,6193],"tr",{},[6188,6189,6190],"th",{},[443,6191,6192],{},"Transporte",[6188,6194,6195,6196,6199,6200,6203,6204],{},"Um único WebSocket autenticado via NIP-42; padrão ",[646,6197,6198],{},"ws:\u002F\u002Flocalhost:3000","; ",[646,6201,6202],{},"http(s):\u002F\u002F"," é normalizado para ",[646,6205,6206],{},"ws(s):\u002F\u002F",[6208,6209,6210,6229,6257,6274,6297,6320,6345,6358,6371,6390,6407,6421],"tbody",{},[6185,6211,6212,6218],{},[6213,6214,6215],"td",{},[443,6216,6217],{},"Autenticação",[6213,6219,6220,6221,6224,6225,6228],{},"Evento AUTH ",[646,6222,6223],{},"kind 22242",", tags ",[646,6226,6227],{},"[[\"relay\", url], [\"challenge\", challenge]]",", conteúdo vazio, assinado com a chave do agente",[6185,6230,6231,6236],{},[6213,6232,6233],{},[443,6234,6235],{},"Inscrições",[6213,6237,6238,1078,6241,6244,6245,6248,6249,6252,6253,6256],{},[443,6239,6240],{},"Por canal",[646,6242,6243],{},"REQ {\"kinds\":[9], \"#h\":[\u003Cuuid>]}"," — um REQ por canal. Um REQ global ",[646,6246,6247],{},"kinds:[9]"," recebe EOSE mas nunca distribui eventos; filtro ",[646,6250,6251],{},"#h"," multivalorado ",[443,6254,6255],{},"não"," funciona",[6185,6258,6259,6264],{},[6213,6260,6261],{},[443,6262,6263],{},"Descoberta",[6213,6265,6266,6269,6270,6273],{},[646,6267,6268],{},"REQ {kinds:[39000]}"," histórico para metadados de canal (",[646,6271,6272],{},"type == \"dm\""," marca canal de mensagem direta)",[6185,6275,6276,6281],{},[6213,6277,6278],{},[443,6279,6280],{},"Associação",[6213,6282,6283,6286,6287,6289,6290,6293,6294],{},[646,6284,6285],{},"REQ {kinds:[44100,44101], \"#p\":[nossa pubkey], since: now-60s}"," ao vivo — 44100 = adição, 44101 = remoção, com ",[646,6288,429],{},"+",[646,6291,6292],{},"h","; atualiza inscrições ",[443,6295,6296],{},"sem reconectar",[6185,6298,6299,6304],{},[6213,6300,6301],{},[443,6302,6303],{},"Eventos de chat",[6213,6305,6306,6309,6310,6313,6314,1082,6317],{},[646,6307,6308],{},"kind 9"," com tags ",[646,6311,6312],{},"[\"h\", canal]",", opcional ",[646,6315,6316],{},"[\"e\", replyTo]",[646,6318,6319],{},"[\"p\", menção]",[6185,6321,6322,6327],{},[6213,6323,6324],{},[443,6325,6326],{},"Edições in-place",[6213,6328,6329,6332,6333,6139,6335,6338,6339,6341,6342,6344],{},[646,6330,6331],{},"kind 40003"," com ",[646,6334,6292],{},[646,6336,6337],{},"e","→alvo; substituição de conteúdo; limite do relay de 64 KB → manter payloads ≤ 60.000 B; respostas longas são fragmentadas — chunk 0 na edição, o restante adicionado como mensagens ",[646,6340,6308],{}," encadeadas (",[646,6343,6337],{},"→raiz)",[6185,6346,6347,6352],{},[6213,6348,6349],{},[443,6350,6351],{},"Quadros CLOSED",[6213,6353,6354,6357],{},[646,6355,6356],{},"auth-required"," antes de AUTH é normal durante o bootstrap (completar AUTH e reabrir inscrições); após AUTH → retentativa delimitada (3 tentativas, backoff 0\u002F1\u002F2 s); reconexão reconstrói tudo",[6185,6359,6360,6365],{},[6213,6361,6362],{},[443,6363,6364],{},"Limites do relay",[6213,6366,6367,6368],{},"≤ 2000 eventos históricos por inscrição, ordenados do mais recente para o mais antigo, mesmo utilizando ",[646,6369,6370],{},"since",[6185,6372,6373,6378],{},[6213,6374,6375],{},[443,6376,6377],{},"Filtro de menções",[6213,6379,6380,6381,6383,6384,6386,6387,6389],{},"Processa ",[646,6382,6308],{}," de entrada apenas quando: (a) tag ",[646,6385,429],{}," inclui nossa pubkey, (b) o canal é DM, ou (c) a raiz ",[646,6388,6337],{}," pertence ao nosso agente. Ignora a própria pubkey (anti-loop)",[6185,6391,6392,6397],{},[6213,6393,6394],{},[443,6395,6396],{},"Menções de saída",[6213,6398,6399,6400,6403,6404,6406],{},"Texto publicado sem alterações — o relay não valida tokens ",[646,6401,6402],{},"@","; tags ",[646,6405,429],{}," incluem o autor de origem mais até 7 outras pubkeys mencionadas (máx. 8)",[6185,6408,6409,6414],{},[6213,6410,6411],{},[443,6412,6413],{},"Mensagens diretas",[6213,6415,6416,6417,6420],{},"Canais de texto simples no escopo do relay (metadados ",[646,6418,6419],{},"type: \"dm\"",") — sem criptografia NIP-04\u002F44 nesta ponte",[6185,6422,6423,6428],{},[6213,6424,6425],{},[443,6426,6427],{},"Anexos (entrada)",[6213,6429,6430,6431,3730,6434,1082,6436,1082,6439,6442],{},"NIP-92 ",[646,6432,6433],{},"imeta",[646,6435,4446],{},[646,6437,6438],{},"sha256",[646,6440,6441],{},"m",") → download http(s), verificação de SHA-256, limite de 20 MB, máx. 4 por mensagem; imagens de saída não suportadas",[429,6444,6445],{},"O diagrama abaixo ilustra o fluxo de inicialização (bootstrap) da ponte do Buzz:",[435,6447],{"src":6448,"alt":6449},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002Fdsh-buzz-bootstrap.webp","Diagrama de sequência ilustrando o processo de bootstrap e autenticação NIP-42 da ponte Buzz",[548,6451,6453],{"id":6452},"streaming-em-tempo-real-via-edições-in-place-do-nostr-kind-40003","Streaming em tempo real via edições in-place do Nostr (Kind 40003)",[429,6455,6456,6457,1275],{},"Como o Nostr não possui indicador nativo de digitação e seus eventos são estritamente cumulativos (append-only), a ponte do Buzz ",[443,6458,6459],{},"simula streaming por meio de edições in-place",[435,6461],{"src":6462,"alt":6463},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002Fdsh-buzz-reply.webp","Diagrama do fluxo de edição in-place simulando respostas em streaming com eventos kind 40003",[456,6465,6466],{},[459,6467,6468],{},[6469,6470,6471,6472,6474,6475,6477],"em",{},"A ponte do Buzz publica primeiro um evento placeholder ",[646,6473,6308],{},", depois o reescreve progressivamente com edições in-place ",[646,6476,6331],{}," com taxa controlada e grava a edição final quando o agente conclui a resposta. Esse mecanismo segue o mesmo padrão consagrado das pontes do Telegram e Discord.",[548,6479,6481],{"id":6480},"conexão-de-workspaces-do-deepseek-harness-via-comandos-de-chat","Conexão de workspaces do DeepSeek Harness via comandos de chat",[429,6483,6484,6485,3730,6488,5509],{},"O recurso de \"Workspaces\" na interface Web do DSH é gerenciado pelo serviço ",[646,6486,6487],{},"workspaceRegistry",[646,6489,6490],{},"@deepseek-ai\u002Fdsh-workspace",[665,6492,6496],{"className":6493,"code":6494,"language":6495,"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",[646,6497,6498],{"__ignoreMap":424},[673,6499,6500,6503,6506,6509,6513,6516,6518,6520,6522,6525,6528,6530,6533],{"class":675,"line":676},[673,6501,6502],{"class":1278},"const",[673,6504,6505],{"class":2006}," existing ",[673,6507,6508],{"class":683},"=",[673,6510,6512],{"class":6511},"s7zQu"," await",[673,6514,6515],{"class":2006}," ctx",[673,6517,607],{"class":683},[673,6519,6487],{"class":2006},[673,6521,607],{"class":683},[673,6523,6524],{"class":786},"resolveByPath",[673,6526,6527],{"class":2006},"(request",[673,6529,607],{"class":683},[673,6531,6532],{"class":2006},"path)",[673,6534,6535],{"class":683},";\n",[429,6537,6538,6539,6542],{},"A ponte do Buzz disponibiliza o comando de chat ",[646,6540,6541],{},"\u002Fworkspace \u003Cpasta>",", que registra uma pasta existente no DSH. Qualquer nova sessão criada pelo gateway é anexada a essa pasta e exibida na interface Web.",[435,6544],{"src":6545,"alt":6546},"https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002Fdsh-buzz-workspace.webp","Arquitetura do registro de espaços de trabalho do DeepSeek Harness a partir de comandos de chat",[429,6548,6549],{},"Três regras de projeto essenciais:",[456,6551,6552,6562,6572],{},[459,6553,6554,6557,6558,6561],{},[443,6555,6556],{},"Mudar de pasta = nova sessão."," O valor de ",[646,6559,6560],{},"cwd"," é gravado no cabeçalho da sessão no momento da criação e não pode ser alterado posteriormente.",[459,6563,6564,6567,6568,6571],{},[443,6565,6566],{},"A pasta deve existir previamente."," O método ",[646,6569,6570],{},"create"," rejeita caminhos inexistentes.",[459,6573,6574,6577,6578,6581],{},[443,6575,6576],{},"Comando com sensibilidade de segurança."," Toda sessão opera sob uma política de ",[443,6579,6580],{},"auto-aprovação",", concedendo acesso aos arquivos da pasta de destino.",[448,6583,6585],{"id":6584},"guia-passo-a-passo-de-instalação-e-configuração","Guia passo a passo de instalação e configuração",[592,6587,6588],{},[459,6589,6590],{},"Execute os seguintes comandos no terminal:",[665,6592,6594],{"className":667,"code":6593,"language":669,"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",[646,6595,6596,6616,6620,6625],{"__ignoreMap":424},[673,6597,6598,6601,6604,6607,6610,6613],{"class":675,"line":676},[673,6599,6600],{"class":679},"dsh",[673,6602,6603],{"class":687}," plugin",[673,6605,6606],{"class":687}," --profile",[673,6608,6609],{"class":687}," web",[673,6611,6612],{"class":687}," add",[673,6614,6615],{"class":687}," https:\u002F\u002Fgithub.com\u002FTech-Voyage-Dev\u002Fdsh-message-gateway.git\n",[673,6617,6618],{"class":675,"line":742},[673,6619,774],{"emptyLinePlaceholder":773},[673,6621,6622],{"class":675,"line":616},[673,6623,6624],{"class":738},"# Start DSH web\n",[673,6626,6627,6629],{"class":675,"line":777},[673,6628,6600],{"class":679},[673,6630,6631],{"class":687}," web\n",[592,6633,6634],{"start":742},[459,6635,6636,6637,6639],{},"Assim que a interface Web do DSH abrir no navegador, clique no ícone \"",[443,6638,6106],{},"\":",[429,6641,6642],{},[435,6643],{"alt":6644,"src":6645},"Barra lateral da interface Web do DeepSeek Harness destacando o menu Message platforms","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002Fdsh-web-ui-message-platforms-sidebar-icon.webp",[592,6647,6648],{"start":616},[459,6649,6650,6651,6653],{},"Selecione \"",[443,6652,445],{},"\" no painel esquerdo:",[429,6655,6656],{},[435,6657],{"alt":6658,"src":6659},"Painel de configurações da ponte Buzz no gateway de mensagens do DeepSeek Harness","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002Fdsh-message-gateway-buzz-config-panel.webp",[592,6661,6662,6673,6684],{"start":777},[459,6663,6664,6665,6668,6669,6672],{},"Clique em \"",[443,6666,6667],{},"Generate keypair","\" para gerar o par de chaves Nostr. Guarde a chave pública ",[646,6670,6671],{},"npub"," em local seguro.",[459,6674,6675,6676,6679,6680,6683],{},"Preencha a ",[443,6677,6678],{},"Relay URL"," e os ",[443,6681,6682],{},"Channels"," (a lista autorizada de UUIDs dos canais que serão assinados).",[459,6685,6686,6687,6689],{},"Clique no botão \"",[443,6688,3323],{},"\".",[429,6691,6692,6693,6696,6697,6700,6701,607],{},"Ao salvar o formulário, as credenciais são armazenadas e ",[443,6694,6695],{},"a ponte é iniciada",". A chave privada ",[646,6698,6699],{},"nsec"," é protegida como segredo e gravada exclusivamente em ",[646,6702,6080],{},[548,6704,6706],{"id":6705},"registro-do-par-de-chaves-do-agente-no-relay-nostr-do-buzz","Registro do par de chaves do agente no relay Nostr do Buzz",[429,6708,6709,6712,6713,6715],{},[443,6710,6711],{},"Adicione o assistente DSH ao relay como membro."," Utilize a chave ",[646,6714,6671],{}," gerada na etapa anterior:",[665,6717,6719],{"className":667,"code":6718,"language":669,"meta":424,"style":424},"docker compose exec relay buzz-admin add-member --pubkey npub123123123\n",[646,6720,6721],{"__ignoreMap":424},[673,6722,6723,6725,6727,6729,6731,6733,6735,6737],{"class":675,"line":676},[673,6724,923],{"class":679},[673,6726,965],{"class":687},[673,6728,1683],{"class":687},[673,6730,1686],{"class":687},[673,6732,1689],{"class":687},[673,6734,1692],{"class":687},[673,6736,1695],{"class":687},[673,6738,6739],{"class":687}," npub123123123\n",[429,6741,6742,6745,6746,6748,6749,6752,6753,6756,6757,6760],{},[443,6743,6744],{},"Adicione o assistente a um canal específico."," Apenas registrar o membro no relay não o torna visível nem pesquisável nos canais. Para adicioná-lo via ",[646,6747,1824],{},", lembre-se de que o parâmetro ",[646,6750,6751],{},"--pubkey"," deve estar no formato ",[443,6754,6755],{},"HEX",", e não npub (o comando ",[646,6758,6759],{},"buzz-admin add-member"," exibe a chave HEX correspondente):",[665,6762,6764],{"className":667,"code":6763,"language":669,"meta":424,"style":424},"buzz channels add-member --channel \u003CCHANNEL_UUID> --pubkey \u003CAGENT_HEX> --role member\n",[646,6765,6766],{"__ignoreMap":424},[673,6767,6768,6770,6772,6774,6776,6778,6780,6782,6784,6786,6788,6791,6794,6796,6799],{"class":675,"line":676},[673,6769,2055],{"class":679},[673,6771,2058],{"class":687},[673,6773,1692],{"class":687},[673,6775,2110],{"class":687},[673,6777,2325],{"class":683},[673,6779,2328],{"class":687},[673,6781,2331],{"class":2006},[673,6783,2010],{"class":683},[673,6785,1695],{"class":687},[673,6787,2325],{"class":683},[673,6789,6790],{"class":687},"AGENT_HE",[673,6792,6793],{"class":2006},"X",[673,6795,2010],{"class":683},[673,6797,6798],{"class":687}," --role",[673,6800,6801],{"class":687}," member\n",[575,6803],{"description":6804,"image":2669,"image-alt":2670,"label":6805,"min-read":6806,"title":6807,"to":6808},"Instruções passo a passo para instalar e configurar o buzz-cli para gerir canais Nostr, chaves de membros e permissões de agentes de IA.","Guia da CLI","5","Como instalar e usar o buzz-cli","\u002Farticle\u002Fself-hosting-buzz-as-the-workspace-where-ai-agents-become-colleagues#install-buzz-cli",[429,6810,6811,6812,1275],{},"Atualize o perfil do assistente no relay Nostr definindo um nome amigável com o ",[646,6813,1824],{},[429,6815,6816],{},[435,6817],{"alt":6818,"src":6819},"Atualização do nome do assistente DeepSeek Harness no relay Nostr usando buzz-cli","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002Fdsh-assistant-buzz-cli-profile-update.webp",[429,6821,6822,6823,6826],{},"Envie uma saudação ",[443,6824,6825],{},"Wave"," (a saudação padrão de DM do Buzz) para o assistente. O retorno confirma a operação:",[429,6828,6829],{},[435,6830],{"alt":6831,"src":6832},"Teste de conexão enviando uma saudação Wave por DM para o assistente DeepSeek Harness no Buzz","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002Fdsh-buzz-dm-wave-greeting-reply.webp",[429,6834,6835],{},[6469,6836,6837],{},"Enviando uma Wave por mensagem direta para o assistente DSH — a ponte está ativa.",[548,6839,6841,6842],{"id":6840},"habilitando-o-acesso-a-pastas-locais-com-workspace","Habilitando o acesso a pastas locais com ",[646,6843,6844],{},"\u002Fworkspace",[429,6846,6847,6848,6851,6852,6855,6856,6858],{},"Como a configuração ",[646,6849,6850],{},"allowWorkspace"," vem desativada (",[646,6853,6854],{},"false",") por padrão, o comando ",[646,6857,6844],{}," será inicialmente recusado:",[429,6860,6861],{},[435,6862],{"alt":6863,"src":6864},"Notificação de erro mostrando a rejeição do comando workspace com allowWorkspace desativado","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002Fdsh-buzz-workspace-command-rejected-error.webp",[429,6866,6867,6868,6871,6872,1275],{},"Ative a funcionalidade em ",[646,6869,6870],{},"~\u002F.dsh\u002Fprofiles\u002Fweb\u002Fcordis.patch.yml"," e reinicie o ",[646,6873,6166],{},[665,6875,6877],{"className":1164,"code":6876,"language":1166,"meta":424,"style":424},"- id: ui-message-gateway\n  config:\n    allowWorkspace: true\n",[646,6878,6879,6892,6899],{"__ignoreMap":424},[673,6880,6881,6884,6887,6889],{"class":675,"line":676},[673,6882,6883],{"class":683},"-",[673,6885,6886],{"class":1256}," id",[673,6888,1275],{"class":683},[673,6890,6891],{"class":687}," ui-message-gateway\n",[673,6893,6894,6897],{"class":675,"line":742},[673,6895,6896],{"class":1256},"  config",[673,6898,1260],{"class":683},[673,6900,6901,6904,6906],{"class":675,"line":616},[673,6902,6903],{"class":1256},"    allowWorkspace",[673,6905,1275],{"class":683},[673,6907,2223],{"class":6908},"sfNiH",[429,6910,6911],{},"Após reiniciar:",[429,6913,6914],{},[435,6915],{"alt":6916,"src":6917},"Mensagem de confirmação de sucesso após executar o comando de registro de workspace no Buzz","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002Fdsh-buzz-workspace-command-success-confirmation.webp",[429,6919,6920,6921,6924],{},"Dica importante: o sistema presume que a pasta do workspace (",[646,6922,6923],{},"TechVoyage"," nas capturas) esteja no diretório padrão do usuário. Caso contrário, informe o caminho absoluto. Qualquer nova sessão criada sob este workspace pelo Buzz também aparecerá na interface Web do DeepSeek Harness.",[429,6926,6927],{},[435,6928],{"alt":6929,"src":6930},"Interface Web do DeepSeek Harness exibindo a sessão de workspace sincronizada do Buzz","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002Fdsh-web-ui-synced-workspace-session.webp",[548,6932,6934],{"id":6933},"comandos-disponíveis-no-buzz","Comandos disponíveis no Buzz",[429,6936,6937],{},"Todos os comandos disponíveis nas demais plataformas suportadas funcionam normalmente no Buzz:",[6179,6939,6940,6950],{},[6182,6941,6942],{},[6185,6943,6944,6947],{},[6188,6945,6946],{},"Comando",[6188,6948,6949],{},"O que faz",[6208,6951,6952,6962,6972,6982,6992,7002,7012,7022,7032,7051,7071],{},[6185,6953,6954,6959],{},[6213,6955,6956],{},[646,6957,6958],{},"\u002Fworkspace \u003Cfolder>",[6213,6960,6961],{},"Registra uma pasta existente como o workspace da conversa (requer habilitação nas configurações)",[6185,6963,6964,6969],{},[6213,6965,6966],{},[646,6967,6968],{},"\u002Fhelp",[6213,6970,6971],{},"Lista os comandos disponíveis",[6185,6973,6974,6979],{},[6213,6975,6976],{},[646,6977,6978],{},"\u002Ftime",[6213,6980,6981],{},"Mostra a hora atual do sistema",[6185,6983,6984,6989],{},[6213,6985,6986],{},[646,6987,6988],{},"\u002Fnew",[6213,6990,6991],{},"Inicia uma nova sessão de conversa limpa",[6185,6993,6994,6999],{},[6213,6995,6996],{},[646,6997,6998],{},"\u002Fclear",[6213,7000,7001],{},"Limpa o histórico da conversa atual",[6185,7003,7004,7009],{},[6213,7005,7006],{},[646,7007,7008],{},"\u002Fstatus",[6213,7010,7011],{},"Exibe o status operacional da ponte",[6185,7013,7014,7019],{},[6213,7015,7016],{},[646,7017,7018],{},"\u002Fstats",[6213,7020,7021],{},"Mostra a contagem de conversas e linhas de status por ponte (todas as plataformas, incluindo Buzz)",[6185,7023,7024,7029],{},[6213,7025,7026],{},[646,7027,7028],{},"\u002Fcommands",[6213,7030,7031],{},"Lista descritiva com todos os comandos",[6185,7033,7034,7039],{},[6213,7035,7036],{},[646,7037,7038],{},"@path\u002Fto\u002Ffile",[6213,7040,7041,7042,1082,7044,3734,7047,7050],{},"Funciona exatamente como menções de arquivos na Web: o modelo lê o arquivo relativo ao workspace; ",[646,7043,6402],{},[646,7045,7046],{},"@prefixo",[646,7048,7049],{},"\u002Ffiles \u003Cprefixo>"," retornam arquivos e pastas correspondentes",[6185,7052,7053,7058],{},[6213,7054,7055],{},[646,7056,7057],{},"\u002Fmodel",[6213,7059,7060,7063,7064,7066,7067,7070],{},[646,7061,7062],{},"[provider model effort]"," — valida contra o catálogo ativo de LLMs; ",[646,7065,7057],{}," lista as opções disponíveis e ",[646,7068,7069],{},"\u002Fmodel reset"," restaura os padrões",[6185,7072,7073,7078],{},[6213,7074,7075],{},[646,7076,7077],{},"\u002Feffort",[6213,7079,7080,7083,7084,7087],{},[646,7081,7082],{},"\u003Cid>"," ajusta apenas o esforço de raciocínio do modelo; ",[646,7085,7086],{},"\u002Feffort reset"," restaura o valor padrão",[548,7089,7091],{"id":7090},"resumo-das-medidas-de-segurança","Resumo das medidas de segurança",[456,7093,7094,7107,7117],{},[459,7095,7096,7097,7099,7100,7102,7103,7106],{},"A chave privada ",[443,7098,6699],{}," reside unicamente em ",[646,7101,6080],{}," (permissões 0600, gravação atômica) — nunca sendo exposta em ",[646,7104,7105],{},"\u002Fgateway\u002Flist"," nem em logs.",[459,7108,7109,7110,3730,7113,7116],{},"Todo evento de entrada passa por ",[443,7111,7112],{},"validação de assinatura criptográfica",[646,7114,7115],{},"verifyEvent","), desduplicação, filtro de mensagens próprias e controle de menções antes de alcançar o agente.",[459,7118,7119,3730,7122,7125],{},[443,7120,7121],{},"O registro de workspaces é bloqueado por configuração",[646,7123,7124],{},"allowWorkspace: false"," por padrão), garantindo controle total contra acesso indevido aos arquivos da máquina.",[448,7127,7129],{"id":7128},"conclusão-colaboração-com-agentes-de-ia-descentralizados-no-buzz","Conclusão: Colaboração com agentes de IA descentralizados no Buzz",[429,7131,7132,7133,7135],{},"O maior desafio ao incorporar o Buzz ao ",[646,7134,6039],{}," esteve na conformidade com o protocolo Nostr. Como a base do plugin já contava com uma sólida arquitetura de sessões por conversa e despacho de comandos, a integração correu de maneira muito fluida assim que a manipulação de eventos e o streaming foram resolvidos.",[448,7137,4524],{"id":2597},[456,7139,7140,7148,7156],{},[459,7141,7142,7147],{},[570,7143,7146],{"href":7144,"rel":7145},"https:\u002F\u002Fgithub.com\u002Fa792883583\u002Fdsh-message-gateway\u002Fblob\u002Fmain\u002Fdocs\u002Farchitecture.md",[1650],"dsh-message-gateway architecture guide"," — guia de arquitetura, receitas de extensão e notas de segurança",[459,7149,7150,7155],{},[570,7151,7154],{"href":7152,"rel":7153},"https:\u002F\u002Fgithub.com\u002Fnbd-wtf\u002Fnostr-tools",[1650],"nostr-tools"," — biblioteca Nostr utilizada sob o capô",[459,7157,7158,7163],{},[570,7159,7162],{"href":7160,"rel":7161},"https:\u002F\u002Fgithub.com\u002Fbytedance\u002Fdeer-flow\u002Fblob\u002Fmain\u002Fbackend\u002Fdocs\u002FIM_CHANNEL_CONNECTIONS.md",[1650],"deer-flow IM channel connections"," — referências para arquiteturas de conexão em canais de mensageria",[2630,7165,7166],{},"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":742,"depth":616,"links":7168},[7169,7170,7174,7181,7182],{"id":6058,"depth":742,"text":6059},{"id":6170,"depth":742,"text":6171,"children":7171},[7172,7173],{"id":6452,"depth":616,"text":6453},{"id":6480,"depth":616,"text":6481},{"id":6584,"depth":742,"text":6585,"children":7175},[7176,7177,7179,7180],{"id":6705,"depth":616,"text":6706},{"id":6840,"depth":616,"text":7178},"Habilitando o acesso a pastas locais com \u002Fworkspace",{"id":6933,"depth":616,"text":6934},{"id":7090,"depth":616,"text":7091},{"id":7128,"depth":742,"text":7129},{"id":2597,"depth":742,"text":4524},[2665,2664,2055,7184],"deepseek-harness","2026-09-30","Integre o DeepSeek Harness ao Block Buzz com uma ponte Nostr. Configure auth NIP-42, streaming de mensagens in-place e espaços de trabalho de agentes de IA.","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FBringing%20Buzz%20to%20DeepSeek%20Harness\u002FPT-Bringing-Buzz-to-DeepSeek-Harness.webp","Um cartão tecnológico premium de 16:9 com detalhes em índigo profundo e âmbar ilustrando como conectar o DeepSeek Harness ao Block Buzz com uma ponte Nostr, apresentando um painel glassmorphic limpo e tipografia centrada.",{"schemaOrg":7190,"robots":2694,"sitemap":7212},[7191,7192],{"@type":2674,"headline":6021,"description":7186,"image":7187},{"@type":2676,"name":6021,"description":7186,"image":7187,"step":7193},[7194,7197,7200,7203,7206,7209],{"@type":2679,"name":7195,"text":7196},"Fase 1: Instalar o plugin de gateway","Instale o plugin dsh-message-gateway e inicie o serviço dsh web.",{"@type":2679,"name":7198,"text":7199},"Fase 2: Acessar Message platforms","Abra a interface Web do DSH e navegue até as configurações de Message platforms.",{"@type":2679,"name":7201,"text":7202},"Fase 3: Configurar a ponte Buzz","Gere um par de chaves Nostr, insira a URL do relay e os canais.",{"@type":2679,"name":7204,"text":7205},"Fase 4: Registrar o agente no relay","Adicione o assistente DSH ao relay Nostr do Buzz usando buzz-admin.",{"@type":2679,"name":7207,"text":7208},"Fase 5: Adicionar o agente ao canal","Vincule a chave HEX do agente aos canais usando buzz-cli.",{"@type":2679,"name":7210,"text":7211},"Fase 6: Habilitar acesso a workspaces","Configure allowWorkspace em cordis.patch.yml para permitir comandos de pastas locais.",{"lastmod":7185},{"title":7214,"description":7186,"ogTitle":6021,"ogDescription":7186,"twitterTitle":6021,"twitterDescription":7186},"Plugin Buzz para DeepSeek Harness: Criar Ponte Nostr","pt\u002Farticle\u002Fbringing-buzz-to-deepseek-harness",[6176,445,2701,7217,6039],"Agentes IA","c3DZPaQeg7cLpNEOnZ4JMkgdCZ3xrLJOL0NosdV2XnI",{"id":2710,"title":2711,"author":2705,"body":2712,"category":4592,"date":4594,"description":4595,"extension":2668,"image":4596,"imageAlt":4597,"isPublished":773,"meta":4598,"minRead":1461,"navigation":773,"path":379,"seo":4605,"stem":4606,"tags":4607,"updatedAt":2696,"__hash__":4609},{"id":7221,"title":7222,"author":424,"body":7223,"category":7777,"date":7778,"description":7779,"extension":2668,"image":7780,"imageAlt":7781,"isPublished":773,"meta":7782,"minRead":783,"navigation":773,"path":367,"seo":7786,"stem":7788,"tags":7789,"updatedAt":2705,"__hash__":7793},"article\u002Fpt\u002Farticle\u002Fhow-ai-agent-skills-replace-nuxt-app-scaffolding-scripts.md","Como habilidades de agentes de IA substituem scripts Nuxt",{"type":426,"value":7224,"toc":7770},[7225,7239,7243,7246,7342,7345,7373,7379,7383,7398,7415,7419,7430,7590,7594,7676,7680,7688,7708,7715,7730,7741,7744,7750,7753,7759,7767],[429,7226,7227,7228,1123,7231,7234,7235,7238],{},"Quando iniciamos uma nova aplicação usando o framework Nuxt, temos que passar por etapas tediosas como instalar módulos e configurar arquivos como ",[646,7229,7230],{},"nuxt.config.ts",[646,7232,7233],{},"wrangler.jsonc",". Um script pode resolver esse problema, mas ele atinge seus limites à medida que as variações aumentam. É por isso que exploramos e substituímos os scripts por uma ",[443,7236,7237],{},"habilidade de agente"," (agent skill).",[448,7240,7242],{"id":7241},"no-que-os-scripts-de-shell-tradicionais-são-bons","No que os scripts de shell tradicionais são bons",[429,7244,7245],{},"Um script é excelente para executar um conjunto fixo de instruções em sequência com decisões predefinidas no próprio código.",[665,7247,7249],{"className":667,"code":7248,"language":669,"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",[646,7250,7251,7256,7263,7267,7306,7310,7320,7324,7333],{"__ignoreMap":424},[673,7252,7253],{"class":675,"line":676},[673,7254,7255],{"class":738},"#!\u002Fusr\u002Fbin\u002Fenv bash\n",[673,7257,7258,7261],{"class":675,"line":742},[673,7259,7260],{"class":786},"set",[673,7262,1626],{"class":687},[673,7264,7265],{"class":675,"line":616},[673,7266,774],{"emptyLinePlaceholder":773},[673,7268,7269,7271,7274,7277,7279,7283,7285,7288,7291,7294,7297,7300,7303],{"class":675,"line":777},[673,7270,4098],{"class":679},[673,7272,7273],{"class":687}," nuxi@latest",[673,7275,7276],{"class":687}," init",[673,7278,684],{"class":683},[673,7280,7282],{"class":7281},"sHdIc","$1",[673,7284,691],{"class":683},[673,7286,7287],{"class":687}," --template",[673,7289,7290],{"class":687}," minimal",[673,7292,7293],{"class":687}," --packageManager",[673,7295,7296],{"class":687}," pnpm",[673,7298,7299],{"class":687}," --no-gitInit",[673,7301,7302],{"class":687}," -M",[673,7304,7305],{"class":687}," @nuxt\u002Fui,@nuxthub\u002Fcore,@vueuse\u002Fnuxt\n",[673,7307,7308],{"class":675,"line":783},[673,7309,774],{"emptyLinePlaceholder":773},[673,7311,7312,7314,7316,7318],{"class":675,"line":828},[673,7313,997],{"class":786},[673,7315,684],{"class":683},[673,7317,7282],{"class":7281},[673,7319,702],{"class":683},[673,7321,7322],{"class":675,"line":833},[673,7323,774],{"emptyLinePlaceholder":773},[673,7325,7326,7328,7331],{"class":675,"line":839},[673,7327,1005],{"class":679},[673,7329,7330],{"class":687}," ~\u002Ftemplates\u002Fnuxt.config.ts",[673,7332,1311],{"class":687},[673,7334,7335,7337,7340],{"class":675,"line":851},[673,7336,1005],{"class":679},[673,7338,7339],{"class":687}," ~\u002Ftemplates\u002Fwrangler.jsonc",[673,7341,1311],{"class":687},[429,7343,7344],{},"Este script funciona até que aconteça o seguinte:",[456,7346,7347,7353,7363],{},[459,7348,7349,7352],{},[443,7350,7351],{},"Valores padrão fixos."," O script traz o módulo Nuxt UI fixado no código; e se quisermos usar o módulo Ant Design UI? Cada nova opção de módulo exige um novo argumento fornecido pelo usuário.",[459,7354,7355,7358,7359,7362],{},[443,7356,7357],{},"Não consegue ler a intenção do usuário."," \"Crie um blog\" precisa do ",[646,7360,7361],{},"@nuxt\u002Fcontent","; \"crie um site com newsletters\" precisa do Cloudflare D1 + Drizzle. Um script não consegue distinguir a diferença — cada variação exige um novo script.",[459,7364,7365,7368,7369,7372],{},[443,7366,7367],{},"Fica desatualizado silenciosamente."," As convenções do Nuxt mudam entre versões principais. O Nuxt 4 mudou o diretório de origem para ",[646,7370,7371],{},"app\u002F",". Um script escrito para o Nuxt 3 criará o scaffolding da estrutura errada sem nunca alertar o usuário.",[429,7374,5470,7375,7378],{},[443,7376,7377],{},"inicialização do projeto"," (app scaffolding) é um problema de decisão, não de execução. O script não escalará quando o número de decisões aumentar.",[448,7380,7382],{"id":7381},"por-que-usar-uma-habilidade-de-agente-de-ia-em-vez-de-scripts-tradicionais","Por que usar uma habilidade de agente de IA em vez de scripts tradicionais?",[429,7384,7385,7386,7389,7390,7393,7394,7397],{},"Uma habilidade de agente (agent skill) não é um bloco de código que simplesmente executa, mas um ",[443,7387,7388],{},"conjunto de conhecimentos que o agente de IA segue",". Ela contém um arquivo ",[646,7391,7392],{},"SKILL.md"," e pode agrupar quaisquer outros arquivos que a tarefa exigir (como documentos de referência, modelos e scripts executáveis). O artigo ",[570,7395,7396],{"href":351},"Habilidades de agentes de IA: o que são e como criá-las"," explica o funcionamento de uma habilidade de agente. Uma habilidade mantém a diligência de um script ao mesmo tempo que adiciona o julgamento razoável que falta ao script:",[456,7399,7400,7403,7406,7409,7412],{},[459,7401,7402],{},"Deduz a intenção do usuário para determinar se o aplicativo precisa de um banco de dados.",[459,7404,7405],{},"Decide quais módulos opcionais são necessários a partir da lista especificada. Por exemplo, Nuxt Content, i18n e analytics são opcionais de acordo com a solicitação do usuário.",[459,7407,7408],{},"Adapta-se ao ecossistema atual usando o framework Nuxt mais recente, o NuxtHub para integrações com o Cloudflare e o Wrangler para o deployment.",[459,7410,7411],{},"Recupera-se quando uma etapa falha.",[459,7413,7414],{},"Valida o projeto por meio de um checklist final antes de entregá-lo.",[448,7416,7418],{"id":7417},"por-trás-dos-bastidores-da-nossa-habilidade-de-scaffolding-do-nuxt-e-cloudflare","Por trás dos bastidores da nossa habilidade de scaffolding do Nuxt e Cloudflare",[429,7420,7421,7422,7429],{},"A habilidade, ",[570,7423,7426],{"href":7424,"rel":7425},"https:\u002F\u002Fgithub.com\u002FTech-Voyage-Dev\u002Fscaffold-nuxt-cloudflare-app-skill",[1650],[646,7427,7428],{},"scaffold-nuxt-cloudflare-app-skill",", guia você por um scaffolding voltado para produção:",[592,7431,7432,7463,7482,7506,7535,7570,7576],{},[459,7433,7434,7437,7438],{},[443,7435,7436],{},"Esclarece qualquer detalhe"," que não possa ser deduzido:\n",[456,7439,7440,7451,7454],{},[459,7441,7442,7443,7446,7447,7450],{},"O kit de UI (",[443,7444,7445],{},"Nuxt UI"," por padrão ou ",[443,7448,7449],{},"Antdv Next",");",[459,7452,7453],{},"Se um banco de dados é necessário (como Cloudflare D1);",[459,7455,7456,7457,3734,7460,7462],{},"Módulos extras como ",[646,7458,7459],{},"@nuxtjs\u002Fi18n",[646,7461,7361],{}," para recursos de CMS.",[459,7464,7465,6332,7468,7471,7472,7474,7475,7478,7479,607],{},[443,7466,7467],{},"Inicializa o aplicativo base",[646,7469,7470],{},"pnpm dlx nuxi@latest init"," para obter a versão mais recente do framework Nuxt com o ",[646,7473,5504],{}," como gerenciador de pacotes. Em seguida, configura listas de permissões para compilações nativas de modo que o ambiente de compilação do Cloudflare possa compilar ",[646,7476,7477],{},"better-sqlite3","\u002F",[646,7480,7481],{},"sharp",[459,7483,7484,1078,7487,3734,7490,1082,7493,1082,7496,1082,7499,1082,7502,7505],{},[443,7485,7486],{},"Instala os módulos a partir de uma tabela de decisão",[646,7488,7489],{},"@nuxt\u002Fui",[646,7491,7492],{},"@antdv-next\u002Fnuxt",[646,7494,7495],{},"@nuxt\u002Fimage",[646,7497,7498],{},"@nuxtjs\u002Fseo",[646,7500,7501],{},"@nuxthub\u002Fcore",[646,7503,7504],{},"@vueuse\u002Fnuxt",", além de Drizzle\u002FD1, Nuxt Content e i18n apenas se forem selecionados.",[459,7507,7508,1260,7511],{},[443,7509,7510],{},"Organiza a estrutura de diretórios",[456,7512,7513,7517,7522,7527,7532],{},[459,7514,7515],{},[646,7516,7371],{},[459,7518,7519],{},[646,7520,7521],{},"server\u002F",[459,7523,7524],{},[646,7525,7526],{},"shared\u002F",[459,7528,7529],{},[646,7530,7531],{},"tests\u002F",[459,7533,7534],{},"arquivos de configuração na raiz.",[459,7536,7537,1260,7542],{},[443,7538,7539,7540],{},"Configura o ",[646,7541,7230],{},[456,7543,7544,7553,7560,7565],{},[459,7545,7546,7478,7549,7552],{},[646,7547,7548],{},"site.url",[646,7550,7551],{},"site.name"," para SEO",[459,7554,7555,7556,7559],{},"Bloco ",[646,7557,7558],{},"hub"," do NuxtHub para o Cloudflare",[459,7561,7562],{},[646,7563,7564],{},"routeRules",[459,7566,7567],{},[646,7568,7569],{},"compatibilityDate",[459,7571,7572],{},[443,7573,7539,7574],{},[646,7575,7233],{},[459,7577,7578,7581,7582,7585,7586,7589],{},[443,7579,7580],{},"Configura o Vitest e o ESLint",", em seguida executa um ",[443,7583,7584],{},"checklist final"," incluindo ",[646,7587,7588],{},"pnpm install && pnpm dev"," antes de dar o trabalho por encerrado.",[448,7591,7593],{"id":7592},"scripts-de-shell-vs-habilidades-de-agentes-de-ia-comparação-direta","Scripts de shell vs habilidades de agentes de IA: comparação direta",[6179,7595,7596,7608],{},[6182,7597,7598],{},[6185,7599,7600,7602,7605],{},[6188,7601],{},[6188,7603,7604],{},"Script",[6188,7606,7607],{},"Habilidade",[6208,7609,7610,7621,7632,7643,7654,7665],{},[6185,7611,7612,7615,7618],{},[6213,7613,7614],{},"Intenção do usuário",[6213,7616,7617],{},"❌ valores fixos",[6213,7619,7620],{},"✅ adapta-se à solicitação",[6185,7622,7623,7626,7629],{},[6213,7624,7625],{},"Tomada de decisão",[6213,7627,7628],{},"apenas com flags predefinidas",[6213,7630,7631],{},"✅ avaliado em tempo de execução",[6185,7633,7634,7637,7640],{},[6213,7635,7636],{},"Mudanças de versão",[6213,7638,7639],{},"reescrita manual",[6213,7641,7642],{},"✅ verifica o estado atual",[6185,7644,7645,7648,7651],{},[6213,7646,7647],{},"Recuperação de erros",[6213,7649,7650],{},"para a execução",[6213,7652,7653],{},"✅ corrige e continua",[6185,7655,7656,7659,7662],{},[6213,7657,7658],{},"Validação do resultado",[6213,7660,7661],{},"❌",[6213,7663,7664],{},"✅ checklist final",[6185,7666,7667,7670,7673],{},[6213,7668,7669],{},"Custo de manutenção",[6213,7671,7672],{},"proliferação de flags, atualizações de versão",[6213,7674,7675],{},"editar Markdown, não código",[448,7677,7679],{"id":7678},"como-instalar-habilidades-de-agentes-de-ia-com-a-cli-npx-skills","Como instalar habilidades de agentes de IA com a CLI npx skills",[429,7681,7682,7683,1275],{},"A instalação é feita em um único comando com a ",[570,7684,7687],{"href":7685,"rel":7686},"https:\u002F\u002Fgithub.com\u002Fvercel-labs\u002Fskills",[1650],"CLI de skills",[665,7689,7691],{"className":667,"code":7690,"language":669,"meta":424,"style":424},"npx skills add https:\u002F\u002Fgithub.com\u002FTech-Voyage-Dev\u002Fscaffold-nuxt-cloudflare-app-skill.git -g\n",[646,7692,7693],{"__ignoreMap":424},[673,7694,7695,7697,7700,7702,7705],{"class":675,"line":676},[673,7696,4098],{"class":679},[673,7698,7699],{"class":687}," skills",[673,7701,6612],{"class":687},[673,7703,7704],{"class":687}," https:\u002F\u002Fgithub.com\u002FTech-Voyage-Dev\u002Fscaffold-nuxt-cloudflare-app-skill.git",[673,7706,7707],{"class":687}," -g\n",[429,7709,7710,7711],{},"A CLI clona o repositório, localiza a habilidade e pergunta a qual dos 77 agentes suportados ela deve ser atribuída:\n",[435,7712],{"alt":7713,"src":7714},"Interface de linha de comando mostrando a instalação da habilidade de scaffolding do Nuxt usando o comando CLI npx skills add","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FHow%20AI%20Agent%20Skills%20Replace%20Nuxt%20App%20Scaffolding%20Scripts\u002Fnpx-skills-add-scaffold-nuxt-installation.webp",[429,7716,7717,7718,7721,7722,7725,7726],{},"Escolhemos o ",[443,7719,7720],{},"Symlink"," (o método recomendado), que instala a habilidade uma única vez em ",[646,7723,7724],{},"~\u002F.agents\u002Fskills"," e aponta cada agente selecionado para esta única cópia.\n",[435,7727],{"alt":7728,"src":7729},"Tela de terminal exibindo o resumo de instalação e configuração do link simbólico para as habilidades de agentes centralizadas","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FHow%20AI%20Agent%20Skills%20Replace%20Nuxt%20App%20Scaffolding%20Scripts\u002Fnpx-skills-installation-summary-details.webp",[456,7731,7732],{},[459,7733,7734],{},[6469,7735,7736,7737,7740],{},"Consulte este artigo, ",[570,7738,7739],{"href":359},"Fim da fragmentação de habilidades de agentes usando npx skills",", sobre como centralizar habilidades de agentes em uma única fonte de verdade.",[429,7742,7743],{},"Ao abrir o Claude Code, você confirma que a habilidade foi instalada com sucesso.",[429,7745,7746],{},[435,7747],{"alt":7748,"src":7749},"Interface de linha de comando do Claude Code mostrando o comando de barra scaffold-nuxt recém-instalado, ativo e pronto para uso","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FHow%20AI%20Agent%20Skills%20Replace%20Nuxt%20App%20Scaffolding%20Scripts\u002Fclaude-code-scaffold-nuxt-slash-command-active.webp",[429,7751,7752],{},"A partir daí, um prompt em linguagem natural é suficiente:",[7754,7755,7756],"blockquote",{},[429,7757,7758],{},"\"Scaffold a new Nuxt app deployed to Cloudflare Workers — Nuxt UI, a blog section, and a D1 database\"",[429,7760,7761,7762,7766],{},"A habilidade é open source; acesse o ",[570,7763,7765],{"href":7424,"rel":7764},[1650],"repositório no GitHub"," e experimente.",[2630,7768,7769],{},"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":742,"depth":616,"links":7771},[7772,7773,7774,7775,7776],{"id":7241,"depth":742,"text":7242},{"id":7381,"depth":742,"text":7382},{"id":7417,"depth":742,"text":7418},{"id":7592,"depth":742,"text":7593},{"id":7678,"depth":742,"text":7679},[2665],"2026-08-25","Crie apps Nuxt no Cloudflare facilmente. Descubra por que substituímos scripts frágeis por habilidades de agentes de IA e como usá-las usando npx skills.","https:\u002F\u002Finimages.techvoyage.dev\u002Farticles\u002FHow%20AI%20Agent%20Skills%20Replace%20Nuxt%20App%20Scaffolding%20Scripts\u002FPT-How-AI-Agent-Skills-Replace-Nuxt-App-Scaffolding-Scripts.webp","Nuxt no Cloudflare: Habilidades de IA vs Scripts de Build - Comparando scripts frágeis com habilidades de agentes de IA.",{"schemaOrg":7783,"robots":2694,"sitemap":7785},[7784],{"@type":2674,"headline":7222,"description":7779,"image":7780},{"lastmod":7778},{"title":7787,"description":7779,"ogTitle":7222,"ogDescription":7779,"twitterTitle":7222,"twitterDescription":7779},"Nuxt no Cloudflare: Habilidades de IA vs Scripts de Build","pt\u002Farticle\u002Fhow-ai-agent-skills-replace-nuxt-app-scaffolding-scripts",[7790,2704,7791,7792],"Nuxt","AI Agent","Scaffolding","oRX3uz8H_2-Dh03snCHuC6xhmBt3UnIdxirrpFcicu4",1792489983610]