prjct-cli 1.6.7 → 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.
Files changed (85) hide show
  1. package/CHANGELOG.md +106 -5
  2. package/README.md +46 -0
  3. package/core/agentic/chain-of-thought.ts +3 -1
  4. package/core/agentic/ground-truth.ts +12 -5
  5. package/core/agentic/index.ts +14 -2
  6. package/core/agentic/memory-system.ts +86 -23
  7. package/core/agentic/services.ts +1 -1
  8. package/core/agentic/template-executor.ts +4 -4
  9. package/core/agentic/template-loader.ts +2 -8
  10. package/core/ai-tools/registry.ts +2 -9
  11. package/core/bus/bus.ts +0 -1
  12. package/core/bus/index.ts +1 -1
  13. package/core/cli/start.ts +0 -2
  14. package/core/commands/base.ts +2 -2
  15. package/core/commands/planning.ts +4 -6
  16. package/core/constants/index.ts +19 -0
  17. package/core/context/generator.ts +0 -2
  18. package/core/context-tools/files-tool.ts +0 -6
  19. package/core/context-tools/imports-tool.ts +0 -6
  20. package/core/context-tools/recent-tool.ts +0 -6
  21. package/core/context-tools/signatures-tool.ts +0 -6
  22. package/core/context-tools/summary-tool.ts +0 -6
  23. package/core/context-tools/token-counter.ts +0 -13
  24. package/core/infrastructure/agent-detector.ts +2 -15
  25. package/core/infrastructure/ai-provider.ts +0 -29
  26. package/core/infrastructure/author-detector.ts +0 -14
  27. package/core/infrastructure/config-manager.ts +1 -1
  28. package/core/infrastructure/path-manager.ts +3 -17
  29. package/core/infrastructure/setup.ts +0 -3
  30. package/core/integrations/jira/client.ts +3 -77
  31. package/core/plugin/hooks.ts +0 -2
  32. package/core/plugin/index.ts +0 -13
  33. package/core/plugin/loader.ts +0 -2
  34. package/core/plugin/registry.ts +0 -2
  35. package/core/server/server.ts +2 -4
  36. package/core/server/sse.ts +115 -59
  37. package/core/services/agent-service.ts +1 -1
  38. package/core/services/context-generator.ts +23 -48
  39. package/core/services/diff-generator.ts +18 -55
  40. package/core/services/hooks-service.ts +0 -1
  41. package/core/services/memory-service.ts +1 -1
  42. package/core/services/project-service.ts +1 -1
  43. package/core/services/stack-detector.ts +4 -20
  44. package/core/services/sync-service.ts +36 -107
  45. package/core/services/sync-verifier.ts +17 -37
  46. package/core/services/watch-service.ts +1 -1
  47. package/core/storage/index.ts +1 -1
  48. package/core/storage/storage.ts +0 -2
  49. package/core/types/citations.ts +22 -0
  50. package/core/types/commands.ts +10 -0
  51. package/core/types/diff.ts +41 -0
  52. package/core/types/errors.ts +111 -0
  53. package/core/types/index.ts +80 -0
  54. package/core/types/infrastructure.ts +14 -0
  55. package/core/types/jira.ts +51 -0
  56. package/core/types/logger.ts +17 -0
  57. package/core/types/output.ts +47 -0
  58. package/core/types/project-sync.ts +109 -0
  59. package/core/types/server.ts +28 -10
  60. package/core/types/services.ts +14 -0
  61. package/core/types/stack.ts +19 -0
  62. package/core/types/sync-verifier.ts +33 -0
  63. package/core/types/workflow.ts +23 -0
  64. package/core/utils/animations.ts +0 -18
  65. package/core/utils/cache.ts +0 -6
  66. package/core/utils/citations.ts +2 -16
  67. package/core/utils/collection-filters.ts +0 -24
  68. package/core/utils/date-helper.ts +0 -20
  69. package/core/utils/error-messages.ts +5 -139
  70. package/core/utils/file-helper.ts +0 -26
  71. package/core/utils/help.ts +0 -9
  72. package/core/utils/jsonl-helper.ts +0 -21
  73. package/core/utils/logger.ts +3 -11
  74. package/core/utils/markdown-builder.ts +0 -3
  75. package/core/utils/next-steps.ts +0 -2
  76. package/core/utils/output.ts +6 -45
  77. package/core/utils/runtime.ts +0 -11
  78. package/core/utils/session-helper.ts +0 -12
  79. package/core/utils/version.ts +0 -12
  80. package/core/workflow/workflow-preferences.ts +18 -31
  81. package/dist/bin/prjct.mjs +319 -351
  82. package/dist/core/infrastructure/command-installer.js +1 -26
  83. package/dist/core/infrastructure/setup.js +1 -28
  84. package/dist/core/utils/version.js +0 -11
  85. package/package.json +1 -1
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Sync Verifier Types
3
+ * Types for sync verification checks.
4
+ */
5
+
6
+ export interface VerificationCheck {
7
+ name: string
8
+ command?: string
9
+ script?: string
10
+ enabled?: boolean
11
+ }
12
+
13
+ export interface VerificationConfig {
14
+ checks?: VerificationCheck[]
15
+ failFast?: boolean
16
+ }
17
+
18
+ export interface VerificationCheckResult {
19
+ name: string
20
+ passed: boolean
21
+ output?: string
22
+ error?: string
23
+ durationMs: number
24
+ }
25
+
26
+ export interface VerificationReport {
27
+ passed: boolean
28
+ checks: VerificationCheckResult[]
29
+ totalMs: number
30
+ failedCount: number
31
+ passedCount: number
32
+ skippedCount: number
33
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Workflow Types
3
+ * Types for workflow preferences and hooks.
4
+ */
5
+
6
+ export type PreferenceScope = 'permanent' | 'session' | 'once'
7
+ export type HookPhase = 'before' | 'after' | 'skip'
8
+ export type HookCommand = 'task' | 'done' | 'ship' | 'sync'
9
+
10
+ export interface WorkflowPreference {
11
+ hook: HookPhase
12
+ command: HookCommand
13
+ action: string
14
+ scope: PreferenceScope
15
+ createdAt: string
16
+ }
17
+
18
+ export interface HookResult {
19
+ success: boolean
20
+ failed?: string
21
+ skipped?: string[]
22
+ output?: string
23
+ }
@@ -249,21 +249,3 @@ ${divider}
249
249
  ${colors.dim('Keep shipping! 🚀')}
250
250
  `
251
251
  }
252
-
253
- // Default export for CommonJS compatibility
254
- export default {
255
- colors,
256
- frames,
257
- banners,
258
- animate,
259
- typeWriter,
260
- progressBar,
261
- sparkle,
262
- formatShip,
263
- formatFocus,
264
- formatSuccess,
265
- formatError,
266
- formatIdea,
267
- formatCleanup,
268
- formatRecap,
269
- }
@@ -185,9 +185,3 @@ export class LazyCache<T> {
185
185
  return !this.loaded || this.data === null
186
186
  }
187
187
  }
188
-
189
- // Default export for CommonJS compatibility
190
- export default {
191
- TTLCache,
192
- LazyCache,
193
- }
@@ -7,23 +7,9 @@
7
7
  * @see PRJ-113
8
8
  */
9
9
 
10
- export type SourceType = 'detected' | 'user-defined' | 'inferred'
10
+ import type { ContextSources, SourceInfo, SourceType } from '../types/citations'
11
11
 
12
- export interface SourceInfo {
13
- file: string
14
- type: SourceType
15
- }
16
-
17
- export interface ContextSources {
18
- name: SourceInfo
19
- version: SourceInfo
20
- ecosystem: SourceInfo
21
- languages: SourceInfo
22
- frameworks: SourceInfo
23
- commands: SourceInfo
24
- projectType: SourceInfo
25
- git: SourceInfo
26
- }
12
+ export type { ContextSources, SourceInfo, SourceType } from '../types/citations'
27
13
 
28
14
  /**
29
15
  * Generate an HTML citation comment
@@ -207,27 +207,3 @@ export function uniqueByField<T, K extends keyof T>(items: T[], field: K): T[] {
207
207
  return true
208
208
  })
209
209
  }
210
-
211
- // Default export for CommonJS compatibility
212
- export default {
213
- PRIORITY_ORDER,
214
- SECTION_ORDER,
215
- filterByField,
216
- filterByFieldIn,
217
- filterByFieldNot,
218
- filterActiveByField,
219
- filterByTruthy,
220
- filterByFalsy,
221
- sortByPriority,
222
- sortBySectionAndPriority,
223
- sortByDate,
224
- filterByDateRange,
225
- filterByLastDays,
226
- groupByField,
227
- countByField,
228
- take,
229
- takeLast,
230
- findByField,
231
- anyByField,
232
- uniqueByField,
233
- }
@@ -164,23 +164,3 @@ export function getEndOfDay(date: Date): Date {
164
164
  result.setHours(23, 59, 59, 999)
165
165
  return result
166
166
  }
167
-
168
- // Default export for CommonJS compatibility
169
- export default {
170
- formatDate,
171
- formatMonth,
172
- getTodayKey,
173
- getDateKey,
174
- getYearMonthDay,
175
- parseDate,
176
- getTimestamp,
177
- getDaysAgo,
178
- getDaysFromNow,
179
- getDateRange,
180
- isToday,
181
- isWithinLastDays,
182
- formatDuration,
183
- calculateDuration,
184
- getStartOfDay,
185
- getEndOfDay,
186
- }
@@ -2,151 +2,17 @@
2
2
  * Error Messages Catalog
3
3
  *
4
4
  * Centralized error messages with context and recovery hints.
5
- * Provides consistent, helpful error output across the CLI.
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
- 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
- // 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 = keyof typeof ERRORS
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
@@ -267,29 +267,3 @@ export function getFileExtension(filePath: string): string {
267
267
  export function getFileNameWithoutExtension(filePath: string): string {
268
268
  return path.basename(filePath, path.extname(filePath))
269
269
  }
270
-
271
- // Default export for CommonJS compatibility
272
- export default {
273
- readJson,
274
- writeJson,
275
- readFile,
276
- writeFile,
277
- atomicWrite,
278
- appendToFile,
279
- appendLine,
280
- prependToFile,
281
- fileExists,
282
- dirExists,
283
- ensureDir,
284
- deleteFile,
285
- deleteDir,
286
- listFiles,
287
- getFileSize,
288
- getFileModifiedTime,
289
- copyFile,
290
- moveFile,
291
- readLines,
292
- writeLines,
293
- getFileExtension,
294
- getFileNameWithoutExtension,
295
- }
@@ -312,12 +312,3 @@ export function getHelp(topic?: string): string {
312
312
 
313
313
  return formatCommandHelp(topic)
314
314
  }
315
-
316
- export default {
317
- formatMainHelp,
318
- formatCommandHelp,
319
- formatCommandList,
320
- formatTerminalCommandHelp,
321
- formatAgentCommandHelp,
322
- getHelp,
323
- }
@@ -288,24 +288,3 @@ export async function checkFileSizeWarning(
288
288
 
289
289
  return { sizeMB, isLarge }
290
290
  }
291
-
292
- // Default export for CommonJS compatibility
293
- export default {
294
- parseJsonLines,
295
- stringifyJsonLines,
296
- readJsonLines,
297
- writeJsonLines,
298
- appendJsonLine,
299
- appendJsonLines,
300
- filterJsonLines,
301
- countJsonLines,
302
- getLastJsonLines,
303
- getFirstJsonLines,
304
- mergeJsonLines,
305
- isJsonLinesEmpty,
306
- readJsonLinesStreaming,
307
- getFileSizeMB,
308
- rotateJsonLinesIfNeeded,
309
- appendJsonLineWithRotation,
310
- checkFileSizeWarning,
311
- }
@@ -16,17 +16,7 @@
16
16
  * log.error('Failed to load', error.message)
17
17
  */
18
18
 
19
- type LogLevel = 'error' | 'warn' | 'info' | 'debug'
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
@@ -278,6 +278,3 @@ export class MarkdownBuilder {
278
278
  export function md(): MarkdownBuilder {
279
279
  return new MarkdownBuilder()
280
280
  }
281
-
282
- // Default export
283
- export default { MarkdownBuilder, md }
@@ -91,5 +91,3 @@ export function showStateInfo(state: WorkflowState): void {
91
91
  const info = workflowStateMachine.getStateInfo(state)
92
92
  console.log(chalk.dim(`📍 State: ${chalk.white(state.toUpperCase())} - ${info.description}`))
93
93
  }
94
-
95
- export default { showNextSteps, getNextSteps, showStateInfo }
@@ -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
@@ -106,14 +106,3 @@ export function getRunCommand(scriptPath: string, args: string[] = []): string {
106
106
 
107
107
  return `node ${scriptPath}${argsStr}`
108
108
  }
109
-
110
- export default {
111
- detectRuntime,
112
- isBunAvailable,
113
- isNodeAvailable,
114
- getRuntimeVersion,
115
- isBun,
116
- isNode,
117
- getPreferredRuntime,
118
- getRunCommand,
119
- }
@@ -276,15 +276,3 @@ export async function cleanEmptySessionDirs(
276
276
 
277
277
  return cleaned
278
278
  }
279
-
280
- // Default export for CommonJS compatibility
281
- export default {
282
- getTodaySessionFilePath,
283
- ensureTodaySessionDir,
284
- writeToSession,
285
- readTodaySession,
286
- readRecentSessions,
287
- getSessionStats,
288
- archiveOldSessions,
289
- cleanEmptySessionDirs,
290
- }
@@ -123,15 +123,3 @@ export function needsMigration(fromVersion: string, toVersion: string | null = n
123
123
 
124
124
  export const VERSION = getVersion()
125
125
  export const PACKAGE_ROOT = getPackageRoot()
126
-
127
- // Default export for CommonJS compatibility
128
- export default {
129
- getVersion,
130
- getPackageRoot,
131
- getPackageInfo,
132
- compareVersions,
133
- isCompatible,
134
- needsMigration,
135
- VERSION,
136
- PACKAGE_ROOT,
137
- }
@@ -17,28 +17,25 @@ import { exec } from 'node:child_process'
17
17
  import { promisify } from 'node:util'
18
18
  import chalk from 'chalk'
19
19
  import memorySystem from '../agentic/memory-system'
20
+ import { WORKFLOW_HELP } from '../constants'
21
+ import type {
22
+ HookCommand,
23
+ HookPhase,
24
+ HookResult,
25
+ PreferenceScope,
26
+ WorkflowPreference,
27
+ } from '../types'
20
28
  import { getErrorMessage } from '../types/fs'
21
29
 
22
30
  const execAsync = promisify(exec)
23
31
 
24
- export type PreferenceScope = 'permanent' | 'session' | 'once'
25
- export type HookPhase = 'before' | 'after' | 'skip'
26
- export type HookCommand = 'task' | 'done' | 'ship' | 'sync'
27
-
28
- export interface WorkflowPreference {
29
- hook: HookPhase
30
- command: HookCommand
31
- action: string // command to run or 'true' for skip
32
- scope: PreferenceScope
33
- createdAt: string
34
- }
35
-
36
- export interface HookResult {
37
- success: boolean
38
- failed?: string
39
- skipped?: string[]
40
- output?: string
41
- }
32
+ export type {
33
+ HookCommand,
34
+ HookPhase,
35
+ HookResult,
36
+ PreferenceScope,
37
+ WorkflowPreference,
38
+ } from '../types'
42
39
 
43
40
  // Session and once preferences (in-memory)
44
41
  const sessionPreferences: Map<string, WorkflowPreference> = new Map()
@@ -265,7 +262,7 @@ export function formatWorkflowPreferences(
265
262
  }>
266
263
  ): string {
267
264
  if (preferences.length === 0) {
268
- return `${chalk.dim('No workflow preferences configured.')}\n\nSet one: "p. workflow antes de ship corre los tests"`
265
+ return `${chalk.dim(WORKFLOW_HELP.NO_PREFERENCES)}\n\nSet one: "${WORKFLOW_HELP.SET_EXAMPLE}"`
269
266
  }
270
267
 
271
268
  const lines: string[] = ['', 'WORKFLOW PREFERENCES', '────────────────────────────']
@@ -282,8 +279,8 @@ export function formatWorkflowPreferences(
282
279
  }
283
280
 
284
281
  lines.push('')
285
- lines.push(chalk.dim('Modify: "p. workflow antes de ship corre npm test"'))
286
- lines.push(chalk.dim('Remove: "p. workflow quita el hook de ship"'))
282
+ lines.push(chalk.dim(`Modify: "${WORKFLOW_HELP.MODIFY_EXAMPLE}"`))
283
+ lines.push(chalk.dim(`Remove: "${WORKFLOW_HELP.REMOVE_EXAMPLE}"`))
287
284
 
288
285
  return lines.join('\n')
289
286
  }
@@ -295,13 +292,3 @@ export function clearSessionPreferences(): void {
295
292
  sessionPreferences.clear()
296
293
  oncePreferences.clear()
297
294
  }
298
-
299
- export default {
300
- setWorkflowPreference,
301
- getWorkflowPreferences,
302
- runWorkflowHooks,
303
- listWorkflowPreferences,
304
- removeWorkflowPreference,
305
- formatWorkflowPreferences,
306
- clearSessionPreferences,
307
- }