prjct-cli 0.18.2 → 0.20.0

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 (246) hide show
  1. package/CHANGELOG.md +82 -0
  2. package/CLAUDE.md +74 -211
  3. package/core/agentic/prompt-builder.ts +3 -7
  4. package/core/command-registry/optional-commands.ts +0 -20
  5. package/core/infrastructure/command-installer/command-installer.ts +8 -1
  6. package/core/infrastructure/command-installer/global-config.ts +31 -1
  7. package/core/infrastructure/command-installer/index.ts +1 -1
  8. package/core/infrastructure/setup.ts +3 -0
  9. package/package.json +3 -17
  10. package/templates/agentic/agents/uxui.md +210 -0
  11. package/templates/commands/bug.md +219 -41
  12. package/templates/commands/done.md +57 -258
  13. package/templates/commands/feature.md +368 -80
  14. package/templates/commands/now.md +72 -277
  15. package/templates/commands/ship.md +167 -246
  16. package/templates/commands/sync.md +62 -3
  17. package/templates/commands/test.md +160 -20
  18. package/templates/global/CLAUDE.md +40 -205
  19. package/templates/global/docs/agents.md +88 -0
  20. package/templates/global/docs/architecture.md +103 -0
  21. package/templates/global/docs/commands.md +98 -0
  22. package/templates/global/docs/validation.md +95 -0
  23. package/bin/dev.js +0 -216
  24. package/bin/serve.js +0 -361
  25. package/packages/web/README.md +0 -36
  26. package/packages/web/app/api/claude/sessions/route.ts +0 -44
  27. package/packages/web/app/api/claude/status/route.ts +0 -34
  28. package/packages/web/app/api/projects/[id]/icon/route.ts +0 -33
  29. package/packages/web/app/api/projects/[id]/momentum/route.ts +0 -257
  30. package/packages/web/app/api/projects/[id]/route.ts +0 -29
  31. package/packages/web/app/api/projects/[id]/stats/route.ts +0 -41
  32. package/packages/web/app/api/projects/[id]/status/route.ts +0 -21
  33. package/packages/web/app/api/projects/route.ts +0 -16
  34. package/packages/web/app/api/sessions/current/route.ts +0 -132
  35. package/packages/web/app/api/sessions/history/route.ts +0 -204
  36. package/packages/web/app/error.tsx +0 -34
  37. package/packages/web/app/favicon.ico +0 -0
  38. package/packages/web/app/globals.css +0 -198
  39. package/packages/web/app/layout.tsx +0 -53
  40. package/packages/web/app/loading.tsx +0 -7
  41. package/packages/web/app/not-found.tsx +0 -25
  42. package/packages/web/app/page.tsx +0 -12
  43. package/packages/web/app/project/[id]/code/layout.tsx +0 -18
  44. package/packages/web/app/project/[id]/code/page.tsx +0 -408
  45. package/packages/web/app/project/[id]/error.tsx +0 -41
  46. package/packages/web/app/project/[id]/loading.tsx +0 -9
  47. package/packages/web/app/project/[id]/not-found.tsx +0 -27
  48. package/packages/web/app/project/[id]/page.tsx +0 -384
  49. package/packages/web/app/project/[id]/reports/page.tsx +0 -59
  50. package/packages/web/app/project/[id]/reports/print/page.tsx +0 -58
  51. package/packages/web/app/sessions/page.tsx +0 -165
  52. package/packages/web/app/settings/page.tsx +0 -151
  53. package/packages/web/components/ActivityTimeline/ActivityTimeline.constants.ts +0 -2
  54. package/packages/web/components/ActivityTimeline/ActivityTimeline.tsx +0 -49
  55. package/packages/web/components/ActivityTimeline/ActivityTimeline.types.ts +0 -8
  56. package/packages/web/components/ActivityTimeline/hooks/index.ts +0 -2
  57. package/packages/web/components/ActivityTimeline/hooks/useExpandable.ts +0 -9
  58. package/packages/web/components/ActivityTimeline/hooks/useGroupedEvents.ts +0 -23
  59. package/packages/web/components/ActivityTimeline/index.ts +0 -2
  60. package/packages/web/components/AgentsCard/AgentsCard.tsx +0 -93
  61. package/packages/web/components/AgentsCard/AgentsCard.types.ts +0 -14
  62. package/packages/web/components/AgentsCard/index.ts +0 -2
  63. package/packages/web/components/AppSidebar/AppSidebar.tsx +0 -316
  64. package/packages/web/components/AppSidebar/index.ts +0 -1
  65. package/packages/web/components/BackLink/BackLink.tsx +0 -18
  66. package/packages/web/components/BackLink/BackLink.types.ts +0 -5
  67. package/packages/web/components/BackLink/index.ts +0 -2
  68. package/packages/web/components/BentoCard/BentoCard.constants.ts +0 -16
  69. package/packages/web/components/BentoCard/BentoCard.tsx +0 -48
  70. package/packages/web/components/BentoCard/BentoCard.types.ts +0 -15
  71. package/packages/web/components/BentoCard/index.ts +0 -2
  72. package/packages/web/components/BentoCardSkeleton/BentoCardSkeleton.constants.ts +0 -9
  73. package/packages/web/components/BentoCardSkeleton/BentoCardSkeleton.tsx +0 -18
  74. package/packages/web/components/BentoCardSkeleton/BentoCardSkeleton.types.ts +0 -5
  75. package/packages/web/components/BentoCardSkeleton/index.ts +0 -2
  76. package/packages/web/components/BentoGrid/BentoGrid.tsx +0 -18
  77. package/packages/web/components/BentoGrid/BentoGrid.types.ts +0 -4
  78. package/packages/web/components/BentoGrid/index.ts +0 -2
  79. package/packages/web/components/BlockersCard/BlockersCard.tsx +0 -75
  80. package/packages/web/components/BlockersCard/BlockersCard.types.ts +0 -12
  81. package/packages/web/components/BlockersCard/index.ts +0 -2
  82. package/packages/web/components/CommandBar/CommandBar.tsx +0 -67
  83. package/packages/web/components/CommandBar/index.ts +0 -1
  84. package/packages/web/components/CommandButton/CommandButton.tsx +0 -46
  85. package/packages/web/components/CommandButton/index.ts +0 -1
  86. package/packages/web/components/ConnectionStatus/ConnectionStatus.tsx +0 -29
  87. package/packages/web/components/ConnectionStatus/index.ts +0 -1
  88. package/packages/web/components/DashboardContent/DashboardContent.tsx +0 -284
  89. package/packages/web/components/DashboardContent/index.ts +0 -1
  90. package/packages/web/components/DateGroup/DateGroup.tsx +0 -18
  91. package/packages/web/components/DateGroup/DateGroup.types.ts +0 -6
  92. package/packages/web/components/DateGroup/DateGroup.utils.ts +0 -11
  93. package/packages/web/components/DateGroup/index.ts +0 -2
  94. package/packages/web/components/EmptyState/EmptyState.tsx +0 -76
  95. package/packages/web/components/EmptyState/EmptyState.types.ts +0 -11
  96. package/packages/web/components/EmptyState/index.ts +0 -2
  97. package/packages/web/components/EventRow/EventRow.constants.ts +0 -10
  98. package/packages/web/components/EventRow/EventRow.tsx +0 -49
  99. package/packages/web/components/EventRow/EventRow.types.ts +0 -7
  100. package/packages/web/components/EventRow/EventRow.utils.ts +0 -49
  101. package/packages/web/components/EventRow/index.ts +0 -2
  102. package/packages/web/components/ExpandButton/ExpandButton.tsx +0 -18
  103. package/packages/web/components/ExpandButton/ExpandButton.types.ts +0 -6
  104. package/packages/web/components/ExpandButton/index.ts +0 -2
  105. package/packages/web/components/HealthGradientBackground/HealthGradientBackground.tsx +0 -14
  106. package/packages/web/components/HealthGradientBackground/HealthGradientBackground.types.ts +0 -5
  107. package/packages/web/components/HealthGradientBackground/HealthGradientBackground.utils.ts +0 -13
  108. package/packages/web/components/HealthGradientBackground/index.ts +0 -2
  109. package/packages/web/components/HeroSection/HeroSection.tsx +0 -92
  110. package/packages/web/components/HeroSection/HeroSection.types.ts +0 -14
  111. package/packages/web/components/HeroSection/HeroSection.utils.ts +0 -11
  112. package/packages/web/components/HeroSection/hooks/index.ts +0 -2
  113. package/packages/web/components/HeroSection/hooks/useCountUp.ts +0 -45
  114. package/packages/web/components/HeroSection/hooks/useWeeklyActivity.ts +0 -18
  115. package/packages/web/components/HeroSection/index.ts +0 -2
  116. package/packages/web/components/IdeasCard/IdeasCard.tsx +0 -115
  117. package/packages/web/components/IdeasCard/IdeasCard.types.ts +0 -10
  118. package/packages/web/components/IdeasCard/index.ts +0 -2
  119. package/packages/web/components/InsightMessage/InsightMessage.tsx +0 -9
  120. package/packages/web/components/InsightMessage/InsightMessage.types.ts +0 -3
  121. package/packages/web/components/InsightMessage/index.ts +0 -2
  122. package/packages/web/components/Logo/Logo.tsx +0 -65
  123. package/packages/web/components/Logo/index.ts +0 -1
  124. package/packages/web/components/MarkdownContent/MarkdownContent.tsx +0 -123
  125. package/packages/web/components/MarkdownContent/index.ts +0 -1
  126. package/packages/web/components/MasonryGrid/MasonryGrid.tsx +0 -18
  127. package/packages/web/components/MasonryGrid/index.ts +0 -1
  128. package/packages/web/components/MomentumWidget/MomentumWidget.tsx +0 -119
  129. package/packages/web/components/MomentumWidget/MomentumWidget.types.ts +0 -16
  130. package/packages/web/components/MomentumWidget/index.ts +0 -2
  131. package/packages/web/components/NowCard/NowCard.tsx +0 -118
  132. package/packages/web/components/NowCard/NowCard.types.ts +0 -16
  133. package/packages/web/components/NowCard/index.ts +0 -2
  134. package/packages/web/components/PageHeader/PageHeader.tsx +0 -24
  135. package/packages/web/components/PageHeader/index.ts +0 -1
  136. package/packages/web/components/ProgressRing/ProgressRing.constants.ts +0 -20
  137. package/packages/web/components/ProgressRing/ProgressRing.tsx +0 -51
  138. package/packages/web/components/ProgressRing/ProgressRing.types.ts +0 -11
  139. package/packages/web/components/ProgressRing/index.ts +0 -2
  140. package/packages/web/components/ProjectAvatar/ProjectAvatar.tsx +0 -54
  141. package/packages/web/components/ProjectAvatar/index.ts +0 -1
  142. package/packages/web/components/ProjectColorDot/ProjectColorDot.tsx +0 -37
  143. package/packages/web/components/ProjectColorDot/index.ts +0 -1
  144. package/packages/web/components/ProjectSelectorModal/ProjectSelectorModal.tsx +0 -104
  145. package/packages/web/components/ProjectSelectorModal/index.ts +0 -1
  146. package/packages/web/components/Providers/Providers.tsx +0 -48
  147. package/packages/web/components/Providers/index.ts +0 -1
  148. package/packages/web/components/QueueCard/QueueCard.tsx +0 -125
  149. package/packages/web/components/QueueCard/QueueCard.types.ts +0 -12
  150. package/packages/web/components/QueueCard/QueueCard.utils.ts +0 -12
  151. package/packages/web/components/QueueCard/index.ts +0 -2
  152. package/packages/web/components/RecoverCard/RecoverCard.tsx +0 -72
  153. package/packages/web/components/RecoverCard/RecoverCard.types.ts +0 -16
  154. package/packages/web/components/RecoverCard/index.ts +0 -2
  155. package/packages/web/components/RoadmapCard/RoadmapCard.tsx +0 -145
  156. package/packages/web/components/RoadmapCard/RoadmapCard.types.ts +0 -16
  157. package/packages/web/components/RoadmapCard/index.ts +0 -2
  158. package/packages/web/components/ShipsCard/ShipsCard.tsx +0 -95
  159. package/packages/web/components/ShipsCard/ShipsCard.types.ts +0 -14
  160. package/packages/web/components/ShipsCard/ShipsCard.utils.ts +0 -4
  161. package/packages/web/components/ShipsCard/index.ts +0 -2
  162. package/packages/web/components/SparklineChart/SparklineChart.tsx +0 -40
  163. package/packages/web/components/SparklineChart/SparklineChart.types.ts +0 -6
  164. package/packages/web/components/SparklineChart/index.ts +0 -2
  165. package/packages/web/components/StatsMasonry/StatsMasonry.tsx +0 -95
  166. package/packages/web/components/StatsMasonry/index.ts +0 -1
  167. package/packages/web/components/StreakCard/StreakCard.constants.ts +0 -2
  168. package/packages/web/components/StreakCard/StreakCard.tsx +0 -55
  169. package/packages/web/components/StreakCard/StreakCard.types.ts +0 -4
  170. package/packages/web/components/StreakCard/index.ts +0 -2
  171. package/packages/web/components/TasksCounter/TasksCounter.tsx +0 -14
  172. package/packages/web/components/TasksCounter/TasksCounter.types.ts +0 -3
  173. package/packages/web/components/TasksCounter/index.ts +0 -2
  174. package/packages/web/components/TechStackBadges/TechStackBadges.tsx +0 -28
  175. package/packages/web/components/TechStackBadges/index.ts +0 -1
  176. package/packages/web/components/TerminalDock/DockToggleTab.tsx +0 -29
  177. package/packages/web/components/TerminalDock/TerminalDock.tsx +0 -386
  178. package/packages/web/components/TerminalDock/TerminalDockTab.tsx +0 -130
  179. package/packages/web/components/TerminalDock/TerminalTabBar.tsx +0 -142
  180. package/packages/web/components/TerminalDock/index.ts +0 -2
  181. package/packages/web/components/TerminalTabs/TerminalTab.tsx +0 -95
  182. package/packages/web/components/TerminalTabs/TerminalTabs.tsx +0 -211
  183. package/packages/web/components/TerminalTabs/index.ts +0 -1
  184. package/packages/web/components/VelocityBadge/VelocityBadge.tsx +0 -32
  185. package/packages/web/components/VelocityBadge/VelocityBadge.types.ts +0 -3
  186. package/packages/web/components/VelocityBadge/index.ts +0 -2
  187. package/packages/web/components/VelocityCard/VelocityCard.tsx +0 -73
  188. package/packages/web/components/VelocityCard/VelocityCard.types.ts +0 -7
  189. package/packages/web/components/VelocityCard/index.ts +0 -2
  190. package/packages/web/components/WeeklyReports/PrintableReport.tsx +0 -259
  191. package/packages/web/components/WeeklyReports/ReportPreviewCard.tsx +0 -187
  192. package/packages/web/components/WeeklyReports/WeekCalendar.tsx +0 -288
  193. package/packages/web/components/WeeklyReports/WeeklyReports.tsx +0 -149
  194. package/packages/web/components/WeeklyReports/index.ts +0 -4
  195. package/packages/web/components/WeeklySparkline/WeeklySparkline.tsx +0 -25
  196. package/packages/web/components/WeeklySparkline/WeeklySparkline.types.ts +0 -4
  197. package/packages/web/components/WeeklySparkline/index.ts +0 -2
  198. package/packages/web/components/charts/SessionsChart.tsx +0 -175
  199. package/packages/web/components/ui/alert-dialog.tsx +0 -157
  200. package/packages/web/components/ui/badge.tsx +0 -46
  201. package/packages/web/components/ui/button.tsx +0 -60
  202. package/packages/web/components/ui/card.tsx +0 -92
  203. package/packages/web/components/ui/chart.tsx +0 -385
  204. package/packages/web/components/ui/dialog.tsx +0 -143
  205. package/packages/web/components/ui/drawer.tsx +0 -135
  206. package/packages/web/components/ui/dropdown-menu.tsx +0 -257
  207. package/packages/web/components/ui/input.tsx +0 -21
  208. package/packages/web/components/ui/scroll-area.tsx +0 -58
  209. package/packages/web/components/ui/select.tsx +0 -187
  210. package/packages/web/components/ui/sheet.tsx +0 -139
  211. package/packages/web/components/ui/tabs.tsx +0 -66
  212. package/packages/web/components/ui/tooltip.tsx +0 -61
  213. package/packages/web/components.json +0 -22
  214. package/packages/web/context/GlobalTerminalContext.tsx +0 -538
  215. package/packages/web/context/TerminalContext.tsx +0 -45
  216. package/packages/web/context/TerminalTabsContext.tsx +0 -181
  217. package/packages/web/eslint.config.mjs +0 -18
  218. package/packages/web/hooks/useClaudeTerminal.ts +0 -425
  219. package/packages/web/hooks/useProjectStats.ts +0 -93
  220. package/packages/web/hooks/useProjects.ts +0 -73
  221. package/packages/web/lib/actions/projects.ts +0 -15
  222. package/packages/web/lib/commands.ts +0 -81
  223. package/packages/web/lib/format.ts +0 -23
  224. package/packages/web/lib/generate-week-report.ts +0 -285
  225. package/packages/web/lib/parse-prjct-files.ts +0 -1123
  226. package/packages/web/lib/project-colors.ts +0 -58
  227. package/packages/web/lib/projects.ts +0 -506
  228. package/packages/web/lib/pty.ts +0 -101
  229. package/packages/web/lib/query-config.ts +0 -44
  230. package/packages/web/lib/services/index.ts +0 -9
  231. package/packages/web/lib/services/projects.server.ts +0 -66
  232. package/packages/web/lib/services/stats.server.ts +0 -562
  233. package/packages/web/lib/unified-loader.ts +0 -396
  234. package/packages/web/lib/utils.ts +0 -6
  235. package/packages/web/next-env.d.ts +0 -6
  236. package/packages/web/next.config.ts +0 -7
  237. package/packages/web/package.json +0 -57
  238. package/packages/web/postcss.config.mjs +0 -7
  239. package/packages/web/public/file.svg +0 -1
  240. package/packages/web/public/globe.svg +0 -1
  241. package/packages/web/public/next.svg +0 -1
  242. package/packages/web/public/vercel.svg +0 -1
  243. package/packages/web/public/window.svg +0 -1
  244. package/packages/web/server.ts +0 -312
  245. package/packages/web/tsconfig.json +0 -34
  246. package/templates/commands/serve.md +0 -121
@@ -0,0 +1,98 @@
1
+ # prjct Commands Reference
2
+
3
+ ## Command Table
4
+
5
+ | Command | Purpose | Arguments |
6
+ |---------|---------|-----------|
7
+ | `/p:sync` | Analyze project, generate agents | - |
8
+ | `/p:now [task] [estimate]` | Start/show current task | task: string, estimate: "2h", "30m" |
9
+ | `/p:done` | Complete current task | - |
10
+ | `/p:ship [feature]` | Ship with quality checks | feature: string |
11
+ | `/p:next` | Show priority queue | - |
12
+ | `/p:feature [desc]` | Add feature to roadmap | desc: string |
13
+ | `/p:idea [text]` | Quick idea capture | text: string |
14
+ | `/p:recap` | Project overview | - |
15
+ | `/p:progress [period]` | Show metrics | period: "week", "month" |
16
+ | `/p:pause [reason]` | Pause current task | reason: string |
17
+ | `/p:resume` | Resume paused task | - |
18
+ | `/p:bug [desc]` | Report bug | desc: string |
19
+
20
+ ## Recommended Workflow
21
+
22
+ ```
23
+ 1. /p:sync → Analyze project, generate agents
24
+ 2. /p:feature → Plan what to build
25
+ 3. /p:now → Start working on task
26
+ 4. [code...] → Do the actual work
27
+ 5. /p:done → Mark task complete
28
+ 6. /p:ship → Ship and celebrate
29
+ ```
30
+
31
+ ## Command Examples
32
+
33
+ ### Starting Work
34
+ ```
35
+ /p:now "implement user authentication" 2h
36
+ ```
37
+ - Sets current task
38
+ - Optional estimate for tracking accuracy
39
+
40
+ ### Completing Work
41
+ ```
42
+ /p:done
43
+ ```
44
+ - Calculates duration
45
+ - Logs metrics (files changed, commits)
46
+ - Clears current task
47
+
48
+ ### Shipping
49
+ ```
50
+ /p:ship "user authentication"
51
+ ```
52
+ - Runs lint/tests (optional)
53
+ - Bumps version
54
+ - Creates git commit
55
+ - Updates CHANGELOG
56
+
57
+ ### Quick Capture
58
+ ```
59
+ /p:idea "add dark mode support"
60
+ ```
61
+ - Saves to ideas backlog
62
+ - Doesn't interrupt current work
63
+
64
+ ## Natural Language Trigger
65
+
66
+ Start message with `p.` for natural language:
67
+
68
+ ```
69
+ p. start working on login form
70
+ → Executes /p:now "login form"
71
+
72
+ p. done with this
73
+ → Executes /p:done
74
+
75
+ p. ship authentication feature
76
+ → Executes /p:ship "authentication"
77
+ ```
78
+
79
+ ## Command Output Format
80
+
81
+ All commands output concise responses:
82
+
83
+ ```
84
+ ✅ [What was done]
85
+
86
+ [Key metrics if applicable]
87
+
88
+ Next: [suggested action]
89
+ ```
90
+
91
+ Example:
92
+ ```
93
+ ✅ implement auth (2h 15m)
94
+
95
+ Files: 5 | +120/-30 | Commits: 3
96
+
97
+ Next: /p:ship or /p:now
98
+ ```
@@ -0,0 +1,95 @@
1
+ # Validation Patterns
2
+
3
+ ## Before Any Command
4
+
5
+ ```javascript
6
+ // 1. Check project exists
7
+ const config = await Read('.prjct/prjct.config.json')
8
+ if (!config) {
9
+ return "No prjct project. Run /p:init first."
10
+ }
11
+
12
+ // 2. Extract projectId
13
+ const { projectId } = JSON.parse(config)
14
+
15
+ // 3. Construct global path
16
+ const globalPath = `~/.prjct-cli/projects/${projectId}`
17
+ ```
18
+
19
+ ## Before /p:done
20
+
21
+ ```javascript
22
+ const state = await Read(`${globalPath}/storage/state.json`)
23
+
24
+ if (!state || !state.currentTask) {
25
+ return "Not working on anything. Use /p:now to start a task."
26
+ }
27
+
28
+ if (state.currentTask.status !== 'active') {
29
+ return "No active task. Use /p:now to start one."
30
+ }
31
+ ```
32
+
33
+ ## Before /p:ship
34
+
35
+ ```javascript
36
+ // Check git status
37
+ const gitStatus = await Bash('git status --porcelain')
38
+
39
+ if (!gitStatus.trim()) {
40
+ return "No changes to ship. Make some commits first."
41
+ }
42
+
43
+ // Verify git repo
44
+ const isGitRepo = await Bash('git rev-parse --is-inside-work-tree')
45
+ if (!isGitRepo) {
46
+ return "Not a git repository. Initialize git first."
47
+ }
48
+ ```
49
+
50
+ ## Before /p:pause
51
+
52
+ ```javascript
53
+ const state = await Read(`${globalPath}/storage/state.json`)
54
+
55
+ if (!state?.currentTask || state.currentTask.status !== 'active') {
56
+ return "No active task to pause."
57
+ }
58
+ ```
59
+
60
+ ## Before /p:resume
61
+
62
+ ```javascript
63
+ const state = await Read(`${globalPath}/storage/state.json`)
64
+
65
+ if (!state?.pausedTask) {
66
+ return "No paused task to resume. Use /p:now to start a new task."
67
+ }
68
+ ```
69
+
70
+ ## Error Handling
71
+
72
+ | Error | Response | Action |
73
+ |-------|----------|--------|
74
+ | Config not found | "No prjct project" | STOP |
75
+ | No current task | "Not working on anything" | STOP |
76
+ | No paused task | "No paused task" | STOP |
77
+ | Git fails | Use defaults for metrics | CONTINUE |
78
+ | Write fails | Log warning | CONTINUE |
79
+ | File not found | Return empty/default state | CONTINUE |
80
+
81
+ ## Path Resolution
82
+
83
+ **CRITICAL**: All paths resolve to global storage.
84
+
85
+ ```javascript
86
+ // Template says:
87
+ "Read: storage/state.json"
88
+
89
+ // Actually reads:
90
+ `~/.prjct-cli/projects/${projectId}/storage/state.json`
91
+
92
+ // NEVER:
93
+ ".prjct/storage/state.json" // Wrong - local
94
+ "./storage/state.json" // Wrong - current dir
95
+ ```
package/bin/dev.js DELETED
@@ -1,216 +0,0 @@
1
- #!/usr/bin/env bun
2
-
3
- /**
4
- * prjct dev - Start prjct web development environment
5
- *
6
- * Launches Next.js fullstack app on port 9472
7
- * - Frontend + API routes + WebSocket for PTY
8
- *
9
- * Usage: prjct dev [--no-open]
10
- */
11
-
12
- const { spawn, exec } = require('child_process')
13
- const path = require('path')
14
- const os = require('os')
15
-
16
- // Configuration
17
- const PORT = process.env.PRJCT_PORT || 9472
18
- const WEB_URL = `http://localhost:${PORT}`
19
-
20
- // Colors for terminal output
21
- const colors = {
22
- reset: '\x1b[0m',
23
- bright: '\x1b[1m',
24
- dim: '\x1b[2m',
25
- cyan: '\x1b[36m',
26
- green: '\x1b[32m',
27
- yellow: '\x1b[33m',
28
- red: '\x1b[31m',
29
- magenta: '\x1b[35m'
30
- }
31
-
32
- // Find prjct-cli root (where packages/ lives)
33
- function findPrjctRoot() {
34
- const locations = [
35
- path.join(__dirname, '..'),
36
- path.join(os.homedir(), 'Apps', 'prjct', 'prjct-cli'),
37
- path.join(os.homedir(), '.prjct-cli', 'source'),
38
- ]
39
-
40
- for (const loc of locations) {
41
- const pkgPath = path.join(loc, 'packages')
42
- try {
43
- require('fs').accessSync(pkgPath)
44
- return loc
45
- } catch {}
46
- }
47
-
48
- return locations[0]
49
- }
50
-
51
- const PRJCT_ROOT = findPrjctRoot()
52
- const WEB_PATH = path.join(PRJCT_ROOT, 'packages', 'web')
53
-
54
- // Print banner
55
- function printBanner() {
56
- console.log(`
57
- ${colors.cyan}${colors.bright}╔═══════════════════════════════════════════════╗
58
- ║ ║
59
- ║ ⚡ prjct dev ║
60
- ║ ║
61
- ║ App: ${colors.green}http://localhost:${PORT}${colors.cyan} ║
62
- ║ ║
63
- ║ ${colors.dim}Press Ctrl+C to stop${colors.cyan}${colors.bright} ║
64
- ║ ║
65
- ╚═══════════════════════════════════════════════╝${colors.reset}
66
- `)
67
- }
68
-
69
- // Open browser based on OS
70
- function openBrowser(url) {
71
- const platform = os.platform()
72
- let command
73
-
74
- switch (platform) {
75
- case 'darwin':
76
- command = `open "${url}"`
77
- break
78
- case 'win32':
79
- command = `start "" "${url}"`
80
- break
81
- default:
82
- command = `xdg-open "${url}"`
83
- }
84
-
85
- exec(command, (err) => {
86
- if (err) {
87
- console.log(`${colors.yellow}Could not open browser automatically. Visit: ${url}${colors.reset}`)
88
- }
89
- })
90
- }
91
-
92
- // Check if port is available
93
- function checkPort(port) {
94
- return new Promise((resolve) => {
95
- const net = require('net')
96
- const server = net.createServer()
97
-
98
- server.once('error', () => resolve(false))
99
- server.once('listening', () => {
100
- server.close()
101
- resolve(true)
102
- })
103
-
104
- server.listen(port)
105
- })
106
- }
107
-
108
- // Wait for server to be ready
109
- function waitForServer(port, maxAttempts = 60) {
110
- return new Promise((resolve, reject) => {
111
- let attempts = 0
112
-
113
- const check = () => {
114
- const http = require('http')
115
- const req = http.get(`http://localhost:${port}`, (res) => {
116
- resolve(true)
117
- })
118
-
119
- req.on('error', () => {
120
- attempts++
121
- if (attempts >= maxAttempts) {
122
- reject(new Error(`Server on port ${port} did not start`))
123
- } else {
124
- setTimeout(check, 500)
125
- }
126
- })
127
-
128
- req.end()
129
- }
130
-
131
- check()
132
- })
133
- }
134
-
135
- // Main function
136
- async function main() {
137
- const args = process.argv.slice(2)
138
- const noOpen = args.includes('--no-open')
139
-
140
- // Check port
141
- const portAvailable = await checkPort(PORT)
142
-
143
- if (!portAvailable) {
144
- console.log(`${colors.red}Port ${PORT} is already in use. Stop other services or set PRJCT_PORT.${colors.reset}`)
145
- process.exit(1)
146
- }
147
-
148
- printBanner()
149
-
150
- // Start Next.js with custom server
151
- console.log(`${colors.cyan}Starting prjct...${colors.reset}`)
152
- const webProc = spawn('npm', ['run', 'dev'], {
153
- cwd: WEB_PATH,
154
- env: { ...process.env, PORT: PORT.toString() },
155
- stdio: ['ignore', 'pipe', 'pipe'],
156
- })
157
-
158
- webProc.stdout.on('data', (data) => {
159
- const lines = data.toString().split('\n').filter(Boolean)
160
- lines.forEach(line => {
161
- // Show relevant output
162
- if (line.includes('ready') || line.includes('Ready') || line.includes('[WS]')) {
163
- console.log(`${colors.green}${line}${colors.reset}`)
164
- } else if (!line.includes('╔') && !line.includes('║') && !line.includes('╚')) {
165
- console.log(`${colors.dim}${line}${colors.reset}`)
166
- }
167
- })
168
- })
169
-
170
- webProc.stderr.on('data', (data) => {
171
- const msg = data.toString().trim()
172
- // Filter out common non-error messages
173
- if (!msg.includes('ExperimentalWarning') && !msg.includes('punycode')) {
174
- console.log(`${colors.red}${msg}${colors.reset}`)
175
- }
176
- })
177
-
178
- // Wait for server and open browser
179
- try {
180
- console.log(`${colors.dim}Waiting for server to start...${colors.reset}`)
181
- await waitForServer(PORT)
182
-
183
- console.log(`${colors.green}${colors.bright}Ready!${colors.reset}\n`)
184
-
185
- if (!noOpen) {
186
- setTimeout(() => openBrowser(WEB_URL), 500)
187
- }
188
- } catch (err) {
189
- console.log(`${colors.red}${err.message}${colors.reset}`)
190
- }
191
-
192
- // Handle shutdown
193
- const cleanup = () => {
194
- console.log(`\n${colors.yellow}Shutting down...${colors.reset}`)
195
- webProc.kill()
196
- process.exit(0)
197
- }
198
-
199
- process.on('SIGINT', cleanup)
200
- process.on('SIGTERM', cleanup)
201
-
202
- webProc.on('error', (err) => {
203
- console.log(`${colors.red}Error: ${err.message}${colors.reset}`)
204
- })
205
-
206
- webProc.on('exit', (code) => {
207
- if (code !== 0 && code !== null) {
208
- console.log(`${colors.red}Exited with code ${code}${colors.reset}`)
209
- }
210
- })
211
- }
212
-
213
- main().catch((err) => {
214
- console.error(`${colors.red}Error: ${err.message}${colors.reset}`)
215
- process.exit(1)
216
- })