@ripla/godd-mcp 1.0.4-canary.8 → 1.0.4

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.
Files changed (348) hide show
  1. package/README.md +89 -94
  2. package/dist/godd.cjs +349 -233
  3. package/dist/godd.js +2193 -838
  4. package/dist/index.js +152 -122
  5. package/{notes-api → notes/api}/.env.example +6 -1
  6. package/{notes-api → notes/api}/README.md +6 -5
  7. package/{notes-api → notes/api}/app/main.py +29 -2
  8. package/{notes-api → notes/api}/app/routers/auth.py +6 -1
  9. package/{notes-api → notes/api}/app/routers/issues.py +157 -1
  10. package/{notes-api → notes/api}/app/routers/pr.py +2 -2
  11. package/{notes-api → notes/api}/app/services/github_app_token.py +32 -1
  12. package/{notes-api → notes/api}/app/services/github_issues.py +101 -11
  13. package/{notes-api → notes/api}/app/services/github_pr.py +6 -1
  14. package/{notes-api → notes/api}/tests/test_github_app_token.py +49 -1
  15. package/{notes-api → notes/api}/tests/test_github_service.py +42 -0
  16. package/notes/api/tests/test_health.py +52 -0
  17. package/{notes-api → notes/api}/tests/test_issues.py +216 -0
  18. package/{notes-api → notes/api}/tests/test_pr.py +24 -0
  19. package/{notes-api → notes/api}/tests/test_pr_chain.py +19 -0
  20. package/{notes-api → notes/api}/uv.lock +178 -2
  21. package/notes/app/DESIGN.md +273 -0
  22. package/{notes-app → notes/app}/README.md +4 -1
  23. package/notes/app/docker/Dockerfile.e2e +19 -0
  24. package/notes/app/docker/Dockerfile.prod +15 -0
  25. package/notes/app/docker/Dockerfile.test +17 -0
  26. package/notes/app/e2e/file-tree.spec.ts +26 -0
  27. package/notes/app/e2e/file-view.spec.ts +25 -0
  28. package/notes/app/e2e/fixtures.ts +28 -0
  29. package/{notes-app → notes/app}/e2e/global-setup.ts +5 -7
  30. package/notes/app/e2e/login.spec.ts +25 -0
  31. package/notes/app/e2e/pages/login-page.ts +29 -0
  32. package/notes/app/e2e/pages/main-page.ts +29 -0
  33. package/notes/app/e2e/panel-resize-handle.spec.ts +213 -0
  34. package/{notes-app → notes/app}/eslint.config.js +9 -0
  35. package/{notes-app → notes/app}/package.json +0 -3
  36. package/{notes-app → notes/app}/pnpm-workspace.yaml +1 -0
  37. package/notes/app/src/components/CommentPanel.test.tsx +194 -0
  38. package/{notes-app → notes/app}/src/components/CommentPanel.tsx +119 -10
  39. package/notes/app/src/components/CommentSelectionPopover.tsx +26 -0
  40. package/notes/app/src/components/EditToolbar.test.tsx +102 -0
  41. package/{notes-app → notes/app}/src/components/EditToolbar.tsx +5 -54
  42. package/notes/app/src/components/FileInfoPanel.branch-tab.test.tsx +250 -0
  43. package/notes/app/src/components/FileInfoPanel.history-tab.test.tsx +146 -0
  44. package/notes/app/src/components/FileInfoPanel.test.tsx +101 -0
  45. package/{notes-app → notes/app}/src/components/FileInfoPanel.tsx +135 -20
  46. package/notes/app/src/components/IssueCommentThread.test.tsx +93 -0
  47. package/notes/app/src/components/IssueCommentThread.tsx +156 -0
  48. package/notes/app/src/components/IssueDetailView.test.tsx +1118 -0
  49. package/notes/app/src/components/IssueDetailView.tsx +476 -0
  50. package/notes/app/src/components/IssueList.test.tsx +545 -0
  51. package/notes/app/src/components/IssueList.tsx +374 -0
  52. package/{notes-app → notes/app}/src/components/LabelSelector.test.tsx +94 -8
  53. package/notes/app/src/components/LabelSelector.tsx +452 -0
  54. package/{notes-app → notes/app}/src/components/MarkdownEditor.tsx +140 -2
  55. package/notes/app/src/components/PanelResizeHandle.test.tsx +481 -0
  56. package/notes/app/src/components/PanelResizeHandle.tsx +96 -0
  57. package/{notes-app → notes/app}/src/hooks/useEditSession.test.ts +171 -23
  58. package/{notes-app → notes/app}/src/hooks/useEditSession.ts +49 -62
  59. package/notes/app/src/hooks/useMdUpLayout.test.ts +10 -0
  60. package/notes/app/src/hooks/useMdUpLayout.ts +27 -0
  61. package/notes/app/src/hooks/usePeriodicSync.test.ts +244 -0
  62. package/notes/app/src/hooks/usePeriodicSync.ts +83 -0
  63. package/notes/app/src/hooks/useResizablePanelWidth.test.ts +251 -0
  64. package/notes/app/src/hooks/useResizablePanelWidth.ts +167 -0
  65. package/{notes-app → notes/app}/src/lib/api.test.ts +81 -1
  66. package/{notes-app → notes/app}/src/lib/api.ts +98 -4
  67. package/notes/app/src/lib/commentAnchor.test.ts +22 -0
  68. package/notes/app/src/lib/commentAnchor.ts +28 -0
  69. package/notes/app/src/lib/commentHighlight.test.ts +110 -0
  70. package/notes/app/src/lib/commentHighlight.ts +44 -0
  71. package/notes/app/src/lib/github-sync.test.ts +126 -0
  72. package/notes/app/src/lib/github-sync.ts +89 -0
  73. package/notes/app/src/lib/issue-list-utils.test.ts +275 -0
  74. package/notes/app/src/lib/issue-list-utils.ts +135 -0
  75. package/notes/app/src/lib/issue-mobile-layout.test.ts +17 -0
  76. package/notes/app/src/lib/issue-mobile-layout.ts +20 -0
  77. package/notes/app/src/lib/issue-url-sync.test.ts +73 -0
  78. package/notes/app/src/lib/issue-url-sync.ts +43 -0
  79. package/notes/app/src/lib/main-page-default-view.test.ts +37 -0
  80. package/notes/app/src/lib/main-page-default-view.ts +15 -0
  81. package/notes/app/src/lib/resizable-panel.test.ts +199 -0
  82. package/notes/app/src/lib/resizable-panel.ts +136 -0
  83. package/notes/app/src/pages/LoginPage.test.tsx +17 -0
  84. package/notes/app/src/pages/MainPage.branch-modal.test.tsx +226 -0
  85. package/notes/app/src/pages/MainPage.issue-sync.test.tsx +145 -0
  86. package/notes/app/src/pages/MainPage.sidebar.test.tsx +361 -0
  87. package/{notes-app → notes/app}/src/pages/MainPage.tsx +406 -61
  88. package/{notes-app → notes/app}/src/pages/SettingsPage.test.tsx +32 -23
  89. package/{notes-app → notes/app}/src/pages/UserManagementPage.test.tsx +8 -18
  90. package/notes/app/src/test/mocks.ts +156 -0
  91. package/notes/app/src/test/render.tsx +27 -0
  92. package/package.json +3 -5
  93. package/notes-api/tests/test_health.py +0 -11
  94. package/notes-app/docker/Dockerfile.e2e +0 -14
  95. package/notes-app/docker/Dockerfile.prod +0 -12
  96. package/notes-app/docker/Dockerfile.test +0 -12
  97. package/notes-app/e2e/file-tree.spec.ts +0 -29
  98. package/notes-app/e2e/file-view.spec.ts +0 -24
  99. package/notes-app/e2e/login.spec.ts +0 -32
  100. package/notes-app/src/components/IssueDetailView.test.tsx +0 -201
  101. package/notes-app/src/components/IssueDetailView.tsx +0 -318
  102. package/notes-app/src/components/IssueList.test.tsx +0 -93
  103. package/notes-app/src/components/IssueList.tsx +0 -169
  104. package/notes-app/src/components/LabelSelector.tsx +0 -276
  105. package/notes-app/src/pages/LoginPage.test.tsx +0 -29
  106. package/stacks/django-vue.yaml +0 -33
  107. package/stacks/fastapi-react.yaml +0 -160
  108. package/stacks/flutter-firebase.yaml +0 -58
  109. package/stacks/nextjs-prisma.yaml +0 -33
  110. package/stacks/schema.json +0 -144
  111. package/templates/agents/architect.hbs +0 -183
  112. package/templates/agents/auto-documenter.hbs +0 -36
  113. package/templates/agents/backend-developer.hbs +0 -175
  114. package/templates/agents/code-reviewer.hbs +0 -29
  115. package/templates/agents/database-developer.hbs +0 -52
  116. package/templates/agents/debug-specialist.hbs +0 -39
  117. package/templates/agents/environment-setup.hbs +0 -41
  118. package/templates/agents/frontend-developer.hbs +0 -45
  119. package/templates/agents/integration-qa.hbs +0 -26
  120. package/templates/agents/performance-qa.hbs +0 -24
  121. package/templates/agents/pr-writer.hbs +0 -53
  122. package/templates/agents/quality-lead.hbs +0 -26
  123. package/templates/agents/requirements-analyst.hbs +0 -26
  124. package/templates/agents/security-analyst.hbs +0 -21
  125. package/templates/agents/security-reviewer.hbs +0 -20
  126. package/templates/agents/ssot-updater.hbs +0 -45
  127. package/templates/agents/technical-writer.hbs +0 -28
  128. package/templates/agents/unit-test-engineer.hbs +0 -19
  129. package/templates/agents/user-clone.hbs +0 -43
  130. package/templates/github-actions/aws/deploy-notes.yml.hbs +0 -117
  131. package/templates/github-actions/azure/deploy-notes.yml.hbs +0 -78
  132. package/templates/github-actions/gcp/deploy-notes.yml.hbs +0 -76
  133. package/templates/github-actions/vercel-railway/deploy-notes.yml.hbs +0 -49
  134. package/templates/mindsets/agent-stdio.hbs +0 -51
  135. package/templates/mindsets/dart.hbs +0 -39
  136. package/templates/mindsets/ddd-clean-architecture.hbs +0 -52
  137. package/templates/mindsets/electron.hbs +0 -41
  138. package/templates/mindsets/fastapi.hbs +0 -40
  139. package/templates/mindsets/flutter.hbs +0 -56
  140. package/templates/mindsets/kotlin.hbs +0 -46
  141. package/templates/mindsets/postgresql.hbs +0 -39
  142. package/templates/mindsets/python.hbs +0 -39
  143. package/templates/mindsets/react.hbs +0 -51
  144. package/templates/mindsets/swift.hbs +0 -46
  145. package/templates/mindsets/terraform.hbs +0 -53
  146. package/templates/mindsets/typescript.hbs +0 -34
  147. package/templates/mindsets/vite.hbs +0 -37
  148. package/templates/notes-compose.yml +0 -82
  149. package/templates/partials/cogito-geo.hbs +0 -84
  150. package/templates/partials/cogito-godd.hbs +0 -22
  151. package/templates/partials/cogito-grammar.hbs +0 -105
  152. package/templates/partials/cogito-particle.hbs +0 -76
  153. package/templates/partials/cogito-root-ai.hbs +0 -79
  154. package/templates/partials/cogito-root-arch.hbs +0 -75
  155. package/templates/partials/cogito-root-core.hbs +0 -75
  156. package/templates/partials/cogito-root-daily.hbs +0 -58
  157. package/templates/partials/cogito-root-dev.hbs +0 -71
  158. package/templates/partials/cogito-root-devops.hbs +0 -71
  159. package/templates/partials/cogito-root-framework.hbs +0 -80
  160. package/templates/partials/cogito-root-lang.hbs +0 -74
  161. package/templates/partials/godd-core.hbs +0 -50
  162. package/templates/partials/project-context.hbs +0 -52
  163. package/templates/partials/ssot-header.hbs +0 -40
  164. package/templates/partials/ssot-rules.hbs +0 -30
  165. package/templates/prompts/adr.hbs +0 -39
  166. package/templates/prompts/agent-dev-workflow.hbs +0 -34
  167. package/templates/prompts/analyze-report.hbs +0 -36
  168. package/templates/prompts/auto-documentation.hbs +0 -37
  169. package/templates/prompts/check.hbs +0 -52
  170. package/templates/prompts/commit.hbs +0 -96
  171. package/templates/prompts/dev.hbs +0 -127
  172. package/templates/prompts/docs-init.hbs +0 -101
  173. package/templates/prompts/docs-update.hbs +0 -51
  174. package/templates/prompts/git-workflow.hbs +0 -125
  175. package/templates/prompts/impact-analysis.hbs +0 -43
  176. package/templates/prompts/install.hbs +0 -40
  177. package/templates/prompts/new-branch.hbs +0 -61
  178. package/templates/prompts/notes-deploy.hbs +0 -138
  179. package/templates/prompts/pr-analyze.hbs +0 -44
  180. package/templates/prompts/pr-create.hbs +0 -125
  181. package/templates/prompts/push-execute.hbs +0 -83
  182. package/templates/prompts/push.hbs +0 -24
  183. package/templates/prompts/release-notes.hbs +0 -38
  184. package/templates/prompts/requirements-to-business-flow.hbs +0 -29
  185. package/templates/prompts/requirements-to-tickets.hbs +0 -26
  186. package/templates/prompts/review.hbs +0 -126
  187. package/templates/prompts/setup.hbs +0 -247
  188. package/templates/prompts/spec.hbs +0 -35
  189. package/templates/prompts/specification-to-tickets.hbs +0 -24
  190. package/templates/prompts/submit.hbs +0 -143
  191. package/templates/prompts/sync.hbs +0 -63
  192. package/templates/prompts/test-plan.hbs +0 -56
  193. package/templates/scripts/aws/terraform-backend-setup.sh.hbs +0 -149
  194. package/templates/terraform/aws/alb.tf.hbs +0 -58
  195. package/templates/terraform/aws/backend.tf.hbs +0 -10
  196. package/templates/terraform/aws/cloudfront.tf.hbs +0 -96
  197. package/templates/terraform/aws/ecr.tf.hbs +0 -30
  198. package/templates/terraform/aws/ecs.tf.hbs +0 -142
  199. package/templates/terraform/aws/iam.tf.hbs +0 -88
  200. package/templates/terraform/aws/local.tf.hbs +0 -34
  201. package/templates/terraform/aws/output.tf.hbs +0 -49
  202. package/templates/terraform/aws/provider.tf.hbs +0 -26
  203. package/templates/terraform/aws/rds.tf.hbs +0 -38
  204. package/templates/terraform/aws/s3.tf.hbs +0 -34
  205. package/templates/terraform/aws/secrets.tf.hbs +0 -53
  206. package/templates/terraform/aws/security_groups.tf.hbs +0 -81
  207. package/templates/terraform/aws/vpc.tf.hbs +0 -63
  208. package/templates/terraform/azure/backend.tf.hbs +0 -8
  209. package/templates/terraform/azure/iam.tf.hbs +0 -36
  210. package/templates/terraform/azure/main.tf.hbs +0 -203
  211. package/templates/terraform/azure/output.tf.hbs +0 -19
  212. package/templates/terraform/azure/provider.tf.hbs +0 -19
  213. package/templates/terraform/gcp/backend.tf.hbs +0 -6
  214. package/templates/terraform/gcp/iam.tf.hbs +0 -47
  215. package/templates/terraform/gcp/main.tf.hbs +0 -175
  216. package/templates/terraform/gcp/output.tf.hbs +0 -15
  217. package/templates/terraform/gcp/provider.tf.hbs +0 -19
  218. package/templates/terraform/vercel-railway/main.tf.hbs +0 -64
  219. package/templates/terraform/vercel-railway/output.tf.hbs +0 -11
  220. /package/{notes-api → notes/api}/.dockerignore +0 -0
  221. /package/{notes-api → notes/api}/alembic/README +0 -0
  222. /package/{notes-api → notes/api}/alembic/env.py +0 -0
  223. /package/{notes-api → notes/api}/alembic/script.py.mako +0 -0
  224. /package/{notes-api → notes/api}/alembic/versions/001_initial_notes_tables.py +0 -0
  225. /package/{notes-api → notes/api}/alembic/versions/002_add_performance_indexes.py +0 -0
  226. /package/{notes-api → notes/api}/alembic/versions/003_add_yjs_documents.py +0 -0
  227. /package/{notes-api → notes/api}/alembic/versions/004_add_comments.py +0 -0
  228. /package/{notes-api → notes/api}/alembic/versions/005_add_github_username.py +0 -0
  229. /package/{notes-api → notes/api}/alembic/versions/006_add_check_constraints.py +0 -0
  230. /package/{notes-api → notes/api}/alembic.ini +0 -0
  231. /package/{notes-api → notes/api}/app/__init__.py +0 -0
  232. /package/{notes-api → notes/api}/app/config.py +0 -0
  233. /package/{notes-api → notes/api}/app/database.py +0 -0
  234. /package/{notes-api → notes/api}/app/http_client.py +0 -0
  235. /package/{notes-api → notes/api}/app/models/__init__.py +0 -0
  236. /package/{notes-api → notes/api}/app/models/audit.py +0 -0
  237. /package/{notes-api → notes/api}/app/models/base.py +0 -0
  238. /package/{notes-api → notes/api}/app/models/collab.py +0 -0
  239. /package/{notes-api → notes/api}/app/models/comment.py +0 -0
  240. /package/{notes-api → notes/api}/app/models/session.py +0 -0
  241. /package/{notes-api → notes/api}/app/models/setting.py +0 -0
  242. /package/{notes-api → notes/api}/app/models/user.py +0 -0
  243. /package/{notes-api → notes/api}/app/path_validation.py +0 -0
  244. /package/{notes-api → notes/api}/app/routers/__init__.py +0 -0
  245. /package/{notes-api → notes/api}/app/routers/collab.py +0 -0
  246. /package/{notes-api → notes/api}/app/routers/comments.py +0 -0
  247. /package/{notes-api → notes/api}/app/routers/files.py +0 -0
  248. /package/{notes-api → notes/api}/app/routers/settings.py +0 -0
  249. /package/{notes-api → notes/api}/app/routers/tree.py +0 -0
  250. /package/{notes-api → notes/api}/app/routers/upload.py +0 -0
  251. /package/{notes-api → notes/api}/app/routers/users.py +0 -0
  252. /package/{notes-api → notes/api}/app/schemas/__init__.py +0 -0
  253. /package/{notes-api → notes/api}/app/schemas/auth.py +0 -0
  254. /package/{notes-api → notes/api}/app/schemas/user.py +0 -0
  255. /package/{notes-api → notes/api}/app/security.py +0 -0
  256. /package/{notes-api → notes/api}/app/services/__init__.py +0 -0
  257. /package/{notes-api → notes/api}/app/services/audit.py +0 -0
  258. /package/{notes-api → notes/api}/app/services/business_date.py +0 -0
  259. /package/{notes-api → notes/api}/app/services/collab.py +0 -0
  260. /package/{notes-api → notes/api}/app/services/github.py +0 -0
  261. /package/{notes-api → notes/api}/app/services/pr_chain.py +0 -0
  262. /package/{notes-api → notes/api}/app/startup.py +0 -0
  263. /package/{notes-api → notes/api}/docker/Dockerfile +0 -0
  264. /package/{notes-api → notes/api}/docker/Dockerfile.test +0 -0
  265. /package/{notes-api → notes/api}/pyproject.toml +0 -0
  266. /package/{notes-api → notes/api}/tests/conftest.py +0 -0
  267. /package/{notes-api → notes/api}/tests/test_audit.py +0 -0
  268. /package/{notes-api → notes/api}/tests/test_auth.py +0 -0
  269. /package/{notes-api → notes/api}/tests/test_business_date.py +0 -0
  270. /package/{notes-api → notes/api}/tests/test_collab.py +0 -0
  271. /package/{notes-api → notes/api}/tests/test_comments.py +0 -0
  272. /package/{notes-api → notes/api}/tests/test_config_ssl.py +0 -0
  273. /package/{notes-api → notes/api}/tests/test_config_warnings.py +0 -0
  274. /package/{notes-api → notes/api}/tests/test_files.py +0 -0
  275. /package/{notes-api → notes/api}/tests/test_path_validation.py +0 -0
  276. /package/{notes-api → notes/api}/tests/test_security.py +0 -0
  277. /package/{notes-api → notes/api}/tests/test_settings.py +0 -0
  278. /package/{notes-api → notes/api}/tests/test_tree.py +0 -0
  279. /package/{notes-api → notes/api}/tests/test_upload.py +0 -0
  280. /package/{notes-api → notes/api}/tests/test_users.py +0 -0
  281. /package/{notes-app → notes/app}/.dockerignore +0 -0
  282. /package/{notes-app → notes/app}/index.html +0 -0
  283. /package/{notes-app → notes/app}/nginx.conf +0 -0
  284. /package/{notes-app → notes/app}/package-lock.json +0 -0
  285. /package/{notes-app → notes/app}/playwright.config.ts +0 -0
  286. /package/{notes-app → notes/app}/pnpm-lock.yaml +0 -0
  287. /package/{notes-app → notes/app}/src/App.tsx +0 -0
  288. /package/{notes-app → notes/app}/src/components/BranchSelectorModal.tsx +0 -0
  289. /package/{notes-app → notes/app}/src/components/CodeBlockView.test.tsx +0 -0
  290. /package/{notes-app → notes/app}/src/components/CodeBlockView.tsx +0 -0
  291. /package/{notes-app → notes/app}/src/components/CollabStatus.tsx +0 -0
  292. /package/{notes-app → notes/app}/src/components/DiffPreview.tsx +0 -0
  293. /package/{notes-app → notes/app}/src/components/DrawioEditor.tsx +0 -0
  294. /package/{notes-app → notes/app}/src/components/DrawioViewer.tsx +0 -0
  295. /package/{notes-app → notes/app}/src/components/ErrorBoundary.test.tsx +0 -0
  296. /package/{notes-app → notes/app}/src/components/ErrorBoundary.tsx +0 -0
  297. /package/{notes-app → notes/app}/src/components/FileContentView.tsx +0 -0
  298. /package/{notes-app → notes/app}/src/components/FileContextMenu.test.tsx +0 -0
  299. /package/{notes-app → notes/app}/src/components/FileContextMenu.tsx +0 -0
  300. /package/{notes-app → notes/app}/src/components/FileDialogs.test.tsx +0 -0
  301. /package/{notes-app → notes/app}/src/components/FileDialogs.tsx +0 -0
  302. /package/{notes-app → notes/app}/src/components/SaveStatusIndicator.test.tsx +0 -0
  303. /package/{notes-app → notes/app}/src/components/SaveStatusIndicator.tsx +0 -0
  304. /package/{notes-app → notes/app}/src/components/Skeleton.tsx +0 -0
  305. /package/{notes-app → notes/app}/src/components/SpreadsheetEditor.test.tsx +0 -0
  306. /package/{notes-app → notes/app}/src/components/SpreadsheetEditor.tsx +0 -0
  307. /package/{notes-app → notes/app}/src/components/TextEditor.tsx +0 -0
  308. /package/{notes-app → notes/app}/src/components/ToastContainer.tsx +0 -0
  309. /package/{notes-app → notes/app}/src/components/TreeNode.tsx +0 -0
  310. /package/{notes-app → notes/app}/src/contexts/AuthContext.test.tsx +0 -0
  311. /package/{notes-app → notes/app}/src/contexts/AuthContext.tsx +0 -0
  312. /package/{notes-app → notes/app}/src/contexts/ToastContext.test.ts +0 -0
  313. /package/{notes-app → notes/app}/src/contexts/ToastContext.tsx +0 -0
  314. /package/{notes-app → notes/app}/src/hooks/useAutoSave.test.ts +0 -0
  315. /package/{notes-app → notes/app}/src/hooks/useAutoSave.ts +0 -0
  316. /package/{notes-app → notes/app}/src/hooks/useCollaboration.ts +0 -0
  317. /package/{notes-app → notes/app}/src/hooks/useComments.ts +0 -0
  318. /package/{notes-app → notes/app}/src/hooks/useYText.ts +0 -0
  319. /package/{notes-app → notes/app}/src/lib/branch-diff.test.ts +0 -0
  320. /package/{notes-app → notes/app}/src/lib/branch-diff.ts +0 -0
  321. /package/{notes-app → notes/app}/src/lib/created-file.test.ts +0 -0
  322. /package/{notes-app → notes/app}/src/lib/created-file.ts +0 -0
  323. /package/{notes-app → notes/app}/src/lib/csv-utils.test.ts +0 -0
  324. /package/{notes-app → notes/app}/src/lib/csv-utils.ts +0 -0
  325. /package/{notes-app → notes/app}/src/lib/deepLinkPathToSearch.test.ts +0 -0
  326. /package/{notes-app → notes/app}/src/lib/deepLinkPathToSearch.ts +0 -0
  327. /package/{notes-app → notes/app}/src/lib/draft-storage.test.ts +0 -0
  328. /package/{notes-app → notes/app}/src/lib/draft-storage.ts +0 -0
  329. /package/{notes-app → notes/app}/src/lib/mermaid-render.ts +0 -0
  330. /package/{notes-app → notes/app}/src/lib/postLoginRedirect.test.ts +0 -0
  331. /package/{notes-app → notes/app}/src/lib/postLoginRedirect.ts +0 -0
  332. /package/{notes-app → notes/app}/src/lib/tree-utils.ts +0 -0
  333. /package/{notes-app → notes/app}/src/lib/user-colors.ts +0 -0
  334. /package/{notes-app → notes/app}/src/lib/xlsx-utils.test.ts +0 -0
  335. /package/{notes-app → notes/app}/src/lib/xlsx-utils.ts +0 -0
  336. /package/{notes-app → notes/app}/src/main.tsx +0 -0
  337. /package/{notes-app → notes/app}/src/pages/LoginPage.tsx +0 -0
  338. /package/{notes-app → notes/app}/src/pages/MainPage.insertChildEntry.test.ts +0 -0
  339. /package/{notes-app → notes/app}/src/pages/SettingsPage.tsx +0 -0
  340. /package/{notes-app → notes/app}/src/pages/UserManagementPage.tsx +0 -0
  341. /package/{notes-app → notes/app}/src/styles/globals.css +0 -0
  342. /package/{notes-app → notes/app}/src/types.ts +0 -0
  343. /package/{notes-app → notes/app}/src/vite-env.d.ts +0 -0
  344. /package/{notes-app → notes/app}/tsconfig.json +0 -0
  345. /package/{notes-app → notes/app}/tsconfig.node.json +0 -0
  346. /package/{notes-app → notes/app}/vite.config.js +0 -0
  347. /package/{notes-app → notes/app}/vite.config.ts +0 -0
  348. /package/{notes-app → notes/app}/vitest.config.ts +0 -0
@@ -1,13 +1,19 @@
1
1
  import { useState, useRef } from "react";
2
- import { X, RefreshCw, Send, Trash2, CheckCircle, ChevronDown, ChevronRight, Reply } from "lucide-react";
2
+ import { X, RefreshCw, Send, Trash2, CheckCircle, ChevronDown, ChevronRight, Reply, Pencil, MessageSquare } from "lucide-react";
3
3
  import type { UseCommentsReturn, Comment } from "@/hooks/useComments";
4
+ import type { CommentAnchor } from "@/lib/commentAnchor";
4
5
  import type { UserInfo } from "@/lib/api";
6
+ import PanelResizeHandle from "@/components/PanelResizeHandle";
7
+ import { RESIZABLE_RIGHT_PANEL_ASIDE_CLASS, type PanelResizeProps } from "@/lib/resizable-panel";
5
8
 
6
9
  type Props = {
7
10
  filePath: string;
8
11
  currentUser: UserInfo | null;
9
12
  comments: UseCommentsReturn;
13
+ pendingAnchor: CommentAnchor | null;
14
+ onClearAnchor: () => void;
10
15
  onClose: () => void;
16
+ panelResize?: PanelResizeProps;
11
17
  };
12
18
 
13
19
  function formatDate(iso: string): string {
@@ -25,6 +31,7 @@ type CommentItemProps = {
25
31
  currentUser: UserInfo | null;
26
32
  onResolve: (id: string) => Promise<boolean>;
27
33
  onDelete: (id: string) => Promise<boolean>;
34
+ onEdit: (id: string, body: string) => Promise<boolean>;
28
35
  onReply: (parentId: string, parentText: string) => void;
29
36
  replies: Comment[];
30
37
  };
@@ -34,10 +41,14 @@ function CommentItem({
34
41
  currentUser,
35
42
  onResolve,
36
43
  onDelete,
44
+ onEdit,
37
45
  onReply,
38
46
  replies,
39
47
  }: CommentItemProps) {
40
48
  const [expanded, setExpanded] = useState(true);
49
+ const [editing, setEditing] = useState(false);
50
+ const [editBody, setEditBody] = useState(comment.body);
51
+ const [savingEdit, setSavingEdit] = useState(false);
41
52
  const isResolved = comment.resolved_at !== null;
42
53
  const isAuthor = currentUser?.id === comment.author_id;
43
54
  const isAdmin = currentUser?.role === "admin";
@@ -92,13 +103,49 @@ function CommentItem({
92
103
  </div>
93
104
 
94
105
  {/* Body */}
95
- <p className="px-2.5 pb-2 text-gray-200 whitespace-pre-wrap break-words">
96
- {comment.body}
97
- </p>
106
+ {editing ? (
107
+ <div className="px-2.5 pb-2 space-y-1">
108
+ <textarea
109
+ value={editBody}
110
+ onChange={(e) => setEditBody(e.target.value)}
111
+ rows={3}
112
+ className="w-full resize-none rounded bg-gray-900 border border-gray-600 text-xs text-gray-200 px-2 py-1.5 outline-none focus:border-blue-500"
113
+ />
114
+ <div className="flex justify-end gap-1">
115
+ <button
116
+ type="button"
117
+ onClick={() => {
118
+ setEditing(false);
119
+ setEditBody(comment.body);
120
+ }}
121
+ className="px-2 py-0.5 rounded text-xs text-gray-400 hover:text-gray-200"
122
+ >
123
+ キャンセル
124
+ </button>
125
+ <button
126
+ type="button"
127
+ disabled={!editBody.trim() || savingEdit}
128
+ onClick={async () => {
129
+ setSavingEdit(true);
130
+ const ok = await onEdit(comment.id, editBody.trim());
131
+ setSavingEdit(false);
132
+ if (ok) setEditing(false);
133
+ }}
134
+ className="px-2 py-0.5 rounded text-xs bg-blue-600 hover:bg-blue-700 text-white disabled:opacity-40"
135
+ >
136
+ {savingEdit ? "保存中…" : "保存"}
137
+ </button>
138
+ </div>
139
+ </div>
140
+ ) : (
141
+ <p className="px-2.5 pb-2 text-gray-200 whitespace-pre-wrap break-words">
142
+ {comment.body}
143
+ </p>
144
+ )}
98
145
 
99
146
  {/* Actions */}
100
147
  <div className="flex items-center gap-2 px-2.5 pb-2 text-gray-500">
101
- {!isResolved && (
148
+ {!isResolved && !editing && (
102
149
  <button
103
150
  type="button"
104
151
  onClick={() => onReply(comment.id, comment.anchor_text ?? comment.body)}
@@ -109,7 +156,21 @@ function CommentItem({
109
156
  返信
110
157
  </button>
111
158
  )}
112
- {!isResolved && canManage && (
159
+ {!isResolved && canManage && !editing && (
160
+ <button
161
+ type="button"
162
+ onClick={() => {
163
+ setEditBody(comment.body);
164
+ setEditing(true);
165
+ }}
166
+ className="flex items-center gap-0.5 hover:text-blue-400 transition-colors"
167
+ title="編集"
168
+ >
169
+ <Pencil className="w-3 h-3" />
170
+ 編集
171
+ </button>
172
+ )}
173
+ {!isResolved && canManage && !editing && (
113
174
  <button
114
175
  type="button"
115
176
  onClick={() => onResolve(comment.id)}
@@ -120,7 +181,7 @@ function CommentItem({
120
181
  解決
121
182
  </button>
122
183
  )}
123
- {canManage && (
184
+ {canManage && !editing && (
124
185
  <button
125
186
  type="button"
126
187
  onClick={() => onDelete(comment.id)}
@@ -162,7 +223,15 @@ function CommentItem({
162
223
  );
163
224
  }
164
225
 
165
- export default function CommentPanel({ filePath, currentUser, comments, onClose }: Props) {
226
+ export default function CommentPanel({
227
+ filePath,
228
+ currentUser,
229
+ comments,
230
+ pendingAnchor,
231
+ onClearAnchor,
232
+ onClose,
233
+ panelResize,
234
+ }: Props) {
166
235
  const {
167
236
  comments: allComments,
168
237
  loading,
@@ -171,6 +240,7 @@ export default function CommentPanel({ filePath, currentUser, comments, onClose
171
240
  reload,
172
241
  setIncludeResolved,
173
242
  addComment,
243
+ editComment,
174
244
  resolveComment,
175
245
  removeComment,
176
246
  } = comments;
@@ -191,12 +261,21 @@ export default function CommentPanel({ filePath, currentUser, comments, onClose
191
261
  const result = await addComment({
192
262
  file_path: filePath,
193
263
  body,
194
- ...(replyTo ? { parent_id: replyTo.id } : {}),
264
+ ...(replyTo
265
+ ? { parent_id: replyTo.id }
266
+ : pendingAnchor
267
+ ? {
268
+ anchor_text: pendingAnchor.anchor_text,
269
+ position_from: pendingAnchor.position_from,
270
+ position_to: pendingAnchor.position_to,
271
+ }
272
+ : {}),
195
273
  });
196
274
  setSubmitting(false);
197
275
  if (result) {
198
276
  setNewBody("");
199
277
  setReplyTo(null);
278
+ onClearAnchor();
200
279
  }
201
280
  };
202
281
 
@@ -208,6 +287,7 @@ export default function CommentPanel({ filePath, currentUser, comments, onClose
208
287
  };
209
288
 
210
289
  const handleReply = (parentId: string, parentText: string) => {
290
+ onClearAnchor();
211
291
  setReplyTo({ id: parentId, preview: parentText });
212
292
  textareaRef.current?.focus();
213
293
  };
@@ -215,7 +295,21 @@ export default function CommentPanel({ filePath, currentUser, comments, onClose
215
295
  const canPost = currentUser?.role !== "viewer";
216
296
 
217
297
  return (
218
- <aside className="absolute inset-0 md:static md:w-80 z-20 border-l border-gray-700 bg-gray-800 flex flex-col shrink-0">
298
+ <aside
299
+ className={RESIZABLE_RIGHT_PANEL_ASIDE_CLASS}
300
+ style={panelResize != null ? { width: panelResize.width } : undefined}
301
+ >
302
+ {panelResize && panelResize.showResizeHandle !== false && (
303
+ <PanelResizeHandle
304
+ edge="inline-start"
305
+ onPointerDown={panelResize.onPointerDown}
306
+ width={panelResize.width}
307
+ minWidth={panelResize.minWidth}
308
+ maxWidth={panelResize.maxWidth}
309
+ onWidthChange={panelResize.onWidthChange}
310
+ ariaLabel="コメントパネルの幅を変更"
311
+ />
312
+ )}
219
313
  {/* Panel header */}
220
314
  <div className="flex items-center justify-between px-3 py-2 border-b border-gray-700 shrink-0">
221
315
  <h3 className="text-sm font-semibold text-gray-300">
@@ -275,6 +369,7 @@ export default function CommentPanel({ filePath, currentUser, comments, onClose
275
369
  currentUser={currentUser}
276
370
  onResolve={resolveComment}
277
371
  onDelete={removeComment}
372
+ onEdit={editComment}
278
373
  onReply={handleReply}
279
374
  replies={repliesFor(comment.id)}
280
375
  />
@@ -284,6 +379,20 @@ export default function CommentPanel({ filePath, currentUser, comments, onClose
284
379
  {/* New comment form */}
285
380
  {canPost && (
286
381
  <div className="border-t border-gray-700 p-2 shrink-0">
382
+ {pendingAnchor && !replyTo && (
383
+ <div className="mb-1.5 flex items-start gap-1 text-xs text-gray-400 bg-yellow-500/10 border border-yellow-500/30 rounded px-2 py-1">
384
+ <MessageSquare className="w-3 h-3 mt-0.5 shrink-0 text-yellow-400" />
385
+ <span className="flex-1 truncate">{pendingAnchor.anchor_text}</span>
386
+ <button
387
+ type="button"
388
+ onClick={onClearAnchor}
389
+ className="text-gray-500 hover:text-gray-300 shrink-0"
390
+ aria-label="アンカーを解除"
391
+ >
392
+ <X className="w-3 h-3" />
393
+ </button>
394
+ </div>
395
+ )}
287
396
  {replyTo && (
288
397
  <div className="mb-1.5 flex items-start gap-1 text-xs text-gray-400 bg-gray-700/50 rounded px-2 py-1">
289
398
  <Reply className="w-3 h-3 mt-0.5 shrink-0" />
@@ -0,0 +1,26 @@
1
+ import { MessageSquare } from "lucide-react";
2
+
3
+ type Props = {
4
+ top: number;
5
+ left: number;
6
+ onAddComment: () => void;
7
+ };
8
+
9
+ export default function CommentSelectionPopover({ top, left, onAddComment }: Props) {
10
+ return (
11
+ <div
12
+ className="fixed z-50 -translate-x-1/2 -translate-y-full"
13
+ style={{ top, left }}
14
+ >
15
+ <button
16
+ type="button"
17
+ onMouseDown={(e) => e.preventDefault()}
18
+ onClick={onAddComment}
19
+ className="flex items-center gap-1 rounded border border-gray-600 bg-gray-800 px-2 py-1 text-xs text-gray-100 shadow-lg hover:bg-gray-700 transition-colors"
20
+ >
21
+ <MessageSquare className="w-3.5 h-3.5" />
22
+ コメント
23
+ </button>
24
+ </div>
25
+ );
26
+ }
@@ -0,0 +1,102 @@
1
+ import { describe, it, expect, vi } from "vitest";
2
+ import { render, screen, fireEvent, act } from "@testing-library/react";
3
+ import EditToolbar from "./EditToolbar";
4
+ import type { EditSession } from "@/hooks/useEditSession";
5
+
6
+ const BASE_SESSION: EditSession = {
7
+ branchName: "edit/user-20260329",
8
+ prNumber: 42,
9
+ prUrl: "https://github.com/org/repo/pull/42",
10
+ prGithub: null,
11
+ commitCount: 3,
12
+ businessDate: "2026-03-29",
13
+ status: "active",
14
+ changedFiles: ["docs/README.md"],
15
+ };
16
+
17
+ const defaultProps = {
18
+ saving: false,
19
+ error: null,
20
+ canEdit: true,
21
+ onCreatePr: vi.fn(async () => null),
22
+ onClearError: vi.fn(),
23
+ };
24
+
25
+ describe("EditToolbar", () => {
26
+ it("session の prNumber / prUrl を PR リンクに表示する", () => {
27
+ render(<EditToolbar session={BASE_SESSION} {...defaultProps} />);
28
+ const link = screen.getByRole("link", { name: /PR #42/i });
29
+ expect(link.getAttribute("href")).toBe(BASE_SESSION.prUrl);
30
+ });
31
+
32
+ it("session 更新時に PR 番号と URL が即座に追従する(リロード不要)", () => {
33
+ const { rerender } = render(
34
+ <EditToolbar session={BASE_SESSION} {...defaultProps} />,
35
+ );
36
+ expect(screen.getByRole("link", { name: /PR #42/i })).toBeTruthy();
37
+
38
+ const updated: EditSession = {
39
+ ...BASE_SESSION,
40
+ prNumber: 99,
41
+ prUrl: "https://github.com/org/repo/pull/99",
42
+ };
43
+ rerender(<EditToolbar session={updated} {...defaultProps} />);
44
+
45
+ const link = screen.getByRole("link", { name: /PR #99/i });
46
+ expect(link.getAttribute("href")).toBe(updated.prUrl);
47
+ expect(screen.queryByRole("link", { name: /PR #42/i })).toBeNull();
48
+ });
49
+
50
+ it("session が null のとき PR リンクを表示しない", () => {
51
+ render(<EditToolbar session={null} {...defaultProps} />);
52
+ expect(screen.queryByRole("link", { name: /PR #/i })).toBeNull();
53
+ });
54
+
55
+ it("prNumber が null のとき PR リンクを表示しない", () => {
56
+ render(
57
+ <EditToolbar
58
+ session={{ ...BASE_SESSION, prNumber: null, prUrl: null }}
59
+ {...defaultProps}
60
+ />,
61
+ );
62
+ expect(screen.queryByRole("link", { name: /PR #/i })).toBeNull();
63
+ });
64
+
65
+ it("コミットあり・PR 未作成時に PR 作成ボタンを表示する", () => {
66
+ render(
67
+ <EditToolbar
68
+ session={{ ...BASE_SESSION, prNumber: null, prUrl: null }}
69
+ {...defaultProps}
70
+ />,
71
+ );
72
+ expect(screen.getByRole("button", { name: /PR 作成/i })).toBeTruthy();
73
+ });
74
+
75
+ it("PR 作成後は onCreatePr のみ呼び出し、session 更新でリンクが表示される", async () => {
76
+ const onCreatePr = vi.fn(async () => "https://github.com/org/repo/pull/1");
77
+ const sessionNoPr: EditSession = {
78
+ ...BASE_SESSION,
79
+ prNumber: null,
80
+ prUrl: null,
81
+ };
82
+ const sessionWithPr: EditSession = {
83
+ ...BASE_SESSION,
84
+ prNumber: 1,
85
+ prUrl: "https://github.com/org/repo/pull/1",
86
+ };
87
+
88
+ const { rerender } = render(
89
+ <EditToolbar session={sessionNoPr} {...defaultProps} onCreatePr={onCreatePr} />,
90
+ );
91
+
92
+ await act(async () => {
93
+ fireEvent.click(screen.getByRole("button", { name: /PR 作成/i }));
94
+ });
95
+ expect(onCreatePr).toHaveBeenCalledOnce();
96
+
97
+ rerender(
98
+ <EditToolbar session={sessionWithPr} {...defaultProps} onCreatePr={onCreatePr} />,
99
+ );
100
+ expect(screen.getByRole("link", { name: /PR #1/i })).toBeTruthy();
101
+ });
102
+ });
@@ -1,5 +1,5 @@
1
1
  import { useState } from "react";
2
- import { GitPullRequest, GitBranch, Trash2, ExternalLink, AlertCircle, Loader2, Send, BookOpen } from "lucide-react";
2
+ import { GitPullRequest, GitBranch, ExternalLink, AlertCircle, Loader2 } from "lucide-react";
3
3
  import type { EditSession } from "@/hooks/useEditSession";
4
4
 
5
5
  type Props = {
@@ -8,9 +8,6 @@ type Props = {
8
8
  error: string | null;
9
9
  canEdit: boolean;
10
10
  onCreatePr: () => Promise<string | null>;
11
- onSubmitPr: () => Promise<boolean>;
12
- onConvertToDraft: () => Promise<boolean>;
13
- onDiscardChanges: () => Promise<boolean>;
14
11
  onClearError: () => void;
15
12
  };
16
13
 
@@ -36,13 +33,9 @@ export default function EditToolbar({
36
33
  error,
37
34
  canEdit,
38
35
  onCreatePr,
39
- onSubmitPr,
40
- onConvertToDraft,
41
- onDiscardChanges,
42
36
  onClearError,
43
37
  }: Props) {
44
38
  const [actionState, setActionState] = useState<ActionState>("idle");
45
- const [prUrl, setPrUrl] = useState<string | null>(session?.prUrl ?? null);
46
39
  const busy = saving || actionState === "busy";
47
40
 
48
41
  const run = async (fn: () => Promise<unknown>) => {
@@ -56,16 +49,13 @@ export default function EditToolbar({
56
49
  };
57
50
 
58
51
  const handleCreatePr = async () => {
59
- const url = await onCreatePr();
60
- if (url) setPrUrl(url);
52
+ await onCreatePr();
61
53
  setActionState("idle");
62
54
  };
63
55
 
64
56
  const prNumber = session?.prNumber ?? null;
65
- const effectivePrUrl = prUrl ?? session?.prUrl ?? null;
57
+ const prUrl = session?.prUrl ?? null;
66
58
  const hasCommits = (session?.commitCount ?? 0) > 0;
67
- const isDraft = session?.status === "draft";
68
- const isSubmitted = session?.status === "submitted";
69
59
 
70
60
  if (!canEdit || !session) return null;
71
61
 
@@ -101,9 +91,9 @@ export default function EditToolbar({
101
91
  )}
102
92
 
103
93
  {/* PR link */}
104
- {effectivePrUrl && (
94
+ {prUrl && prNumber != null && (
105
95
  <a
106
- href={effectivePrUrl}
96
+ href={prUrl}
107
97
  target="_blank"
108
98
  rel="noopener noreferrer"
109
99
  className="flex items-center gap-1 text-blue-400 hover:text-blue-300 transition-colors"
@@ -129,45 +119,6 @@ export default function EditToolbar({
129
119
  PR 作成
130
120
  </button>
131
121
  )}
132
-
133
- {prNumber && !isSubmitted && !isDraft && !busy && (
134
- <button
135
- type="button"
136
- onClick={() => void run(onConvertToDraft)}
137
- className="flex items-center gap-1 px-2 py-0.5 rounded text-yellow-400 hover:bg-yellow-900/30 border border-yellow-700/40 transition-colors"
138
- title="PR をドラフトに変更する"
139
- >
140
- <BookOpen className="w-3 h-3" />
141
- ドラフト
142
- </button>
143
- )}
144
-
145
- {prNumber && !isSubmitted && !busy && (
146
- <button
147
- type="button"
148
- onClick={() => void run(onSubmitPr)}
149
- className="flex items-center gap-1 px-2 py-0.5 rounded bg-blue-600 hover:bg-blue-500 text-white transition-colors"
150
- title="PR を提出する(マージ可能状態にする)"
151
- >
152
- <Send className="w-3 h-3" />
153
- 提出
154
- </button>
155
- )}
156
-
157
- {hasCommits && !busy && (
158
- <button
159
- type="button"
160
- onClick={() => {
161
- if (!window.confirm("変更をすべて破棄しますか?ブランチとセッションが削除されます。")) return;
162
- void run(onDiscardChanges);
163
- }}
164
- className="flex items-center gap-1 px-2 py-0.5 rounded text-red-400 hover:bg-red-900/30 border border-red-700/40 transition-colors"
165
- title="変更を破棄してブランチを削除する"
166
- >
167
- <Trash2 className="w-3 h-3" />
168
- 破棄
169
- </button>
170
- )}
171
122
  </div>
172
123
  );
173
124
  }