prjct-cli 0.48.0 → 0.50.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.
- package/CHANGELOG.md +31 -2
- package/core/commands/analytics.ts +1 -1
- package/core/commands/cleanup.ts +1 -1
- package/core/commands/planning.ts +4 -4
- package/core/commands/shipping.ts +1 -1
- package/core/commands/snapshots.ts +6 -6
- package/core/commands/workflow.ts +6 -6
- package/core/utils/error-messages.ts +161 -0
- package/core/utils/output.ts +136 -4
- package/dist/bin/prjct.mjs +247 -24
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,10 +1,39 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## [0.
|
|
3
|
+
## [0.50.0] - 2026-01-30
|
|
4
4
|
|
|
5
5
|
### Features
|
|
6
6
|
|
|
7
|
-
-
|
|
7
|
+
- Unified output system with new methods - PRJ-130 (#76)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
## [0.50.0] - 2026-01-30
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **Unified output system with new methods** (PRJ-130)
|
|
15
|
+
- Added `ICONS` constant for centralized icon definitions
|
|
16
|
+
- New methods: `info()`, `debug()`, `success()`, `list()`, `table()`, `box()`
|
|
17
|
+
- `debug()` only shows output when `DEBUG=1`
|
|
18
|
+
- Refactored existing methods to use `ICONS` for consistency
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
## [0.49.0] - 2026-01-30
|
|
22
|
+
|
|
23
|
+
### Features
|
|
24
|
+
|
|
25
|
+
- Error messages with context and recovery hints - PRJ-131 (#75)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
## [0.49.1] - 2026-01-30
|
|
29
|
+
|
|
30
|
+
### Improved
|
|
31
|
+
|
|
32
|
+
- **Error messages with context and recovery hints** (PRJ-131)
|
|
33
|
+
- Created error catalog with 15+ error types
|
|
34
|
+
- Added `out.failWithHint()` for rich error output
|
|
35
|
+
- Errors now show file path and recovery hints
|
|
36
|
+
- Example: `✗ Project ID not found` → `💡 Run 'prjct init'`
|
|
8
37
|
|
|
9
38
|
|
|
10
39
|
## [0.49.0] - 2026-01-30
|
|
@@ -39,7 +39,7 @@ export class AnalyticsCommands extends PrjctCommandsBase {
|
|
|
39
39
|
|
|
40
40
|
const projectId = await configManager.getProjectId(projectPath)
|
|
41
41
|
if (!projectId) {
|
|
42
|
-
out.
|
|
42
|
+
out.failWithHint('NO_PROJECT_ID')
|
|
43
43
|
return { success: false, error: 'No project ID found' }
|
|
44
44
|
}
|
|
45
45
|
|
package/core/commands/cleanup.ts
CHANGED
|
@@ -254,7 +254,7 @@ export class PlanningCommands extends PrjctCommandsBase {
|
|
|
254
254
|
|
|
255
255
|
const projectId = await configManager.getProjectId(projectPath)
|
|
256
256
|
if (!projectId) {
|
|
257
|
-
out.
|
|
257
|
+
out.failWithHint('NO_PROJECT_ID')
|
|
258
258
|
return { success: false, error: 'No project ID found' }
|
|
259
259
|
}
|
|
260
260
|
|
|
@@ -325,7 +325,7 @@ export class PlanningCommands extends PrjctCommandsBase {
|
|
|
325
325
|
|
|
326
326
|
const projectId = await configManager.getProjectId(projectPath)
|
|
327
327
|
if (!projectId) {
|
|
328
|
-
out.
|
|
328
|
+
out.failWithHint('NO_PROJECT_ID')
|
|
329
329
|
return { success: false, error: 'No project ID found' }
|
|
330
330
|
}
|
|
331
331
|
|
|
@@ -485,7 +485,7 @@ export class PlanningCommands extends PrjctCommandsBase {
|
|
|
485
485
|
|
|
486
486
|
const projectId = await configManager.getProjectId(projectPath)
|
|
487
487
|
if (!projectId) {
|
|
488
|
-
out.
|
|
488
|
+
out.failWithHint('NO_PROJECT_ID')
|
|
489
489
|
return { success: false, error: 'No project ID found' }
|
|
490
490
|
}
|
|
491
491
|
|
|
@@ -562,7 +562,7 @@ Generated: ${new Date().toLocaleString()}
|
|
|
562
562
|
|
|
563
563
|
const projectId = await configManager.getProjectId(projectPath)
|
|
564
564
|
if (!projectId) {
|
|
565
|
-
out.
|
|
565
|
+
out.failWithHint('NO_PROJECT_ID')
|
|
566
566
|
return { success: false, error: 'No project ID found' }
|
|
567
567
|
}
|
|
568
568
|
|
|
@@ -60,7 +60,7 @@ export class ShippingCommands extends PrjctCommandsBase {
|
|
|
60
60
|
|
|
61
61
|
const projectId = await configManager.getProjectId(projectPath)
|
|
62
62
|
if (!projectId) {
|
|
63
|
-
out.
|
|
63
|
+
out.failWithHint('NO_PROJECT_ID')
|
|
64
64
|
return { success: false, error: 'No project ID found' }
|
|
65
65
|
}
|
|
66
66
|
|
|
@@ -28,7 +28,7 @@ export async function recover(projectPath: string = process.cwd()): Promise<Comm
|
|
|
28
28
|
try {
|
|
29
29
|
const projectId = await configManager.getProjectId(projectPath)
|
|
30
30
|
if (!projectId) {
|
|
31
|
-
out.
|
|
31
|
+
out.failWithHint('NO_PROJECT_ID')
|
|
32
32
|
return { success: false, error: 'No project ID found' }
|
|
33
33
|
}
|
|
34
34
|
|
|
@@ -85,7 +85,7 @@ export async function undo(projectPath: string = process.cwd()): Promise<Command
|
|
|
85
85
|
|
|
86
86
|
const projectId = await configManager.getProjectId(projectPath)
|
|
87
87
|
if (!projectId) {
|
|
88
|
-
out.
|
|
88
|
+
out.failWithHint('NO_PROJECT_ID')
|
|
89
89
|
return { success: false, error: 'No project ID found' }
|
|
90
90
|
}
|
|
91
91
|
|
|
@@ -147,7 +147,7 @@ export async function undo(projectPath: string = process.cwd()): Promise<Command
|
|
|
147
147
|
out.done('changes stashed (use /p:redo to restore)')
|
|
148
148
|
return { success: true, snapshotId: stashMessage }
|
|
149
149
|
} catch (gitError) {
|
|
150
|
-
out.
|
|
150
|
+
out.failWithHint('GIT_OPERATION_FAILED')
|
|
151
151
|
return { success: false, error: (gitError as Error).message }
|
|
152
152
|
}
|
|
153
153
|
} catch (error) {
|
|
@@ -165,7 +165,7 @@ export async function redo(projectPath: string = process.cwd()): Promise<Command
|
|
|
165
165
|
|
|
166
166
|
const projectId = await configManager.getProjectId(projectPath)
|
|
167
167
|
if (!projectId) {
|
|
168
|
-
out.
|
|
168
|
+
out.failWithHint('NO_PROJECT_ID')
|
|
169
169
|
return { success: false, error: 'No project ID found' }
|
|
170
170
|
}
|
|
171
171
|
|
|
@@ -231,7 +231,7 @@ export async function redo(projectPath: string = process.cwd()): Promise<Command
|
|
|
231
231
|
out.done('changes restored')
|
|
232
232
|
return { success: true }
|
|
233
233
|
} catch (gitError) {
|
|
234
|
-
out.
|
|
234
|
+
out.failWithHint('GIT_OPERATION_FAILED')
|
|
235
235
|
return { success: false, error: (gitError as Error).message }
|
|
236
236
|
}
|
|
237
237
|
} catch (error) {
|
|
@@ -247,7 +247,7 @@ export async function history(projectPath: string = process.cwd()): Promise<Comm
|
|
|
247
247
|
try {
|
|
248
248
|
const projectId = await configManager.getProjectId(projectPath)
|
|
249
249
|
if (!projectId) {
|
|
250
|
-
out.
|
|
250
|
+
out.failWithHint('NO_PROJECT_ID')
|
|
251
251
|
return { success: false, error: 'No project ID found' }
|
|
252
252
|
}
|
|
253
253
|
|
|
@@ -43,7 +43,7 @@ export class WorkflowCommands extends PrjctCommandsBase {
|
|
|
43
43
|
|
|
44
44
|
const projectId = await configManager.getProjectId(projectPath)
|
|
45
45
|
if (!projectId) {
|
|
46
|
-
out.
|
|
46
|
+
out.failWithHint('NO_PROJECT_ID')
|
|
47
47
|
return { success: false, error: 'No project ID found' }
|
|
48
48
|
}
|
|
49
49
|
|
|
@@ -163,7 +163,7 @@ export class WorkflowCommands extends PrjctCommandsBase {
|
|
|
163
163
|
|
|
164
164
|
const projectId = await configManager.getProjectId(projectPath)
|
|
165
165
|
if (!projectId) {
|
|
166
|
-
out.
|
|
166
|
+
out.failWithHint('NO_PROJECT_ID')
|
|
167
167
|
return { success: false, error: 'No project ID found' }
|
|
168
168
|
}
|
|
169
169
|
|
|
@@ -246,7 +246,7 @@ export class WorkflowCommands extends PrjctCommandsBase {
|
|
|
246
246
|
|
|
247
247
|
const projectId = await configManager.getProjectId(projectPath)
|
|
248
248
|
if (!projectId) {
|
|
249
|
-
out.
|
|
249
|
+
out.failWithHint('NO_PROJECT_ID')
|
|
250
250
|
return { success: false, error: 'No project ID found' }
|
|
251
251
|
}
|
|
252
252
|
|
|
@@ -278,7 +278,7 @@ export class WorkflowCommands extends PrjctCommandsBase {
|
|
|
278
278
|
|
|
279
279
|
const projectId = await configManager.getProjectId(projectPath)
|
|
280
280
|
if (!projectId) {
|
|
281
|
-
out.
|
|
281
|
+
out.failWithHint('NO_PROJECT_ID')
|
|
282
282
|
return { success: false, error: 'No project ID found' }
|
|
283
283
|
}
|
|
284
284
|
|
|
@@ -323,7 +323,7 @@ export class WorkflowCommands extends PrjctCommandsBase {
|
|
|
323
323
|
|
|
324
324
|
const projectId = await configManager.getProjectId(projectPath)
|
|
325
325
|
if (!projectId) {
|
|
326
|
-
out.
|
|
326
|
+
out.failWithHint('NO_PROJECT_ID')
|
|
327
327
|
return { success: false, error: 'No project ID found' }
|
|
328
328
|
}
|
|
329
329
|
|
|
@@ -374,7 +374,7 @@ export class WorkflowCommands extends PrjctCommandsBase {
|
|
|
374
374
|
|
|
375
375
|
const projectId = await configManager.getProjectId(projectPath)
|
|
376
376
|
if (!projectId) {
|
|
377
|
-
out.
|
|
377
|
+
out.failWithHint('NO_PROJECT_ID')
|
|
378
378
|
return { success: false, error: 'No project ID found' }
|
|
379
379
|
}
|
|
380
380
|
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error Messages Catalog
|
|
3
|
+
*
|
|
4
|
+
* Centralized error messages with context and recovery hints.
|
|
5
|
+
* Provides consistent, helpful error output across the CLI.
|
|
6
|
+
*
|
|
7
|
+
* @see PRJ-131
|
|
8
|
+
* @module utils/error-messages
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
export interface ErrorWithHint {
|
|
12
|
+
message: string
|
|
13
|
+
hint?: string
|
|
14
|
+
file?: string
|
|
15
|
+
docs?: string
|
|
16
|
+
code?: string
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Common error messages with recovery hints
|
|
21
|
+
*/
|
|
22
|
+
export const ERRORS = {
|
|
23
|
+
// Project errors
|
|
24
|
+
NO_PROJECT: {
|
|
25
|
+
message: 'No prjct project found in this directory',
|
|
26
|
+
hint: "Run 'prjct init' to set up a new project",
|
|
27
|
+
file: '.prjct/prjct.config.json',
|
|
28
|
+
},
|
|
29
|
+
|
|
30
|
+
NO_PROJECT_ID: {
|
|
31
|
+
message: 'Project ID not found',
|
|
32
|
+
hint: "Run 'prjct init' or check .prjct/prjct.config.json",
|
|
33
|
+
file: '.prjct/prjct.config.json',
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
CONFIG_NOT_FOUND: {
|
|
37
|
+
message: 'Configuration file not found',
|
|
38
|
+
hint: "Run 'prjct init' to create project configuration",
|
|
39
|
+
file: '.prjct/prjct.config.json',
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
CONFIG_INVALID: {
|
|
43
|
+
message: 'Invalid configuration file',
|
|
44
|
+
hint: 'Check JSON syntax or delete .prjct/ and run init again',
|
|
45
|
+
file: '.prjct/prjct.config.json',
|
|
46
|
+
},
|
|
47
|
+
|
|
48
|
+
// Git errors
|
|
49
|
+
GIT_NOT_FOUND: {
|
|
50
|
+
message: 'Git repository not detected',
|
|
51
|
+
hint: "Run 'git init' first, then 'prjct init'",
|
|
52
|
+
},
|
|
53
|
+
|
|
54
|
+
GIT_NO_COMMITS: {
|
|
55
|
+
message: 'No commits in repository',
|
|
56
|
+
hint: 'Make an initial commit before using prjct',
|
|
57
|
+
},
|
|
58
|
+
|
|
59
|
+
GIT_DIRTY: {
|
|
60
|
+
message: 'Working directory has uncommitted changes',
|
|
61
|
+
hint: "Commit or stash changes, or use '--force' to override",
|
|
62
|
+
},
|
|
63
|
+
|
|
64
|
+
GIT_ON_MAIN: {
|
|
65
|
+
message: 'Cannot ship from main/master branch',
|
|
66
|
+
hint: 'Create a feature branch first: git checkout -b feature/your-feature',
|
|
67
|
+
},
|
|
68
|
+
|
|
69
|
+
GIT_OPERATION_FAILED: {
|
|
70
|
+
message: 'Git operation failed',
|
|
71
|
+
hint: 'Check git status and resolve any conflicts',
|
|
72
|
+
},
|
|
73
|
+
|
|
74
|
+
// Auth errors
|
|
75
|
+
GH_NOT_AUTHENTICATED: {
|
|
76
|
+
message: 'GitHub CLI not authenticated',
|
|
77
|
+
hint: "Run 'gh auth login' to authenticate",
|
|
78
|
+
docs: 'https://cli.github.com/manual/gh_auth_login',
|
|
79
|
+
},
|
|
80
|
+
|
|
81
|
+
LINEAR_NOT_CONFIGURED: {
|
|
82
|
+
message: 'Linear integration not configured',
|
|
83
|
+
hint: "Run 'p. linear setup' to configure Linear",
|
|
84
|
+
},
|
|
85
|
+
|
|
86
|
+
LINEAR_API_ERROR: {
|
|
87
|
+
message: 'Linear API error',
|
|
88
|
+
hint: 'Check your API key or network connection',
|
|
89
|
+
},
|
|
90
|
+
|
|
91
|
+
// Task errors
|
|
92
|
+
NO_ACTIVE_TASK: {
|
|
93
|
+
message: 'No active task',
|
|
94
|
+
hint: 'Start a task with \'p. task "description"\'',
|
|
95
|
+
},
|
|
96
|
+
|
|
97
|
+
TASK_ALREADY_ACTIVE: {
|
|
98
|
+
message: 'A task is already in progress',
|
|
99
|
+
hint: "Complete it with 'p. done' or pause with 'p. pause'",
|
|
100
|
+
},
|
|
101
|
+
|
|
102
|
+
// Sync errors
|
|
103
|
+
SYNC_FAILED: {
|
|
104
|
+
message: 'Project sync failed',
|
|
105
|
+
hint: 'Check file permissions and try again',
|
|
106
|
+
},
|
|
107
|
+
|
|
108
|
+
// Ship errors
|
|
109
|
+
NOTHING_TO_SHIP: {
|
|
110
|
+
message: 'Nothing to ship',
|
|
111
|
+
hint: 'Make some changes first, then run ship',
|
|
112
|
+
},
|
|
113
|
+
|
|
114
|
+
PR_CREATE_FAILED: {
|
|
115
|
+
message: 'Failed to create pull request',
|
|
116
|
+
hint: 'Check GitHub auth and remote configuration',
|
|
117
|
+
},
|
|
118
|
+
|
|
119
|
+
// Provider errors
|
|
120
|
+
NO_AI_PROVIDER: {
|
|
121
|
+
message: 'No AI provider detected',
|
|
122
|
+
hint: "Install Claude Code or Gemini CLI, then run 'prjct start'",
|
|
123
|
+
docs: 'https://prjct.app/docs',
|
|
124
|
+
},
|
|
125
|
+
|
|
126
|
+
PROVIDER_NOT_CONFIGURED: {
|
|
127
|
+
message: 'AI provider not configured for prjct',
|
|
128
|
+
hint: "Run 'prjct start' to configure your provider",
|
|
129
|
+
},
|
|
130
|
+
|
|
131
|
+
// Generic
|
|
132
|
+
UNKNOWN: {
|
|
133
|
+
message: 'An unexpected error occurred',
|
|
134
|
+
hint: 'Check the error details and try again',
|
|
135
|
+
},
|
|
136
|
+
} as const
|
|
137
|
+
|
|
138
|
+
export type ErrorCode = keyof typeof ERRORS
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Get error with optional overrides
|
|
142
|
+
*/
|
|
143
|
+
export function getError(code: ErrorCode, overrides?: Partial<ErrorWithHint>): ErrorWithHint {
|
|
144
|
+
const base = ERRORS[code]
|
|
145
|
+
return { ...base, ...overrides }
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Create a custom error with hint
|
|
150
|
+
*/
|
|
151
|
+
export function createError(
|
|
152
|
+
message: string,
|
|
153
|
+
hint?: string,
|
|
154
|
+
options?: { file?: string; docs?: string }
|
|
155
|
+
): ErrorWithHint {
|
|
156
|
+
return {
|
|
157
|
+
message,
|
|
158
|
+
hint,
|
|
159
|
+
...options,
|
|
160
|
+
}
|
|
161
|
+
}
|
package/core/utils/output.ts
CHANGED
|
@@ -1,17 +1,37 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Unified Output System for prjct-cli
|
|
3
3
|
* Spinner while working → Single line result
|
|
4
4
|
* With prjct branding
|
|
5
5
|
*
|
|
6
6
|
* Supports --quiet mode for CI/CD and scripting
|
|
7
|
+
*
|
|
8
|
+
* @see PRJ-130
|
|
7
9
|
*/
|
|
8
10
|
|
|
9
11
|
import chalk from 'chalk'
|
|
10
12
|
import branding from './branding'
|
|
13
|
+
import type { ErrorCode, ErrorWithHint } from './error-messages'
|
|
14
|
+
import { getError } from './error-messages'
|
|
11
15
|
|
|
12
16
|
const _FRAMES = branding.spinner.frames
|
|
13
17
|
const SPEED = branding.spinner.speed
|
|
14
18
|
|
|
19
|
+
/**
|
|
20
|
+
* Centralized icons for consistent output
|
|
21
|
+
*/
|
|
22
|
+
export const ICONS = {
|
|
23
|
+
success: chalk.green('✓'),
|
|
24
|
+
fail: chalk.red('✗'),
|
|
25
|
+
warn: chalk.yellow('⚠'),
|
|
26
|
+
info: chalk.blue('ℹ'),
|
|
27
|
+
debug: chalk.dim('🔧'),
|
|
28
|
+
bullet: chalk.dim('•'),
|
|
29
|
+
arrow: chalk.dim('→'),
|
|
30
|
+
check: chalk.green('✓'),
|
|
31
|
+
cross: chalk.red('✗'),
|
|
32
|
+
spinner: chalk.cyan('◐'),
|
|
33
|
+
} as const
|
|
34
|
+
|
|
15
35
|
let interval: ReturnType<typeof setInterval> | null = null
|
|
16
36
|
let frame = 0
|
|
17
37
|
|
|
@@ -53,7 +73,14 @@ interface Output {
|
|
|
53
73
|
spin(msg: string): Output
|
|
54
74
|
done(msg: string, metrics?: OutputMetrics): Output
|
|
55
75
|
fail(msg: string): Output
|
|
76
|
+
failWithHint(error: ErrorWithHint | ErrorCode): Output
|
|
56
77
|
warn(msg: string): Output
|
|
78
|
+
info(msg: string): Output
|
|
79
|
+
debug(msg: string): Output
|
|
80
|
+
success(msg: string, metrics?: OutputMetrics): Output
|
|
81
|
+
list(items: string[], options?: { bullet?: string; indent?: number }): Output
|
|
82
|
+
table(rows: Array<Record<string, string | number>>, options?: { header?: boolean }): Output
|
|
83
|
+
box(title: string, content: string): Output
|
|
57
84
|
stop(): Output
|
|
58
85
|
step(current: number, total: number, msg: string): Output
|
|
59
86
|
progress(current: number, total: number, msg?: string): Output
|
|
@@ -96,7 +123,7 @@ const out: Output = {
|
|
|
96
123
|
suffix = chalk.dim(` [${parts.join(' | ')}]`)
|
|
97
124
|
}
|
|
98
125
|
}
|
|
99
|
-
console.log(`${
|
|
126
|
+
console.log(`${ICONS.success} ${truncate(msg, 50)}${suffix}`)
|
|
100
127
|
}
|
|
101
128
|
return this
|
|
102
129
|
},
|
|
@@ -104,13 +131,116 @@ const out: Output = {
|
|
|
104
131
|
// Errors go to stderr even in quiet mode
|
|
105
132
|
fail(msg: string) {
|
|
106
133
|
this.stop()
|
|
107
|
-
console.error(`${
|
|
134
|
+
console.error(`${ICONS.fail} ${truncate(msg, 65)}`)
|
|
135
|
+
return this
|
|
136
|
+
},
|
|
137
|
+
|
|
138
|
+
// Rich error with context and recovery hint
|
|
139
|
+
failWithHint(error: ErrorWithHint | ErrorCode) {
|
|
140
|
+
this.stop()
|
|
141
|
+
const err = typeof error === 'string' ? getError(error) : error
|
|
142
|
+
console.error()
|
|
143
|
+
console.error(`${ICONS.fail} ${err.message}`)
|
|
144
|
+
if (err.file) {
|
|
145
|
+
console.error(chalk.dim(` File: ${err.file}`))
|
|
146
|
+
}
|
|
147
|
+
if (err.hint) {
|
|
148
|
+
console.error(chalk.yellow(` 💡 ${err.hint}`))
|
|
149
|
+
}
|
|
150
|
+
if (err.docs) {
|
|
151
|
+
console.error(chalk.dim(` Docs: ${err.docs}`))
|
|
152
|
+
}
|
|
153
|
+
console.error()
|
|
108
154
|
return this
|
|
109
155
|
},
|
|
110
156
|
|
|
111
157
|
warn(msg: string) {
|
|
112
158
|
this.stop()
|
|
113
|
-
if (!quietMode) console.log(`${
|
|
159
|
+
if (!quietMode) console.log(`${ICONS.warn} ${truncate(msg, 65)}`)
|
|
160
|
+
return this
|
|
161
|
+
},
|
|
162
|
+
|
|
163
|
+
// Informational message
|
|
164
|
+
info(msg: string) {
|
|
165
|
+
this.stop()
|
|
166
|
+
if (!quietMode) console.log(`${ICONS.info} ${msg}`)
|
|
167
|
+
return this
|
|
168
|
+
},
|
|
169
|
+
|
|
170
|
+
// Debug message (only if DEBUG=1 or DEBUG=true)
|
|
171
|
+
debug(msg: string) {
|
|
172
|
+
this.stop()
|
|
173
|
+
const debugEnabled = process.env.DEBUG === '1' || process.env.DEBUG === 'true'
|
|
174
|
+
if (!quietMode && debugEnabled) {
|
|
175
|
+
console.log(`${ICONS.debug} ${chalk.dim(msg)}`)
|
|
176
|
+
}
|
|
177
|
+
return this
|
|
178
|
+
},
|
|
179
|
+
|
|
180
|
+
// Alias for done - explicit success indicator
|
|
181
|
+
success(msg: string, metrics?: OutputMetrics) {
|
|
182
|
+
return this.done(msg, metrics)
|
|
183
|
+
},
|
|
184
|
+
|
|
185
|
+
// Bulleted list
|
|
186
|
+
list(items: string[], options: { bullet?: string; indent?: number } = {}) {
|
|
187
|
+
this.stop()
|
|
188
|
+
if (quietMode) return this
|
|
189
|
+
const bullet = options.bullet || ICONS.bullet
|
|
190
|
+
const indent = ' '.repeat(options.indent || 0)
|
|
191
|
+
for (const item of items) {
|
|
192
|
+
console.log(`${indent}${bullet} ${item}`)
|
|
193
|
+
}
|
|
194
|
+
return this
|
|
195
|
+
},
|
|
196
|
+
|
|
197
|
+
// Simple table output
|
|
198
|
+
table(rows: Array<Record<string, string | number>>, options: { header?: boolean } = {}) {
|
|
199
|
+
this.stop()
|
|
200
|
+
if (quietMode || rows.length === 0) return this
|
|
201
|
+
|
|
202
|
+
const keys = Object.keys(rows[0])
|
|
203
|
+
const colWidths: Record<string, number> = {}
|
|
204
|
+
|
|
205
|
+
// Calculate column widths
|
|
206
|
+
for (const key of keys) {
|
|
207
|
+
colWidths[key] = key.length
|
|
208
|
+
for (const row of rows) {
|
|
209
|
+
const val = String(row[key] ?? '')
|
|
210
|
+
if (val.length > colWidths[key]) colWidths[key] = val.length
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// Print header if requested
|
|
215
|
+
if (options.header !== false) {
|
|
216
|
+
const headerLine = keys.map((k) => k.padEnd(colWidths[k])).join(' ')
|
|
217
|
+
console.log(chalk.dim(headerLine))
|
|
218
|
+
console.log(chalk.dim('─'.repeat(headerLine.length)))
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// Print rows
|
|
222
|
+
for (const row of rows) {
|
|
223
|
+
const line = keys.map((k) => String(row[k] ?? '').padEnd(colWidths[k])).join(' ')
|
|
224
|
+
console.log(line)
|
|
225
|
+
}
|
|
226
|
+
return this
|
|
227
|
+
},
|
|
228
|
+
|
|
229
|
+
// Boxed content
|
|
230
|
+
box(title: string, content: string) {
|
|
231
|
+
this.stop()
|
|
232
|
+
if (quietMode) return this
|
|
233
|
+
const lines = content.split('\n')
|
|
234
|
+
const maxLen = Math.max(title.length, ...lines.map((l) => l.length))
|
|
235
|
+
const border = '─'.repeat(maxLen + 2)
|
|
236
|
+
|
|
237
|
+
console.log(chalk.dim(`┌${border}┐`))
|
|
238
|
+
console.log(chalk.dim('│') + ` ${chalk.bold(title.padEnd(maxLen))} ` + chalk.dim('│'))
|
|
239
|
+
console.log(chalk.dim(`├${border}┤`))
|
|
240
|
+
for (const line of lines) {
|
|
241
|
+
console.log(chalk.dim('│') + ` ${line.padEnd(maxLen)} ` + chalk.dim('│'))
|
|
242
|
+
}
|
|
243
|
+
console.log(chalk.dim(`└${border}┘`))
|
|
114
244
|
return this
|
|
115
245
|
},
|
|
116
246
|
|
|
@@ -151,4 +281,6 @@ const out: Output = {
|
|
|
151
281
|
}
|
|
152
282
|
|
|
153
283
|
export type { OutputMetrics }
|
|
284
|
+
export type { ErrorCode, ErrorWithHint } from './error-messages'
|
|
285
|
+
export { createError, ERRORS, getError } from './error-messages'
|
|
154
286
|
export default out
|
package/dist/bin/prjct.mjs
CHANGED
|
@@ -1944,10 +1944,131 @@ var init_branding = __esm({
|
|
|
1944
1944
|
}
|
|
1945
1945
|
});
|
|
1946
1946
|
|
|
1947
|
+
// core/utils/error-messages.ts
|
|
1948
|
+
function getError(code, overrides) {
|
|
1949
|
+
const base = ERRORS[code];
|
|
1950
|
+
return { ...base, ...overrides };
|
|
1951
|
+
}
|
|
1952
|
+
function createError(message, hint, options) {
|
|
1953
|
+
return {
|
|
1954
|
+
message,
|
|
1955
|
+
hint,
|
|
1956
|
+
...options
|
|
1957
|
+
};
|
|
1958
|
+
}
|
|
1959
|
+
var ERRORS;
|
|
1960
|
+
var init_error_messages = __esm({
|
|
1961
|
+
"core/utils/error-messages.ts"() {
|
|
1962
|
+
"use strict";
|
|
1963
|
+
ERRORS = {
|
|
1964
|
+
// Project errors
|
|
1965
|
+
NO_PROJECT: {
|
|
1966
|
+
message: "No prjct project found in this directory",
|
|
1967
|
+
hint: "Run 'prjct init' to set up a new project",
|
|
1968
|
+
file: ".prjct/prjct.config.json"
|
|
1969
|
+
},
|
|
1970
|
+
NO_PROJECT_ID: {
|
|
1971
|
+
message: "Project ID not found",
|
|
1972
|
+
hint: "Run 'prjct init' or check .prjct/prjct.config.json",
|
|
1973
|
+
file: ".prjct/prjct.config.json"
|
|
1974
|
+
},
|
|
1975
|
+
CONFIG_NOT_FOUND: {
|
|
1976
|
+
message: "Configuration file not found",
|
|
1977
|
+
hint: "Run 'prjct init' to create project configuration",
|
|
1978
|
+
file: ".prjct/prjct.config.json"
|
|
1979
|
+
},
|
|
1980
|
+
CONFIG_INVALID: {
|
|
1981
|
+
message: "Invalid configuration file",
|
|
1982
|
+
hint: "Check JSON syntax or delete .prjct/ and run init again",
|
|
1983
|
+
file: ".prjct/prjct.config.json"
|
|
1984
|
+
},
|
|
1985
|
+
// Git errors
|
|
1986
|
+
GIT_NOT_FOUND: {
|
|
1987
|
+
message: "Git repository not detected",
|
|
1988
|
+
hint: "Run 'git init' first, then 'prjct init'"
|
|
1989
|
+
},
|
|
1990
|
+
GIT_NO_COMMITS: {
|
|
1991
|
+
message: "No commits in repository",
|
|
1992
|
+
hint: "Make an initial commit before using prjct"
|
|
1993
|
+
},
|
|
1994
|
+
GIT_DIRTY: {
|
|
1995
|
+
message: "Working directory has uncommitted changes",
|
|
1996
|
+
hint: "Commit or stash changes, or use '--force' to override"
|
|
1997
|
+
},
|
|
1998
|
+
GIT_ON_MAIN: {
|
|
1999
|
+
message: "Cannot ship from main/master branch",
|
|
2000
|
+
hint: "Create a feature branch first: git checkout -b feature/your-feature"
|
|
2001
|
+
},
|
|
2002
|
+
GIT_OPERATION_FAILED: {
|
|
2003
|
+
message: "Git operation failed",
|
|
2004
|
+
hint: "Check git status and resolve any conflicts"
|
|
2005
|
+
},
|
|
2006
|
+
// Auth errors
|
|
2007
|
+
GH_NOT_AUTHENTICATED: {
|
|
2008
|
+
message: "GitHub CLI not authenticated",
|
|
2009
|
+
hint: "Run 'gh auth login' to authenticate",
|
|
2010
|
+
docs: "https://cli.github.com/manual/gh_auth_login"
|
|
2011
|
+
},
|
|
2012
|
+
LINEAR_NOT_CONFIGURED: {
|
|
2013
|
+
message: "Linear integration not configured",
|
|
2014
|
+
hint: "Run 'p. linear setup' to configure Linear"
|
|
2015
|
+
},
|
|
2016
|
+
LINEAR_API_ERROR: {
|
|
2017
|
+
message: "Linear API error",
|
|
2018
|
+
hint: "Check your API key or network connection"
|
|
2019
|
+
},
|
|
2020
|
+
// Task errors
|
|
2021
|
+
NO_ACTIVE_TASK: {
|
|
2022
|
+
message: "No active task",
|
|
2023
|
+
hint: `Start a task with 'p. task "description"'`
|
|
2024
|
+
},
|
|
2025
|
+
TASK_ALREADY_ACTIVE: {
|
|
2026
|
+
message: "A task is already in progress",
|
|
2027
|
+
hint: "Complete it with 'p. done' or pause with 'p. pause'"
|
|
2028
|
+
},
|
|
2029
|
+
// Sync errors
|
|
2030
|
+
SYNC_FAILED: {
|
|
2031
|
+
message: "Project sync failed",
|
|
2032
|
+
hint: "Check file permissions and try again"
|
|
2033
|
+
},
|
|
2034
|
+
// Ship errors
|
|
2035
|
+
NOTHING_TO_SHIP: {
|
|
2036
|
+
message: "Nothing to ship",
|
|
2037
|
+
hint: "Make some changes first, then run ship"
|
|
2038
|
+
},
|
|
2039
|
+
PR_CREATE_FAILED: {
|
|
2040
|
+
message: "Failed to create pull request",
|
|
2041
|
+
hint: "Check GitHub auth and remote configuration"
|
|
2042
|
+
},
|
|
2043
|
+
// Provider errors
|
|
2044
|
+
NO_AI_PROVIDER: {
|
|
2045
|
+
message: "No AI provider detected",
|
|
2046
|
+
hint: "Install Claude Code or Gemini CLI, then run 'prjct start'",
|
|
2047
|
+
docs: "https://prjct.app/docs"
|
|
2048
|
+
},
|
|
2049
|
+
PROVIDER_NOT_CONFIGURED: {
|
|
2050
|
+
message: "AI provider not configured for prjct",
|
|
2051
|
+
hint: "Run 'prjct start' to configure your provider"
|
|
2052
|
+
},
|
|
2053
|
+
// Generic
|
|
2054
|
+
UNKNOWN: {
|
|
2055
|
+
message: "An unexpected error occurred",
|
|
2056
|
+
hint: "Check the error details and try again"
|
|
2057
|
+
}
|
|
2058
|
+
};
|
|
2059
|
+
__name(getError, "getError");
|
|
2060
|
+
__name(createError, "createError");
|
|
2061
|
+
}
|
|
2062
|
+
});
|
|
2063
|
+
|
|
1947
2064
|
// core/utils/output.ts
|
|
1948
2065
|
var output_exports = {};
|
|
1949
2066
|
__export(output_exports, {
|
|
2067
|
+
ERRORS: () => ERRORS,
|
|
2068
|
+
ICONS: () => ICONS,
|
|
2069
|
+
createError: () => createError,
|
|
1950
2070
|
default: () => output_default,
|
|
2071
|
+
getError: () => getError,
|
|
1951
2072
|
isQuietMode: () => isQuietMode,
|
|
1952
2073
|
setQuietMode: () => setQuietMode
|
|
1953
2074
|
});
|
|
@@ -1958,13 +2079,27 @@ function setQuietMode(enabled) {
|
|
|
1958
2079
|
function isQuietMode() {
|
|
1959
2080
|
return quietMode;
|
|
1960
2081
|
}
|
|
1961
|
-
var _FRAMES, SPEED, interval, frame, quietMode, truncate, clear, out, output_default;
|
|
2082
|
+
var _FRAMES, SPEED, ICONS, interval, frame, quietMode, truncate, clear, out, output_default;
|
|
1962
2083
|
var init_output = __esm({
|
|
1963
2084
|
"core/utils/output.ts"() {
|
|
1964
2085
|
"use strict";
|
|
1965
2086
|
init_branding();
|
|
2087
|
+
init_error_messages();
|
|
2088
|
+
init_error_messages();
|
|
1966
2089
|
_FRAMES = branding_default.spinner.frames;
|
|
1967
2090
|
SPEED = branding_default.spinner.speed;
|
|
2091
|
+
ICONS = {
|
|
2092
|
+
success: chalk2.green("\u2713"),
|
|
2093
|
+
fail: chalk2.red("\u2717"),
|
|
2094
|
+
warn: chalk2.yellow("\u26A0"),
|
|
2095
|
+
info: chalk2.blue("\u2139"),
|
|
2096
|
+
debug: chalk2.dim("\u{1F527}"),
|
|
2097
|
+
bullet: chalk2.dim("\u2022"),
|
|
2098
|
+
arrow: chalk2.dim("\u2192"),
|
|
2099
|
+
check: chalk2.green("\u2713"),
|
|
2100
|
+
cross: chalk2.red("\u2717"),
|
|
2101
|
+
spinner: chalk2.cyan("\u25D0")
|
|
2102
|
+
};
|
|
1968
2103
|
interval = null;
|
|
1969
2104
|
frame = 0;
|
|
1970
2105
|
quietMode = false;
|
|
@@ -2005,19 +2140,107 @@ var init_output = __esm({
|
|
|
2005
2140
|
suffix = chalk2.dim(` [${parts.join(" | ")}]`);
|
|
2006
2141
|
}
|
|
2007
2142
|
}
|
|
2008
|
-
console.log(`${
|
|
2143
|
+
console.log(`${ICONS.success} ${truncate(msg, 50)}${suffix}`);
|
|
2009
2144
|
}
|
|
2010
2145
|
return this;
|
|
2011
2146
|
},
|
|
2012
2147
|
// Errors go to stderr even in quiet mode
|
|
2013
2148
|
fail(msg) {
|
|
2014
2149
|
this.stop();
|
|
2015
|
-
console.error(`${
|
|
2150
|
+
console.error(`${ICONS.fail} ${truncate(msg, 65)}`);
|
|
2151
|
+
return this;
|
|
2152
|
+
},
|
|
2153
|
+
// Rich error with context and recovery hint
|
|
2154
|
+
failWithHint(error) {
|
|
2155
|
+
this.stop();
|
|
2156
|
+
const err = typeof error === "string" ? getError(error) : error;
|
|
2157
|
+
console.error();
|
|
2158
|
+
console.error(`${ICONS.fail} ${err.message}`);
|
|
2159
|
+
if (err.file) {
|
|
2160
|
+
console.error(chalk2.dim(` File: ${err.file}`));
|
|
2161
|
+
}
|
|
2162
|
+
if (err.hint) {
|
|
2163
|
+
console.error(chalk2.yellow(` \u{1F4A1} ${err.hint}`));
|
|
2164
|
+
}
|
|
2165
|
+
if (err.docs) {
|
|
2166
|
+
console.error(chalk2.dim(` Docs: ${err.docs}`));
|
|
2167
|
+
}
|
|
2168
|
+
console.error();
|
|
2016
2169
|
return this;
|
|
2017
2170
|
},
|
|
2018
2171
|
warn(msg) {
|
|
2019
2172
|
this.stop();
|
|
2020
|
-
if (!quietMode) console.log(`${
|
|
2173
|
+
if (!quietMode) console.log(`${ICONS.warn} ${truncate(msg, 65)}`);
|
|
2174
|
+
return this;
|
|
2175
|
+
},
|
|
2176
|
+
// Informational message
|
|
2177
|
+
info(msg) {
|
|
2178
|
+
this.stop();
|
|
2179
|
+
if (!quietMode) console.log(`${ICONS.info} ${msg}`);
|
|
2180
|
+
return this;
|
|
2181
|
+
},
|
|
2182
|
+
// Debug message (only if DEBUG=1 or DEBUG=true)
|
|
2183
|
+
debug(msg) {
|
|
2184
|
+
this.stop();
|
|
2185
|
+
const debugEnabled = process.env.DEBUG === "1" || process.env.DEBUG === "true";
|
|
2186
|
+
if (!quietMode && debugEnabled) {
|
|
2187
|
+
console.log(`${ICONS.debug} ${chalk2.dim(msg)}`);
|
|
2188
|
+
}
|
|
2189
|
+
return this;
|
|
2190
|
+
},
|
|
2191
|
+
// Alias for done - explicit success indicator
|
|
2192
|
+
success(msg, metrics) {
|
|
2193
|
+
return this.done(msg, metrics);
|
|
2194
|
+
},
|
|
2195
|
+
// Bulleted list
|
|
2196
|
+
list(items, options = {}) {
|
|
2197
|
+
this.stop();
|
|
2198
|
+
if (quietMode) return this;
|
|
2199
|
+
const bullet = options.bullet || ICONS.bullet;
|
|
2200
|
+
const indent = " ".repeat(options.indent || 0);
|
|
2201
|
+
for (const item of items) {
|
|
2202
|
+
console.log(`${indent}${bullet} ${item}`);
|
|
2203
|
+
}
|
|
2204
|
+
return this;
|
|
2205
|
+
},
|
|
2206
|
+
// Simple table output
|
|
2207
|
+
table(rows, options = {}) {
|
|
2208
|
+
this.stop();
|
|
2209
|
+
if (quietMode || rows.length === 0) return this;
|
|
2210
|
+
const keys = Object.keys(rows[0]);
|
|
2211
|
+
const colWidths = {};
|
|
2212
|
+
for (const key of keys) {
|
|
2213
|
+
colWidths[key] = key.length;
|
|
2214
|
+
for (const row of rows) {
|
|
2215
|
+
const val = String(row[key] ?? "");
|
|
2216
|
+
if (val.length > colWidths[key]) colWidths[key] = val.length;
|
|
2217
|
+
}
|
|
2218
|
+
}
|
|
2219
|
+
if (options.header !== false) {
|
|
2220
|
+
const headerLine = keys.map((k) => k.padEnd(colWidths[k])).join(" ");
|
|
2221
|
+
console.log(chalk2.dim(headerLine));
|
|
2222
|
+
console.log(chalk2.dim("\u2500".repeat(headerLine.length)));
|
|
2223
|
+
}
|
|
2224
|
+
for (const row of rows) {
|
|
2225
|
+
const line = keys.map((k) => String(row[k] ?? "").padEnd(colWidths[k])).join(" ");
|
|
2226
|
+
console.log(line);
|
|
2227
|
+
}
|
|
2228
|
+
return this;
|
|
2229
|
+
},
|
|
2230
|
+
// Boxed content
|
|
2231
|
+
box(title, content) {
|
|
2232
|
+
this.stop();
|
|
2233
|
+
if (quietMode) return this;
|
|
2234
|
+
const lines = content.split("\n");
|
|
2235
|
+
const maxLen = Math.max(title.length, ...lines.map((l) => l.length));
|
|
2236
|
+
const border = "\u2500".repeat(maxLen + 2);
|
|
2237
|
+
console.log(chalk2.dim(`\u250C${border}\u2510`));
|
|
2238
|
+
console.log(chalk2.dim("\u2502") + ` ${chalk2.bold(title.padEnd(maxLen))} ` + chalk2.dim("\u2502"));
|
|
2239
|
+
console.log(chalk2.dim(`\u251C${border}\u2524`));
|
|
2240
|
+
for (const line of lines) {
|
|
2241
|
+
console.log(chalk2.dim("\u2502") + ` ${line.padEnd(maxLen)} ` + chalk2.dim("\u2502"));
|
|
2242
|
+
}
|
|
2243
|
+
console.log(chalk2.dim(`\u2514${border}\u2518`));
|
|
2021
2244
|
return this;
|
|
2022
2245
|
},
|
|
2023
2246
|
stop() {
|
|
@@ -16738,7 +16961,7 @@ Generated: ${(/* @__PURE__ */ new Date()).toLocaleString()}
|
|
|
16738
16961
|
}
|
|
16739
16962
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
16740
16963
|
if (!projectId) {
|
|
16741
|
-
output_default.
|
|
16964
|
+
output_default.failWithHint("NO_PROJECT_ID");
|
|
16742
16965
|
return { success: false, error: "No project ID found" };
|
|
16743
16966
|
}
|
|
16744
16967
|
output_default.spin(`planning ${description}...`);
|
|
@@ -16795,7 +17018,7 @@ Generated: ${(/* @__PURE__ */ new Date()).toLocaleString()}
|
|
|
16795
17018
|
}
|
|
16796
17019
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
16797
17020
|
if (!projectId) {
|
|
16798
|
-
output_default.
|
|
17021
|
+
output_default.failWithHint("NO_PROJECT_ID");
|
|
16799
17022
|
return { success: false, error: "No project ID found" };
|
|
16800
17023
|
}
|
|
16801
17024
|
output_default.spin("tracking bug...");
|
|
@@ -16918,7 +17141,7 @@ ${"=".repeat(60)}`);
|
|
|
16918
17141
|
}
|
|
16919
17142
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
16920
17143
|
if (!projectId) {
|
|
16921
|
-
output_default.
|
|
17144
|
+
output_default.failWithHint("NO_PROJECT_ID");
|
|
16922
17145
|
return { success: false, error: "No project ID found" };
|
|
16923
17146
|
}
|
|
16924
17147
|
const wordCount = description.split(/\s+/).length;
|
|
@@ -16976,7 +17199,7 @@ Generated: ${(/* @__PURE__ */ new Date()).toLocaleString()}
|
|
|
16976
17199
|
if (!initResult.success) return initResult;
|
|
16977
17200
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
16978
17201
|
if (!projectId) {
|
|
16979
|
-
output_default.
|
|
17202
|
+
output_default.failWithHint("NO_PROJECT_ID");
|
|
16980
17203
|
return { success: false, error: "No project ID found" };
|
|
16981
17204
|
}
|
|
16982
17205
|
if (!featureName) {
|
|
@@ -21067,7 +21290,7 @@ var init_analytics = __esm({
|
|
|
21067
21290
|
if (!initResult.success) return initResult;
|
|
21068
21291
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
21069
21292
|
if (!projectId) {
|
|
21070
|
-
output_default.
|
|
21293
|
+
output_default.failWithHint("NO_PROJECT_ID");
|
|
21071
21294
|
return { success: false, error: "No project ID found" };
|
|
21072
21295
|
}
|
|
21073
21296
|
const projectName = path45.basename(projectPath);
|
|
@@ -21507,7 +21730,7 @@ async function cleanup(options = {}, projectPath = process.cwd()) {
|
|
|
21507
21730
|
output_default.spin("cleaning up...");
|
|
21508
21731
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
21509
21732
|
if (!projectId) {
|
|
21510
|
-
output_default.
|
|
21733
|
+
output_default.failWithHint("NO_PROJECT_ID");
|
|
21511
21734
|
return { success: false, error: "No project ID found" };
|
|
21512
21735
|
}
|
|
21513
21736
|
const cleaned = [];
|
|
@@ -21666,7 +21889,7 @@ async function recover(projectPath = process.cwd()) {
|
|
|
21666
21889
|
try {
|
|
21667
21890
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
21668
21891
|
if (!projectId) {
|
|
21669
|
-
output_default.
|
|
21892
|
+
output_default.failWithHint("NO_PROJECT_ID");
|
|
21670
21893
|
return { success: false, error: "No project ID found" };
|
|
21671
21894
|
}
|
|
21672
21895
|
output_default.spin("checking for abandoned sessions...");
|
|
@@ -21710,7 +21933,7 @@ async function undo(projectPath = process.cwd()) {
|
|
|
21710
21933
|
output_default.spin("creating undo point...");
|
|
21711
21934
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
21712
21935
|
if (!projectId) {
|
|
21713
|
-
output_default.
|
|
21936
|
+
output_default.failWithHint("NO_PROJECT_ID");
|
|
21714
21937
|
return { success: false, error: "No project ID found" };
|
|
21715
21938
|
}
|
|
21716
21939
|
const snapshotsPath = path49.join(path_manager_default.getGlobalProjectPath(projectId), "snapshots");
|
|
@@ -21755,7 +21978,7 @@ async function undo(projectPath = process.cwd()) {
|
|
|
21755
21978
|
output_default.done("changes stashed (use /p:redo to restore)");
|
|
21756
21979
|
return { success: true, snapshotId: stashMessage };
|
|
21757
21980
|
} catch (gitError) {
|
|
21758
|
-
output_default.
|
|
21981
|
+
output_default.failWithHint("GIT_OPERATION_FAILED");
|
|
21759
21982
|
return { success: false, error: gitError.message };
|
|
21760
21983
|
}
|
|
21761
21984
|
} catch (error) {
|
|
@@ -21768,7 +21991,7 @@ async function redo(projectPath = process.cwd()) {
|
|
|
21768
21991
|
output_default.spin("restoring changes...");
|
|
21769
21992
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
21770
21993
|
if (!projectId) {
|
|
21771
|
-
output_default.
|
|
21994
|
+
output_default.failWithHint("NO_PROJECT_ID");
|
|
21772
21995
|
return { success: false, error: "No project ID found" };
|
|
21773
21996
|
}
|
|
21774
21997
|
const snapshotsPath = path49.join(path_manager_default.getGlobalProjectPath(projectId), "snapshots");
|
|
@@ -21816,7 +22039,7 @@ async function redo(projectPath = process.cwd()) {
|
|
|
21816
22039
|
output_default.done("changes restored");
|
|
21817
22040
|
return { success: true };
|
|
21818
22041
|
} catch (gitError) {
|
|
21819
|
-
output_default.
|
|
22042
|
+
output_default.failWithHint("GIT_OPERATION_FAILED");
|
|
21820
22043
|
return { success: false, error: gitError.message };
|
|
21821
22044
|
}
|
|
21822
22045
|
} catch (error) {
|
|
@@ -21828,7 +22051,7 @@ async function history(projectPath = process.cwd()) {
|
|
|
21828
22051
|
try {
|
|
21829
22052
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
21830
22053
|
if (!projectId) {
|
|
21831
|
-
output_default.
|
|
22054
|
+
output_default.failWithHint("NO_PROJECT_ID");
|
|
21832
22055
|
return { success: false, error: "No project ID found" };
|
|
21833
22056
|
}
|
|
21834
22057
|
const snapshotsPath = path49.join(path_manager_default.getGlobalProjectPath(projectId), "snapshots");
|
|
@@ -22483,7 +22706,7 @@ ${result.stderr}`.trim();
|
|
|
22483
22706
|
if (!initResult.success) return initResult;
|
|
22484
22707
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
22485
22708
|
if (!projectId) {
|
|
22486
|
-
output_default.
|
|
22709
|
+
output_default.failWithHint("NO_PROJECT_ID");
|
|
22487
22710
|
return { success: false, error: "No project ID found" };
|
|
22488
22711
|
}
|
|
22489
22712
|
let featureName = feature;
|
|
@@ -23557,7 +23780,7 @@ var init_workflow = __esm({
|
|
|
23557
23780
|
if (!initResult.success) return initResult;
|
|
23558
23781
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
23559
23782
|
if (!projectId) {
|
|
23560
|
-
output_default.
|
|
23783
|
+
output_default.failWithHint("NO_PROJECT_ID");
|
|
23561
23784
|
return { success: false, error: "No project ID found" };
|
|
23562
23785
|
}
|
|
23563
23786
|
if (task) {
|
|
@@ -23649,7 +23872,7 @@ var init_workflow = __esm({
|
|
|
23649
23872
|
if (!initResult.success) return initResult;
|
|
23650
23873
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
23651
23874
|
if (!projectId) {
|
|
23652
|
-
output_default.
|
|
23875
|
+
output_default.failWithHint("NO_PROJECT_ID");
|
|
23653
23876
|
return { success: false, error: "No project ID found" };
|
|
23654
23877
|
}
|
|
23655
23878
|
const currentTask = await stateStorage.getCurrentTask(projectId);
|
|
@@ -23715,7 +23938,7 @@ var init_workflow = __esm({
|
|
|
23715
23938
|
if (!initResult.success) return initResult;
|
|
23716
23939
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
23717
23940
|
if (!projectId) {
|
|
23718
|
-
output_default.
|
|
23941
|
+
output_default.failWithHint("NO_PROJECT_ID");
|
|
23719
23942
|
return { success: false, error: "No project ID found" };
|
|
23720
23943
|
}
|
|
23721
23944
|
const tasks = await queueStorage.getActiveTasks(projectId);
|
|
@@ -23740,7 +23963,7 @@ var init_workflow = __esm({
|
|
|
23740
23963
|
if (!initResult.success) return initResult;
|
|
23741
23964
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
23742
23965
|
if (!projectId) {
|
|
23743
|
-
output_default.
|
|
23966
|
+
output_default.failWithHint("NO_PROJECT_ID");
|
|
23744
23967
|
return { success: false, error: "No project ID found" };
|
|
23745
23968
|
}
|
|
23746
23969
|
const currentTask = await stateStorage.getCurrentTask(projectId);
|
|
@@ -23773,7 +23996,7 @@ var init_workflow = __esm({
|
|
|
23773
23996
|
if (!initResult.success) return initResult;
|
|
23774
23997
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
23775
23998
|
if (!projectId) {
|
|
23776
|
-
output_default.
|
|
23999
|
+
output_default.failWithHint("NO_PROJECT_ID");
|
|
23777
24000
|
return { success: false, error: "No project ID found" };
|
|
23778
24001
|
}
|
|
23779
24002
|
const currentTask = await stateStorage.getCurrentTask(projectId);
|
|
@@ -23811,7 +24034,7 @@ var init_workflow = __esm({
|
|
|
23811
24034
|
if (!initResult.success) return initResult;
|
|
23812
24035
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
23813
24036
|
if (!projectId) {
|
|
23814
|
-
output_default.
|
|
24037
|
+
output_default.failWithHint("NO_PROJECT_ID");
|
|
23815
24038
|
return { success: false, error: "No project ID found" };
|
|
23816
24039
|
}
|
|
23817
24040
|
if (!input) {
|
|
@@ -24080,7 +24303,7 @@ var require_package = __commonJS({
|
|
|
24080
24303
|
"package.json"(exports, module) {
|
|
24081
24304
|
module.exports = {
|
|
24082
24305
|
name: "prjct-cli",
|
|
24083
|
-
version: "0.
|
|
24306
|
+
version: "0.50.0",
|
|
24084
24307
|
description: "Context layer for AI agents. Project context for Claude Code, Gemini CLI, and more.",
|
|
24085
24308
|
main: "core/index.ts",
|
|
24086
24309
|
bin: {
|