prjct-cli 0.12.1 → 0.13.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 (38) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/CLAUDE.md +18 -6
  3. package/bin/serve.js +12 -30
  4. package/core/data/index.ts +19 -5
  5. package/core/data/md-base-manager.ts +203 -0
  6. package/core/data/md-queue-manager.ts +179 -0
  7. package/core/data/md-state-manager.ts +133 -0
  8. package/core/serializers/index.ts +20 -0
  9. package/core/serializers/queue-serializer.ts +210 -0
  10. package/core/serializers/state-serializer.ts +136 -0
  11. package/core/utils/file-helper.ts +12 -0
  12. package/package.json +1 -1
  13. package/packages/web/app/api/projects/[id]/stats/route.ts +6 -29
  14. package/packages/web/app/project/[id]/page.tsx +34 -1
  15. package/packages/web/app/project/[id]/stats/page.tsx +11 -5
  16. package/packages/web/app/settings/page.tsx +2 -221
  17. package/packages/web/components/AppSidebar/AppSidebar.tsx +5 -3
  18. package/packages/web/components/BlockersCard/BlockersCard.tsx +67 -0
  19. package/packages/web/components/BlockersCard/BlockersCard.types.ts +11 -0
  20. package/packages/web/components/BlockersCard/index.ts +2 -0
  21. package/packages/web/components/CommandButton/CommandButton.tsx +10 -3
  22. package/packages/web/lib/projects.ts +28 -27
  23. package/packages/web/lib/services/projects.server.ts +25 -21
  24. package/packages/web/lib/services/stats.server.ts +355 -57
  25. package/packages/web/package.json +0 -2
  26. package/templates/commands/decision.md +226 -0
  27. package/templates/commands/done.md +100 -68
  28. package/templates/commands/feature.md +102 -103
  29. package/templates/commands/idea.md +41 -38
  30. package/templates/commands/now.md +94 -33
  31. package/templates/commands/pause.md +90 -30
  32. package/templates/commands/ship.md +179 -74
  33. package/templates/commands/sync.md +324 -200
  34. package/packages/web/app/api/migrate/route.ts +0 -46
  35. package/packages/web/app/api/settings/route.ts +0 -97
  36. package/packages/web/app/api/v2/projects/[id]/unified/route.ts +0 -57
  37. package/packages/web/lib/json-loader.ts +0 -630
  38. package/packages/web/lib/services/migration.server.ts +0 -600
@@ -1,46 +0,0 @@
1
- import { NextResponse } from 'next/server'
2
- import { migrateProject, getProjectsToMigrate } from '@/lib/services/migration.server'
3
-
4
- export async function GET() {
5
- try {
6
- const projects = await getProjectsToMigrate()
7
- return NextResponse.json({
8
- success: true,
9
- data: { projects }
10
- })
11
- } catch (error) {
12
- return NextResponse.json(
13
- { success: false, error: 'Failed to list projects' },
14
- { status: 500 }
15
- )
16
- }
17
- }
18
-
19
- export async function POST(request: Request) {
20
- try {
21
- const body = await request.json()
22
- const { projectId } = body
23
-
24
- if (!projectId) {
25
- return NextResponse.json(
26
- { success: false, error: 'Project ID is required' },
27
- { status: 400 }
28
- )
29
- }
30
-
31
- const result = await migrateProject(projectId)
32
-
33
- return NextResponse.json({
34
- success: result.success,
35
- data: result
36
- })
37
- } catch (error) {
38
- return NextResponse.json(
39
- {
40
- success: false,
41
- error: error instanceof Error ? error.message : 'Migration failed'
42
- },
43
- { status: 500 }
44
- )
45
- }
46
- }
@@ -1,97 +0,0 @@
1
- import { NextResponse } from 'next/server'
2
- import { promises as fs } from 'fs'
3
- import { join } from 'path'
4
- import { homedir } from 'os'
5
-
6
- const SETTINGS_PATH = join(homedir(), '.prjct-cli', 'settings.json')
7
-
8
- interface Settings {
9
- openRouterApiKey?: string
10
- }
11
-
12
- async function getSettings(): Promise<Settings> {
13
- try {
14
- const content = await fs.readFile(SETTINGS_PATH, 'utf-8')
15
- return JSON.parse(content)
16
- } catch {
17
- return {}
18
- }
19
- }
20
-
21
- async function saveSettings(settings: Settings): Promise<void> {
22
- const dir = join(homedir(), '.prjct-cli')
23
- await fs.mkdir(dir, { recursive: true })
24
- await fs.writeFile(SETTINGS_PATH, JSON.stringify(settings, null, 2))
25
- }
26
-
27
- export async function GET() {
28
- try {
29
- const settings = await getSettings()
30
- // Mask the API key for security (only show last 4 chars)
31
- const maskedKey = settings.openRouterApiKey
32
- ? `sk-...${settings.openRouterApiKey.slice(-4)}`
33
- : null
34
-
35
- return NextResponse.json({
36
- success: true,
37
- data: {
38
- hasApiKey: !!settings.openRouterApiKey,
39
- maskedKey
40
- }
41
- })
42
- } catch (error) {
43
- return NextResponse.json(
44
- { success: false, error: 'Failed to read settings' },
45
- { status: 500 }
46
- )
47
- }
48
- }
49
-
50
- export async function POST(request: Request) {
51
- try {
52
- const body = await request.json()
53
- const { openRouterApiKey } = body
54
-
55
- if (!openRouterApiKey || typeof openRouterApiKey !== 'string') {
56
- return NextResponse.json(
57
- { success: false, error: 'Invalid API key' },
58
- { status: 400 }
59
- )
60
- }
61
-
62
- const settings = await getSettings()
63
- settings.openRouterApiKey = openRouterApiKey
64
- await saveSettings(settings)
65
-
66
- return NextResponse.json({
67
- success: true,
68
- data: {
69
- hasApiKey: true,
70
- maskedKey: `sk-...${openRouterApiKey.slice(-4)}`
71
- }
72
- })
73
- } catch (error) {
74
- return NextResponse.json(
75
- { success: false, error: 'Failed to save settings' },
76
- { status: 500 }
77
- )
78
- }
79
- }
80
-
81
- export async function DELETE() {
82
- try {
83
- const settings = await getSettings()
84
- delete settings.openRouterApiKey
85
- await saveSettings(settings)
86
-
87
- return NextResponse.json({
88
- success: true,
89
- data: { hasApiKey: false, maskedKey: null }
90
- })
91
- } catch (error) {
92
- return NextResponse.json(
93
- { success: false, error: 'Failed to delete API key' },
94
- { status: 500 }
95
- )
96
- }
97
- }
@@ -1,57 +0,0 @@
1
- import { NextRequest, NextResponse } from 'next/server'
2
- import { loadUnifiedJsonData } from '@/lib/json-loader'
3
-
4
- export async function GET(
5
- request: NextRequest,
6
- { params }: { params: Promise<{ id: string }> }
7
- ) {
8
- const { id: projectId } = await params
9
-
10
- if (!projectId) {
11
- return NextResponse.json(
12
- { success: false, error: 'Project ID required' },
13
- { status: 400 }
14
- )
15
- }
16
-
17
- try {
18
- // Load all JSON data directly
19
- const jsonData = await loadUnifiedJsonData(projectId)
20
-
21
- if (!jsonData.hasJsonData) {
22
- // No JSON files exist yet
23
- return NextResponse.json({
24
- success: true,
25
- version: 'v2-empty',
26
- state: null,
27
- project: null,
28
- agents: [],
29
- ideas: [],
30
- roadmap: [],
31
- shipped: [],
32
- analysis: null,
33
- outcomes: [],
34
- insights: {
35
- healthScore: 0,
36
- estimateAccuracy: 0,
37
- topBlockers: [],
38
- patternsDetected: [],
39
- recommendations: ['Run /p:sync to initialize project data'],
40
- },
41
- hasJsonData: false,
42
- })
43
- }
44
-
45
- return NextResponse.json({
46
- success: true,
47
- version: 'v2',
48
- ...jsonData,
49
- })
50
- } catch (error) {
51
- console.error('[API v2] Error getting unified project data:', error)
52
- return NextResponse.json(
53
- { success: false, error: 'Failed to get project data' },
54
- { status: 500 }
55
- )
56
- }
57
- }