create-einja-app 0.1.1

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 (235) hide show
  1. package/README.md +307 -0
  2. package/dist/cli.d.ts +2 -0
  3. package/dist/cli.js +1041 -0
  4. package/dist/cli.js.map +1 -0
  5. package/package.json +62 -0
  6. package/templates/turborepo-pandacss/.biomeignore +15 -0
  7. package/templates/turborepo-pandacss/.claude/hooks/einja/biome-format.sh +49 -0
  8. package/templates/turborepo-pandacss/.claude/hooks/einja/design-doc-check.sh +61 -0
  9. package/templates/turborepo-pandacss/.claude/hooks/einja/detect-secrets.sh +62 -0
  10. package/templates/turborepo-pandacss/.claude/hooks/einja/large-file-warning.sh +42 -0
  11. package/templates/turborepo-pandacss/.claude/hooks/einja/playwright-resize.sh +36 -0
  12. package/templates/turborepo-pandacss/.claude/hooks/einja/typecheck.sh +37 -0
  13. package/templates/turborepo-pandacss/.claude/hooks/einja/unset-volta-recursion.sh +32 -0
  14. package/templates/turborepo-pandacss/.claude/hooks/einja/validate-git-commit.sh +239 -0
  15. package/templates/turborepo-pandacss/.claude/hooks/einja/warn-index-ts.sh +34 -0
  16. package/templates/turborepo-pandacss/.claude/hooks/einja/warn-relative-import.sh +48 -0
  17. package/templates/turborepo-pandacss/.claude/settings.json +174 -0
  18. package/templates/turborepo-pandacss/.claude/skills/create-einja-app-release/SKILL.md +186 -0
  19. package/templates/turborepo-pandacss/.claude/skills/dev-cli-release/SKILL.md +173 -0
  20. package/templates/turborepo-pandacss/.cursor/commands/spec-create.md +227 -0
  21. package/templates/turborepo-pandacss/.cursor/commands/start-dev.md +98 -0
  22. package/templates/turborepo-pandacss/.cursor/commands/task-exec.md +287 -0
  23. package/templates/turborepo-pandacss/.cursor/commands/task-vibe-kanban-loop.md +532 -0
  24. package/templates/turborepo-pandacss/.cursor/commands/update-docs-by-task-specs.md +448 -0
  25. package/templates/turborepo-pandacss/.cursor/mcp.json +45 -0
  26. package/templates/turborepo-pandacss/.cursor/rules/api-rules.mdc +171 -0
  27. package/templates/turborepo-pandacss/.cursor/rules/api-test-rules.mdc +181 -0
  28. package/templates/turborepo-pandacss/.cursor/rules/base-code.mdc +70 -0
  29. package/templates/turborepo-pandacss/.cursor/rules/base-commit-rules.mdc +174 -0
  30. package/templates/turborepo-pandacss/.cursor/rules/base-design.mdc +12 -0
  31. package/templates/turborepo-pandacss/.cursor/rules/base-rules.mdc +231 -0
  32. package/templates/turborepo-pandacss/.cursor/rules/error-handling-rules.mdc +188 -0
  33. package/templates/turborepo-pandacss/.cursor/rules/refactor-rules.mdc +93 -0
  34. package/templates/turborepo-pandacss/.dockerignore +126 -0
  35. package/templates/turborepo-pandacss/.einja-sync.json +35 -0
  36. package/templates/turborepo-pandacss/.env.ci +25 -0
  37. package/templates/turborepo-pandacss/.env.example +35 -0
  38. package/templates/turborepo-pandacss/.env.personal.example +27 -0
  39. package/templates/turborepo-pandacss/.envrc +4 -0
  40. package/templates/turborepo-pandacss/.gitattributes +5 -0
  41. package/templates/turborepo-pandacss/.husky/pre-commit +1 -0
  42. package/templates/turborepo-pandacss/.lintstagedrc.js +24 -0
  43. package/templates/turborepo-pandacss/.mcp.json +45 -0
  44. package/templates/turborepo-pandacss/.node-version +1 -0
  45. package/templates/turborepo-pandacss/.templateignore +60 -0
  46. package/templates/turborepo-pandacss/.vscode/extensions.json +3 -0
  47. package/templates/turborepo-pandacss/CLAUDE.md +415 -0
  48. package/templates/turborepo-pandacss/README.md +322 -0
  49. package/templates/turborepo-pandacss/apps/web/middleware.ts +28 -0
  50. package/templates/turborepo-pandacss/apps/web/next.config.ts +10 -0
  51. package/templates/turborepo-pandacss/apps/web/package.json +80 -0
  52. package/templates/turborepo-pandacss/apps/web/panda.config.ts +114 -0
  53. package/templates/turborepo-pandacss/apps/web/postcss.config.cjs +6 -0
  54. package/templates/turborepo-pandacss/apps/web/public/file.svg +1 -0
  55. package/templates/turborepo-pandacss/apps/web/public/globe.svg +1 -0
  56. package/templates/turborepo-pandacss/apps/web/public/next.svg +1 -0
  57. package/templates/turborepo-pandacss/apps/web/public/vercel.svg +1 -0
  58. package/templates/turborepo-pandacss/apps/web/public/window.svg +1 -0
  59. package/templates/turborepo-pandacss/apps/web/src/app/(authenticated)/dashboard/page.tsx +79 -0
  60. package/templates/turborepo-pandacss/apps/web/src/app/(authenticated)/data/_components/UserTable.tsx +203 -0
  61. package/templates/turborepo-pandacss/apps/web/src/app/(authenticated)/data/page.tsx +57 -0
  62. package/templates/turborepo-pandacss/apps/web/src/app/(authenticated)/layout-client.tsx +31 -0
  63. package/templates/turborepo-pandacss/apps/web/src/app/(authenticated)/layout.tsx +17 -0
  64. package/templates/turborepo-pandacss/apps/web/src/app/(authenticated)/profile/page.tsx +59 -0
  65. package/templates/turborepo-pandacss/apps/web/src/app/api/auth/[...nextauth]/route.ts +3 -0
  66. package/templates/turborepo-pandacss/apps/web/src/app/api/auth/signup/route.ts +70 -0
  67. package/templates/turborepo-pandacss/apps/web/src/app/error.tsx +106 -0
  68. package/templates/turborepo-pandacss/apps/web/src/app/favicon.ico +0 -0
  69. package/templates/turborepo-pandacss/apps/web/src/app/global-error.tsx +110 -0
  70. package/templates/turborepo-pandacss/apps/web/src/app/globals.css +121 -0
  71. package/templates/turborepo-pandacss/apps/web/src/app/layout.tsx +28 -0
  72. package/templates/turborepo-pandacss/apps/web/src/app/not-found.tsx +54 -0
  73. package/templates/turborepo-pandacss/apps/web/src/app/page.module.css +165 -0
  74. package/templates/turborepo-pandacss/apps/web/src/app/page.test.tsx +52 -0
  75. package/templates/turborepo-pandacss/apps/web/src/app/page.tsx +284 -0
  76. package/templates/turborepo-pandacss/apps/web/src/app/signin/page.tsx +296 -0
  77. package/templates/turborepo-pandacss/apps/web/src/app/signup/page.tsx +395 -0
  78. package/templates/turborepo-pandacss/apps/web/src/application/use-cases/UserUseCases.test.ts +229 -0
  79. package/templates/turborepo-pandacss/apps/web/src/application/use-cases/UserUseCases.ts +115 -0
  80. package/templates/turborepo-pandacss/apps/web/src/components/auth/login-button.tsx +35 -0
  81. package/templates/turborepo-pandacss/apps/web/src/components/auth/logout-button.tsx +24 -0
  82. package/templates/turborepo-pandacss/apps/web/src/components/auth/user-avatar.test.tsx +68 -0
  83. package/templates/turborepo-pandacss/apps/web/src/components/auth/user-avatar.tsx +43 -0
  84. package/templates/turborepo-pandacss/apps/web/src/components/dashboard/dashboard-stats.tsx +128 -0
  85. package/templates/turborepo-pandacss/apps/web/src/components/providers/query-provider.tsx +30 -0
  86. package/templates/turborepo-pandacss/apps/web/src/components/providers/session-provider.tsx +12 -0
  87. package/templates/turborepo-pandacss/apps/web/src/components/shared/Sidebar.tsx +175 -0
  88. package/templates/turborepo-pandacss/apps/web/src/components/shared/header.tsx +166 -0
  89. package/templates/turborepo-pandacss/apps/web/src/components/ui/accordion.tsx +64 -0
  90. package/templates/turborepo-pandacss/apps/web/src/components/ui/alert-dialog.tsx +135 -0
  91. package/templates/turborepo-pandacss/apps/web/src/components/ui/alert.tsx +60 -0
  92. package/templates/turborepo-pandacss/apps/web/src/components/ui/aspect-ratio.tsx +9 -0
  93. package/templates/turborepo-pandacss/apps/web/src/components/ui/avatar.tsx +41 -0
  94. package/templates/turborepo-pandacss/apps/web/src/components/ui/badge.tsx +39 -0
  95. package/templates/turborepo-pandacss/apps/web/src/components/ui/breadcrumb.tsx +101 -0
  96. package/templates/turborepo-pandacss/apps/web/src/components/ui/button.tsx +56 -0
  97. package/templates/turborepo-pandacss/apps/web/src/components/ui/card.tsx +75 -0
  98. package/templates/turborepo-pandacss/apps/web/src/components/ui/checkbox.tsx +29 -0
  99. package/templates/turborepo-pandacss/apps/web/src/components/ui/data-table.tsx +189 -0
  100. package/templates/turborepo-pandacss/apps/web/src/components/ui/dialog-hook.tsx +210 -0
  101. package/templates/turborepo-pandacss/apps/web/src/components/ui/dialog.tsx +129 -0
  102. package/templates/turborepo-pandacss/apps/web/src/components/ui/drawer.tsx +124 -0
  103. package/templates/turborepo-pandacss/apps/web/src/components/ui/dropdown-menu.tsx +228 -0
  104. package/templates/turborepo-pandacss/apps/web/src/components/ui/form.tsx +152 -0
  105. package/templates/turborepo-pandacss/apps/web/src/components/ui/hover-card.tsx +38 -0
  106. package/templates/turborepo-pandacss/apps/web/src/components/ui/input.tsx +21 -0
  107. package/templates/turborepo-pandacss/apps/web/src/components/ui/label.tsx +21 -0
  108. package/templates/turborepo-pandacss/apps/web/src/components/ui/pagination.tsx +105 -0
  109. package/templates/turborepo-pandacss/apps/web/src/components/ui/popover.tsx +42 -0
  110. package/templates/turborepo-pandacss/apps/web/src/components/ui/progress.tsx +28 -0
  111. package/templates/turborepo-pandacss/apps/web/src/components/ui/select.tsx +170 -0
  112. package/templates/turborepo-pandacss/apps/web/src/components/ui/separator.tsx +28 -0
  113. package/templates/turborepo-pandacss/apps/web/src/components/ui/skeleton.tsx +13 -0
  114. package/templates/turborepo-pandacss/apps/web/src/components/ui/sonner.tsx +25 -0
  115. package/templates/turborepo-pandacss/apps/web/src/components/ui/table.tsx +92 -0
  116. package/templates/turborepo-pandacss/apps/web/src/components/ui/tabs.tsx +54 -0
  117. package/templates/turborepo-pandacss/apps/web/src/components/ui/textarea.tsx +18 -0
  118. package/templates/turborepo-pandacss/apps/web/src/components/ui/tooltip.tsx +57 -0
  119. package/templates/turborepo-pandacss/apps/web/src/components/ui/typography.tsx +158 -0
  120. package/templates/turborepo-pandacss/apps/web/src/lib/auth/guard.ts +36 -0
  121. package/templates/turborepo-pandacss/apps/web/src/lib/auth/index.ts +22 -0
  122. package/templates/turborepo-pandacss/apps/web/src/lib/prisma.ts +3 -0
  123. package/templates/turborepo-pandacss/apps/web/src/lib/utils.ts +6 -0
  124. package/templates/turborepo-pandacss/apps/web/test/globals.d.ts +1 -0
  125. package/templates/turborepo-pandacss/apps/web/test/matchers.d.ts +1 -0
  126. package/templates/turborepo-pandacss/apps/web/test/setup.ts +22 -0
  127. package/templates/turborepo-pandacss/apps/web/tsconfig.json +37 -0
  128. package/templates/turborepo-pandacss/apps/web/vitest.config.ts +20 -0
  129. package/templates/turborepo-pandacss/apps/web/vitest.d.ts +2 -0
  130. package/templates/turborepo-pandacss/biome.json +60 -0
  131. package/templates/turborepo-pandacss/components.json +21 -0
  132. package/templates/turborepo-pandacss/docker-compose.yml +27 -0
  133. package/templates/turborepo-pandacss/middleware.ts +32 -0
  134. package/templates/turborepo-pandacss/next.config.ts +10 -0
  135. package/templates/turborepo-pandacss/package-lock.json +9346 -0
  136. package/templates/turborepo-pandacss/package.json +64 -0
  137. package/templates/turborepo-pandacss/packages/config/package.json +41 -0
  138. package/templates/turborepo-pandacss/packages/config/panda.config.ts +114 -0
  139. package/templates/turborepo-pandacss/packages/config/src/index.ts +24 -0
  140. package/templates/turborepo-pandacss/packages/config/src/worktree-config-loader.ts +129 -0
  141. package/templates/turborepo-pandacss/packages/config/src/worktree-config.ts +75 -0
  142. package/templates/turborepo-pandacss/packages/config/tsconfig.build.json +19 -0
  143. package/templates/turborepo-pandacss/packages/config/tsconfig.json +24 -0
  144. package/templates/turborepo-pandacss/packages/config/typescript/base.json +19 -0
  145. package/templates/turborepo-pandacss/packages/front-core/package.json +24 -0
  146. package/templates/turborepo-pandacss/packages/front-core/src/auth/config.ts +84 -0
  147. package/templates/turborepo-pandacss/packages/front-core/src/auth/index.ts +5 -0
  148. package/templates/turborepo-pandacss/packages/front-core/src/auth/types/next-auth.d.ts +20 -0
  149. package/templates/turborepo-pandacss/packages/front-core/src/auth/utils.ts +29 -0
  150. package/templates/turborepo-pandacss/packages/front-core/src/context/index.ts +2 -0
  151. package/templates/turborepo-pandacss/packages/front-core/src/hooks/index.ts +2 -0
  152. package/templates/turborepo-pandacss/packages/front-core/src/index.ts +4 -0
  153. package/templates/turborepo-pandacss/packages/front-core/src/utils/index.ts +2 -0
  154. package/templates/turborepo-pandacss/packages/front-core/tsconfig.json +14 -0
  155. package/templates/turborepo-pandacss/packages/server-core/package.json +32 -0
  156. package/templates/turborepo-pandacss/packages/server-core/prisma/schema.prisma +102 -0
  157. package/templates/turborepo-pandacss/packages/server-core/prisma/seed.ts +67 -0
  158. package/templates/turborepo-pandacss/packages/server-core/prisma.config.ts +8 -0
  159. package/templates/turborepo-pandacss/packages/server-core/src/__generated__/fabbrica/index.d.ts +270 -0
  160. package/templates/turborepo-pandacss/packages/server-core/src/__generated__/fabbrica/index.js +484 -0
  161. package/templates/turborepo-pandacss/packages/server-core/src/core/result.test.ts +78 -0
  162. package/templates/turborepo-pandacss/packages/server-core/src/core/result.ts +53 -0
  163. package/templates/turborepo-pandacss/packages/server-core/src/domain/.gitkeep +0 -0
  164. package/templates/turborepo-pandacss/packages/server-core/src/domain/entities/User.test.ts +232 -0
  165. package/templates/turborepo-pandacss/packages/server-core/src/domain/entities/User.ts +105 -0
  166. package/templates/turborepo-pandacss/packages/server-core/src/domain/repository-interfaces/IUserRepository.ts +101 -0
  167. package/templates/turborepo-pandacss/packages/server-core/src/infrastructure/database/client.ts +15 -0
  168. package/templates/turborepo-pandacss/packages/server-core/src/infrastructure/database/mappers/UserMapper.test.ts +278 -0
  169. package/templates/turborepo-pandacss/packages/server-core/src/infrastructure/database/mappers/UserMapper.ts +103 -0
  170. package/templates/turborepo-pandacss/packages/server-core/src/infrastructure/database/repositories/UserRepository.test.ts +317 -0
  171. package/templates/turborepo-pandacss/packages/server-core/src/infrastructure/database/repositories/UserRepository.ts +169 -0
  172. package/templates/turborepo-pandacss/packages/server-core/src/testing/factories/index.ts +22 -0
  173. package/templates/turborepo-pandacss/packages/server-core/src/testing/factories/user.factory.ts +123 -0
  174. package/templates/turborepo-pandacss/packages/server-core/src/testing/fixtures/users.ts +92 -0
  175. package/templates/turborepo-pandacss/packages/server-core/src/testing/helpers/date.ts +49 -0
  176. package/templates/turborepo-pandacss/packages/server-core/src/testing/helpers/password.ts +50 -0
  177. package/templates/turborepo-pandacss/packages/server-core/src/testing/index.ts +26 -0
  178. package/templates/turborepo-pandacss/packages/server-core/tsconfig.json +14 -0
  179. package/templates/turborepo-pandacss/packages/server-core/vitest.config.ts +15 -0
  180. package/templates/turborepo-pandacss/packages/ui/package.json +37 -0
  181. package/templates/turborepo-pandacss/packages/ui/src/accordion.tsx +66 -0
  182. package/templates/turborepo-pandacss/packages/ui/src/alert-dialog.tsx +157 -0
  183. package/templates/turborepo-pandacss/packages/ui/src/alert.tsx +66 -0
  184. package/templates/turborepo-pandacss/packages/ui/src/aspect-ratio.tsx +11 -0
  185. package/templates/turborepo-pandacss/packages/ui/src/avatar.tsx +53 -0
  186. package/templates/turborepo-pandacss/packages/ui/src/badge.tsx +46 -0
  187. package/templates/turborepo-pandacss/packages/ui/src/breadcrumb.tsx +108 -0
  188. package/templates/turborepo-pandacss/packages/ui/src/button.tsx +59 -0
  189. package/templates/turborepo-pandacss/packages/ui/src/card.tsx +92 -0
  190. package/templates/turborepo-pandacss/packages/ui/src/checkbox.tsx +32 -0
  191. package/templates/turborepo-pandacss/packages/ui/src/data-table.tsx +216 -0
  192. package/templates/turborepo-pandacss/packages/ui/src/dialog-hook.tsx +226 -0
  193. package/templates/turborepo-pandacss/packages/ui/src/dialog.tsx +143 -0
  194. package/templates/turborepo-pandacss/packages/ui/src/drawer.tsx +135 -0
  195. package/templates/turborepo-pandacss/packages/ui/src/dropdown-menu.tsx +257 -0
  196. package/templates/turborepo-pandacss/packages/ui/src/form.tsx +168 -0
  197. package/templates/turborepo-pandacss/packages/ui/src/hover-card.tsx +44 -0
  198. package/templates/turborepo-pandacss/packages/ui/src/input.tsx +21 -0
  199. package/templates/turborepo-pandacss/packages/ui/src/label.tsx +24 -0
  200. package/templates/turborepo-pandacss/packages/ui/src/lib/utils.ts +6 -0
  201. package/templates/turborepo-pandacss/packages/ui/src/pagination.tsx +126 -0
  202. package/templates/turborepo-pandacss/packages/ui/src/popover.tsx +48 -0
  203. package/templates/turborepo-pandacss/packages/ui/src/progress.tsx +31 -0
  204. package/templates/turborepo-pandacss/packages/ui/src/select.tsx +185 -0
  205. package/templates/turborepo-pandacss/packages/ui/src/separator.tsx +28 -0
  206. package/templates/turborepo-pandacss/packages/ui/src/skeleton.tsx +13 -0
  207. package/templates/turborepo-pandacss/packages/ui/src/sonner.tsx +25 -0
  208. package/templates/turborepo-pandacss/packages/ui/src/table.tsx +116 -0
  209. package/templates/turborepo-pandacss/packages/ui/src/tabs.tsx +66 -0
  210. package/templates/turborepo-pandacss/packages/ui/src/textarea.tsx +18 -0
  211. package/templates/turborepo-pandacss/packages/ui/src/tooltip.tsx +61 -0
  212. package/templates/turborepo-pandacss/packages/ui/src/typography.tsx +187 -0
  213. package/templates/turborepo-pandacss/packages/ui/tsconfig.json +20 -0
  214. package/templates/turborepo-pandacss/panda.config.ts +114 -0
  215. package/templates/turborepo-pandacss/pnpm-lock.yaml +9032 -0
  216. package/templates/turborepo-pandacss/pnpm-workspace.yaml +11 -0
  217. package/templates/turborepo-pandacss/postcss.config.cjs +6 -0
  218. package/templates/turborepo-pandacss/prisma/schema.prisma +82 -0
  219. package/templates/turborepo-pandacss/public/file.svg +1 -0
  220. package/templates/turborepo-pandacss/public/globe.svg +1 -0
  221. package/templates/turborepo-pandacss/public/next.svg +1 -0
  222. package/templates/turborepo-pandacss/public/vercel.svg +1 -0
  223. package/templates/turborepo-pandacss/public/window.svg +1 -0
  224. package/templates/turborepo-pandacss/scripts/cli-template-update.ts +387 -0
  225. package/templates/turborepo-pandacss/scripts/env-show.ts +129 -0
  226. package/templates/turborepo-pandacss/scripts/env.ts +555 -0
  227. package/templates/turborepo-pandacss/scripts/init.sh +92 -0
  228. package/templates/turborepo-pandacss/scripts/setup-dev.ts +640 -0
  229. package/templates/turborepo-pandacss/scripts/template-update.ts +277 -0
  230. package/templates/turborepo-pandacss/scripts/worktree/dev.ts +872 -0
  231. package/templates/turborepo-pandacss/test/globals.d.ts +1 -0
  232. package/templates/turborepo-pandacss/test/setup.ts +22 -0
  233. package/templates/turborepo-pandacss/tsconfig.json +46 -0
  234. package/templates/turborepo-pandacss/turbo.json +57 -0
  235. package/templates/turborepo-pandacss/vitest.config.ts +20 -0
@@ -0,0 +1,11 @@
1
+ packages:
2
+ - apps/*
3
+ - packages/*
4
+
5
+ onlyBuiltDependencies:
6
+ - "@biomejs/biome"
7
+ - "@prisma/client"
8
+ - "@prisma/engines"
9
+ - "esbuild"
10
+ - "prisma"
11
+ - "sharp"
@@ -0,0 +1,6 @@
1
+ module.exports = {
2
+ plugins: {
3
+ "@pandacss/dev/postcss": {},
4
+ "@tailwindcss/postcss": {},
5
+ },
6
+ };
@@ -0,0 +1,82 @@
1
+ // This is your Prisma schema file,
2
+ // learn more about it in the docs: https://pris.ly/d/prisma-schema
3
+
4
+ generator client {
5
+ provider = "prisma-client-js"
6
+ }
7
+
8
+ datasource db {
9
+ provider = "postgresql"
10
+ url = env("DATABASE_URL")
11
+ }
12
+
13
+ model User {
14
+ id String @id @default(cuid())
15
+ name String?
16
+ email String @unique
17
+ emailVerified DateTime?
18
+ image String?
19
+ password String? // パスワードフィールドを追加
20
+ accounts Account[]
21
+ sessions Session[]
22
+ // Optional for WebAuthn support
23
+ Authenticator Authenticator[]
24
+
25
+ createdAt DateTime @default(now())
26
+ updatedAt DateTime @updatedAt
27
+ }
28
+
29
+ model Account {
30
+ userId String
31
+ type String
32
+ provider String
33
+ providerAccountId String
34
+ refresh_token String?
35
+ access_token String?
36
+ expires_at Int?
37
+ token_type String?
38
+ scope String?
39
+ id_token String?
40
+ session_state String?
41
+
42
+ createdAt DateTime @default(now())
43
+ updatedAt DateTime @updatedAt
44
+
45
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
46
+
47
+ @@id([provider, providerAccountId])
48
+ }
49
+
50
+ model Session {
51
+ sessionToken String @unique
52
+ userId String
53
+ expires DateTime
54
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
55
+
56
+ createdAt DateTime @default(now())
57
+ updatedAt DateTime @updatedAt
58
+ }
59
+
60
+ model VerificationToken {
61
+ identifier String
62
+ token String
63
+ expires DateTime
64
+
65
+ @@id([identifier, token])
66
+ }
67
+
68
+ // Optional for WebAuthn support
69
+ model Authenticator {
70
+ credentialID String @unique
71
+ userId String
72
+ providerAccountId String
73
+ credentialPublicKey String
74
+ counter Int
75
+ credentialDeviceType String
76
+ credentialBackedUp Boolean
77
+ transports String?
78
+
79
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
80
+
81
+ @@id([userId, credentialID])
82
+ }
@@ -0,0 +1 @@
1
+ <svg fill="none" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M14.5 13.5V5.41a1 1 0 0 0-.3-.7L9.8.29A1 1 0 0 0 9.08 0H1.5v13.5A2.5 2.5 0 0 0 4 16h8a2.5 2.5 0 0 0 2.5-2.5m-1.5 0v-7H8v-5H3v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1M9.5 5V2.12L12.38 5zM5.13 5h-.62v1.25h2.12V5zm-.62 3h7.12v1.25H4.5zm.62 3h-.62v1.25h7.12V11z" clip-rule="evenodd" fill="#666" fill-rule="evenodd"/></svg>
@@ -0,0 +1 @@
1
+ <svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><g clip-path="url(#a)"><path fill-rule="evenodd" clip-rule="evenodd" d="M10.27 14.1a6.5 6.5 0 0 0 3.67-3.45q-1.24.21-2.7.34-.31 1.83-.97 3.1M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.48-1.52a7 7 0 0 1-.96 0H7.5a4 4 0 0 1-.84-1.32q-.38-.89-.63-2.08a40 40 0 0 0 3.92 0q-.25 1.2-.63 2.08a4 4 0 0 1-.84 1.31zm2.94-4.76q1.66-.15 2.95-.43a7 7 0 0 0 0-2.58q-1.3-.27-2.95-.43a18 18 0 0 1 0 3.44m-1.27-3.54a17 17 0 0 1 0 3.64 39 39 0 0 1-4.3 0 17 17 0 0 1 0-3.64 39 39 0 0 1 4.3 0m1.1-1.17q1.45.13 2.69.34a6.5 6.5 0 0 0-3.67-3.44q.65 1.26.98 3.1M8.48 1.5l.01.02q.41.37.84 1.31.38.89.63 2.08a40 40 0 0 0-3.92 0q.25-1.2.63-2.08a4 4 0 0 1 .85-1.32 7 7 0 0 1 .96 0m-2.75.4a6.5 6.5 0 0 0-3.67 3.44 29 29 0 0 1 2.7-.34q.31-1.83.97-3.1M4.58 6.28q-1.66.16-2.95.43a7 7 0 0 0 0 2.58q1.3.27 2.95.43a18 18 0 0 1 0-3.44m.17 4.71q-1.45-.12-2.69-.34a6.5 6.5 0 0 0 3.67 3.44q-.65-1.27-.98-3.1" fill="#666"/></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h16v16H0z"/></clipPath></defs></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 394 80"><path fill="#000" d="M262 0h68.5v12.7h-27.2v66.6h-13.6V12.7H262V0ZM149 0v12.7H94v20.4h44.3v12.6H94v21h55v12.6H80.5V0h68.7zm34.3 0h-17.8l63.8 79.4h17.9l-32-39.7 32-39.6h-17.9l-23 28.6-23-28.6zm18.3 56.7-9-11-27.1 33.7h17.8l18.3-22.7z"/><path fill="#000" d="M81 79.3 17 0H0v79.3h13.6V17l50.2 62.3H81Zm252.6-.4c-1 0-1.8-.4-2.5-1s-1.1-1.6-1.1-2.6.3-1.8 1-2.5 1.6-1 2.6-1 1.8.3 2.5 1a3.4 3.4 0 0 1 .6 4.3 3.7 3.7 0 0 1-3 1.8zm23.2-33.5h6v23.3c0 2.1-.4 4-1.3 5.5a9.1 9.1 0 0 1-3.8 3.5c-1.6.8-3.5 1.3-5.7 1.3-2 0-3.7-.4-5.3-1s-2.8-1.8-3.7-3.2c-.9-1.3-1.4-3-1.4-5h6c.1.8.3 1.6.7 2.2s1 1.2 1.6 1.5c.7.4 1.5.5 2.4.5 1 0 1.8-.2 2.4-.6a4 4 0 0 0 1.6-1.8c.3-.8.5-1.8.5-3V45.5zm30.9 9.1a4.4 4.4 0 0 0-2-3.3 7.5 7.5 0 0 0-4.3-1.1c-1.3 0-2.4.2-3.3.5-.9.4-1.6 1-2 1.6a3.5 3.5 0 0 0-.3 4c.3.5.7.9 1.3 1.2l1.8 1 2 .5 3.2.8c1.3.3 2.5.7 3.7 1.2a13 13 0 0 1 3.2 1.8 8.1 8.1 0 0 1 3 6.5c0 2-.5 3.7-1.5 5.1a10 10 0 0 1-4.4 3.5c-1.8.8-4.1 1.2-6.8 1.2-2.6 0-4.9-.4-6.8-1.2-2-.8-3.4-2-4.5-3.5a10 10 0 0 1-1.7-5.6h6a5 5 0 0 0 3.5 4.6c1 .4 2.2.6 3.4.6 1.3 0 2.5-.2 3.5-.6 1-.4 1.8-1 2.4-1.7a4 4 0 0 0 .8-2.4c0-.9-.2-1.6-.7-2.2a11 11 0 0 0-2.1-1.4l-3.2-1-3.8-1c-2.8-.7-5-1.7-6.6-3.2a7.2 7.2 0 0 1-2.4-5.7 8 8 0 0 1 1.7-5 10 10 0 0 1 4.3-3.5c2-.8 4-1.2 6.4-1.2 2.3 0 4.4.4 6.2 1.2 1.8.8 3.2 2 4.3 3.4 1 1.4 1.5 3 1.5 5h-5.8z"/></svg>
@@ -0,0 +1 @@
1
+ <svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1155 1000"><path d="m577.3 0 577.4 1000H0z" fill="#fff"/></svg>
@@ -0,0 +1 @@
1
+ <svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 2.5h13v10a1 1 0 0 1-1 1h-11a1 1 0 0 1-1-1zM0 1h16v11.5a2.5 2.5 0 0 1-2.5 2.5h-11A2.5 2.5 0 0 1 0 12.5zm3.75 4.5a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5M7 4.75a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0m1.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5" fill="#666"/></svg>
@@ -0,0 +1,387 @@
1
+ #!/usr/bin/env tsx
2
+ /**
3
+ * cli-template:update スクリプト
4
+ *
5
+ * プロジェクトの最新コンテンツをCLIプリセットに反映する内部開発用スクリプト。
6
+ *
7
+ * 使用例:
8
+ * pnpm cli-template:update # 全プリセット更新
9
+ * pnpm cli-template:update --dry-run # 差分確認のみ
10
+ * pnpm cli-template:update --preset minimal # 特定プリセットのみ
11
+ * pnpm cli-template:update --force # 強制上書き
12
+ */
13
+
14
+ import * as readline from "node:readline/promises";
15
+ import { stdin as input, stdout as output } from "node:process";
16
+ import { CLIRepoDetector } from "../packages/cli/src/lib/preset-update/cli-repo-detector.js";
17
+ import { PresetFinder } from "../packages/cli/src/lib/preset-update/preset-finder.js";
18
+ import { FileCopier } from "../packages/cli/src/lib/preset-update/file-copier.js";
19
+ import type {
20
+ Preset,
21
+ CopyResult,
22
+ } from "../packages/cli/src/types/preset-update.js";
23
+
24
+ /**
25
+ * コマンドラインオプション
26
+ */
27
+ interface CliOptions {
28
+ /** 更新対象のプリセット名(minimal, turborepo-pandacss, all) */
29
+ preset: string;
30
+ /** ドライランモード(ファイル変更なし) */
31
+ dryRun: boolean;
32
+ /** 強制上書き(確認プロンプトなし) */
33
+ force: boolean;
34
+ /** JSON形式で結果を出力 */
35
+ json: boolean;
36
+ }
37
+
38
+ /**
39
+ * スクリプト実行結果
40
+ */
41
+ interface ExecutionResult {
42
+ status: "success" | "error";
43
+ summary?: {
44
+ totalFiles: number;
45
+ updated: number;
46
+ skipped: number;
47
+ };
48
+ presets?: Record<
49
+ string,
50
+ {
51
+ files: Array<{
52
+ source: string;
53
+ destination: string;
54
+ action: "copied" | "skipped";
55
+ }>;
56
+ count: number;
57
+ }
58
+ >;
59
+ error?: string;
60
+ }
61
+
62
+ /**
63
+ * コマンドライン引数を解析
64
+ */
65
+ function parseArguments(): CliOptions {
66
+ const args = process.argv.slice(2);
67
+ const options: CliOptions = {
68
+ preset: "all",
69
+ dryRun: false,
70
+ force: false,
71
+ json: false,
72
+ };
73
+
74
+ for (let i = 0; i < args.length; i++) {
75
+ const arg = args[i];
76
+
77
+ switch (arg) {
78
+ case "--preset":
79
+ case "-p":
80
+ options.preset = args[++i] || "all";
81
+ break;
82
+ case "--dry-run":
83
+ case "-d":
84
+ options.dryRun = true;
85
+ break;
86
+ case "--force":
87
+ case "-f":
88
+ options.force = true;
89
+ break;
90
+ case "--json":
91
+ case "-j":
92
+ options.json = true;
93
+ break;
94
+ case "--help":
95
+ case "-h":
96
+ printHelp();
97
+ process.exit(0);
98
+ default:
99
+ if (arg.startsWith("-")) {
100
+ console.error(`Unknown option: ${arg}`);
101
+ process.exit(1);
102
+ }
103
+ }
104
+ }
105
+
106
+ return options;
107
+ }
108
+
109
+ /**
110
+ * ヘルプメッセージを表示
111
+ */
112
+ function printHelp(): void {
113
+ console.log(`
114
+ Usage: pnpm cli-template:update [options]
115
+
116
+ Options:
117
+ -p, --preset <name> 更新対象のプリセット名(minimal, turborepo-pandacss, all)
118
+ -d, --dry-run 実際の変更を行わず、コピー予定のファイル一覧を表示
119
+ -f, --force 確認プロンプトなしで上書き実行
120
+ -j, --json JSON形式で結果を出力
121
+ -h, --help このヘルプメッセージを表示
122
+
123
+ Examples:
124
+ pnpm cli-template:update
125
+ pnpm cli-template:update --dry-run
126
+ pnpm cli-template:update --preset turborepo-pandacss
127
+ pnpm cli-template:update --force
128
+ `);
129
+ }
130
+
131
+ /**
132
+ * 確認プロンプトを表示
133
+ */
134
+ async function confirmOverwrite(
135
+ presets: Preset[],
136
+ fileCount: number
137
+ ): Promise<boolean> {
138
+ const rl = readline.createInterface({ input, output });
139
+
140
+ try {
141
+ const presetNames = presets.map((p) => p.name).join(", ");
142
+ const answer = await rl.question(
143
+ `\n⚠️ ${presetNames}プリセットに${fileCount}ファイルをコピーします。\n既存ファイルを上書きします。続けますか? (y/N): `
144
+ );
145
+
146
+ return answer.toLowerCase() === "y" || answer.toLowerCase() === "yes";
147
+ } finally {
148
+ rl.close();
149
+ }
150
+ }
151
+
152
+ /**
153
+ * 通常モードの出力
154
+ */
155
+ function printNormalOutput(
156
+ presets: Preset[],
157
+ results: Map<string, CopyResult>,
158
+ dryRun: boolean
159
+ ): void {
160
+ console.log("\n🔄 プリセット更新を開始...\n");
161
+
162
+ let totalFiles = 0;
163
+ let totalUpdated = 0;
164
+ let totalSkipped = 0;
165
+
166
+ for (const preset of presets) {
167
+ const result = results.get(preset.name);
168
+ if (!result) continue;
169
+
170
+ console.log(`📁 ${preset.name}`);
171
+
172
+ if (dryRun) {
173
+ console.log(` コピー予定: ${result.files.length}ファイル`);
174
+ for (const file of result.files.slice(0, 5)) {
175
+ console.log(` ${file.source} → ${file.destination}`);
176
+ }
177
+ if (result.files.length > 5) {
178
+ console.log(` ... 他${result.files.length - 5}ファイル`);
179
+ }
180
+ } else {
181
+ console.log(` ✓ ${result.files.length}ファイル更新`);
182
+ }
183
+
184
+ if (result.skipped.length > 0) {
185
+ console.log(` スキップ: ${result.skipped.length}ファイル`);
186
+ }
187
+
188
+ totalFiles += result.files.length + result.skipped.length;
189
+ totalUpdated += result.files.length;
190
+ totalSkipped += result.skipped.length;
191
+
192
+ console.log("");
193
+ }
194
+
195
+ if (dryRun) {
196
+ console.log("✅ 差分確認完了(ファイル変更なし)");
197
+ } else {
198
+ console.log("✅ プリセット更新完了!");
199
+ }
200
+
201
+ console.log(` - 合計: ${totalFiles}ファイル`);
202
+ console.log(` - 更新: ${totalUpdated}ファイル`);
203
+ console.log(` - スキップ: ${totalSkipped}ファイル\n`);
204
+ }
205
+
206
+ /**
207
+ * JSON形式で結果を出力
208
+ */
209
+ function printJsonOutput(
210
+ presets: Preset[],
211
+ results: Map<string, CopyResult>
212
+ ): void {
213
+ let totalFiles = 0;
214
+ let totalUpdated = 0;
215
+ let totalSkipped = 0;
216
+
217
+ const presetsData: ExecutionResult["presets"] = {};
218
+
219
+ for (const preset of presets) {
220
+ const result = results.get(preset.name);
221
+ if (!result) continue;
222
+
223
+ presetsData[preset.name] = {
224
+ files: result.files,
225
+ count: result.files.length,
226
+ };
227
+
228
+ totalFiles += result.files.length + result.skipped.length;
229
+ totalUpdated += result.files.length;
230
+ totalSkipped += result.skipped.length;
231
+ }
232
+
233
+ const output: ExecutionResult = {
234
+ status: "success",
235
+ summary: {
236
+ totalFiles,
237
+ updated: totalUpdated,
238
+ skipped: totalSkipped,
239
+ },
240
+ presets: presetsData,
241
+ };
242
+
243
+ console.log(JSON.stringify(output, null, 2));
244
+ }
245
+
246
+ /**
247
+ * エラーを出力
248
+ */
249
+ function printError(message: string, json: boolean): void {
250
+ if (json) {
251
+ const output: ExecutionResult = {
252
+ status: "error",
253
+ error: message,
254
+ };
255
+ console.log(JSON.stringify(output, null, 2));
256
+ } else {
257
+ console.error(`\n❌ エラー: ${message}\n`);
258
+ }
259
+ }
260
+
261
+ /**
262
+ * メイン処理
263
+ */
264
+ async function main(): Promise<void> {
265
+ const options = parseArguments();
266
+
267
+ // JSON出力モードの場合、標準エラー出力にログを出力
268
+ const log = options.json ? console.error : console.log;
269
+
270
+ try {
271
+ // 1. CLIリポジトリかどうかを検証
272
+ if (options.json) {
273
+ log("🔍 CLIリポジトリを検証中...");
274
+ }
275
+
276
+ const detector = new CLIRepoDetector();
277
+ const validation = await detector.validateRepository();
278
+
279
+ if (!validation.valid) {
280
+ printError(validation.error || "不明なエラー", options.json);
281
+ process.exit(1);
282
+ }
283
+
284
+ const cliPackagePath = validation.cliPackagePath!;
285
+
286
+ // 2. プリセットを検出
287
+ if (options.json) {
288
+ log("📦 プリセットを検出中...");
289
+ }
290
+
291
+ const finder = new PresetFinder();
292
+ let presetsToUpdate: Preset[] = [];
293
+
294
+ if (options.preset === "all") {
295
+ presetsToUpdate = await finder.findPresets(cliPackagePath);
296
+
297
+ if (presetsToUpdate.length === 0) {
298
+ printError("プリセットが見つかりませんでした", options.json);
299
+ process.exit(1);
300
+ }
301
+ } else {
302
+ const preset = await finder.getPreset(options.preset, cliPackagePath);
303
+
304
+ if (!preset) {
305
+ const availablePresets = await finder.findPresets(cliPackagePath);
306
+ const presetNames = availablePresets.map((p) => p.name).join(", ");
307
+ printError(
308
+ `無効なプリセット: ${options.preset}。有効な値: ${presetNames}, all`,
309
+ options.json
310
+ );
311
+ process.exit(1);
312
+ }
313
+
314
+ presetsToUpdate = [preset];
315
+ }
316
+
317
+ // 3. コピー対象ファイルをスキャン
318
+ if (options.json) {
319
+ log("🔍 コピー対象をスキャン中...");
320
+ }
321
+
322
+ const copier = new FileCopier();
323
+ const sourceFiles = await copier.scanSourceFiles(process.cwd());
324
+
325
+ if (sourceFiles.length === 0) {
326
+ printError("コピー対象ファイルが見つかりませんでした", options.json);
327
+ process.exit(1);
328
+ }
329
+
330
+ if (options.json) {
331
+ log(`✓ ${sourceFiles.length}ファイルを検出`);
332
+ }
333
+
334
+ // 4. 確認プロンプト(--forceまたは--dry-runでない場合)
335
+ if (!options.force && !options.dryRun) {
336
+ const confirmed = await confirmOverwrite(
337
+ presetsToUpdate,
338
+ sourceFiles.length
339
+ );
340
+
341
+ if (!confirmed) {
342
+ if (!options.json) {
343
+ log("\n処理がキャンセルされました\n");
344
+ }
345
+ process.exit(0);
346
+ }
347
+ }
348
+
349
+ // 5. 各プリセットにコピー
350
+ const results = new Map<string, CopyResult>();
351
+
352
+ if (!options.json && !options.dryRun) {
353
+ log("\n⚙️ プリセットへコピー中...\n");
354
+ } else if (options.json) {
355
+ log("\n⚙️ プリセットへコピー中...");
356
+ }
357
+
358
+ for (const preset of presetsToUpdate) {
359
+ const result = await copier.copyToPreset({
360
+ preset,
361
+ dryRun: options.dryRun,
362
+ force: options.force,
363
+ });
364
+
365
+ results.set(preset.name, result);
366
+
367
+ if (options.json) {
368
+ log(`✓ ${preset.name}: ${result.files.length}ファイル`);
369
+ }
370
+ }
371
+
372
+ // 6. 結果を出力
373
+ if (options.json) {
374
+ printJsonOutput(presetsToUpdate, results);
375
+ } else {
376
+ printNormalOutput(presetsToUpdate, results, options.dryRun);
377
+ }
378
+ } catch (error) {
379
+ const message =
380
+ error instanceof Error ? error.message : String(error);
381
+ printError(message, options.json);
382
+ process.exit(1);
383
+ }
384
+ }
385
+
386
+ // スクリプト実行
387
+ main();
@@ -0,0 +1,129 @@
1
+ /**
2
+ * 環境変数表示スクリプト(非対話式)
3
+ *
4
+ * 指定した環境の.envファイルを復号して表示
5
+ * 使用方法:
6
+ * pnpm env:show → .env.local
7
+ * pnpm env:show staging → .env.staging
8
+ * pnpm env:show production → .env.production
9
+ */
10
+
11
+ import { execSync } from "node:child_process";
12
+ import fs from "node:fs";
13
+ import path from "node:path";
14
+
15
+ const cwd = process.cwd();
16
+ const ENV_KEYS_PATH = path.join(cwd, ".env.keys");
17
+
18
+ interface EnvironmentConfig {
19
+ name: string;
20
+ file: string;
21
+ privateKeyEnv: string;
22
+ }
23
+
24
+ const ENVIRONMENTS: EnvironmentConfig[] = [
25
+ { name: "local", file: ".env.local", privateKeyEnv: "DOTENV_PRIVATE_KEY_LOCAL" },
26
+ { name: "development", file: ".env.development", privateKeyEnv: "DOTENV_PRIVATE_KEY_DEVELOPMENT" },
27
+ { name: "staging", file: ".env.staging", privateKeyEnv: "DOTENV_PRIVATE_KEY_STAGING" },
28
+ { name: "production", file: ".env.production", privateKeyEnv: "DOTENV_PRIVATE_KEY_PRODUCTION" },
29
+ { name: "ci", file: ".env.ci", privateKeyEnv: "DOTENV_PRIVATE_KEY_CI" },
30
+ ];
31
+
32
+ function parseEnvFile(filePath: string): Record<string, string> {
33
+ if (!fs.existsSync(filePath)) {
34
+ return {};
35
+ }
36
+ const content = fs.readFileSync(filePath, "utf-8");
37
+ const result: Record<string, string> = {};
38
+
39
+ for (const line of content.split("\n")) {
40
+ const trimmed = line.trim();
41
+ if (!trimmed || trimmed.startsWith("#")) continue;
42
+
43
+ const match = trimmed.match(/^([^=]+)=(.*)$/);
44
+ if (match) {
45
+ const key = match[1].trim();
46
+ let value = match[2].trim();
47
+ if (
48
+ (value.startsWith('"') && value.endsWith('"')) ||
49
+ (value.startsWith("'") && value.endsWith("'"))
50
+ ) {
51
+ value = value.slice(1, -1);
52
+ }
53
+ result[key] = value;
54
+ }
55
+ }
56
+ return result;
57
+ }
58
+
59
+ function getPrivateKey(privateKeyEnv: string): string | null {
60
+ if (!fs.existsSync(ENV_KEYS_PATH)) {
61
+ return null;
62
+ }
63
+ const keys = parseEnvFile(ENV_KEYS_PATH);
64
+ return keys[privateKeyEnv] || null;
65
+ }
66
+
67
+ function showUsage(): void {
68
+ console.log("使用方法: pnpm env:show [環境名]");
69
+ console.log("");
70
+ console.log("環境名:");
71
+ for (const env of ENVIRONMENTS) {
72
+ console.log(` ${env.name.padEnd(12)} → ${env.file}`);
73
+ }
74
+ console.log("");
75
+ console.log("例:");
76
+ console.log(" pnpm env:show # .env.local を表示");
77
+ console.log(" pnpm env:show staging # .env.staging を表示");
78
+ }
79
+
80
+ function main(): void {
81
+ const arg = process.argv[2];
82
+
83
+ // ヘルプ
84
+ if (arg === "-h" || arg === "--help") {
85
+ showUsage();
86
+ process.exit(0);
87
+ }
88
+
89
+ // 環境を特定
90
+ const envName = arg || "local";
91
+ const env = ENVIRONMENTS.find((e) => e.name === envName);
92
+
93
+ if (!env) {
94
+ console.error(`❌ 不明な環境: ${envName}`);
95
+ console.error("");
96
+ showUsage();
97
+ process.exit(1);
98
+ }
99
+
100
+ const envFilePath = path.join(cwd, env.file);
101
+
102
+ if (!fs.existsSync(envFilePath)) {
103
+ console.error(`❌ ${env.file} が見つかりません`);
104
+ process.exit(1);
105
+ }
106
+
107
+ const privateKey = getPrivateKey(env.privateKeyEnv);
108
+ if (!privateKey) {
109
+ console.error(`❌ .env.keys に ${env.privateKeyEnv} が見つかりません`);
110
+ console.error(" チームから .env.keys を共有してもらってください");
111
+ process.exit(1);
112
+ }
113
+
114
+ // dotenvx で復号
115
+ try {
116
+ const decrypted = execSync(`dotenvx decrypt -f ${env.file} --stdout`, {
117
+ cwd,
118
+ encoding: "utf-8",
119
+ env: { ...process.env, [env.privateKeyEnv]: privateKey },
120
+ });
121
+ console.log(decrypted);
122
+ } catch (error) {
123
+ console.error("❌ 復号に失敗しました");
124
+ console.error(error);
125
+ process.exit(1);
126
+ }
127
+ }
128
+
129
+ main();