prjct-cli 0.47.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 +52 -3821
- package/core/agentic/context-builder.ts +4 -4
- package/core/agentic/memory-system.ts +3 -1
- package/core/agentic/prompt-builder.ts +6 -2
- package/core/agentic/smart-context.ts +2 -2
- package/core/ai-tools/generator.ts +11 -1
- package/core/cli/linear.ts +5 -4
- package/core/commands/analytics.ts +4 -2
- package/core/commands/cleanup.ts +1 -1
- package/core/commands/commands.ts +1 -1
- package/core/commands/planning.ts +4 -4
- package/core/commands/registry.ts +3 -2
- package/core/commands/shipping.ts +1 -1
- package/core/commands/snapshots.ts +6 -6
- package/core/commands/workflow.ts +6 -6
- package/core/constants/index.ts +3 -1
- package/core/context-tools/imports-tool.ts +1 -1
- package/core/context-tools/signatures-tool.ts +1 -1
- package/core/plugin/hooks.ts +1 -1
- package/core/services/agent-generator.ts +58 -6
- package/core/services/context-generator.ts +35 -15
- package/core/utils/error-messages.ts +161 -0
- package/core/utils/help.ts +0 -1
- package/core/utils/markdown-builder.ts +9 -3
- package/core/utils/output.ts +24 -0
- package/core/utils/preserve-sections.ts +1 -1
- package/core/utils/project-commands.ts +0 -6
- package/core/utils/subtask-table.ts +1 -1
- package/dist/bin/prjct.mjs +308 -96
- package/package.json +1 -1
- package/templates/global/CLAUDE.md +27 -0
|
@@ -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/help.ts
CHANGED
|
@@ -117,7 +117,9 @@ export class MarkdownBuilder {
|
|
|
117
117
|
* Add multiple list items
|
|
118
118
|
*/
|
|
119
119
|
list(items: string[], options?: { checked?: boolean }): this {
|
|
120
|
-
|
|
120
|
+
for (const item of items) {
|
|
121
|
+
this.li(item, options)
|
|
122
|
+
}
|
|
121
123
|
return this
|
|
122
124
|
}
|
|
123
125
|
|
|
@@ -125,7 +127,9 @@ export class MarkdownBuilder {
|
|
|
125
127
|
* Add multiple numbered list items
|
|
126
128
|
*/
|
|
127
129
|
orderedList(items: string[]): this {
|
|
128
|
-
|
|
130
|
+
for (let i = 0; i < items.length; i++) {
|
|
131
|
+
this.oli(items[i], i + 1)
|
|
132
|
+
}
|
|
129
133
|
return this
|
|
130
134
|
}
|
|
131
135
|
|
|
@@ -225,7 +229,9 @@ export class MarkdownBuilder {
|
|
|
225
229
|
* Iterate and build for each item
|
|
226
230
|
*/
|
|
227
231
|
each<T>(items: T[], builder: (md: MarkdownBuilder, item: T, index: number) => void): this {
|
|
228
|
-
|
|
232
|
+
for (let i = 0; i < items.length; i++) {
|
|
233
|
+
builder(this, items[i], i)
|
|
234
|
+
}
|
|
229
235
|
return this
|
|
230
236
|
}
|
|
231
237
|
|
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
|
|
@@ -3,12 +3,6 @@ import type { DetectedProjectCommands } from '../types'
|
|
|
3
3
|
import * as fileHelper from './file-helper'
|
|
4
4
|
|
|
5
5
|
type PackageManager = 'npm' | 'pnpm' | 'yarn' | 'bun'
|
|
6
|
-
type DetectedStack = 'js' | 'python' | 'go' | 'rust' | 'dotnet' | 'java' | 'unknown'
|
|
7
|
-
|
|
8
|
-
interface DetectedCommand {
|
|
9
|
-
command: string
|
|
10
|
-
tool: string
|
|
11
|
-
}
|
|
12
6
|
|
|
13
7
|
interface PackageJson {
|
|
14
8
|
scripts?: Record<string, string>
|
|
@@ -72,7 +72,7 @@ function formatSubtaskLine(
|
|
|
72
72
|
const domain = `${domainColor}${subtask.domain.padEnd(10)}${RESET}`
|
|
73
73
|
const desc =
|
|
74
74
|
subtask.description.length > 32
|
|
75
|
-
? subtask.description.slice(0, 29)
|
|
75
|
+
? `${subtask.description.slice(0, 29)}...`
|
|
76
76
|
: subtask.description.padEnd(32)
|
|
77
77
|
|
|
78
78
|
let status: string
|