@mndrk/agx 2.4.8 → 2.4.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -53
- package/cloud-runtime/standalone/apps/local/.next/BUILD_ID +1 -1
- package/cloud-runtime/standalone/apps/local/.next/build-manifest.json +2 -2
- package/cloud-runtime/standalone/apps/local/.next/prerender-manifest.json +3 -3
- package/cloud-runtime/standalone/apps/local/.next/server/app/_global-error.html +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/_global-error.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/_not-found.html +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/_not-found.rsc +3 -3
- package/cloud-runtime/standalone/apps/local/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
- package/cloud-runtime/standalone/apps/local/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/agents/[id]/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/agents/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/agents.html +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/agents.rsc +3 -3
- package/cloud-runtime/standalone/apps/local/.next/server/app/agents.segments/_full.segment.rsc +3 -3
- package/cloud-runtime/standalone/apps/local/.next/server/app/agents.segments/_head.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/agents.segments/_index.segment.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/agents.segments/_tree.segment.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/agents.segments/agents/__PAGE__.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/agents.segments/agents.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/agent-specs/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/agents/[id]/profile/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/agents/export/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/chat/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/file-search/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/participants/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/projects/[id]/objectives/[objectiveId]/scheduled-tasks/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/projects/[id]/objectives/[objectiveId]/worker/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/projects/[id]/search/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/projects/[id]/teams/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/prompt-jobs/poll/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/providers/check/[id]/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/providers/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/queue/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/schedules/debug/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/schedules/poll/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/skills/assign/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/skills/available/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/skills/detail/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/skills/history/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/skills/learn/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/skills/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/skills/unlearn/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/status/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/summarize/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/tasks/[id]/comments/[commentId]/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/tasks/[id]/comments/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/tasks/[id]/nodes/[nodeId]/verify/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/tasks/[id]/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/tasks/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/threads/knowledge/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/threads/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/items/[id]/recap/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/runs/scripted/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/status/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/update-check/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/index.html +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/index.rsc +4 -4
- package/cloud-runtime/standalone/apps/local/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/index.segments/_full.segment.rsc +4 -4
- package/cloud-runtime/standalone/apps/local/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/index.segments/_index.segment.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/integrations/github/select-repos/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/integrations/github/select-repos.html +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/integrations/github/select-repos.rsc +4 -4
- package/cloud-runtime/standalone/apps/local/.next/server/app/integrations/github/select-repos.segments/_full.segment.rsc +4 -4
- package/cloud-runtime/standalone/apps/local/.next/server/app/integrations/github/select-repos.segments/_head.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/integrations/github/select-repos.segments/_index.segment.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/integrations/github/select-repos.segments/_tree.segment.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/integrations/github/select-repos.segments/integrations/github/select-repos/__PAGE__.segment.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/integrations/github/select-repos.segments/integrations/github/select-repos.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/integrations/github/select-repos.segments/integrations/github.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/integrations/github/select-repos.segments/integrations.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/automations/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/automations/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/env-vars/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/env-vars/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/folders/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/folders/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/graph/[taskId]/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/graph/[taskId]/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/notifications/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/notifications/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/objectives/[objectiveId]/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/objectives/[objectiveId]/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/objectives/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/objectives/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/prs/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/prs/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/teams/[teamId]/agents/[agentId]/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/teams/[teamId]/agents/[agentId]/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/teams/[teamId]/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/teams/[teamId]/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/teams/adopt/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/teams/adopt/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/teams/new/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/teams/new/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/teams/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/teams/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/teams/replace/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/teams/replace/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/terminal/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/terminal/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/thread/[threadId]/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/thread/[threadId]/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/thread/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/thread/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/tracking/[tracker]/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/tracking/[tracker]/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/tracking/connect/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/tracking/connect/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/tracking/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/tracking/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects.html +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects.rsc +4 -4
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects.segments/_full.segment.rsc +4 -4
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects.segments/_head.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects.segments/_index.segment.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects.segments/_tree.segment.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects.segments/projects/__PAGE__.segment.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects.segments/projects.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/setup/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/setup.html +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/setup.rsc +4 -4
- package/cloud-runtime/standalone/apps/local/.next/server/app/setup.segments/_full.segment.rsc +4 -4
- package/cloud-runtime/standalone/apps/local/.next/server/app/setup.segments/_head.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/setup.segments/_index.segment.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/setup.segments/_tree.segment.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/setup.segments/setup/__PAGE__.segment.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/setup.segments/setup.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/status/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/status.html +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/status.rsc +3 -3
- package/cloud-runtime/standalone/apps/local/.next/server/app/status.segments/_full.segment.rsc +3 -3
- package/cloud-runtime/standalone/apps/local/.next/server/app/status.segments/_head.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/status.segments/_index.segment.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/status.segments/_tree.segment.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/status.segments/status/__PAGE__.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/status.segments/status.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/[root-of-the-server]__8917bc4c._.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/apps_local_22ab9b7c._.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/ssr/[root-of-the-server]__5187dece._.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/ssr/[root-of-the-server]__7752d2d2._.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/ssr/[root-of-the-server]__7a31a76d._.js +3 -0
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/ssr/[root-of-the-server]__9193284e._.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/ssr/[root-of-the-server]__c0bc6058._.js +7 -0
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/ssr/[root-of-the-server]__e8c6a1f1._.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/ssr/apps_local_988d29c0._.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/ssr/apps_local_app_projects_[slug]_page_tsx_76330306._.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/ssr/apps_local_app_projects_page_tsx_b5cec607._.js +5 -5
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/ssr/apps_local_app_setup_page_tsx_9a67cfaf._.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/ssr/apps_local_components_ProjectModal_tsx_c447494c._.js +3 -0
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/ssr/apps_local_components_TrackerBoard_tsx_98970bab._.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/ssr/apps_local_components_projects_ProjectObjectivesWorkspace_tsx_751ab3d3._.js +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/ssr/apps_local_eec36ab6._.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/ssr/apps_local_fed01721._.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/middleware-manifest.json +5 -5
- package/cloud-runtime/standalone/apps/local/.next/server/pages/404.html +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/pages/500.html +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/server-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/server-reference-manifest.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/23b7c6b08d8bf807.js +1 -0
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/{d6a9cc66254693b8.js → 46add4300ec4ed84.js} +1 -1
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/5709a6f7c5c182d6.js +1 -0
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/{ed606d6f94457578.css → 6d8a7494a0cea7a0.css} +1 -1
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/9ac96f1f33a266f9.js +1 -0
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/{8b87c2521c519a1f.js → afad1102543847bf.js} +1 -1
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/{c9a2c4b55bb76f4f.js → b27f760849f14f13.js} +5 -5
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/{52a7b1805199c6fb.js → b4716c6337e3335c.js} +1 -1
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/b53629835d2a70f0.js +16 -0
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/bb99cb03648e6fae.js +1 -0
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/c8c0c4b13e08bb14.js +1 -0
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/{7bfbfcd072f8d61e.js → d0ba5f3dc5296486.js} +3 -3
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/{3fce625820bc2bd4.js → de56d09bb0de7dd5.js} +2 -2
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/{1585dd5f9ec4866a.js → e5fdfbbe9bae1f03.js} +1 -1
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/{90dd4ab03ab145d1.js → f007705fe5db26f1.js} +1 -1
- package/cloud-runtime/standalone/apps/local/app/api/projects/[id]/route.ts +4 -1
- package/cloud-runtime/standalone/apps/local/app/api/projects/payload.ts +23 -9
- package/cloud-runtime/standalone/apps/local/app/api/projects/route.ts +4 -1
- package/cloud-runtime/standalone/apps/local/app/integrations/github/select-repos/page.tsx +2 -0
- package/cloud-runtime/standalone/apps/local/app/layout.tsx +1 -1
- package/cloud-runtime/standalone/apps/local/app/page.tsx +2 -2
- package/cloud-runtime/standalone/apps/local/app/projects/[slug]/page.tsx +1 -1
- package/cloud-runtime/standalone/apps/local/app/projects/page.tsx +7 -3
- package/cloud-runtime/standalone/apps/local/components/ProjectModal.tsx +111 -91
- package/cloud-runtime/standalone/apps/local/components/TrackerBoard.tsx +2 -2
- package/cloud-runtime/standalone/apps/local/components/project-repo-validation.ts +65 -0
- package/cloud-runtime/standalone/apps/local/components/projects/ProjectObjectivesWorkspace.tsx +22 -2
- package/cloud-runtime/standalone/apps/local/components/setup/McpSetupStep.tsx +1 -1
- package/cloud-runtime/standalone/apps/local/components/setup/ProviderStep.tsx +2 -2
- package/cloud-runtime/standalone/apps/local/components/thread/WorkspaceSidebar.tsx +6 -2
- package/cloud-runtime/standalone/apps/local/components/tracking/TrackerSetup.tsx +2 -2
- package/cloud-runtime/standalone/apps/local/worker/index.js +4 -2
- package/package.json +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/ssr/[root-of-the-server]__636799fb._.js +0 -3
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/ssr/[root-of-the-server]__e02a457c._.js +0 -3
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/ssr/apps_local_ae1a134f._.js +0 -7
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/0d22a723b9b96e65.js +0 -1
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/1bc8cc9cbb99c1ed.js +0 -1
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/c352706a0ad7e35d.js +0 -1
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/cf33cb29946990e3.js +0 -16
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/e3bdd1e0f385114e.js +0 -1
- /package/cloud-runtime/standalone/apps/local/.next/static/{O3Yu8lY-DN5fauB8GipIL → x7w3oijN4B1r7IvTuL96T}/_buildManifest.js +0 -0
- /package/cloud-runtime/standalone/apps/local/.next/static/{O3Yu8lY-DN5fauB8GipIL → x7w3oijN4B1r7IvTuL96T}/_clientMiddlewareManifest.json +0 -0
- /package/cloud-runtime/standalone/apps/local/.next/static/{O3Yu8lY-DN5fauB8GipIL → x7w3oijN4B1r7IvTuL96T}/_ssgManifest.js +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { NextRequest, NextResponse } from "next/server";
|
|
2
2
|
import { db } from "@/lib/db-instance";
|
|
3
|
-
import { buildProjectUpdatePayload } from "../payload";
|
|
3
|
+
import { buildProjectUpdatePayload, InvalidProjectPayloadError } from "../payload";
|
|
4
4
|
import { LOCAL_USER } from "@/lib/auth-mode";
|
|
5
5
|
import { PROJECT_OBJECTIVES_METADATA_KEY, readProjectObjectivesWorkspace } from "@/lib/project-objectives";
|
|
6
6
|
import { getObjectiveRepository } from "@/src/objectives/repository";
|
|
@@ -98,6 +98,9 @@ export async function PATCH(request: NextRequest, { params }: { params: ParamsAr
|
|
|
98
98
|
|
|
99
99
|
return NextResponse.json({ project: hydrateProjectObjectiveMetadata(project) });
|
|
100
100
|
} catch (err) {
|
|
101
|
+
if (err instanceof InvalidProjectPayloadError) {
|
|
102
|
+
return NextResponse.json({ error: err.message }, { status: 400 });
|
|
103
|
+
}
|
|
101
104
|
logger.error("Error updating project", logger.formatError(err));
|
|
102
105
|
return NextResponse.json({ error: "Failed to update project" }, { status: 500 });
|
|
103
106
|
}
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import type { ProjectInput, ProjectRepoInput, ProjectUpdatePayload } from "@/lib/db-adapter.interface";
|
|
2
2
|
|
|
3
|
+
export class InvalidProjectPayloadError extends Error {
|
|
4
|
+
constructor(message: string) {
|
|
5
|
+
super(message);
|
|
6
|
+
this.name = "InvalidProjectPayloadError";
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
|
|
3
10
|
function toOptionalString(value: unknown): string | undefined {
|
|
4
11
|
if (typeof value !== "string") return undefined;
|
|
5
12
|
const trimmed = value.trim();
|
|
@@ -23,16 +30,28 @@ function parseProjectRepos(value: unknown): ProjectRepoInput[] | undefined {
|
|
|
23
30
|
if (!Array.isArray(value)) return undefined;
|
|
24
31
|
|
|
25
32
|
const repos: ProjectRepoInput[] = [];
|
|
26
|
-
value.forEach((item) => {
|
|
33
|
+
value.forEach((item, index) => {
|
|
27
34
|
if (!item || typeof item !== "object") return;
|
|
28
35
|
|
|
29
36
|
const rawName = (item as Record<string, unknown>).name;
|
|
37
|
+
const rawPath = (item as Record<string, unknown>).path;
|
|
30
38
|
const name = typeof rawName === "string" ? rawName.trim() : "";
|
|
31
|
-
|
|
39
|
+
const path = typeof rawPath === "string" ? rawPath.trim() : "";
|
|
40
|
+
|
|
41
|
+
if (!name && !path) return;
|
|
42
|
+
if (!name) {
|
|
43
|
+
throw new InvalidProjectPayloadError(
|
|
44
|
+
`Folder name is required for repos[${index}] when a local path is provided`
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
if (!path) {
|
|
48
|
+
throw new InvalidProjectPayloadError(
|
|
49
|
+
`Local path is required for repos[${index}] when a folder name is provided`
|
|
50
|
+
);
|
|
51
|
+
}
|
|
32
52
|
|
|
33
53
|
const repo: Partial<ProjectRepoInput> = { name };
|
|
34
54
|
const rawId = (item as Record<string, unknown>).id;
|
|
35
|
-
const rawPath = (item as Record<string, unknown>).path;
|
|
36
55
|
const rawGitUrl = (item as Record<string, unknown>).git_url;
|
|
37
56
|
const rawNotes = (item as Record<string, unknown>).notes;
|
|
38
57
|
|
|
@@ -40,12 +59,7 @@ function parseProjectRepos(value: unknown): ProjectRepoInput[] | undefined {
|
|
|
40
59
|
repo.id = rawId.trim();
|
|
41
60
|
}
|
|
42
61
|
|
|
43
|
-
|
|
44
|
-
repo.path = rawPath.trim();
|
|
45
|
-
} else {
|
|
46
|
-
// Path is mandatory
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
62
|
+
repo.path = path;
|
|
49
63
|
|
|
50
64
|
if (typeof rawGitUrl === "string" && rawGitUrl.trim()) {
|
|
51
65
|
repo.git_url = rawGitUrl.trim();
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { NextRequest, NextResponse } from "next/server";
|
|
2
2
|
import { db } from "@/lib/db-instance";
|
|
3
|
-
import { buildProjectInput } from "./payload";
|
|
3
|
+
import { buildProjectInput, InvalidProjectPayloadError } from "./payload";
|
|
4
4
|
import { LOCAL_USER } from "@/lib/auth-mode";
|
|
5
5
|
import { hydrateProjectsObjectiveMetadata } from "./objective-metadata";
|
|
6
6
|
import { logger } from "@/lib/logger";
|
|
@@ -57,6 +57,9 @@ export async function POST(request: NextRequest) {
|
|
|
57
57
|
const project = await db.createProject(userId, projectInput);
|
|
58
58
|
return NextResponse.json({ project }, { status: 201 });
|
|
59
59
|
} catch (error) {
|
|
60
|
+
if (error instanceof InvalidProjectPayloadError) {
|
|
61
|
+
return NextResponse.json({ error: error.message }, { status: 400 });
|
|
62
|
+
}
|
|
60
63
|
logger.error("Error creating project", logger.formatError(error));
|
|
61
64
|
if (isMissingProjectsSchemaError(error)) {
|
|
62
65
|
return NextResponse.json(
|
|
@@ -18,7 +18,7 @@ const geistMono = Geist_Mono({
|
|
|
18
18
|
|
|
19
19
|
export const metadata: Metadata = {
|
|
20
20
|
title: "AGX",
|
|
21
|
-
description: "
|
|
21
|
+
description: "Workflow surface for AI-assisted dev work — tickets, repos, PRs, and agents in one window.",
|
|
22
22
|
};
|
|
23
23
|
|
|
24
24
|
const themeBootstrapScript = `
|
|
@@ -79,7 +79,7 @@ export default function Home() {
|
|
|
79
79
|
<EmptyStateCard
|
|
80
80
|
icon={<FolderPlus className="w-6 h-6 text-[var(--foreground)]" />}
|
|
81
81
|
title="Create your first project"
|
|
82
|
-
description="A project groups your
|
|
82
|
+
description="A project groups your tickets, repos, and PRs — plus the agent teams that work them. Create one to get started."
|
|
83
83
|
ctaLabel="Create a project"
|
|
84
84
|
ctaHref="/projects?new=1"
|
|
85
85
|
/>
|
|
@@ -92,7 +92,7 @@ export default function Home() {
|
|
|
92
92
|
<EmptyStateCard
|
|
93
93
|
icon={<Users className="w-6 h-6 text-[var(--foreground)]" />}
|
|
94
94
|
title={`Add a team to ${state.projectName}`}
|
|
95
|
-
description="Teams
|
|
95
|
+
description="Teams are the agents that work through your tickets and PRs. Add one to start shipping."
|
|
96
96
|
ctaLabel="Add a team"
|
|
97
97
|
ctaHref={`/projects/${state.projectSlug}/teams/new`}
|
|
98
98
|
/>
|
|
@@ -47,7 +47,7 @@ export default function ProjectPage({
|
|
|
47
47
|
<EmptyStateCard
|
|
48
48
|
icon={<Users className="w-6 h-6 text-[var(--foreground)]" />}
|
|
49
49
|
title={`Add a team to ${project.name}`}
|
|
50
|
-
description="Teams
|
|
50
|
+
description="Teams are the agents that work through your tickets and PRs. Add one to start shipping."
|
|
51
51
|
ctaLabel="Add a team"
|
|
52
52
|
ctaHref={`/projects/${project.slug}/teams/new`}
|
|
53
53
|
/>
|
|
@@ -5,6 +5,10 @@ import { useRouter, useSearchParams } from "next/navigation";
|
|
|
5
5
|
import Layout from "@/components/Layout";
|
|
6
6
|
import ProjectCard from "@/components/ProjectCard";
|
|
7
7
|
import ProjectModal, { useProjectFormState, createProjectPayload } from "@/components/ProjectModal";
|
|
8
|
+
import {
|
|
9
|
+
findInvalidProjectRepoDraft,
|
|
10
|
+
formatInvalidProjectRepoDraftMessage,
|
|
11
|
+
} from "@/components/project-repo-validation";
|
|
8
12
|
import TaskList from "@/components/TaskList";
|
|
9
13
|
import { Task } from "@/components/TaskCard";
|
|
10
14
|
import { useTasks } from "@/hooks/useTasks";
|
|
@@ -91,9 +95,9 @@ export default function ProjectsPage() {
|
|
|
91
95
|
return;
|
|
92
96
|
}
|
|
93
97
|
|
|
94
|
-
const invalidRepo = modalRepos
|
|
98
|
+
const invalidRepo = findInvalidProjectRepoDraft(modalRepos);
|
|
95
99
|
if (invalidRepo) {
|
|
96
|
-
setModalFormError(
|
|
100
|
+
setModalFormError(formatInvalidProjectRepoDraftMessage(invalidRepo));
|
|
97
101
|
return;
|
|
98
102
|
}
|
|
99
103
|
|
|
@@ -169,7 +173,7 @@ export default function ProjectsPage() {
|
|
|
169
173
|
</div>
|
|
170
174
|
<h2 className="text-2xl font-bold mb-2">You have no projects</h2>
|
|
171
175
|
<p className="text-[var(--muted-foreground)] text-center max-w-sm mb-8 leading-relaxed">
|
|
172
|
-
Create your first project to
|
|
176
|
+
Create your first project to connect your tickets, repos, and agent teams — and start shipping PRs.
|
|
173
177
|
</p>
|
|
174
178
|
<button
|
|
175
179
|
onClick={openNewProjectModal}
|
|
@@ -3,6 +3,12 @@
|
|
|
3
3
|
import { useCallback, useEffect, useRef, useState } from "react";
|
|
4
4
|
import { ProjectWithRepos } from "@/hooks/useProjects";
|
|
5
5
|
import DirectoryBrowser from "@/components/DirectoryBrowser";
|
|
6
|
+
import {
|
|
7
|
+
findInvalidProjectRepoDraft,
|
|
8
|
+
formatInvalidProjectRepoDraftMessage,
|
|
9
|
+
getProjectRepoValidationIssue,
|
|
10
|
+
isCompleteProjectRepoDraft,
|
|
11
|
+
} from "@/components/project-repo-validation";
|
|
6
12
|
|
|
7
13
|
export interface ProjectFormState {
|
|
8
14
|
name: string;
|
|
@@ -99,8 +105,13 @@ export function createProjectPayload(
|
|
|
99
105
|
form: ProjectFormState,
|
|
100
106
|
repos: RepoDraft[]
|
|
101
107
|
) {
|
|
108
|
+
const invalidRepo = findInvalidProjectRepoDraft(repos);
|
|
109
|
+
if (invalidRepo) {
|
|
110
|
+
throw new Error(formatInvalidProjectRepoDraftMessage(invalidRepo));
|
|
111
|
+
}
|
|
112
|
+
|
|
102
113
|
const repoPayload = repos
|
|
103
|
-
.filter((repo) =>
|
|
114
|
+
.filter((repo) => isCompleteProjectRepoDraft(repo))
|
|
104
115
|
.map((repo) => ({
|
|
105
116
|
...(repo.id ? { id: repo.id } : {}),
|
|
106
117
|
name: repo.name.trim(),
|
|
@@ -229,107 +240,116 @@ function ProjectFormFields({
|
|
|
229
240
|
</button>
|
|
230
241
|
</div>
|
|
231
242
|
<div className="space-y-4">
|
|
232
|
-
{repos.map((repo, index) =>
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
</button>
|
|
254
|
-
)}
|
|
255
|
-
{repos.length > 1 && (
|
|
256
|
-
<button
|
|
257
|
-
type="button"
|
|
258
|
-
onClick={() => onRemoveRepo(index)}
|
|
259
|
-
className="text-xs font-semibold text-[var(--destructive)] hover:underline"
|
|
260
|
-
disabled={isSubmitting}
|
|
261
|
-
>
|
|
262
|
-
Remove
|
|
263
|
-
</button>
|
|
264
|
-
)}
|
|
265
|
-
</div>
|
|
266
|
-
</div>
|
|
267
|
-
{isRepoExpanded(index) ? (
|
|
268
|
-
<div className="grid gap-3 md:grid-cols-2">
|
|
269
|
-
<input
|
|
270
|
-
value={repo.name}
|
|
271
|
-
onChange={(e) => onRepoChange(index, "name", e.target.value)}
|
|
272
|
-
placeholder="Name (e.g. Frontend, API Docs, Design System)"
|
|
273
|
-
className="input text-sm"
|
|
274
|
-
disabled={isSubmitting}
|
|
275
|
-
/>
|
|
276
|
-
<div className="space-y-1">
|
|
277
|
-
<div className="flex items-center gap-2">
|
|
278
|
-
<input
|
|
279
|
-
value={repo.path}
|
|
280
|
-
onChange={(e) => onRepoChange(index, "path", e.target.value)}
|
|
281
|
-
placeholder="Local path to folder"
|
|
282
|
-
className={`input text-sm flex-1${repo.name.trim() && !repo.path.trim() ? " border-[var(--destructive)]/50 ring-1 ring-[var(--destructive)]/20" : ""}`}
|
|
243
|
+
{repos.map((repo, index) => {
|
|
244
|
+
const validationIssue = getProjectRepoValidationIssue(repo);
|
|
245
|
+
|
|
246
|
+
return (
|
|
247
|
+
<div key={index} className="p-4 rounded-2xl border border-[var(--card-border)] bg-[var(--muted)]/20 space-y-3 relative group">
|
|
248
|
+
<div className="flex items-center justify-between">
|
|
249
|
+
<div>
|
|
250
|
+
<div className="text-xs font-bold text-[var(--foreground)] uppercase">Folder #{index + 1}</div>
|
|
251
|
+
{isEditingProject && !isRepoExpanded(index) ? (
|
|
252
|
+
<div className="mt-1 text-sm text-[var(--muted-foreground)]">
|
|
253
|
+
<div>{repo.name || "Unnamed folder"}</div>
|
|
254
|
+
<div className="truncate">{repo.path || "No local path set"}</div>
|
|
255
|
+
</div>
|
|
256
|
+
) : null}
|
|
257
|
+
</div>
|
|
258
|
+
<div className="flex items-center gap-3">
|
|
259
|
+
{isEditingProject && (
|
|
260
|
+
<button
|
|
261
|
+
type="button"
|
|
262
|
+
onClick={() => toggleRepoExpanded(index)}
|
|
263
|
+
className="text-xs font-semibold text-[var(--primary)] hover:underline"
|
|
283
264
|
disabled={isSubmitting}
|
|
284
|
-
|
|
265
|
+
>
|
|
266
|
+
{isRepoExpanded(index) ? "Done" : "Edit"}
|
|
267
|
+
</button>
|
|
268
|
+
)}
|
|
269
|
+
{repos.length > 1 && (
|
|
285
270
|
<button
|
|
286
271
|
type="button"
|
|
287
|
-
onClick={
|
|
288
|
-
|
|
289
|
-
const res = await fetch("/api/filesystem/pick-folder", { method: "POST" });
|
|
290
|
-
const data = await res.json();
|
|
291
|
-
if (data.path) {
|
|
292
|
-
onRepoChange(index, "path", data.path);
|
|
293
|
-
}
|
|
294
|
-
} catch {
|
|
295
|
-
setBrowsingRepoIndex(browsingRepoIndex === index ? null : index);
|
|
296
|
-
}
|
|
297
|
-
}}
|
|
298
|
-
className="px-3 py-2 rounded-xl border border-[var(--card-border)] bg-[var(--muted)]/30 hover:bg-[var(--muted)]/60 transition-colors text-xs font-semibold text-[var(--muted-foreground)] whitespace-nowrap"
|
|
272
|
+
onClick={() => onRemoveRepo(index)}
|
|
273
|
+
className="text-xs font-semibold text-[var(--destructive)] hover:underline"
|
|
299
274
|
disabled={isSubmitting}
|
|
300
275
|
>
|
|
301
|
-
|
|
276
|
+
Remove
|
|
302
277
|
</button>
|
|
303
|
-
</div>
|
|
304
|
-
{repo.name.trim() && !repo.path.trim() && (
|
|
305
|
-
<p className="text-[11px] text-[var(--destructive)]">Local path is required</p>
|
|
306
278
|
)}
|
|
307
279
|
</div>
|
|
308
|
-
|
|
280
|
+
</div>
|
|
281
|
+
{isRepoExpanded(index) ? (
|
|
282
|
+
<div className="grid gap-3 md:grid-cols-2">
|
|
283
|
+
<div className="space-y-1">
|
|
284
|
+
<input
|
|
285
|
+
value={repo.name}
|
|
286
|
+
onChange={(e) => onRepoChange(index, "name", e.target.value)}
|
|
287
|
+
placeholder="Name (e.g. Frontend, API Docs, Design System)"
|
|
288
|
+
className={`input text-sm w-full${validationIssue === "missing_name" ? " border-[var(--destructive)]/50 ring-1 ring-[var(--destructive)]/20" : ""}`}
|
|
289
|
+
disabled={isSubmitting}
|
|
290
|
+
/>
|
|
291
|
+
{validationIssue === "missing_name" && (
|
|
292
|
+
<p className="text-[11px] text-[var(--destructive)]">Folder name is required</p>
|
|
293
|
+
)}
|
|
294
|
+
</div>
|
|
295
|
+
<div className="space-y-1">
|
|
296
|
+
<div className="flex items-center gap-2">
|
|
297
|
+
<input
|
|
298
|
+
value={repo.path}
|
|
299
|
+
onChange={(e) => onRepoChange(index, "path", e.target.value)}
|
|
300
|
+
placeholder="Local path to folder"
|
|
301
|
+
className={`input text-sm flex-1${validationIssue === "missing_path" ? " border-[var(--destructive)]/50 ring-1 ring-[var(--destructive)]/20" : ""}`}
|
|
302
|
+
disabled={isSubmitting}
|
|
303
|
+
/>
|
|
304
|
+
<button
|
|
305
|
+
type="button"
|
|
306
|
+
onClick={async () => {
|
|
307
|
+
try {
|
|
308
|
+
const res = await fetch("/api/filesystem/pick-folder", { method: "POST" });
|
|
309
|
+
const data = await res.json();
|
|
310
|
+
if (data.path) {
|
|
311
|
+
onRepoChange(index, "path", data.path);
|
|
312
|
+
}
|
|
313
|
+
} catch {
|
|
314
|
+
setBrowsingRepoIndex(browsingRepoIndex === index ? null : index);
|
|
315
|
+
}
|
|
316
|
+
}}
|
|
317
|
+
className="px-3 py-2 rounded-xl border border-[var(--card-border)] bg-[var(--muted)]/30 hover:bg-[var(--muted)]/60 transition-colors text-xs font-semibold text-[var(--muted-foreground)] whitespace-nowrap"
|
|
318
|
+
disabled={isSubmitting}
|
|
319
|
+
>
|
|
320
|
+
Browse
|
|
321
|
+
</button>
|
|
322
|
+
</div>
|
|
323
|
+
{validationIssue === "missing_path" && (
|
|
324
|
+
<p className="text-[11px] text-[var(--destructive)]">Local path is required</p>
|
|
325
|
+
)}
|
|
326
|
+
</div>
|
|
327
|
+
{browsingRepoIndex === index && (
|
|
328
|
+
<div className="md:col-span-2">
|
|
329
|
+
<DirectoryBrowser
|
|
330
|
+
initialPath={repo.path || ""}
|
|
331
|
+
onSelect={(selectedPath) => {
|
|
332
|
+
onRepoChange(index, "path", selectedPath);
|
|
333
|
+
setBrowsingRepoIndex(null);
|
|
334
|
+
}}
|
|
335
|
+
onCancel={() => setBrowsingRepoIndex(null)}
|
|
336
|
+
/>
|
|
337
|
+
</div>
|
|
338
|
+
)}
|
|
309
339
|
<div className="md:col-span-2">
|
|
310
|
-
<
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
}
|
|
316
|
-
onCancel={() => setBrowsingRepoIndex(null)}
|
|
340
|
+
<textarea
|
|
341
|
+
value={repo.notes}
|
|
342
|
+
onChange={(e) => onRepoChange(index, "notes", e.target.value)}
|
|
343
|
+
placeholder="Notes for this folder — e.g. coding conventions, deploy steps, ownership, doc standards..."
|
|
344
|
+
className="input text-sm w-full min-h-24 resize-y"
|
|
345
|
+
disabled={isSubmitting}
|
|
317
346
|
/>
|
|
318
347
|
</div>
|
|
319
|
-
)}
|
|
320
|
-
<div className="md:col-span-2">
|
|
321
|
-
<textarea
|
|
322
|
-
value={repo.notes}
|
|
323
|
-
onChange={(e) => onRepoChange(index, "notes", e.target.value)}
|
|
324
|
-
placeholder="Notes for this folder — e.g. coding conventions, deploy steps, ownership, doc standards..."
|
|
325
|
-
className="input text-sm w-full min-h-24 resize-y"
|
|
326
|
-
disabled={isSubmitting}
|
|
327
|
-
/>
|
|
328
348
|
</div>
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
)
|
|
349
|
+
) : null}
|
|
350
|
+
</div>
|
|
351
|
+
);
|
|
352
|
+
})}
|
|
333
353
|
</div>
|
|
334
354
|
</div>
|
|
335
355
|
</div>
|
|
@@ -408,7 +428,7 @@ export default function ProjectModal({
|
|
|
408
428
|
};
|
|
409
429
|
}, [editingProject]);
|
|
410
430
|
|
|
411
|
-
const hasIncompleteRepo =
|
|
431
|
+
const hasIncompleteRepo = Boolean(findInvalidProjectRepoDraft(repos));
|
|
412
432
|
const isFormInvalid = !form.name.trim() || hasIncompleteRepo;
|
|
413
433
|
|
|
414
434
|
if (!isOpen) return null;
|
|
@@ -1904,7 +1904,7 @@ export default function TrackerBoard({ trackerType, projectId, projectSlug, init
|
|
|
1904
1904
|
/>
|
|
1905
1905
|
) : isAwaitingRestore ? null : participants.length === 0 ? (
|
|
1906
1906
|
<div className="flex h-full items-center justify-center text-xs text-[var(--muted-foreground)]">
|
|
1907
|
-
Add
|
|
1907
|
+
Add an agent team so you can pick a ticket and start shipping.
|
|
1908
1908
|
</div>
|
|
1909
1909
|
) : (
|
|
1910
1910
|
<TicketPanel
|
|
@@ -2518,7 +2518,7 @@ export default function TrackerBoard({ trackerType, projectId, projectSlug, init
|
|
|
2518
2518
|
</div>
|
|
2519
2519
|
) : isAwaitingRestore ? null : participants.length === 0 ? (
|
|
2520
2520
|
<div className="flex h-full items-center justify-center text-xs text-[var(--muted-foreground)]">
|
|
2521
|
-
Add
|
|
2521
|
+
Add an agent team so you can pick a ticket and start shipping.
|
|
2522
2522
|
</div>
|
|
2523
2523
|
) : (
|
|
2524
2524
|
<TicketPanel
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
export interface ProjectRepoDraftLike {
|
|
4
|
+
name: string;
|
|
5
|
+
path: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export type ProjectRepoValidationIssue = "missing_name" | "missing_path";
|
|
9
|
+
|
|
10
|
+
export interface InvalidProjectRepoDraft<T extends ProjectRepoDraftLike = ProjectRepoDraftLike> {
|
|
11
|
+
index: number;
|
|
12
|
+
issue: ProjectRepoValidationIssue;
|
|
13
|
+
repo: T;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function trimRepoFields(repo: ProjectRepoDraftLike) {
|
|
17
|
+
return {
|
|
18
|
+
name: repo.name.trim(),
|
|
19
|
+
path: repo.path.trim(),
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function getProjectRepoValidationIssue(
|
|
24
|
+
repo: ProjectRepoDraftLike
|
|
25
|
+
): ProjectRepoValidationIssue | null {
|
|
26
|
+
const { name, path } = trimRepoFields(repo);
|
|
27
|
+
|
|
28
|
+
if (!name && !path) {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
if (!name) {
|
|
32
|
+
return "missing_name";
|
|
33
|
+
}
|
|
34
|
+
if (!path) {
|
|
35
|
+
return "missing_path";
|
|
36
|
+
}
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function findInvalidProjectRepoDraft<T extends ProjectRepoDraftLike>(
|
|
41
|
+
repos: T[]
|
|
42
|
+
): InvalidProjectRepoDraft<T> | null {
|
|
43
|
+
for (const [index, repo] of repos.entries()) {
|
|
44
|
+
const issue = getProjectRepoValidationIssue(repo);
|
|
45
|
+
if (issue) {
|
|
46
|
+
return { index, issue, repo };
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function isCompleteProjectRepoDraft(repo: ProjectRepoDraftLike): boolean {
|
|
53
|
+
const { name, path } = trimRepoFields(repo);
|
|
54
|
+
return Boolean(name && path);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function formatInvalidProjectRepoDraftMessage(
|
|
58
|
+
invalidRepo: InvalidProjectRepoDraft
|
|
59
|
+
): string {
|
|
60
|
+
const { issue, repo } = invalidRepo;
|
|
61
|
+
if (issue === "missing_name") {
|
|
62
|
+
return `Folder name is required for local path "${repo.path.trim()}"`;
|
|
63
|
+
}
|
|
64
|
+
return `Local path is required for folder "${repo.name.trim()}"`;
|
|
65
|
+
}
|
package/cloud-runtime/standalone/apps/local/components/projects/ProjectObjectivesWorkspace.tsx
CHANGED
|
@@ -71,6 +71,7 @@ interface ProjectObjectivesWorkspaceProps {
|
|
|
71
71
|
interface ProjectObjectiveDetailProps extends ProjectObjectivesWorkspaceProps {
|
|
72
72
|
objectiveId: string;
|
|
73
73
|
onObjectiveDeleted?: () => void;
|
|
74
|
+
onBack?: () => void;
|
|
74
75
|
}
|
|
75
76
|
|
|
76
77
|
interface ObjectiveEditorDraft {
|
|
@@ -1574,7 +1575,9 @@ export function ProjectObjectivesOverview({
|
|
|
1574
1575
|
<div className="flex h-full min-h-0 overflow-hidden bg-[var(--background)] text-[var(--foreground)]">
|
|
1575
1576
|
{/* Left panel: objective list */}
|
|
1576
1577
|
<div
|
|
1577
|
-
className=
|
|
1578
|
+
className={`flex-shrink-0 flex-col border-r border-[var(--border)] bg-[var(--background)] max-md:!w-full max-md:border-r-0 ${
|
|
1579
|
+
selectedObjectiveId ? "hidden md:flex" : "flex"
|
|
1580
|
+
}`}
|
|
1578
1581
|
style={{ width: listPanelWidth }}
|
|
1579
1582
|
>
|
|
1580
1583
|
<div className="flex items-center justify-between border-b border-[var(--border)] px-4 py-3">
|
|
@@ -1641,12 +1644,17 @@ export function ProjectObjectivesOverview({
|
|
|
1641
1644
|
<ObjectiveListResizeHandle onResize={handleListPanelResize} />
|
|
1642
1645
|
|
|
1643
1646
|
{/* Right panel: objective detail */}
|
|
1644
|
-
<div
|
|
1647
|
+
<div
|
|
1648
|
+
className={`flex-1 min-w-0 min-h-0 overflow-hidden ${
|
|
1649
|
+
selectedObjectiveId ? "" : "max-md:hidden"
|
|
1650
|
+
}`}
|
|
1651
|
+
>
|
|
1645
1652
|
{selectedObjectiveId ? (
|
|
1646
1653
|
<ProjectObjectiveDetail
|
|
1647
1654
|
projectSlug={projectSlug}
|
|
1648
1655
|
objectiveId={selectedObjectiveId}
|
|
1649
1656
|
onObjectiveDeleted={() => setSelectedObjectiveId(null)}
|
|
1657
|
+
onBack={() => setSelectedObjectiveId(null)}
|
|
1650
1658
|
/>
|
|
1651
1659
|
) : (
|
|
1652
1660
|
<div className="flex h-full items-center justify-center text-sm text-[var(--muted-foreground)]">
|
|
@@ -1676,6 +1684,7 @@ export function ProjectObjectiveDetail({
|
|
|
1676
1684
|
projectSlug,
|
|
1677
1685
|
objectiveId,
|
|
1678
1686
|
onObjectiveDeleted,
|
|
1687
|
+
onBack,
|
|
1679
1688
|
}: ProjectObjectiveDetailProps) {
|
|
1680
1689
|
const router = useRouter();
|
|
1681
1690
|
const { isLoading, project, workspace, teams, persistWorkspace, refetchProject } =
|
|
@@ -2235,6 +2244,17 @@ export function ProjectObjectiveDetail({
|
|
|
2235
2244
|
<div className="max-w-5xl mx-auto pt-16 px-8 pb-20">
|
|
2236
2245
|
<ErrorBanner message={saveError} />
|
|
2237
2246
|
|
|
2247
|
+
{onBack ? (
|
|
2248
|
+
<button
|
|
2249
|
+
type="button"
|
|
2250
|
+
onClick={onBack}
|
|
2251
|
+
className="md:hidden mb-4 inline-flex items-center gap-1.5 rounded-md border border-[var(--border)] bg-[var(--card-bg)] px-2.5 py-1 text-xs text-[var(--muted-foreground)] transition-colors hover:bg-[var(--secondary)] hover:text-[var(--foreground)]"
|
|
2252
|
+
>
|
|
2253
|
+
<ArrowLeft className="h-3.5 w-3.5" />
|
|
2254
|
+
Back to objectives
|
|
2255
|
+
</button>
|
|
2256
|
+
) : null}
|
|
2257
|
+
|
|
2238
2258
|
<div className="flex items-center gap-3 mb-4">
|
|
2239
2259
|
<span className="rounded-full border border-[var(--tone-neutral-border)] bg-[var(--tone-neutral-bg)] px-2.5 py-0.5 text-[10px] font-mono uppercase tracking-wider text-[var(--tone-neutral)]">
|
|
2240
2260
|
{objective.key}
|
|
@@ -17,7 +17,7 @@ const MCP_SERVERS: McpServer[] = [
|
|
|
17
17
|
{
|
|
18
18
|
id: "linear",
|
|
19
19
|
name: "Linear",
|
|
20
|
-
description: "
|
|
20
|
+
description: "So your Linear tickets show up in AGX and agents can move them through to a PR.",
|
|
21
21
|
docsUrl: "https://linear.app/docs/mcp",
|
|
22
22
|
},
|
|
23
23
|
];
|
|
@@ -161,8 +161,8 @@ export function ProviderStep({ clis, readyState, authenticatedCount, totalCount,
|
|
|
161
161
|
<div className="text-center mb-8">
|
|
162
162
|
<h1 className="text-[24px] font-bold text-[var(--foreground)] tracking-tight">Connect a Provider</h1>
|
|
163
163
|
<p className="mt-2 text-[14px] text-[var(--muted-foreground)] leading-relaxed">
|
|
164
|
-
AGX
|
|
165
|
-
Connect
|
|
164
|
+
AGX runs AI-assisted dev work across your tickets, repos, and PRs.<br />
|
|
165
|
+
Connect one or more providers to power the agents that do the work.
|
|
166
166
|
</p>
|
|
167
167
|
</div>
|
|
168
168
|
|
|
@@ -35,6 +35,10 @@ import { useFocusManagement } from "@/hooks/useFocusManagement";
|
|
|
35
35
|
import type { SidebarStageResult } from "@/hooks/useSidebarStage";
|
|
36
36
|
import { agentAvatarUrl, AgentForm, type AgentFormData } from "@/components/chat-ui/ParticipantBar";
|
|
37
37
|
import ProjectModal, { createProjectPayload, useProjectFormState } from "@/components/ProjectModal";
|
|
38
|
+
import {
|
|
39
|
+
findInvalidProjectRepoDraft,
|
|
40
|
+
formatInvalidProjectRepoDraftMessage,
|
|
41
|
+
} from "@/components/project-repo-validation";
|
|
38
42
|
import { readProjectObjectivesWorkspace } from "@/lib/project-objectives";
|
|
39
43
|
import { TaskTrackingNav } from "@/components/tracking/TaskTrackingNav";
|
|
40
44
|
import { LinearIcon } from "@/lib/tracker/adapters/linear/linear-icon";
|
|
@@ -455,9 +459,9 @@ export function WorkspaceSidebar({
|
|
|
455
459
|
projectFormState.setFormError("Project name is required");
|
|
456
460
|
return;
|
|
457
461
|
}
|
|
458
|
-
const invalidRepo = projectFormState.repos
|
|
462
|
+
const invalidRepo = findInvalidProjectRepoDraft(projectFormState.repos);
|
|
459
463
|
if (invalidRepo) {
|
|
460
|
-
projectFormState.setFormError(
|
|
464
|
+
projectFormState.setFormError(formatInvalidProjectRepoDraftMessage(invalidRepo));
|
|
461
465
|
return;
|
|
462
466
|
}
|
|
463
467
|
projectFormState.setFormError(null);
|
|
@@ -82,7 +82,7 @@ export default function TrackerSetup({
|
|
|
82
82
|
<div className="space-y-2">
|
|
83
83
|
<h3 className="text-xl font-bold text-foreground capitalize">{trackerType} Connected</h3>
|
|
84
84
|
<p className="text-sm text-muted-foreground leading-relaxed">
|
|
85
|
-
Your {trackerType}
|
|
85
|
+
Your {trackerType} tickets now live in AGX. Assign them to agents, review the work, and ship PRs from one window.
|
|
86
86
|
</p>
|
|
87
87
|
</div>
|
|
88
88
|
<div className="mt-2 px-4 py-1.5 rounded-full bg-background border text-xs font-medium text-muted-foreground flex items-center gap-2">
|
|
@@ -130,7 +130,7 @@ export default function TrackerSetup({
|
|
|
130
130
|
<span className="text-sm font-medium">MCP Server</span>
|
|
131
131
|
</div>
|
|
132
132
|
<p className="text-xs text-muted-foreground leading-relaxed -mt-2">
|
|
133
|
-
|
|
133
|
+
Connect your {trackerType} workspace so your tickets show up in AGX and agents can work them through to a PR.
|
|
134
134
|
</p>
|
|
135
135
|
{activeClis.map((cli) => {
|
|
136
136
|
const label = CLI_LABELS[cli];
|