[{"data":1,"prerenderedAt":708},["ShallowReactive",2],{"navigation":3,"/docs/integrations/setup":156,"/docs/integrations/setup-surround":703},[4,23,83,103,118,133,141],{"title":5,"path":6,"stem":7,"children":8,"icon":22},"Getting Started","/docs/getting-started","docs/1.getting-started/1.index",[9,12,17],{"title":10,"path":6,"stem":7,"icon":11},"What is TaskView","i-lucide-house",{"title":13,"path":14,"stem":15,"icon":16},"Installation","/docs/getting-started/installation","docs/1.getting-started/2.installation","i-lucide-download",{"title":18,"path":19,"stem":20,"icon":21},"Quick Start","/docs/getting-started/usage","docs/1.getting-started/3.usage","i-lucide-rocket",false,{"title":24,"icon":22,"path":25,"stem":26,"children":27,"page":22},"Features","/docs/features","docs/2.features",[28,33,38,43,48,53,58,63,68,73,78],{"title":29,"path":30,"stem":31,"icon":32},"Projects and Lists","/docs/features/projects-and-lists","docs/2.features/1.projects-and-lists","i-lucide-folder",{"title":34,"path":35,"stem":36,"icon":37},"Organizations","/docs/features/organizations","docs/2.features/10.organizations","i-lucide-building-2",{"title":39,"path":40,"stem":41,"icon":42},"SSO (Single Sign-On)","/docs/features/sso","docs/2.features/11.sso","i-lucide-shield-check",{"title":44,"path":45,"stem":46,"icon":47},"Tasks","/docs/features/tasks","docs/2.features/2.tasks","i-lucide-check-square",{"title":49,"path":50,"stem":51,"icon":52},"Kanban Board","/docs/features/kanban","docs/2.features/3.kanban","i-lucide-columns-3",{"title":54,"path":55,"stem":56,"icon":57},"Dependency Graph","/docs/features/graph","docs/2.features/4.graph","i-lucide-git-branch",{"title":59,"path":60,"stem":61,"icon":62},"Dashboard","/docs/features/dashboard","docs/2.features/5.dashboard","i-lucide-layout-dashboard",{"title":64,"path":65,"stem":66,"icon":67},"Notifications","/docs/features/notifications","docs/2.features/6.notifications","i-lucide-bell",{"title":69,"path":70,"stem":71,"icon":72},"Webhooks","/docs/features/webhooks","docs/2.features/7.webhooks","i-lucide-webhook",{"title":74,"path":75,"stem":76,"icon":77},"API Tokens","/docs/features/api-tokens","docs/2.features/8.api-tokens","i-lucide-key-round",{"title":79,"path":80,"stem":81,"icon":82},"Sessions & Devices","/docs/features/sessions","docs/2.features/9.sessions","i-lucide-monitor-smartphone",{"title":84,"icon":22,"path":85,"stem":86,"children":87,"page":22},"Integrations","/docs/integrations","docs/3.integrations",[88,93,98],{"title":89,"path":90,"stem":91,"icon":92},"GitHub & GitLab Setup","/docs/integrations/setup","docs/3.integrations/1.setup","i-lucide-git-pull-request",{"title":94,"path":95,"stem":96,"icon":97},"MCP Server","/docs/integrations/mcp","docs/3.integrations/2.mcp","i-lucide-bot",{"title":99,"path":100,"stem":101,"icon":102},"Telegram & Slack Setup","/docs/integrations/messaging","docs/3.integrations/3.messaging","i-lucide-send",{"title":104,"icon":22,"path":105,"stem":106,"children":107,"page":22},"Configuration","/docs/configuration","docs/4.configuration",[108,113],{"title":109,"path":110,"stem":111,"icon":112},"Environment Variables","/docs/configuration/environment-variables","docs/4.configuration/1.environment-variables","i-lucide-settings",{"title":114,"path":115,"stem":116,"icon":117},"Authentication","/docs/configuration/authentication","docs/4.configuration/2.authentication","i-lucide-lock",{"title":119,"icon":22,"path":120,"stem":121,"children":122,"page":22},"Collaboration","/docs/collaboration","docs/5.collaboration",[123,128],{"title":124,"path":125,"stem":126,"icon":127},"Team Members","/docs/collaboration/members","docs/5.collaboration/1.members","i-lucide-users",{"title":129,"path":130,"stem":131,"icon":132},"Roles and Permissions","/docs/collaboration/roles-and-permissions","docs/5.collaboration/2.roles-and-permissions","i-lucide-shield",{"title":134,"path":135,"stem":136,"children":137,"icon":22},"FAQ","/docs/faq","docs/6.faq/1.index",[138],{"title":139,"path":135,"stem":136,"icon":140},"Frequently Asked Questions","i-lucide-circle-help",{"title":142,"icon":22,"path":143,"stem":144,"children":145,"page":22},"Guides","/docs/guides","docs/7.guides",[146,151],{"title":147,"path":148,"stem":149,"icon":150},"Deploy TaskView on a VPS with Nginx","/docs/guides/deploy-vps-nginx","docs/7.guides/1.deploy-vps-nginx","i-lucide-server",{"title":152,"path":153,"stem":154,"icon":155},"TaskView for Freelancers","/docs/guides/taskview-for-freelancers","docs/7.guides/2.taskview-for-freelancers","i-lucide-briefcase",{"id":157,"title":89,"body":158,"description":697,"extension":698,"meta":699,"navigation":700,"path":90,"seo":701,"stem":91,"__hash__":702},"docs/docs/3.integrations/1.setup.md",{"type":159,"value":160,"toc":684},"minimark",[161,165,170,187,190,194,209,211,215,218,250,256,264,266,270,337,342,348,369,371,375,430,434,440,442,449,538,540,544,577,580,582,586,619,621,625,628,630,634,650,659,674,680],[162,163,164],"p",{},"TaskView integrations allow you to connect GitHub or GitLab repositories to your projects. After connecting, issues from the repository are synced as tasks in TaskView and kept up to date via webhooks.",[166,167,169],"h2",{"id":168},"prerequisites","Prerequisites",[171,172,173,177,180],"ul",{},[174,175,176],"li",{},"TaskView API running",[174,178,179],{},"PostgreSQL database with migrations applied",[174,181,182,186],{},[183,184,185],"code",{},".env.taskview"," file configured",[188,189],"hr",{},[166,191,193],{"id":192},"_1-database-migration","1. Database Migration",[162,195,196,197,200,201,204,205,208],{},"The migration creates the required tables (",[183,198,199],{},"tasks.integrations"," and ",[183,202,203],{},"tasks.integration_task_map",") automatically. The migration container handles this on startup - no manual steps needed. Just make sure you've run ",[183,206,207],{},"docker compose up"," and the migration container completed successfully.",[188,210],{},[166,212,214],{"id":213},"_2-generate-encryption-key","2. Generate Encryption Key",[162,216,217],{},"Tokens are encrypted with AES-256-GCM. You need a 32-byte hex key (64 characters):",[219,220,225],"pre",{"className":221,"code":222,"language":223,"meta":224,"style":224},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","node -e \"console.log(require('crypto').randomBytes(32).toString('hex'))\"\n","bash","",[183,226,227],{"__ignoreMap":224},[228,229,232,236,240,244,247],"span",{"class":230,"line":231},"line",1,[228,233,235],{"class":234},"sBMFI","node",[228,237,239],{"class":238},"sfazB"," -e",[228,241,243],{"class":242},"sMK4o"," \"",[228,245,246],{"class":238},"console.log(require('crypto').randomBytes(32).toString('hex'))",[228,248,249],{"class":242},"\"\n",[162,251,252,253,255],{},"Add it to ",[183,254,185],{},":",[219,257,262],{"className":258,"code":260,"language":261},[259],"language-text","ENCRYPTION_KEY=\u003Cyour-64-char-hex-key>\n","text",[183,263,260],{"__ignoreMap":224},[188,265],{},[166,267,269],{"id":268},"_3-create-github-oauth-app","3. Create GitHub OAuth App",[271,272,273,283,290,322,327],"ol",{},[174,274,275,276],{},"Go to ",[277,278,282],"a",{"href":279,"rel":280},"https://github.com/settings/developers",[281],"nofollow","GitHub Developer Settings",[174,284,285,286],{},"Click ",[287,288,289],"strong",{},"\"New OAuth App\"",[174,291,292,293],{},"Fill in:\n",[171,294,295,305,314],{},[174,296,297,300,301,304],{},[287,298,299],{},"Application name",": ",[183,302,303],{},"TaskView Integrations"," (or any name)",[174,306,307,300,310,313],{},[287,308,309],{},"Homepage URL",[183,311,312],{},"http://localhost:3000"," (your frontend URL)",[174,315,316,300,319],{},[287,317,318],{},"Authorization callback URL",[183,320,321],{},"http://localhost:1401/module/integrations/oauth/github/callback",[174,323,285,324],{},[287,325,326],{},"\"Register application\"",[174,328,329,330,333,334],{},"Copy ",[287,331,332],{},"Client ID"," and generate a ",[287,335,336],{},"Client Secret",[162,338,339,340,255],{},"Add to ",[183,341,185],{},[219,343,346],{"className":344,"code":345,"language":261},[259],"GITHUB_INTEGRATION_CLIENT_ID=\u003Cyour-client-id>\nGITHUB_INTEGRATION_CLIENT_SECRET=\u003Cyour-client-secret>\nGITHUB_INTEGRATION_CALLBACK_URL=http://localhost:1401/module/integrations/oauth/github/callback\n",[183,347,345],{"__ignoreMap":224},[349,350,351],"blockquote",{},[162,352,353,356,357,360,361,364,365,368],{},[287,354,355],{},"Note",": This is a separate OAuth App from the one used for login (",[183,358,359],{},"GITHUB_CLIENT_ID","). The integrations app requests ",[183,362,363],{},"repo"," scope, while the login app only requests ",[183,366,367],{},"user:email",".",[188,370],{},[166,372,374],{"id":373},"_4-create-gitlab-oauth-app-optional","4. Create GitLab OAuth App (optional)",[271,376,377,384,389,417,422],{},[174,378,275,379],{},[277,380,383],{"href":381,"rel":382},"https://gitlab.com/-/user_settings/applications",[281],"GitLab Applications",[174,385,285,386],{},[287,387,388],{},"\"New application\"",[174,390,292,391],{},[171,392,393,400,408],{},[174,394,395,300,398],{},[287,396,397],{},"Name",[183,399,303],{},[174,401,402,300,405],{},[287,403,404],{},"Redirect URI",[183,406,407],{},"http://localhost:1401/module/integrations/oauth/gitlab/callback",[174,409,410,413,414],{},[287,411,412],{},"Scopes",": check ",[183,415,416],{},"api",[174,418,285,419],{},[287,420,421],{},"\"Save application\"",[174,423,329,424,200,427],{},[287,425,426],{},"Application ID",[287,428,429],{},"Secret",[162,431,339,432,255],{},[183,433,185],{},[219,435,438],{"className":436,"code":437,"language":261},[259],"GITLAB_INTEGRATION_CLIENT_ID=\u003Cyour-application-id>\nGITLAB_INTEGRATION_CLIENT_SECRET=\u003Cyour-secret>\nGITLAB_INTEGRATION_CALLBACK_URL=http://localhost:1401/module/integrations/oauth/gitlab/callback\n",[183,439,437],{"__ignoreMap":224},[188,441],{},[166,443,445,446,448],{"id":444},"_5-full-envtaskview-example","5. Full ",[183,447,185],{}," Example",[219,450,454],{"className":451,"code":452,"language":453,"meta":224,"style":224},"language-env shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","# ... existing vars ...\n\n# Encryption (required for integrations)\nENCRYPTION_KEY=a1b2c3d4e5f6...  # 64 hex characters\n\n# GitHub Integration OAuth\nGITHUB_INTEGRATION_CLIENT_ID=Iv1.abc123\nGITHUB_INTEGRATION_CLIENT_SECRET=secret_abc123\nGITHUB_INTEGRATION_CALLBACK_URL=http://localhost:1401/module/integrations/oauth/github/callback\n\n# GitLab Integration OAuth (optional)\nGITLAB_INTEGRATION_CLIENT_ID=app_id_123\nGITLAB_INTEGRATION_CLIENT_SECRET=secret_123\nGITLAB_INTEGRATION_CALLBACK_URL=http://localhost:1401/module/integrations/oauth/gitlab/callback\n","env",[183,455,456,461,468,474,480,485,491,497,503,509,514,520,526,532],{"__ignoreMap":224},[228,457,458],{"class":230,"line":231},[228,459,460],{},"# ... existing vars ...\n",[228,462,464],{"class":230,"line":463},2,[228,465,467],{"emptyLinePlaceholder":466},true,"\n",[228,469,471],{"class":230,"line":470},3,[228,472,473],{},"# Encryption (required for integrations)\n",[228,475,477],{"class":230,"line":476},4,[228,478,479],{},"ENCRYPTION_KEY=a1b2c3d4e5f6...  # 64 hex characters\n",[228,481,483],{"class":230,"line":482},5,[228,484,467],{"emptyLinePlaceholder":466},[228,486,488],{"class":230,"line":487},6,[228,489,490],{},"# GitHub Integration OAuth\n",[228,492,494],{"class":230,"line":493},7,[228,495,496],{},"GITHUB_INTEGRATION_CLIENT_ID=Iv1.abc123\n",[228,498,500],{"class":230,"line":499},8,[228,501,502],{},"GITHUB_INTEGRATION_CLIENT_SECRET=secret_abc123\n",[228,504,506],{"class":230,"line":505},9,[228,507,508],{},"GITHUB_INTEGRATION_CALLBACK_URL=http://localhost:1401/module/integrations/oauth/github/callback\n",[228,510,512],{"class":230,"line":511},10,[228,513,467],{"emptyLinePlaceholder":466},[228,515,517],{"class":230,"line":516},11,[228,518,519],{},"# GitLab Integration OAuth (optional)\n",[228,521,523],{"class":230,"line":522},12,[228,524,525],{},"GITLAB_INTEGRATION_CLIENT_ID=app_id_123\n",[228,527,529],{"class":230,"line":528},13,[228,530,531],{},"GITLAB_INTEGRATION_CLIENT_SECRET=secret_123\n",[228,533,535],{"class":230,"line":534},14,[228,536,537],{},"GITLAB_INTEGRATION_CALLBACK_URL=http://localhost:1401/module/integrations/oauth/gitlab/callback\n",[188,539],{},[166,541,543],{"id":542},"_6-usage","6. Usage",[271,545,546,549,555,560,571,574],{},[174,547,548],{},"Open a project in TaskView",[174,550,551,552],{},"Right-click the project in the sidebar → ",[287,553,554],{},"\"Integrations\"",[174,556,285,557],{},[287,558,559],{},"\"Add Integration\"",[174,561,562,563,566,567,570],{},"Choose ",[287,564,565],{},"GitHub"," or ",[287,568,569],{},"GitLab"," - you'll be redirected to authorize",[174,572,573],{},"After authorization, select a repository from the list",[174,575,576],{},"Done - the integration is active",[162,578,579],{},"You can toggle integrations on/off or delete them from the integrations page.",[188,581],{},[166,583,585],{"id":584},"production-notes","Production Notes",[171,587,588,598,604,610],{},[174,589,590,593,594,597],{},[287,591,592],{},"Callback URLs",": Update to your production domain (e.g., ",[183,595,596],{},"https://api.yourdomain.com/module/integrations/oauth/github/callback",")",[174,599,600,603],{},[287,601,602],{},"ENCRYPTION_KEY",": Store securely, never commit to git. If changed, existing encrypted tokens become unreadable",[174,605,606,609],{},[287,607,608],{},"Separate OAuth Apps",": Create new GitHub/GitLab OAuth Apps for production with production callback URLs",[174,611,612,615,616],{},[287,613,614],{},"CORS",": Ensure your production frontend domain is in ",[183,617,618],{},"CORS_ALLOWED_ORIGINS",[188,620],{},[166,622,624],{"id":623},"api-endpoints","API Endpoints",[162,626,627],{},"Watch in the source code.",[188,629],{},[166,631,633],{"id":632},"troubleshooting","Troubleshooting",[162,635,636,639,640,566,643,646,647],{},[287,637,638],{},"\"GitHub integration OAuth is not configured\"","\n→ ",[183,641,642],{},"GITHUB_INTEGRATION_CLIENT_ID",[183,644,645],{},"GITHUB_INTEGRATION_CALLBACK_URL"," is missing in ",[183,648,649],{},".env",[162,651,652,655,656],{},[287,653,654],{},"\"ENCRYPTION_KEY must be a 64-character hex string\"","\n→ Generate a key: ",[183,657,658],{},"node -e \"console.log(require('crypto').randomBytes(32).toString('hex'))\"",[162,660,661,664,665,668,669,671,672,597],{},[287,662,663],{},"OAuth redirects to wrong URL after callback","\n→ Check that ",[183,666,667],{},"APP_URL"," in ",[183,670,649],{}," matches your frontend URL (e.g., ",[183,673,312],{},[162,675,676,679],{},[287,677,678],{},"Empty repo list after OAuth","\n→ The token may have expired or the integration record wasn't created. Check server logs and re-authorize.",[681,682,683],"style",{},"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 .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":224,"searchDepth":463,"depth":463,"links":685},[686,687,688,689,690,691,693,694,695,696],{"id":168,"depth":463,"text":169},{"id":192,"depth":463,"text":193},{"id":213,"depth":463,"text":214},{"id":268,"depth":463,"text":269},{"id":373,"depth":463,"text":374},{"id":444,"depth":463,"text":692},"5. Full .env.taskview Example",{"id":542,"depth":463,"text":543},{"id":584,"depth":463,"text":585},{"id":623,"depth":463,"text":624},{"id":632,"depth":463,"text":633},"Connect GitHub and GitLab repositories to TaskView. Import and sync issues as tasks with OAuth authorization, webhook-based real-time updates, and AES-256 encrypted token storage. Supports GitHub Enterprise and self-hosted GitLab.","md",{},{"icon":92},{"title":89,"description":697},"oCOShinpvo1_AmbO8JCMzDct-UAQ0msllfXOkYl5fWg",[704,706],{"title":79,"path":80,"stem":81,"description":705,"icon":82,"children":-1},"Manage active sessions in TaskView. View logged-in devices, close individual sessions, or sign out of all devices at once.",{"title":94,"path":95,"stem":96,"description":707,"icon":97,"children":-1},"Connect AI assistants like Claude Code and Claude Desktop to TaskView via the Model Context Protocol (MCP). Manage projects and tasks with a scoped API token.",1783289464129]