prjct-cli 0.48.0 → 0.49.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 +13 -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 +24 -0
- package/dist/bin/prjct.mjs +160 -20
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,10 +1,21 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## [0.
|
|
3
|
+
## [0.49.0] - 2026-01-30
|
|
4
4
|
|
|
5
5
|
### Features
|
|
6
6
|
|
|
7
|
-
-
|
|
7
|
+
- Error messages with context and recovery hints - PRJ-131 (#75)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
## [0.49.1] - 2026-01-30
|
|
11
|
+
|
|
12
|
+
### Improved
|
|
13
|
+
|
|
14
|
+
- **Error messages with context and recovery hints** (PRJ-131)
|
|
15
|
+
- Created error catalog with 15+ error types
|
|
16
|
+
- Added `out.failWithHint()` for rich error output
|
|
17
|
+
- Errors now show file path and recovery hints
|
|
18
|
+
- Example: `✗ Project ID not found` → `💡 Run 'prjct init'`
|
|
8
19
|
|
|
9
20
|
|
|
10
21
|
## [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
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
|
|
9
9
|
import chalk from 'chalk'
|
|
10
10
|
import branding from './branding'
|
|
11
|
+
import type { ErrorCode, ErrorWithHint } from './error-messages'
|
|
12
|
+
import { getError } from './error-messages'
|
|
11
13
|
|
|
12
14
|
const _FRAMES = branding.spinner.frames
|
|
13
15
|
const SPEED = branding.spinner.speed
|
|
@@ -53,6 +55,7 @@ interface Output {
|
|
|
53
55
|
spin(msg: string): Output
|
|
54
56
|
done(msg: string, metrics?: OutputMetrics): Output
|
|
55
57
|
fail(msg: string): Output
|
|
58
|
+
failWithHint(error: ErrorWithHint | ErrorCode): Output
|
|
56
59
|
warn(msg: string): Output
|
|
57
60
|
stop(): Output
|
|
58
61
|
step(current: number, total: number, msg: string): Output
|
|
@@ -108,6 +111,25 @@ const out: Output = {
|
|
|
108
111
|
return this
|
|
109
112
|
},
|
|
110
113
|
|
|
114
|
+
// Rich error with context and recovery hint
|
|
115
|
+
failWithHint(error: ErrorWithHint | ErrorCode) {
|
|
116
|
+
this.stop()
|
|
117
|
+
const err = typeof error === 'string' ? getError(error) : error
|
|
118
|
+
console.error()
|
|
119
|
+
console.error(`${chalk.red('✗')} ${err.message}`)
|
|
120
|
+
if (err.file) {
|
|
121
|
+
console.error(chalk.dim(` File: ${err.file}`))
|
|
122
|
+
}
|
|
123
|
+
if (err.hint) {
|
|
124
|
+
console.error(chalk.yellow(` 💡 ${err.hint}`))
|
|
125
|
+
}
|
|
126
|
+
if (err.docs) {
|
|
127
|
+
console.error(chalk.dim(` Docs: ${err.docs}`))
|
|
128
|
+
}
|
|
129
|
+
console.error()
|
|
130
|
+
return this
|
|
131
|
+
},
|
|
132
|
+
|
|
111
133
|
warn(msg: string) {
|
|
112
134
|
this.stop()
|
|
113
135
|
if (!quietMode) console.log(`${chalk.yellow('⚠')} ${truncate(msg, 65)}`)
|
|
@@ -151,4 +173,6 @@ const out: Output = {
|
|
|
151
173
|
}
|
|
152
174
|
|
|
153
175
|
export type { OutputMetrics }
|
|
176
|
+
export type { ErrorCode, ErrorWithHint } from './error-messages'
|
|
177
|
+
export { createError, ERRORS, getError } from './error-messages'
|
|
154
178
|
export default out
|
package/dist/bin/prjct.mjs
CHANGED
|
@@ -1944,10 +1944,130 @@ 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
|
+
createError: () => createError,
|
|
1950
2069
|
default: () => output_default,
|
|
2070
|
+
getError: () => getError,
|
|
1951
2071
|
isQuietMode: () => isQuietMode,
|
|
1952
2072
|
setQuietMode: () => setQuietMode
|
|
1953
2073
|
});
|
|
@@ -1963,6 +2083,8 @@ var init_output = __esm({
|
|
|
1963
2083
|
"core/utils/output.ts"() {
|
|
1964
2084
|
"use strict";
|
|
1965
2085
|
init_branding();
|
|
2086
|
+
init_error_messages();
|
|
2087
|
+
init_error_messages();
|
|
1966
2088
|
_FRAMES = branding_default.spinner.frames;
|
|
1967
2089
|
SPEED = branding_default.spinner.speed;
|
|
1968
2090
|
interval = null;
|
|
@@ -2015,6 +2137,24 @@ var init_output = __esm({
|
|
|
2015
2137
|
console.error(`${chalk2.red("\u2717")} ${truncate(msg, 65)}`);
|
|
2016
2138
|
return this;
|
|
2017
2139
|
},
|
|
2140
|
+
// Rich error with context and recovery hint
|
|
2141
|
+
failWithHint(error) {
|
|
2142
|
+
this.stop();
|
|
2143
|
+
const err = typeof error === "string" ? getError(error) : error;
|
|
2144
|
+
console.error();
|
|
2145
|
+
console.error(`${chalk2.red("\u2717")} ${err.message}`);
|
|
2146
|
+
if (err.file) {
|
|
2147
|
+
console.error(chalk2.dim(` File: ${err.file}`));
|
|
2148
|
+
}
|
|
2149
|
+
if (err.hint) {
|
|
2150
|
+
console.error(chalk2.yellow(` \u{1F4A1} ${err.hint}`));
|
|
2151
|
+
}
|
|
2152
|
+
if (err.docs) {
|
|
2153
|
+
console.error(chalk2.dim(` Docs: ${err.docs}`));
|
|
2154
|
+
}
|
|
2155
|
+
console.error();
|
|
2156
|
+
return this;
|
|
2157
|
+
},
|
|
2018
2158
|
warn(msg) {
|
|
2019
2159
|
this.stop();
|
|
2020
2160
|
if (!quietMode) console.log(`${chalk2.yellow("\u26A0")} ${truncate(msg, 65)}`);
|
|
@@ -16738,7 +16878,7 @@ Generated: ${(/* @__PURE__ */ new Date()).toLocaleString()}
|
|
|
16738
16878
|
}
|
|
16739
16879
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
16740
16880
|
if (!projectId) {
|
|
16741
|
-
output_default.
|
|
16881
|
+
output_default.failWithHint("NO_PROJECT_ID");
|
|
16742
16882
|
return { success: false, error: "No project ID found" };
|
|
16743
16883
|
}
|
|
16744
16884
|
output_default.spin(`planning ${description}...`);
|
|
@@ -16795,7 +16935,7 @@ Generated: ${(/* @__PURE__ */ new Date()).toLocaleString()}
|
|
|
16795
16935
|
}
|
|
16796
16936
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
16797
16937
|
if (!projectId) {
|
|
16798
|
-
output_default.
|
|
16938
|
+
output_default.failWithHint("NO_PROJECT_ID");
|
|
16799
16939
|
return { success: false, error: "No project ID found" };
|
|
16800
16940
|
}
|
|
16801
16941
|
output_default.spin("tracking bug...");
|
|
@@ -16918,7 +17058,7 @@ ${"=".repeat(60)}`);
|
|
|
16918
17058
|
}
|
|
16919
17059
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
16920
17060
|
if (!projectId) {
|
|
16921
|
-
output_default.
|
|
17061
|
+
output_default.failWithHint("NO_PROJECT_ID");
|
|
16922
17062
|
return { success: false, error: "No project ID found" };
|
|
16923
17063
|
}
|
|
16924
17064
|
const wordCount = description.split(/\s+/).length;
|
|
@@ -16976,7 +17116,7 @@ Generated: ${(/* @__PURE__ */ new Date()).toLocaleString()}
|
|
|
16976
17116
|
if (!initResult.success) return initResult;
|
|
16977
17117
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
16978
17118
|
if (!projectId) {
|
|
16979
|
-
output_default.
|
|
17119
|
+
output_default.failWithHint("NO_PROJECT_ID");
|
|
16980
17120
|
return { success: false, error: "No project ID found" };
|
|
16981
17121
|
}
|
|
16982
17122
|
if (!featureName) {
|
|
@@ -21067,7 +21207,7 @@ var init_analytics = __esm({
|
|
|
21067
21207
|
if (!initResult.success) return initResult;
|
|
21068
21208
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
21069
21209
|
if (!projectId) {
|
|
21070
|
-
output_default.
|
|
21210
|
+
output_default.failWithHint("NO_PROJECT_ID");
|
|
21071
21211
|
return { success: false, error: "No project ID found" };
|
|
21072
21212
|
}
|
|
21073
21213
|
const projectName = path45.basename(projectPath);
|
|
@@ -21507,7 +21647,7 @@ async function cleanup(options = {}, projectPath = process.cwd()) {
|
|
|
21507
21647
|
output_default.spin("cleaning up...");
|
|
21508
21648
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
21509
21649
|
if (!projectId) {
|
|
21510
|
-
output_default.
|
|
21650
|
+
output_default.failWithHint("NO_PROJECT_ID");
|
|
21511
21651
|
return { success: false, error: "No project ID found" };
|
|
21512
21652
|
}
|
|
21513
21653
|
const cleaned = [];
|
|
@@ -21666,7 +21806,7 @@ async function recover(projectPath = process.cwd()) {
|
|
|
21666
21806
|
try {
|
|
21667
21807
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
21668
21808
|
if (!projectId) {
|
|
21669
|
-
output_default.
|
|
21809
|
+
output_default.failWithHint("NO_PROJECT_ID");
|
|
21670
21810
|
return { success: false, error: "No project ID found" };
|
|
21671
21811
|
}
|
|
21672
21812
|
output_default.spin("checking for abandoned sessions...");
|
|
@@ -21710,7 +21850,7 @@ async function undo(projectPath = process.cwd()) {
|
|
|
21710
21850
|
output_default.spin("creating undo point...");
|
|
21711
21851
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
21712
21852
|
if (!projectId) {
|
|
21713
|
-
output_default.
|
|
21853
|
+
output_default.failWithHint("NO_PROJECT_ID");
|
|
21714
21854
|
return { success: false, error: "No project ID found" };
|
|
21715
21855
|
}
|
|
21716
21856
|
const snapshotsPath = path49.join(path_manager_default.getGlobalProjectPath(projectId), "snapshots");
|
|
@@ -21755,7 +21895,7 @@ async function undo(projectPath = process.cwd()) {
|
|
|
21755
21895
|
output_default.done("changes stashed (use /p:redo to restore)");
|
|
21756
21896
|
return { success: true, snapshotId: stashMessage };
|
|
21757
21897
|
} catch (gitError) {
|
|
21758
|
-
output_default.
|
|
21898
|
+
output_default.failWithHint("GIT_OPERATION_FAILED");
|
|
21759
21899
|
return { success: false, error: gitError.message };
|
|
21760
21900
|
}
|
|
21761
21901
|
} catch (error) {
|
|
@@ -21768,7 +21908,7 @@ async function redo(projectPath = process.cwd()) {
|
|
|
21768
21908
|
output_default.spin("restoring changes...");
|
|
21769
21909
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
21770
21910
|
if (!projectId) {
|
|
21771
|
-
output_default.
|
|
21911
|
+
output_default.failWithHint("NO_PROJECT_ID");
|
|
21772
21912
|
return { success: false, error: "No project ID found" };
|
|
21773
21913
|
}
|
|
21774
21914
|
const snapshotsPath = path49.join(path_manager_default.getGlobalProjectPath(projectId), "snapshots");
|
|
@@ -21816,7 +21956,7 @@ async function redo(projectPath = process.cwd()) {
|
|
|
21816
21956
|
output_default.done("changes restored");
|
|
21817
21957
|
return { success: true };
|
|
21818
21958
|
} catch (gitError) {
|
|
21819
|
-
output_default.
|
|
21959
|
+
output_default.failWithHint("GIT_OPERATION_FAILED");
|
|
21820
21960
|
return { success: false, error: gitError.message };
|
|
21821
21961
|
}
|
|
21822
21962
|
} catch (error) {
|
|
@@ -21828,7 +21968,7 @@ async function history(projectPath = process.cwd()) {
|
|
|
21828
21968
|
try {
|
|
21829
21969
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
21830
21970
|
if (!projectId) {
|
|
21831
|
-
output_default.
|
|
21971
|
+
output_default.failWithHint("NO_PROJECT_ID");
|
|
21832
21972
|
return { success: false, error: "No project ID found" };
|
|
21833
21973
|
}
|
|
21834
21974
|
const snapshotsPath = path49.join(path_manager_default.getGlobalProjectPath(projectId), "snapshots");
|
|
@@ -22483,7 +22623,7 @@ ${result.stderr}`.trim();
|
|
|
22483
22623
|
if (!initResult.success) return initResult;
|
|
22484
22624
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
22485
22625
|
if (!projectId) {
|
|
22486
|
-
output_default.
|
|
22626
|
+
output_default.failWithHint("NO_PROJECT_ID");
|
|
22487
22627
|
return { success: false, error: "No project ID found" };
|
|
22488
22628
|
}
|
|
22489
22629
|
let featureName = feature;
|
|
@@ -23557,7 +23697,7 @@ var init_workflow = __esm({
|
|
|
23557
23697
|
if (!initResult.success) return initResult;
|
|
23558
23698
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
23559
23699
|
if (!projectId) {
|
|
23560
|
-
output_default.
|
|
23700
|
+
output_default.failWithHint("NO_PROJECT_ID");
|
|
23561
23701
|
return { success: false, error: "No project ID found" };
|
|
23562
23702
|
}
|
|
23563
23703
|
if (task) {
|
|
@@ -23649,7 +23789,7 @@ var init_workflow = __esm({
|
|
|
23649
23789
|
if (!initResult.success) return initResult;
|
|
23650
23790
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
23651
23791
|
if (!projectId) {
|
|
23652
|
-
output_default.
|
|
23792
|
+
output_default.failWithHint("NO_PROJECT_ID");
|
|
23653
23793
|
return { success: false, error: "No project ID found" };
|
|
23654
23794
|
}
|
|
23655
23795
|
const currentTask = await stateStorage.getCurrentTask(projectId);
|
|
@@ -23715,7 +23855,7 @@ var init_workflow = __esm({
|
|
|
23715
23855
|
if (!initResult.success) return initResult;
|
|
23716
23856
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
23717
23857
|
if (!projectId) {
|
|
23718
|
-
output_default.
|
|
23858
|
+
output_default.failWithHint("NO_PROJECT_ID");
|
|
23719
23859
|
return { success: false, error: "No project ID found" };
|
|
23720
23860
|
}
|
|
23721
23861
|
const tasks = await queueStorage.getActiveTasks(projectId);
|
|
@@ -23740,7 +23880,7 @@ var init_workflow = __esm({
|
|
|
23740
23880
|
if (!initResult.success) return initResult;
|
|
23741
23881
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
23742
23882
|
if (!projectId) {
|
|
23743
|
-
output_default.
|
|
23883
|
+
output_default.failWithHint("NO_PROJECT_ID");
|
|
23744
23884
|
return { success: false, error: "No project ID found" };
|
|
23745
23885
|
}
|
|
23746
23886
|
const currentTask = await stateStorage.getCurrentTask(projectId);
|
|
@@ -23773,7 +23913,7 @@ var init_workflow = __esm({
|
|
|
23773
23913
|
if (!initResult.success) return initResult;
|
|
23774
23914
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
23775
23915
|
if (!projectId) {
|
|
23776
|
-
output_default.
|
|
23916
|
+
output_default.failWithHint("NO_PROJECT_ID");
|
|
23777
23917
|
return { success: false, error: "No project ID found" };
|
|
23778
23918
|
}
|
|
23779
23919
|
const currentTask = await stateStorage.getCurrentTask(projectId);
|
|
@@ -23811,7 +23951,7 @@ var init_workflow = __esm({
|
|
|
23811
23951
|
if (!initResult.success) return initResult;
|
|
23812
23952
|
const projectId = await config_manager_default.getProjectId(projectPath);
|
|
23813
23953
|
if (!projectId) {
|
|
23814
|
-
output_default.
|
|
23954
|
+
output_default.failWithHint("NO_PROJECT_ID");
|
|
23815
23955
|
return { success: false, error: "No project ID found" };
|
|
23816
23956
|
}
|
|
23817
23957
|
if (!input) {
|
|
@@ -24080,7 +24220,7 @@ var require_package = __commonJS({
|
|
|
24080
24220
|
"package.json"(exports, module) {
|
|
24081
24221
|
module.exports = {
|
|
24082
24222
|
name: "prjct-cli",
|
|
24083
|
-
version: "0.
|
|
24223
|
+
version: "0.49.0",
|
|
24084
24224
|
description: "Context layer for AI agents. Project context for Claude Code, Gemini CLI, and more.",
|
|
24085
24225
|
main: "core/index.ts",
|
|
24086
24226
|
bin: {
|