prjct-cli 1.6.8 → 1.6.9
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 +50 -0
- package/README.md +46 -0
- package/core/ai-tools/registry.ts +2 -9
- package/core/commands/planning.ts +3 -5
- package/core/infrastructure/agent-detector.ts +2 -2
- package/core/infrastructure/path-manager.ts +3 -17
- package/core/integrations/jira/client.ts +3 -77
- package/core/server/server.ts +2 -4
- package/core/server/sse.ts +115 -59
- package/core/services/context-generator.ts +22 -47
- package/core/services/diff-generator.ts +18 -43
- package/core/services/stack-detector.ts +4 -20
- package/core/services/sync-service.ts +35 -106
- package/core/services/sync-verifier.ts +17 -37
- package/core/types/citations.ts +22 -0
- package/core/types/commands.ts +10 -0
- package/core/types/diff.ts +41 -0
- package/core/types/errors.ts +111 -0
- package/core/types/index.ts +80 -0
- package/core/types/infrastructure.ts +14 -0
- package/core/types/jira.ts +51 -0
- package/core/types/logger.ts +17 -0
- package/core/types/output.ts +47 -0
- package/core/types/project-sync.ts +109 -0
- package/core/types/server.ts +28 -10
- package/core/types/services.ts +14 -0
- package/core/types/stack.ts +19 -0
- package/core/types/sync-verifier.ts +33 -0
- package/core/types/workflow.ts +23 -0
- package/core/utils/citations.ts +2 -16
- package/core/utils/error-messages.ts +5 -139
- package/core/utils/logger.ts +3 -11
- package/core/utils/output.ts +6 -45
- package/core/workflow/workflow-preferences.ts +14 -18
- package/dist/bin/prjct.mjs +120 -52
- package/package.json +1 -1
|
@@ -2,151 +2,17 @@
|
|
|
2
2
|
* Error Messages Catalog
|
|
3
3
|
*
|
|
4
4
|
* Centralized error messages with context and recovery hints.
|
|
5
|
-
*
|
|
5
|
+
* Types and catalog live in core/types/errors.ts.
|
|
6
6
|
*
|
|
7
7
|
* @see PRJ-131
|
|
8
8
|
* @module utils/error-messages
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
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
|
-
// Command errors
|
|
132
|
-
UNKNOWN_COMMAND: {
|
|
133
|
-
message: 'Unknown command',
|
|
134
|
-
hint: "Run 'prjct --help' to see available commands",
|
|
135
|
-
},
|
|
136
|
-
|
|
137
|
-
MISSING_PARAM: {
|
|
138
|
-
message: 'Missing required parameter',
|
|
139
|
-
hint: 'Check command usage below',
|
|
140
|
-
},
|
|
141
|
-
|
|
142
|
-
// Generic
|
|
143
|
-
UNKNOWN: {
|
|
144
|
-
message: 'An unexpected error occurred',
|
|
145
|
-
hint: 'Check the error details and try again',
|
|
146
|
-
},
|
|
147
|
-
} as const
|
|
11
|
+
import type { ErrorCode, ErrorWithHint } from '../types/errors'
|
|
12
|
+
import { ERRORS } from '../types/errors'
|
|
148
13
|
|
|
149
|
-
export type ErrorCode
|
|
14
|
+
export type { ErrorCode, ErrorWithHint } from '../types/errors'
|
|
15
|
+
export { ERRORS } from '../types/errors'
|
|
150
16
|
|
|
151
17
|
/**
|
|
152
18
|
* Get error with optional overrides
|
package/core/utils/logger.ts
CHANGED
|
@@ -16,17 +16,7 @@
|
|
|
16
16
|
* log.error('Failed to load', error.message)
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
-
type
|
|
20
|
-
type LogFunction = (...args: unknown[]) => void
|
|
21
|
-
|
|
22
|
-
interface Logger {
|
|
23
|
-
error: LogFunction
|
|
24
|
-
warn: LogFunction
|
|
25
|
-
info: LogFunction
|
|
26
|
-
debug: LogFunction
|
|
27
|
-
isEnabled: () => boolean
|
|
28
|
-
level: () => LogLevel | 'disabled'
|
|
29
|
-
}
|
|
19
|
+
import type { LogFunction, Logger, LogLevel } from '../types/logger'
|
|
30
20
|
|
|
31
21
|
const LEVELS: Record<LogLevel, number> = { error: 0, warn: 1, info: 2, debug: 3 }
|
|
32
22
|
const TRUTHY_VALUES = new Set(['1', 'true', '*'])
|
|
@@ -36,6 +26,8 @@ const TRUTHY_VALUES = new Set(['1', 'true', '*'])
|
|
|
36
26
|
* Returns -1 (disabled) or a level from LEVELS
|
|
37
27
|
*/
|
|
38
28
|
function getLogLevel(): { level: number; name: LogLevel | 'disabled' } {
|
|
29
|
+
// PRJCT_DEBUG (primary) or DEBUG (fallback): Enable debug logging
|
|
30
|
+
// Values: '1', 'true', a log level name, or 'prjct' to match
|
|
39
31
|
const debugEnv = process.env.PRJCT_DEBUG || process.env.DEBUG || ''
|
|
40
32
|
|
|
41
33
|
// Disabled if empty
|
package/core/utils/output.ts
CHANGED
|
@@ -11,31 +11,22 @@
|
|
|
11
11
|
|
|
12
12
|
import chalk from 'chalk'
|
|
13
13
|
import { OUTPUT_LIMITS } from '../constants'
|
|
14
|
+
import type { ErrorCode, ErrorWithHint } from '../types/errors'
|
|
15
|
+
import type { Output, OutputMetrics, OutputTier, TierConfig } from '../types/output'
|
|
14
16
|
import branding from './branding'
|
|
15
|
-
import type { ErrorCode, ErrorWithHint } from './error-messages'
|
|
16
17
|
import { getError } from './error-messages'
|
|
17
18
|
|
|
18
19
|
const _FRAMES = branding.spinner.frames
|
|
19
20
|
const SPEED = branding.spinner.speed
|
|
20
21
|
|
|
21
|
-
|
|
22
|
-
* Output tier configuration
|
|
23
|
-
* Controls verbosity of CLI output
|
|
24
|
-
*/
|
|
25
|
-
export type OutputTier = 'silent' | 'minimal' | 'compact' | 'verbose'
|
|
26
|
-
|
|
27
|
-
export interface TierConfig {
|
|
28
|
-
maxLines: number
|
|
29
|
-
maxCharsPerLine: number
|
|
30
|
-
showMetrics: boolean
|
|
31
|
-
}
|
|
22
|
+
export type { Output, OutputMetrics, OutputTier, TierConfig } from '../types/output'
|
|
32
23
|
|
|
33
24
|
export const OUTPUT_TIERS: Record<OutputTier, TierConfig> = {
|
|
34
25
|
silent: { maxLines: 0, maxCharsPerLine: 0, showMetrics: false },
|
|
35
26
|
minimal: { maxLines: 1, maxCharsPerLine: 65, showMetrics: false },
|
|
36
27
|
compact: { maxLines: 4, maxCharsPerLine: 80, showMetrics: true },
|
|
37
28
|
verbose: { maxLines: Infinity, maxCharsPerLine: Infinity, showMetrics: true },
|
|
38
|
-
}
|
|
29
|
+
} as const
|
|
39
30
|
|
|
40
31
|
// Current output tier (default: compact for human-readable output)
|
|
41
32
|
let currentTier: OutputTier = 'compact'
|
|
@@ -184,36 +175,6 @@ export function formatForHuman(data: unknown): string {
|
|
|
184
175
|
const clear = (): boolean =>
|
|
185
176
|
process.stdout.isTTY ? process.stdout.write(`\r${' '.repeat(OUTPUT_LIMITS.CLEAR_WIDTH)}\r`) : true
|
|
186
177
|
|
|
187
|
-
/**
|
|
188
|
-
* Metrics to display after command completion
|
|
189
|
-
* Shows value provided by prjct (compression, agent count, etc.)
|
|
190
|
-
*/
|
|
191
|
-
interface OutputMetrics {
|
|
192
|
-
agents?: number // Number of agents used
|
|
193
|
-
reduction?: number // Context reduction percentage
|
|
194
|
-
tokens?: number // Token count (in thousands)
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
interface Output {
|
|
198
|
-
start(): Output
|
|
199
|
-
end(): Output
|
|
200
|
-
spin(msg: string): Output
|
|
201
|
-
done(msg: string, metrics?: OutputMetrics): Output
|
|
202
|
-
fail(msg: string): Output
|
|
203
|
-
failWithHint(error: ErrorWithHint | ErrorCode): Output
|
|
204
|
-
warn(msg: string): Output
|
|
205
|
-
info(msg: string): Output
|
|
206
|
-
debug(msg: string): Output
|
|
207
|
-
success(msg: string, metrics?: OutputMetrics): Output
|
|
208
|
-
list(items: string[], options?: { bullet?: string; indent?: number }): Output
|
|
209
|
-
table(rows: Array<Record<string, string | number>>, options?: { header?: boolean }): Output
|
|
210
|
-
box(title: string, content: string): Output
|
|
211
|
-
section(title: string): Output
|
|
212
|
-
stop(): Output
|
|
213
|
-
step(current: number, total: number, msg: string): Output
|
|
214
|
-
progress(current: number, total: number, msg?: string): Output
|
|
215
|
-
}
|
|
216
|
-
|
|
217
178
|
const out: Output = {
|
|
218
179
|
// Branding: Show header at start
|
|
219
180
|
start() {
|
|
@@ -273,7 +234,7 @@ const out: Output = {
|
|
|
273
234
|
// Rich error with context and recovery hint
|
|
274
235
|
failWithHint(error: ErrorWithHint | ErrorCode) {
|
|
275
236
|
this.stop()
|
|
276
|
-
const err = typeof error === 'string' ? getError(error) : error
|
|
237
|
+
const err = typeof error === 'string' ? getError(error as ErrorCode) : error
|
|
277
238
|
console.error()
|
|
278
239
|
console.error(`${ICONS.fail} ${err.message}`)
|
|
279
240
|
if (err.file) {
|
|
@@ -305,6 +266,7 @@ const out: Output = {
|
|
|
305
266
|
// Debug message (only if DEBUG=1 or DEBUG=true)
|
|
306
267
|
debug(msg: string) {
|
|
307
268
|
this.stop()
|
|
269
|
+
// DEBUG: Enable debug output (values: '1' or 'true')
|
|
308
270
|
const debugEnabled = process.env.DEBUG === '1' || process.env.DEBUG === 'true'
|
|
309
271
|
if (!quietMode && debugEnabled) {
|
|
310
272
|
console.log(`${ICONS.debug} ${chalk.dim(msg)}`)
|
|
@@ -436,7 +398,6 @@ const out: Output = {
|
|
|
436
398
|
},
|
|
437
399
|
}
|
|
438
400
|
|
|
439
|
-
export type { OutputMetrics }
|
|
440
401
|
export type { ErrorCode, ErrorWithHint } from './error-messages'
|
|
441
402
|
export { createError, ERRORS, getError } from './error-messages'
|
|
442
403
|
export default out
|
|
@@ -18,28 +18,24 @@ import { promisify } from 'node:util'
|
|
|
18
18
|
import chalk from 'chalk'
|
|
19
19
|
import memorySystem from '../agentic/memory-system'
|
|
20
20
|
import { WORKFLOW_HELP } from '../constants'
|
|
21
|
+
import type {
|
|
22
|
+
HookCommand,
|
|
23
|
+
HookPhase,
|
|
24
|
+
HookResult,
|
|
25
|
+
PreferenceScope,
|
|
26
|
+
WorkflowPreference,
|
|
27
|
+
} from '../types'
|
|
21
28
|
import { getErrorMessage } from '../types/fs'
|
|
22
29
|
|
|
23
30
|
const execAsync = promisify(exec)
|
|
24
31
|
|
|
25
|
-
export type
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
action: string // command to run or 'true' for skip
|
|
33
|
-
scope: PreferenceScope
|
|
34
|
-
createdAt: string
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export interface HookResult {
|
|
38
|
-
success: boolean
|
|
39
|
-
failed?: string
|
|
40
|
-
skipped?: string[]
|
|
41
|
-
output?: string
|
|
42
|
-
}
|
|
32
|
+
export type {
|
|
33
|
+
HookCommand,
|
|
34
|
+
HookPhase,
|
|
35
|
+
HookResult,
|
|
36
|
+
PreferenceScope,
|
|
37
|
+
WorkflowPreference,
|
|
38
|
+
} from '../types'
|
|
43
39
|
|
|
44
40
|
// Session and once preferences (in-memory)
|
|
45
41
|
const sessionPreferences: Map<string, WorkflowPreference> = new Map()
|
package/dist/bin/prjct.mjs
CHANGED
|
@@ -2020,6 +2020,13 @@ var init_logger = __esm({
|
|
|
2020
2020
|
}
|
|
2021
2021
|
});
|
|
2022
2022
|
|
|
2023
|
+
// core/types/server.ts
|
|
2024
|
+
var init_server = __esm({
|
|
2025
|
+
"core/types/server.ts"() {
|
|
2026
|
+
"use strict";
|
|
2027
|
+
}
|
|
2028
|
+
});
|
|
2029
|
+
|
|
2023
2030
|
// core/constants/index.ts
|
|
2024
2031
|
function getTimeout(key) {
|
|
2025
2032
|
const envVar = `PRJCT_TIMEOUT_${key}`;
|
|
@@ -2183,24 +2190,12 @@ var init_branding = __esm({
|
|
|
2183
2190
|
}
|
|
2184
2191
|
});
|
|
2185
2192
|
|
|
2186
|
-
// core/
|
|
2187
|
-
function getError(code, overrides) {
|
|
2188
|
-
const base = ERRORS[code];
|
|
2189
|
-
return { ...base, ...overrides };
|
|
2190
|
-
}
|
|
2191
|
-
function createError(message, hint, options) {
|
|
2192
|
-
return {
|
|
2193
|
-
message,
|
|
2194
|
-
hint,
|
|
2195
|
-
...options
|
|
2196
|
-
};
|
|
2197
|
-
}
|
|
2193
|
+
// core/types/errors.ts
|
|
2198
2194
|
var ERRORS;
|
|
2199
|
-
var
|
|
2200
|
-
"core/
|
|
2195
|
+
var init_errors2 = __esm({
|
|
2196
|
+
"core/types/errors.ts"() {
|
|
2201
2197
|
"use strict";
|
|
2202
2198
|
ERRORS = {
|
|
2203
|
-
// Project errors
|
|
2204
2199
|
NO_PROJECT: {
|
|
2205
2200
|
message: "No prjct project found in this directory",
|
|
2206
2201
|
hint: "Run 'prjct init' to set up a new project",
|
|
@@ -2221,7 +2216,6 @@ var init_error_messages = __esm({
|
|
|
2221
2216
|
hint: "Check JSON syntax or delete .prjct/ and run init again",
|
|
2222
2217
|
file: ".prjct/prjct.config.json"
|
|
2223
2218
|
},
|
|
2224
|
-
// Git errors
|
|
2225
2219
|
GIT_NOT_FOUND: {
|
|
2226
2220
|
message: "Git repository not detected",
|
|
2227
2221
|
hint: "Run 'git init' first, then 'prjct init'"
|
|
@@ -2242,7 +2236,6 @@ var init_error_messages = __esm({
|
|
|
2242
2236
|
message: "Git operation failed",
|
|
2243
2237
|
hint: "Check git status and resolve any conflicts"
|
|
2244
2238
|
},
|
|
2245
|
-
// Auth errors
|
|
2246
2239
|
GH_NOT_AUTHENTICATED: {
|
|
2247
2240
|
message: "GitHub CLI not authenticated",
|
|
2248
2241
|
hint: "Run 'gh auth login' to authenticate",
|
|
@@ -2256,7 +2249,6 @@ var init_error_messages = __esm({
|
|
|
2256
2249
|
message: "Linear API error",
|
|
2257
2250
|
hint: "Check your API key or network connection"
|
|
2258
2251
|
},
|
|
2259
|
-
// Task errors
|
|
2260
2252
|
NO_ACTIVE_TASK: {
|
|
2261
2253
|
message: "No active task",
|
|
2262
2254
|
hint: `Start a task with 'p. task "description"'`
|
|
@@ -2265,12 +2257,10 @@ var init_error_messages = __esm({
|
|
|
2265
2257
|
message: "A task is already in progress",
|
|
2266
2258
|
hint: "Complete it with 'p. done' or pause with 'p. pause'"
|
|
2267
2259
|
},
|
|
2268
|
-
// Sync errors
|
|
2269
2260
|
SYNC_FAILED: {
|
|
2270
2261
|
message: "Project sync failed",
|
|
2271
2262
|
hint: "Check file permissions and try again"
|
|
2272
2263
|
},
|
|
2273
|
-
// Ship errors
|
|
2274
2264
|
NOTHING_TO_SHIP: {
|
|
2275
2265
|
message: "Nothing to ship",
|
|
2276
2266
|
hint: "Make some changes first, then run ship"
|
|
@@ -2279,7 +2269,6 @@ var init_error_messages = __esm({
|
|
|
2279
2269
|
message: "Failed to create pull request",
|
|
2280
2270
|
hint: "Check GitHub auth and remote configuration"
|
|
2281
2271
|
},
|
|
2282
|
-
// Provider errors
|
|
2283
2272
|
NO_AI_PROVIDER: {
|
|
2284
2273
|
message: "No AI provider detected",
|
|
2285
2274
|
hint: "Install Claude Code or Gemini CLI, then run 'prjct start'",
|
|
@@ -2289,7 +2278,6 @@ var init_error_messages = __esm({
|
|
|
2289
2278
|
message: "AI provider not configured for prjct",
|
|
2290
2279
|
hint: "Run 'prjct start' to configure your provider"
|
|
2291
2280
|
},
|
|
2292
|
-
// Command errors
|
|
2293
2281
|
UNKNOWN_COMMAND: {
|
|
2294
2282
|
message: "Unknown command",
|
|
2295
2283
|
hint: "Run 'prjct --help' to see available commands"
|
|
@@ -2298,12 +2286,31 @@ var init_error_messages = __esm({
|
|
|
2298
2286
|
message: "Missing required parameter",
|
|
2299
2287
|
hint: "Check command usage below"
|
|
2300
2288
|
},
|
|
2301
|
-
// Generic
|
|
2302
2289
|
UNKNOWN: {
|
|
2303
2290
|
message: "An unexpected error occurred",
|
|
2304
2291
|
hint: "Check the error details and try again"
|
|
2305
2292
|
}
|
|
2306
2293
|
};
|
|
2294
|
+
}
|
|
2295
|
+
});
|
|
2296
|
+
|
|
2297
|
+
// core/utils/error-messages.ts
|
|
2298
|
+
function getError(code, overrides) {
|
|
2299
|
+
const base = ERRORS[code];
|
|
2300
|
+
return { ...base, ...overrides };
|
|
2301
|
+
}
|
|
2302
|
+
function createError(message, hint, options) {
|
|
2303
|
+
return {
|
|
2304
|
+
message,
|
|
2305
|
+
hint,
|
|
2306
|
+
...options
|
|
2307
|
+
};
|
|
2308
|
+
}
|
|
2309
|
+
var init_error_messages = __esm({
|
|
2310
|
+
"core/utils/error-messages.ts"() {
|
|
2311
|
+
"use strict";
|
|
2312
|
+
init_errors2();
|
|
2313
|
+
init_errors2();
|
|
2307
2314
|
__name(getError, "getError");
|
|
2308
2315
|
__name(createError, "createError");
|
|
2309
2316
|
}
|
|
@@ -13320,9 +13327,11 @@ var init_types3 = __esm({
|
|
|
13320
13327
|
"use strict";
|
|
13321
13328
|
init_agentic();
|
|
13322
13329
|
init_bus();
|
|
13330
|
+
init_errors2();
|
|
13323
13331
|
init_fs();
|
|
13324
13332
|
init_integrations();
|
|
13325
13333
|
init_memory();
|
|
13334
|
+
init_server();
|
|
13326
13335
|
}
|
|
13327
13336
|
});
|
|
13328
13337
|
|
|
@@ -22952,13 +22961,7 @@ You are the ${name} expert for this project. Apply best practices for the detect
|
|
|
22952
22961
|
projectPath: this.projectPath,
|
|
22953
22962
|
globalPath: this.globalPath
|
|
22954
22963
|
});
|
|
22955
|
-
return generator.generate(
|
|
22956
|
-
{ branch: git.branch, commits: git.commits },
|
|
22957
|
-
stats,
|
|
22958
|
-
commands,
|
|
22959
|
-
agents,
|
|
22960
|
-
sources
|
|
22961
|
-
);
|
|
22964
|
+
return generator.generate(git, stats, commands, agents, sources);
|
|
22962
22965
|
}
|
|
22963
22966
|
// ==========================================================================
|
|
22964
22967
|
// PROJECT.JSON UPDATE
|
|
@@ -28646,7 +28649,7 @@ var require_package = __commonJS({
|
|
|
28646
28649
|
"package.json"(exports, module) {
|
|
28647
28650
|
module.exports = {
|
|
28648
28651
|
name: "prjct-cli",
|
|
28649
|
-
version: "1.6.
|
|
28652
|
+
version: "1.6.9",
|
|
28650
28653
|
description: "Context layer for AI agents. Project context for Claude Code, Gemini CLI, and more.",
|
|
28651
28654
|
main: "core/index.ts",
|
|
28652
28655
|
bin: {
|
|
@@ -29665,9 +29668,47 @@ function createExtendedRoutes() {
|
|
|
29665
29668
|
__name(createExtendedRoutes, "createExtendedRoutes");
|
|
29666
29669
|
|
|
29667
29670
|
// core/server/sse.ts
|
|
29671
|
+
init_server();
|
|
29668
29672
|
import { streamSSE } from "hono/streaming";
|
|
29673
|
+
var MAX_CLIENT_TTL_MS = 60 * 60 * 1e3;
|
|
29674
|
+
var REAPER_INTERVAL_MS = 5 * 60 * 1e3;
|
|
29675
|
+
var HEARTBEAT_INTERVAL_MS = 3e4;
|
|
29669
29676
|
function createSSEManager() {
|
|
29670
29677
|
const clients = /* @__PURE__ */ new Map();
|
|
29678
|
+
let reaperInterval = null;
|
|
29679
|
+
function removeClient(clientId) {
|
|
29680
|
+
const entry = clients.get(clientId);
|
|
29681
|
+
if (!entry) return;
|
|
29682
|
+
clearInterval(entry.heartbeatInterval);
|
|
29683
|
+
clearTimeout(entry.ttlTimeout);
|
|
29684
|
+
entry.abortController.abort();
|
|
29685
|
+
clients.delete(clientId);
|
|
29686
|
+
}
|
|
29687
|
+
__name(removeClient, "removeClient");
|
|
29688
|
+
function startReaper() {
|
|
29689
|
+
if (reaperInterval) return;
|
|
29690
|
+
reaperInterval = setInterval(() => {
|
|
29691
|
+
const now = Date.now();
|
|
29692
|
+
for (const [id, entry] of clients) {
|
|
29693
|
+
const connectedMs = now - new Date(entry.client.connectedAt).getTime();
|
|
29694
|
+
if (connectedMs > MAX_CLIENT_TTL_MS) {
|
|
29695
|
+
removeClient(id);
|
|
29696
|
+
}
|
|
29697
|
+
}
|
|
29698
|
+
}, REAPER_INTERVAL_MS);
|
|
29699
|
+
if (reaperInterval && typeof reaperInterval === "object" && "unref" in reaperInterval) {
|
|
29700
|
+
reaperInterval.unref();
|
|
29701
|
+
}
|
|
29702
|
+
}
|
|
29703
|
+
__name(startReaper, "startReaper");
|
|
29704
|
+
function stopReaper() {
|
|
29705
|
+
if (reaperInterval) {
|
|
29706
|
+
clearInterval(reaperInterval);
|
|
29707
|
+
reaperInterval = null;
|
|
29708
|
+
}
|
|
29709
|
+
}
|
|
29710
|
+
__name(stopReaper, "stopReaper");
|
|
29711
|
+
startReaper();
|
|
29671
29712
|
return {
|
|
29672
29713
|
/**
|
|
29673
29714
|
* Handle a new SSE connection
|
|
@@ -29675,8 +29716,11 @@ function createSSEManager() {
|
|
|
29675
29716
|
handleConnection(c) {
|
|
29676
29717
|
return streamSSE(c, async (stream) => {
|
|
29677
29718
|
const clientId = crypto.randomUUID();
|
|
29719
|
+
const connectedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
29720
|
+
const abortController = new AbortController();
|
|
29678
29721
|
const client = {
|
|
29679
29722
|
id: clientId,
|
|
29723
|
+
connectedAt,
|
|
29680
29724
|
send: /* @__PURE__ */ __name((event, data) => {
|
|
29681
29725
|
stream.writeSSE({
|
|
29682
29726
|
event,
|
|
@@ -29684,34 +29728,47 @@ function createSSEManager() {
|
|
|
29684
29728
|
});
|
|
29685
29729
|
}, "send"),
|
|
29686
29730
|
close: /* @__PURE__ */ __name(() => {
|
|
29687
|
-
|
|
29731
|
+
removeClient(clientId);
|
|
29688
29732
|
}, "close")
|
|
29689
29733
|
};
|
|
29690
|
-
|
|
29734
|
+
const heartbeatInterval = setInterval(async () => {
|
|
29735
|
+
try {
|
|
29736
|
+
await stream.writeSSE({
|
|
29737
|
+
event: "heartbeat",
|
|
29738
|
+
data: JSON.stringify({ timestamp: (/* @__PURE__ */ new Date()).toISOString() })
|
|
29739
|
+
});
|
|
29740
|
+
} catch {
|
|
29741
|
+
removeClient(clientId);
|
|
29742
|
+
}
|
|
29743
|
+
}, HEARTBEAT_INTERVAL_MS);
|
|
29744
|
+
const ttlTimeout = setTimeout(() => {
|
|
29745
|
+
removeClient(clientId);
|
|
29746
|
+
}, MAX_CLIENT_TTL_MS);
|
|
29747
|
+
if (typeof heartbeatInterval === "object" && "unref" in heartbeatInterval) {
|
|
29748
|
+
heartbeatInterval.unref();
|
|
29749
|
+
}
|
|
29750
|
+
if (typeof ttlTimeout === "object" && "unref" in ttlTimeout) {
|
|
29751
|
+
ttlTimeout.unref();
|
|
29752
|
+
}
|
|
29753
|
+
clients.set(clientId, {
|
|
29754
|
+
client,
|
|
29755
|
+
heartbeatInterval,
|
|
29756
|
+
ttlTimeout,
|
|
29757
|
+
abortController
|
|
29758
|
+
});
|
|
29691
29759
|
await stream.writeSSE({
|
|
29692
29760
|
event: "connected",
|
|
29693
29761
|
data: JSON.stringify({
|
|
29694
29762
|
clientId,
|
|
29695
|
-
timestamp:
|
|
29763
|
+
timestamp: connectedAt,
|
|
29696
29764
|
message: "Connected to prjct-cli server"
|
|
29697
29765
|
})
|
|
29698
29766
|
});
|
|
29699
|
-
const heartbeat = setInterval(async () => {
|
|
29700
|
-
try {
|
|
29701
|
-
await stream.writeSSE({
|
|
29702
|
-
event: "heartbeat",
|
|
29703
|
-
data: JSON.stringify({ timestamp: (/* @__PURE__ */ new Date()).toISOString() })
|
|
29704
|
-
});
|
|
29705
|
-
} catch (_error) {
|
|
29706
|
-
clearInterval(heartbeat);
|
|
29707
|
-
clients.delete(clientId);
|
|
29708
|
-
}
|
|
29709
|
-
}, 3e4);
|
|
29710
29767
|
stream.onAbort(() => {
|
|
29711
|
-
|
|
29712
|
-
clients.delete(clientId);
|
|
29768
|
+
removeClient(clientId);
|
|
29713
29769
|
});
|
|
29714
|
-
await new Promise(() => {
|
|
29770
|
+
await new Promise((resolve) => {
|
|
29771
|
+
abortController.signal.addEventListener("abort", () => resolve(), { once: true });
|
|
29715
29772
|
});
|
|
29716
29773
|
});
|
|
29717
29774
|
},
|
|
@@ -29724,11 +29781,11 @@ function createSSEManager() {
|
|
|
29724
29781
|
data,
|
|
29725
29782
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
29726
29783
|
};
|
|
29727
|
-
for (const
|
|
29784
|
+
for (const [id, entry] of clients) {
|
|
29728
29785
|
try {
|
|
29729
|
-
client.send(event, message);
|
|
29730
|
-
} catch
|
|
29731
|
-
|
|
29786
|
+
entry.client.send(event, message);
|
|
29787
|
+
} catch {
|
|
29788
|
+
removeClient(id);
|
|
29732
29789
|
}
|
|
29733
29790
|
}
|
|
29734
29791
|
},
|
|
@@ -29737,6 +29794,16 @@ function createSSEManager() {
|
|
|
29737
29794
|
*/
|
|
29738
29795
|
getClientCount() {
|
|
29739
29796
|
return clients.size;
|
|
29797
|
+
},
|
|
29798
|
+
/**
|
|
29799
|
+
* Shut down all clients and stop the reaper.
|
|
29800
|
+
* Called on server stop.
|
|
29801
|
+
*/
|
|
29802
|
+
shutdown() {
|
|
29803
|
+
stopReaper();
|
|
29804
|
+
for (const id of [...clients.keys()]) {
|
|
29805
|
+
removeClient(id);
|
|
29806
|
+
}
|
|
29740
29807
|
}
|
|
29741
29808
|
};
|
|
29742
29809
|
}
|
|
@@ -29818,6 +29885,7 @@ function createServer(config) {
|
|
|
29818
29885
|
console.log(` Dashboard: http://localhost:${port}`);
|
|
29819
29886
|
},
|
|
29820
29887
|
stop() {
|
|
29888
|
+
sseManager.shutdown();
|
|
29821
29889
|
if (server) {
|
|
29822
29890
|
server.stop();
|
|
29823
29891
|
server = null;
|