prjct-cli 0.45.0 → 0.45.4

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 (207) hide show
  1. package/CHANGELOG.md +82 -0
  2. package/bin/prjct.ts +117 -10
  3. package/core/__tests__/agentic/memory-system.test.ts +39 -26
  4. package/core/__tests__/agentic/plan-mode.test.ts +64 -46
  5. package/core/__tests__/agentic/prompt-builder.test.ts +14 -14
  6. package/core/__tests__/services/project-index.test.ts +353 -0
  7. package/core/__tests__/types/fs.test.ts +3 -3
  8. package/core/__tests__/utils/date-helper.test.ts +10 -10
  9. package/core/__tests__/utils/output.test.ts +9 -6
  10. package/core/__tests__/utils/project-commands.test.ts +5 -6
  11. package/core/agentic/agent-router.ts +9 -10
  12. package/core/agentic/chain-of-thought.ts +16 -4
  13. package/core/agentic/command-executor.ts +66 -40
  14. package/core/agentic/context-builder.ts +8 -5
  15. package/core/agentic/ground-truth.ts +15 -9
  16. package/core/agentic/index.ts +145 -152
  17. package/core/agentic/loop-detector.ts +40 -11
  18. package/core/agentic/memory-system.ts +98 -35
  19. package/core/agentic/orchestrator-executor.ts +135 -71
  20. package/core/agentic/plan-mode.ts +46 -16
  21. package/core/agentic/prompt-builder.ts +108 -42
  22. package/core/agentic/services.ts +10 -9
  23. package/core/agentic/skill-loader.ts +9 -15
  24. package/core/agentic/smart-context.ts +129 -79
  25. package/core/agentic/template-executor.ts +13 -12
  26. package/core/agentic/template-loader.ts +7 -4
  27. package/core/agentic/tool-registry.ts +16 -13
  28. package/core/agents/index.ts +1 -1
  29. package/core/agents/performance.ts +10 -27
  30. package/core/ai-tools/formatters.ts +8 -6
  31. package/core/ai-tools/generator.ts +4 -4
  32. package/core/ai-tools/index.ts +1 -1
  33. package/core/ai-tools/registry.ts +21 -11
  34. package/core/bus/bus.ts +23 -16
  35. package/core/bus/index.ts +2 -2
  36. package/core/cli/linear.ts +3 -5
  37. package/core/cli/start.ts +28 -25
  38. package/core/commands/analysis.ts +58 -39
  39. package/core/commands/analytics.ts +52 -44
  40. package/core/commands/base.ts +15 -13
  41. package/core/commands/cleanup.ts +6 -13
  42. package/core/commands/command-data.ts +28 -4
  43. package/core/commands/commands.ts +57 -24
  44. package/core/commands/context.ts +4 -4
  45. package/core/commands/design.ts +3 -10
  46. package/core/commands/index.ts +5 -8
  47. package/core/commands/maintenance.ts +7 -4
  48. package/core/commands/planning.ts +179 -56
  49. package/core/commands/register.ts +13 -9
  50. package/core/commands/registry.ts +15 -14
  51. package/core/commands/setup.ts +26 -14
  52. package/core/commands/shipping.ts +11 -16
  53. package/core/commands/snapshots.ts +16 -32
  54. package/core/commands/uninstall.ts +541 -0
  55. package/core/commands/workflow.ts +24 -28
  56. package/core/constants/index.ts +10 -22
  57. package/core/context/generator.ts +82 -33
  58. package/core/context-tools/files-tool.ts +18 -19
  59. package/core/context-tools/imports-tool.ts +13 -33
  60. package/core/context-tools/index.ts +29 -54
  61. package/core/context-tools/recent-tool.ts +16 -22
  62. package/core/context-tools/signatures-tool.ts +17 -26
  63. package/core/context-tools/summary-tool.ts +20 -22
  64. package/core/context-tools/token-counter.ts +25 -20
  65. package/core/context-tools/types.ts +5 -5
  66. package/core/domain/agent-generator.ts +7 -5
  67. package/core/domain/agent-loader.ts +2 -2
  68. package/core/domain/analyzer.ts +19 -16
  69. package/core/domain/architecture-generator.ts +6 -3
  70. package/core/domain/context-estimator.ts +3 -4
  71. package/core/domain/snapshot-manager.ts +25 -22
  72. package/core/domain/task-stack.ts +24 -14
  73. package/core/errors.ts +1 -1
  74. package/core/events/events.ts +2 -4
  75. package/core/events/index.ts +1 -2
  76. package/core/index.ts +28 -16
  77. package/core/infrastructure/agent-detector.ts +3 -3
  78. package/core/infrastructure/ai-provider.ts +23 -20
  79. package/core/infrastructure/author-detector.ts +16 -10
  80. package/core/infrastructure/capability-installer.ts +2 -2
  81. package/core/infrastructure/claude-agent.ts +6 -6
  82. package/core/infrastructure/command-installer.ts +22 -17
  83. package/core/infrastructure/config-manager.ts +18 -14
  84. package/core/infrastructure/editors-config.ts +8 -4
  85. package/core/infrastructure/path-manager.ts +8 -6
  86. package/core/infrastructure/permission-manager.ts +20 -17
  87. package/core/infrastructure/setup.ts +42 -38
  88. package/core/infrastructure/update-checker.ts +5 -5
  89. package/core/integrations/issue-tracker/enricher.ts +8 -19
  90. package/core/integrations/issue-tracker/index.ts +2 -2
  91. package/core/integrations/issue-tracker/manager.ts +15 -15
  92. package/core/integrations/issue-tracker/types.ts +5 -22
  93. package/core/integrations/jira/client.ts +67 -59
  94. package/core/integrations/jira/index.ts +11 -14
  95. package/core/integrations/jira/mcp-adapter.ts +5 -10
  96. package/core/integrations/jira/service.ts +10 -10
  97. package/core/integrations/linear/client.ts +27 -18
  98. package/core/integrations/linear/index.ts +9 -12
  99. package/core/integrations/linear/service.ts +11 -11
  100. package/core/integrations/linear/sync.ts +8 -8
  101. package/core/outcomes/analyzer.ts +5 -18
  102. package/core/outcomes/index.ts +2 -2
  103. package/core/outcomes/recorder.ts +3 -3
  104. package/core/plugin/builtin/webhook.ts +19 -15
  105. package/core/plugin/hooks.ts +29 -21
  106. package/core/plugin/index.ts +7 -7
  107. package/core/plugin/loader.ts +19 -19
  108. package/core/plugin/registry.ts +12 -23
  109. package/core/schemas/agents.ts +1 -1
  110. package/core/schemas/analysis.ts +1 -1
  111. package/core/schemas/enriched-task.ts +62 -49
  112. package/core/schemas/ideas.ts +13 -13
  113. package/core/schemas/index.ts +17 -27
  114. package/core/schemas/issues.ts +40 -25
  115. package/core/schemas/metrics.ts +25 -25
  116. package/core/schemas/outcomes.ts +70 -62
  117. package/core/schemas/permissions.ts +15 -12
  118. package/core/schemas/prd.ts +27 -14
  119. package/core/schemas/project.ts +3 -3
  120. package/core/schemas/roadmap.ts +47 -34
  121. package/core/schemas/schemas.ts +3 -4
  122. package/core/schemas/shipped.ts +3 -3
  123. package/core/schemas/state.ts +43 -29
  124. package/core/server/index.ts +5 -6
  125. package/core/server/routes-extended.ts +68 -72
  126. package/core/server/routes.ts +3 -3
  127. package/core/server/server.ts +31 -26
  128. package/core/services/agent-generator.ts +237 -0
  129. package/core/services/agent-service.ts +2 -2
  130. package/core/services/breakdown-service.ts +2 -4
  131. package/core/services/context-generator.ts +299 -0
  132. package/core/services/context-selector.ts +420 -0
  133. package/core/services/doctor-service.ts +426 -0
  134. package/core/services/file-categorizer.ts +448 -0
  135. package/core/services/file-scorer.ts +270 -0
  136. package/core/services/git-analyzer.ts +267 -0
  137. package/core/services/index.ts +27 -10
  138. package/core/services/memory-service.ts +3 -4
  139. package/core/services/project-index.ts +911 -0
  140. package/core/services/project-service.ts +4 -4
  141. package/core/services/skill-installer.ts +14 -17
  142. package/core/services/skill-lock.ts +3 -3
  143. package/core/services/skill-service.ts +12 -6
  144. package/core/services/stack-detector.ts +245 -0
  145. package/core/services/sync-service.ts +87 -345
  146. package/core/services/watch-service.ts +294 -0
  147. package/core/session/compaction.ts +23 -31
  148. package/core/session/index.ts +11 -5
  149. package/core/session/log-migration.ts +3 -3
  150. package/core/session/metrics.ts +19 -14
  151. package/core/session/session-log-manager.ts +12 -17
  152. package/core/session/task-session-manager.ts +25 -25
  153. package/core/session/utils.ts +1 -1
  154. package/core/storage/ideas-storage.ts +41 -57
  155. package/core/storage/index-storage.ts +514 -0
  156. package/core/storage/index.ts +41 -17
  157. package/core/storage/metrics-storage.ts +39 -34
  158. package/core/storage/queue-storage.ts +35 -45
  159. package/core/storage/shipped-storage.ts +17 -20
  160. package/core/storage/state-storage.ts +50 -30
  161. package/core/storage/storage-manager.ts +6 -6
  162. package/core/storage/storage.ts +18 -15
  163. package/core/sync/auth-config.ts +3 -3
  164. package/core/sync/index.ts +13 -19
  165. package/core/sync/oauth-handler.ts +3 -3
  166. package/core/sync/sync-client.ts +4 -9
  167. package/core/sync/sync-manager.ts +12 -14
  168. package/core/types/commands.ts +42 -7
  169. package/core/types/index.ts +284 -305
  170. package/core/types/integrations.ts +3 -3
  171. package/core/types/storage.ts +14 -14
  172. package/core/types/utils.ts +3 -3
  173. package/core/utils/agent-stream.ts +3 -1
  174. package/core/utils/animations.ts +14 -11
  175. package/core/utils/branding.ts +7 -7
  176. package/core/utils/cache.ts +1 -3
  177. package/core/utils/collection-filters.ts +3 -15
  178. package/core/utils/date-helper.ts +2 -7
  179. package/core/utils/file-helper.ts +13 -8
  180. package/core/utils/jsonl-helper.ts +13 -10
  181. package/core/utils/keychain.ts +4 -8
  182. package/core/utils/logger.ts +1 -1
  183. package/core/utils/next-steps.ts +3 -3
  184. package/core/utils/output.ts +58 -11
  185. package/core/utils/project-commands.ts +6 -6
  186. package/core/utils/project-credentials.ts +5 -12
  187. package/core/utils/runtime.ts +2 -2
  188. package/core/utils/session-helper.ts +3 -4
  189. package/core/utils/version.ts +3 -3
  190. package/core/wizard/index.ts +13 -0
  191. package/core/wizard/onboarding.ts +633 -0
  192. package/core/workflow/state-machine.ts +7 -7
  193. package/dist/bin/prjct.mjs +18755 -15574
  194. package/dist/core/infrastructure/command-installer.js +86 -79
  195. package/dist/core/infrastructure/editors-config.js +6 -6
  196. package/dist/core/infrastructure/setup.js +246 -225
  197. package/dist/core/utils/version.js +9 -9
  198. package/package.json +11 -12
  199. package/scripts/build.js +3 -3
  200. package/scripts/postinstall.js +2 -2
  201. package/templates/mcp-config.json +6 -1
  202. package/templates/permissions/permissive.jsonc +1 -1
  203. package/templates/permissions/strict.jsonc +5 -9
  204. package/templates/global/docs/agents.md +0 -88
  205. package/templates/global/docs/architecture.md +0 -103
  206. package/templates/global/docs/commands.md +0 -96
  207. package/templates/global/docs/validation.md +0 -95
@@ -0,0 +1,267 @@
1
+ /**
2
+ * GitAnalyzer - Git repository analysis
3
+ *
4
+ * Extracted from sync-service.ts for single responsibility.
5
+ * Analyzes git state: branch, commits, contributors, changes, etc.
6
+ *
7
+ * @version 1.0.0
8
+ */
9
+
10
+ import { exec } from 'node:child_process'
11
+ import { promisify } from 'node:util'
12
+
13
+ const execAsync = promisify(exec)
14
+
15
+ // ============================================================================
16
+ // TYPES
17
+ // ============================================================================
18
+
19
+ export interface GitData {
20
+ branch: string
21
+ commits: number
22
+ contributors: number
23
+ hasChanges: boolean
24
+ stagedFiles: string[]
25
+ modifiedFiles: string[]
26
+ untrackedFiles: string[]
27
+ recentCommits: { hash: string; message: string; date: string }[]
28
+ weeklyCommits: number
29
+ }
30
+
31
+ // ============================================================================
32
+ // GIT ANALYZER CLASS
33
+ // ============================================================================
34
+
35
+ export class GitAnalyzer {
36
+ private projectPath: string
37
+
38
+ constructor(projectPath: string) {
39
+ this.projectPath = projectPath
40
+ }
41
+
42
+ /**
43
+ * Analyze git repository state
44
+ */
45
+ async analyze(): Promise<GitData> {
46
+ const data: GitData = {
47
+ branch: 'main',
48
+ commits: 0,
49
+ contributors: 0,
50
+ hasChanges: false,
51
+ stagedFiles: [],
52
+ modifiedFiles: [],
53
+ untrackedFiles: [],
54
+ recentCommits: [],
55
+ weeklyCommits: 0,
56
+ }
57
+
58
+ try {
59
+ // Run independent git commands in parallel for speed
60
+ const [branch, commits, contributors, status, log, weekly] = await Promise.all([
61
+ this.getBranch(),
62
+ this.getCommitCount(),
63
+ this.getContributorCount(),
64
+ this.getStatus(),
65
+ this.getRecentCommits(),
66
+ this.getWeeklyCommitCount(),
67
+ ])
68
+
69
+ data.branch = branch
70
+ data.commits = commits
71
+ data.contributors = contributors
72
+ data.hasChanges = status.hasChanges
73
+ data.stagedFiles = status.stagedFiles
74
+ data.modifiedFiles = status.modifiedFiles
75
+ data.untrackedFiles = status.untrackedFiles
76
+ data.recentCommits = log
77
+ data.weeklyCommits = weekly
78
+ } catch {
79
+ // Not a git repo - use defaults
80
+ }
81
+
82
+ return data
83
+ }
84
+
85
+ /**
86
+ * Get current branch name
87
+ */
88
+ async getBranch(): Promise<string> {
89
+ try {
90
+ const { stdout } = await execAsync('git branch --show-current', {
91
+ cwd: this.projectPath,
92
+ })
93
+ return stdout.trim() || 'main'
94
+ } catch {
95
+ return 'main'
96
+ }
97
+ }
98
+
99
+ /**
100
+ * Get total commit count
101
+ */
102
+ async getCommitCount(): Promise<number> {
103
+ try {
104
+ const { stdout } = await execAsync('git rev-list --count HEAD', {
105
+ cwd: this.projectPath,
106
+ })
107
+ return parseInt(stdout.trim(), 10) || 0
108
+ } catch {
109
+ return 0
110
+ }
111
+ }
112
+
113
+ /**
114
+ * Get contributor count
115
+ */
116
+ async getContributorCount(): Promise<number> {
117
+ try {
118
+ const { stdout } = await execAsync('git shortlog -sn --all | wc -l', {
119
+ cwd: this.projectPath,
120
+ })
121
+ return parseInt(stdout.trim(), 10) || 0
122
+ } catch {
123
+ return 0
124
+ }
125
+ }
126
+
127
+ /**
128
+ * Get working tree status
129
+ */
130
+ async getStatus(): Promise<{
131
+ hasChanges: boolean
132
+ stagedFiles: string[]
133
+ modifiedFiles: string[]
134
+ untrackedFiles: string[]
135
+ }> {
136
+ const result = {
137
+ hasChanges: false,
138
+ stagedFiles: [] as string[],
139
+ modifiedFiles: [] as string[],
140
+ untrackedFiles: [] as string[],
141
+ }
142
+
143
+ try {
144
+ const { stdout } = await execAsync('git status --porcelain', {
145
+ cwd: this.projectPath,
146
+ })
147
+ const lines = stdout.trim().split('\n').filter(Boolean)
148
+ result.hasChanges = lines.length > 0
149
+
150
+ for (const line of lines) {
151
+ const code = line.substring(0, 2)
152
+ const file = line.substring(3)
153
+
154
+ if (code.startsWith('A') || code.startsWith('M ')) {
155
+ result.stagedFiles.push(file)
156
+ } else if (code.includes('M')) {
157
+ result.modifiedFiles.push(file)
158
+ } else if (code.startsWith('??')) {
159
+ result.untrackedFiles.push(file)
160
+ }
161
+ }
162
+ } catch {
163
+ // Not a git repo
164
+ }
165
+
166
+ return result
167
+ }
168
+
169
+ /**
170
+ * Get recent commits
171
+ */
172
+ async getRecentCommits(
173
+ count: number = 20
174
+ ): Promise<{ hash: string; message: string; date: string }[]> {
175
+ try {
176
+ const { stdout } = await execAsync(
177
+ `git log --oneline -${count} --pretty=format:"%h|%s|%ad" --date=short`,
178
+ { cwd: this.projectPath }
179
+ )
180
+
181
+ return stdout
182
+ .split('\n')
183
+ .filter(Boolean)
184
+ .map((line) => {
185
+ const [hash, message, date] = line.split('|')
186
+ return { hash, message, date }
187
+ })
188
+ } catch {
189
+ return []
190
+ }
191
+ }
192
+
193
+ /**
194
+ * Get commit count in the last week
195
+ */
196
+ async getWeeklyCommitCount(): Promise<number> {
197
+ try {
198
+ const { stdout } = await execAsync('git log --oneline --since="1 week ago" | wc -l', {
199
+ cwd: this.projectPath,
200
+ })
201
+ return parseInt(stdout.trim(), 10) || 0
202
+ } catch {
203
+ return 0
204
+ }
205
+ }
206
+
207
+ /**
208
+ * Check if directory is a git repository
209
+ */
210
+ async isGitRepo(): Promise<boolean> {
211
+ try {
212
+ await execAsync('git rev-parse --is-inside-work-tree', {
213
+ cwd: this.projectPath,
214
+ })
215
+ return true
216
+ } catch {
217
+ return false
218
+ }
219
+ }
220
+
221
+ /**
222
+ * Get default main branch name (main or master)
223
+ */
224
+ async getDefaultBranch(): Promise<string> {
225
+ try {
226
+ // Try to get from remote
227
+ const { stdout } = await execAsync(
228
+ 'git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed "s@^refs/remotes/origin/@@"',
229
+ { cwd: this.projectPath }
230
+ )
231
+ const branch = stdout.trim()
232
+ if (branch) return branch
233
+ } catch {
234
+ // Ignore
235
+ }
236
+
237
+ // Fallback: check if main or master exists
238
+ try {
239
+ await execAsync('git show-ref --verify --quiet refs/heads/main', {
240
+ cwd: this.projectPath,
241
+ })
242
+ return 'main'
243
+ } catch {
244
+ return 'master'
245
+ }
246
+ }
247
+ }
248
+
249
+ /**
250
+ * Get empty GitData for non-git repos or errors
251
+ */
252
+ export function getEmptyGitData(): GitData {
253
+ return {
254
+ branch: 'main',
255
+ commits: 0,
256
+ contributors: 0,
257
+ hasChanges: false,
258
+ stagedFiles: [],
259
+ modifiedFiles: [],
260
+ untrackedFiles: [],
261
+ recentCommits: [],
262
+ weeklyCommits: 0,
263
+ }
264
+ }
265
+
266
+ export const gitAnalyzer = (projectPath: string) => new GitAnalyzer(projectPath)
267
+ export default GitAnalyzer
@@ -5,19 +5,36 @@
5
5
  * Services encapsulate business logic extracted from CommandBase.
6
6
  */
7
7
 
8
- export { agentService, AgentService } from './agent-service'
9
- export { projectService, ProjectService } from './project-service'
10
- export { memoryService, MemoryService } from './memory-service'
11
- export { breakdownService, BreakdownService } from './breakdown-service'
12
- export { syncService, SyncService } from './sync-service'
13
- export type { SyncResult } from './sync-service'
14
-
15
8
  // Re-export types from canonical source
16
9
  export type {
17
- Severity,
18
10
  ComplexityEstimate,
19
- SkillMetadata,
11
+ MemoryServiceEntry,
12
+ Severity,
20
13
  Skill,
14
+ SkillMetadata,
21
15
  SkillSearchResult,
22
- MemoryServiceEntry,
23
16
  } from '../types'
17
+ export type { AgentInfo, ProjectStats } from './agent-generator'
18
+ // Agent Generator - Extracted from sync-service (PRJ-87)
19
+ export { AgentGenerator, createAgentGenerator } from './agent-generator'
20
+ export { AgentService, agentService } from './agent-service'
21
+ export { BreakdownService, breakdownService } from './breakdown-service'
22
+ export type { ContextSelectionOptions, SelectedContext } from './context-selector'
23
+ // Context Selector - Task-based context selection (PRJ-85)
24
+ export { ContextSelector, contextSelector } from './context-selector'
25
+ export type { CategorizationOptions, CategorizationResult } from './file-categorizer'
26
+ // File Categorizer - Smart Context Selection (PRJ-85)
27
+ export { FileCategorizer, fileCategorizer } from './file-categorizer'
28
+ export type { FileScore, FileStats, ScoringContext } from './file-scorer'
29
+ // File Scorer
30
+ export { FileScorer, fileScorer } from './file-scorer'
31
+ export type { GitData } from './git-analyzer'
32
+ // Git Analyzer - Extracted from sync-service (PRJ-85)
33
+ export { GitAnalyzer, getEmptyGitData, gitAnalyzer } from './git-analyzer'
34
+ export { MemoryService, memoryService } from './memory-service'
35
+ export type { IndexOptions, RelevantContext, ScanResult } from './project-index'
36
+ // Project Index - Persistent scanning with scoring
37
+ export { createProjectIndexer, ProjectIndexer, RELEVANCE_THRESHOLD } from './project-index'
38
+ export { ProjectService, projectService } from './project-service'
39
+ export type { SyncResult } from './sync-service'
40
+ export { SyncService, syncService } from './sync-service'
@@ -4,13 +4,12 @@
4
4
  * Handles logging actions to memory for audit trail and context building.
5
5
  */
6
6
 
7
- import pathManager from '../infrastructure/path-manager'
8
7
  import configManager from '../infrastructure/config-manager'
8
+ import pathManager from '../infrastructure/path-manager'
9
+ import type { MemoryServiceEntry } from '../types'
10
+ import { isNotFoundError } from '../types/fs'
9
11
  import { getTimestamp } from '../utils/date-helper'
10
12
  import jsonlHelper from '../utils/jsonl-helper'
11
- import { isNotFoundError } from '../types/fs'
12
-
13
- import type { MemoryServiceEntry } from '../types'
14
13
 
15
14
  export class MemoryService {
16
15
  /**