prjct-cli 0.44.1 → 0.45.3

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 +114 -0
  2. package/bin/prjct.ts +131 -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 +287 -29
  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 +49 -8
  43. package/core/commands/commands.ts +60 -23
  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 +14 -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 +583 -0
  59. package/core/context-tools/imports-tool.ts +403 -0
  60. package/core/context-tools/index.ts +433 -0
  61. package/core/context-tools/recent-tool.ts +307 -0
  62. package/core/context-tools/signatures-tool.ts +501 -0
  63. package/core/context-tools/summary-tool.ts +307 -0
  64. package/core/context-tools/token-counter.ts +284 -0
  65. package/core/context-tools/types.ts +253 -0
  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 -12
  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 +143 -0
  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 +170 -329
  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 -13
  157. package/core/storage/metrics-storage.ts +320 -0
  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 -302
  170. package/core/types/integrations.ts +3 -3
  171. package/core/types/storage.ts +49 -0
  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 +18907 -13189
  194. package/dist/core/infrastructure/command-installer.js +96 -111
  195. package/dist/core/infrastructure/editors-config.js +6 -6
  196. package/dist/core/infrastructure/setup.js +256 -257
  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,253 @@
1
+ /**
2
+ * Context Tools Types
3
+ *
4
+ * Shared interfaces for all context filtering tools.
5
+ * These tools are designed for AI agents to efficiently explore
6
+ * codebases WITHOUT consuming tokens for filtering.
7
+ *
8
+ * @module context-tools/types
9
+ * @version 1.0.0
10
+ */
11
+
12
+ // =============================================================================
13
+ // Token Measurement Types
14
+ // =============================================================================
15
+
16
+ /**
17
+ * Cost savings breakdown by model
18
+ */
19
+ export interface CostBreakdown {
20
+ model: string
21
+ inputSaved: number // $ saved on input tokens
22
+ outputPotential: number // $ potential savings on output (estimated)
23
+ total: number // Combined savings
24
+ }
25
+
26
+ /**
27
+ * Token measurement result
28
+ */
29
+ export interface TokenMetrics {
30
+ tokens: {
31
+ original: number
32
+ filtered: number
33
+ saved: number
34
+ }
35
+ compression: number // 0-1 (e.g., 0.90 = 90% reduction)
36
+ cost: {
37
+ saved: number // $ saved (using default model)
38
+ formatted: string // Human-readable (e.g., "$0.02")
39
+ byModel: CostBreakdown[] // Breakdown by popular models
40
+ }
41
+ }
42
+
43
+ // =============================================================================
44
+ // Files Tool Types
45
+ // =============================================================================
46
+
47
+ /**
48
+ * Relevance score reasons
49
+ */
50
+ export type ScoreReason =
51
+ | `keyword:${string}` // Matched keyword in path
52
+ | `domain:${string}` // Matched domain pattern
53
+ | `recent:${string}` // Recently modified (e.g., "3d" = 3 days)
54
+ | `import:${number}` // Import distance from entry point
55
+ | `extension:${string}` // File extension match
56
+
57
+ /**
58
+ * File with relevance score
59
+ */
60
+ export interface ScoredFile {
61
+ path: string
62
+ score: number // 0-1
63
+ reasons: ScoreReason[]
64
+ }
65
+
66
+ /**
67
+ * Files tool output
68
+ */
69
+ export interface FilesToolOutput {
70
+ files: ScoredFile[]
71
+ metrics: {
72
+ filesScanned: number
73
+ filesReturned: number
74
+ scanDuration: number // ms
75
+ }
76
+ }
77
+
78
+ // =============================================================================
79
+ // Signatures Tool Types
80
+ // =============================================================================
81
+
82
+ /**
83
+ * Code signature types
84
+ */
85
+ export type SignatureType =
86
+ | 'function'
87
+ | 'method'
88
+ | 'class'
89
+ | 'interface'
90
+ | 'type'
91
+ | 'enum'
92
+ | 'const'
93
+ | 'variable'
94
+ | 'export'
95
+ | 'import'
96
+
97
+ /**
98
+ * Extracted code signature
99
+ */
100
+ export interface CodeSignature {
101
+ type: SignatureType
102
+ name: string
103
+ signature: string // Full signature string (e.g., "(token: string) => Promise<User>")
104
+ exported: boolean
105
+ line: number
106
+ docstring?: string
107
+ }
108
+
109
+ /**
110
+ * Signatures tool output
111
+ */
112
+ export interface SignaturesToolOutput {
113
+ file: string
114
+ language: string
115
+ signatures: CodeSignature[]
116
+ fallback: boolean // True if full file was returned (no grammar)
117
+ fallbackReason?: string
118
+ metrics: TokenMetrics
119
+ }
120
+
121
+ // =============================================================================
122
+ // Imports Tool Types
123
+ // =============================================================================
124
+
125
+ /**
126
+ * Import relationship
127
+ */
128
+ export interface ImportRelation {
129
+ source: string // Import path (e.g., "./types", "lodash")
130
+ resolved: string | null // Resolved file path (null for external)
131
+ isExternal: boolean
132
+ importedNames?: string[] // Named imports
133
+ isDefault?: boolean
134
+ isNamespace?: boolean // import * as X
135
+ }
136
+
137
+ /**
138
+ * File that imports the target
139
+ */
140
+ export interface ImportedBy {
141
+ file: string
142
+ importedNames?: string[]
143
+ }
144
+
145
+ /**
146
+ * Dependency tree node
147
+ */
148
+ export interface DependencyNode {
149
+ file: string
150
+ imports: DependencyNode[]
151
+ depth: number
152
+ }
153
+
154
+ /**
155
+ * Imports tool output
156
+ */
157
+ export interface ImportsToolOutput {
158
+ file: string
159
+ imports: ImportRelation[]
160
+ importedBy: ImportedBy[]
161
+ dependencyTree?: DependencyNode
162
+ metrics: {
163
+ totalImports: number
164
+ externalImports: number
165
+ internalImports: number
166
+ importedByCount: number
167
+ }
168
+ }
169
+
170
+ // =============================================================================
171
+ // Recent Tool Types
172
+ // =============================================================================
173
+
174
+ /**
175
+ * Hot file from git analysis
176
+ */
177
+ export interface HotFile {
178
+ path: string
179
+ changes: number // Number of commits touching this file
180
+ heatScore: number // 0-1 normalized score
181
+ lastChanged: string // Human-readable (e.g., "2h ago", "3d ago")
182
+ lastChangedAt: string // ISO timestamp
183
+ }
184
+
185
+ /**
186
+ * Recent tool output
187
+ */
188
+ export interface RecentToolOutput {
189
+ hotFiles: HotFile[]
190
+ branchOnlyFiles: string[] // Files only changed in current branch
191
+ metrics: {
192
+ commitsAnalyzed: number
193
+ totalFilesChanged: number
194
+ filesReturned: number
195
+ analysisWindow: string // e.g., "30 commits", "main..HEAD"
196
+ }
197
+ }
198
+
199
+ // =============================================================================
200
+ // Summary Tool Types
201
+ // =============================================================================
202
+
203
+ /**
204
+ * Public API entry
205
+ */
206
+ export interface PublicAPIEntry {
207
+ name: string
208
+ type: SignatureType
209
+ signature: string
210
+ description?: string // From JSDoc/docstring
211
+ }
212
+
213
+ /**
214
+ * Summary tool output
215
+ */
216
+ export interface SummaryToolOutput {
217
+ file: string
218
+ purpose: string // Short description of file purpose
219
+ publicAPI: PublicAPIEntry[]
220
+ dependencies: string[] // Key dependencies
221
+ metrics: TokenMetrics
222
+ }
223
+
224
+ // =============================================================================
225
+ // Context Tool Usage Tracking
226
+ // =============================================================================
227
+
228
+ /**
229
+ * Tool usage record for metrics
230
+ */
231
+ export interface ContextToolUsage {
232
+ tool: 'files' | 'signatures' | 'imports' | 'recent' | 'summary'
233
+ timestamp: string
234
+ inputArgs: string
235
+ tokensSaved: number
236
+ compressionRate: number
237
+ duration: number // ms
238
+ }
239
+
240
+ // =============================================================================
241
+ // Main Tool Result Type
242
+ // =============================================================================
243
+
244
+ /**
245
+ * Union type for all tool outputs
246
+ */
247
+ export type ContextToolOutput =
248
+ | { tool: 'files'; result: FilesToolOutput }
249
+ | { tool: 'signatures'; result: SignaturesToolOutput }
250
+ | { tool: 'imports'; result: ImportsToolOutput }
251
+ | { tool: 'recent'; result: RecentToolOutput }
252
+ | { tool: 'summary'; result: SummaryToolOutput }
253
+ | { tool: 'error'; result: { error: string; code: string } }
@@ -4,11 +4,11 @@
4
4
  * @version 1.0.0
5
5
  */
6
6
 
7
- import fs from 'fs/promises'
8
- import path from 'path'
9
- import os from 'os'
10
- import AgentLoader from './agent-loader'
7
+ import fs from 'node:fs/promises'
8
+ import os from 'node:os'
9
+ import path from 'node:path'
11
10
  import log from '../utils/logger'
11
+ import AgentLoader from './agent-loader'
12
12
 
13
13
  interface AgentConfig {
14
14
  role?: string
@@ -152,7 +152,9 @@ ${config.contextFilter || 'Only relevant files'}
152
152
  async listAgents(): Promise<string[]> {
153
153
  try {
154
154
  const files = await fs.readdir(this.outputDir)
155
- return files.filter((f) => f.endsWith('.md') && !f.startsWith('.')).map((f) => f.replace('.md', ''))
155
+ return files
156
+ .filter((f) => f.endsWith('.md') && !f.startsWith('.'))
157
+ .map((f) => f.replace('.md', ''))
156
158
  } catch (_error) {
157
159
  return []
158
160
  }
@@ -6,8 +6,8 @@
6
6
  * @version 1.0.0
7
7
  */
8
8
 
9
- import fs from 'fs/promises'
10
- import path from 'path'
9
+ import fs from 'node:fs/promises'
10
+ import path from 'node:path'
11
11
  import pathManager from '../infrastructure/path-manager'
12
12
  import { isNotFoundError } from '../types/fs'
13
13
 
@@ -10,10 +10,10 @@
10
10
  * @version 0.6.0 - Fully agentic refactor
11
11
  */
12
12
 
13
- import fs from 'fs/promises'
14
- import path from 'path'
15
- import { promisify } from 'util'
16
- import { exec as execCallback } from 'child_process'
13
+ import { exec as execCallback } from 'node:child_process'
14
+ import fs from 'node:fs/promises'
15
+ import path from 'node:path'
16
+ import { promisify } from 'node:util'
17
17
  import { isNotFoundError } from '../types/fs'
18
18
 
19
19
  const exec = promisify(execCallback)
@@ -209,11 +209,11 @@ class CodebaseAnalyzer {
209
209
  .forEach((line) => {
210
210
  const match = line.trim().match(/^\s*(\d+)\s+(\.\w+)$/)
211
211
  if (match) {
212
- extensions[match[2]] = parseInt(match[1])
212
+ extensions[match[2]] = parseInt(match[1], 10)
213
213
  }
214
214
  })
215
215
  return extensions
216
- } catch (error) {
216
+ } catch (_error) {
217
217
  // exec errors (find command not available, etc.) - return empty
218
218
  return {}
219
219
  }
@@ -278,7 +278,7 @@ class CodebaseAnalyzer {
278
278
  cwd: this.projectPath!,
279
279
  })
280
280
  return stdout
281
- } catch (error) {
281
+ } catch (_error) {
282
282
  // Git errors (not a repo, git not installed) - return empty
283
283
  return ''
284
284
  }
@@ -297,16 +297,19 @@ class CodebaseAnalyzer {
297
297
  cwd: this.projectPath!,
298
298
  })
299
299
 
300
- const { stdout: firstCommit } = await exec('git log --reverse --pretty=format:"%ar" | head -1', {
301
- cwd: this.projectPath!,
302
- })
300
+ const { stdout: firstCommit } = await exec(
301
+ 'git log --reverse --pretty=format:"%ar" | head -1',
302
+ {
303
+ cwd: this.projectPath!,
304
+ }
305
+ )
303
306
 
304
307
  return {
305
- totalCommits: parseInt(totalCommits.trim()) || 0,
306
- contributors: parseInt(contributors.trim()) || 0,
308
+ totalCommits: parseInt(totalCommits.trim(), 10) || 0,
309
+ contributors: parseInt(contributors.trim(), 10) || 0,
307
310
  age: firstCommit.trim() || 'unknown',
308
311
  }
309
- } catch (error) {
312
+ } catch (_error) {
310
313
  // Git errors (not a repo, git not installed) - return defaults
311
314
  return {
312
315
  totalCommits: 0,
@@ -325,8 +328,8 @@ class CodebaseAnalyzer {
325
328
  'find . -type f ! -path "*/node_modules/*" ! -path "*/.git/*" ! -path "*/dist/*" | wc -l',
326
329
  { cwd: this.projectPath! }
327
330
  )
328
- return parseInt(stdout.trim()) || 0
329
- } catch (error) {
331
+ return parseInt(stdout.trim(), 10) || 0
332
+ } catch (_error) {
330
333
  // exec errors (find command not available, etc.) - return 0
331
334
  return 0
332
335
  }
@@ -372,7 +375,7 @@ class CodebaseAnalyzer {
372
375
  { cwd: this.projectPath! }
373
376
  )
374
377
  return stdout.trim().split('\n').filter(Boolean)
375
- } catch (error) {
378
+ } catch (_error) {
376
379
  // exec errors (find command not available, etc.) - return empty
377
380
  return []
378
381
  }
@@ -4,8 +4,8 @@
4
4
  * This file only provides structure - real content from Claude
5
5
  */
6
6
 
7
- import path from 'path'
8
- import fs from 'fs/promises'
7
+ import fs from 'node:fs/promises'
8
+ import path from 'node:path'
9
9
 
10
10
  interface ArchitectureContext {
11
11
  [key: string]: unknown
@@ -40,7 +40,10 @@ class ArchitectureGenerator {
40
40
  * Generate architecture skeleton
41
41
  * AGENTIC: Claude fills in content using templates
42
42
  */
43
- async generateArchitecture(idea: string, context: ArchitectureContext = {}): Promise<Architecture> {
43
+ async generateArchitecture(
44
+ idea: string,
45
+ _context: ArchitectureContext = {}
46
+ ): Promise<Architecture> {
44
47
  // Return skeleton - Claude generates actual content via templates
45
48
  return {
46
49
  id: `arch-${Date.now()}`,
@@ -7,7 +7,6 @@
7
7
  * @version 1.0.0
8
8
  */
9
9
 
10
- import path from 'path'
11
10
  import { glob } from 'glob'
12
11
  import log from '../utils/logger'
13
12
 
@@ -79,7 +78,7 @@ class ContextEstimator {
79
78
  * 100% AGENTIC: Uses REAL project data, not hardcoded patterns.
80
79
  * No domain-specific assumptions or language→extension mapping.
81
80
  */
82
- getPatternsForDomain(domain: string, projectData: ProjectTech): FilePatterns {
81
+ getPatternsForDomain(_domain: string, projectData: ProjectTech): FilePatterns {
83
82
  const patterns: FilePatterns = {
84
83
  include: [],
85
84
  extensions: [],
@@ -87,7 +86,7 @@ class ContextEstimator {
87
86
  }
88
87
 
89
88
  // Use REAL extensions from project (if provided in projectData)
90
- if (projectData && projectData.extensions) {
89
+ if (projectData?.extensions) {
91
90
  // projectData.extensions is {'.js': 45, '.ts': 23, ...}
92
91
  patterns.extensions = Object.keys(projectData.extensions)
93
92
  .filter((ext) => ext.startsWith('.'))
@@ -95,7 +94,7 @@ class ContextEstimator {
95
94
  }
96
95
 
97
96
  // Use REAL directories from project (if provided in projectData)
98
- if (projectData && projectData.directories) {
97
+ if (projectData?.directories) {
99
98
  patterns.include = projectData.directories.filter((dir) => !patterns.exclude.includes(dir))
100
99
  }
101
100
 
@@ -9,13 +9,13 @@
9
9
  * @version 1.0.0
10
10
  */
11
11
 
12
- import fs from 'fs/promises'
13
- import path from 'path'
14
- import { exec } from 'child_process'
15
- import { promisify } from 'util'
16
- import pathManager from '../infrastructure/path-manager'
17
- import configManager from '../infrastructure/config-manager'
12
+ import { exec } from 'node:child_process'
13
+ import fs from 'node:fs/promises'
14
+ import path from 'node:path'
15
+ import { promisify } from 'node:util'
18
16
  import { emit } from '../bus'
17
+ import configManager from '../infrastructure/config-manager'
18
+ import pathManager from '../infrastructure/path-manager'
19
19
  import { isNotFoundError } from '../types/fs'
20
20
 
21
21
  const execAsync = promisify(exec)
@@ -100,7 +100,9 @@ class SnapshotManager {
100
100
  await execAsync(`git config user.name "prjct-snapshots"`, { cwd: this.snapshotDir! })
101
101
 
102
102
  // Create initial empty commit
103
- await execAsync(`git commit --allow-empty -m "init: snapshot system"`, { cwd: this.snapshotDir! })
103
+ await execAsync(`git commit --allow-empty -m "init: snapshot system"`, {
104
+ cwd: this.snapshotDir!,
105
+ })
104
106
  }
105
107
 
106
108
  /**
@@ -236,9 +238,12 @@ class SnapshotManager {
236
238
  if (!this.initialized) await this.initialize()
237
239
 
238
240
  // Get files changed in that commit
239
- const { stdout: filesOutput } = await execAsync(`git diff-tree --no-commit-id --name-only -r ${hash}`, {
240
- cwd: this.snapshotDir!,
241
- })
241
+ const { stdout: filesOutput } = await execAsync(
242
+ `git diff-tree --no-commit-id --name-only -r ${hash}`,
243
+ {
244
+ cwd: this.snapshotDir!,
245
+ }
246
+ )
242
247
 
243
248
  const files = filesOutput.split('\n').filter(Boolean)
244
249
 
@@ -337,11 +342,10 @@ class SnapshotManager {
337
342
  */
338
343
  async logSnapshot(snapshot: SnapshotInfo): Promise<void> {
339
344
  const manifestPath = path.join(this.snapshotDir!, 'manifest.jsonl')
340
- const entry =
341
- JSON.stringify({
342
- type: 'snapshot',
343
- ...snapshot,
344
- }) + '\n'
345
+ const entry = `${JSON.stringify({
346
+ type: 'snapshot',
347
+ ...snapshot,
348
+ })}\n`
345
349
 
346
350
  await fs.appendFile(manifestPath, entry)
347
351
  }
@@ -351,13 +355,12 @@ class SnapshotManager {
351
355
  */
352
356
  async logRestore(hash: string, files: string[]): Promise<void> {
353
357
  const manifestPath = path.join(this.snapshotDir!, 'manifest.jsonl')
354
- const entry =
355
- JSON.stringify({
356
- type: 'restore',
357
- hash,
358
- files,
359
- timestamp: new Date().toISOString(),
360
- }) + '\n'
358
+ const entry = `${JSON.stringify({
359
+ type: 'restore',
360
+ hash,
361
+ files,
362
+ timestamp: new Date().toISOString(),
363
+ })}\n`
361
364
 
362
365
  await fs.appendFile(manifestPath, entry)
363
366
  }
@@ -3,23 +3,22 @@
3
3
  * Manages task breakdown and hierarchical task tracking.
4
4
  */
5
5
 
6
- import path from 'path'
7
- import fs from 'fs/promises'
8
- import { exec } from 'child_process'
9
- import { promisify } from 'util'
10
- import log from '../utils/logger'
11
- import { isNotFoundError } from '../types/fs'
6
+ import { exec } from 'node:child_process'
7
+ import fs from 'node:fs/promises'
8
+ import path from 'node:path'
9
+ import { promisify } from 'node:util'
12
10
  import type {
13
- TaskStackEntry,
14
11
  ParsedNowFile,
12
+ TaskStackEntry,
15
13
  TaskStackMigrationResult,
16
- TaskSwitchResult,
17
14
  TaskStackSummary,
15
+ TaskSwitchResult,
18
16
  } from '../types'
17
+ import { isNotFoundError } from '../types/fs'
18
+ import log from '../utils/logger'
19
19
 
20
20
  const execAsync = promisify(exec)
21
21
 
22
-
23
22
  // =============================================================================
24
23
  // Parser
25
24
  // =============================================================================
@@ -129,7 +128,7 @@ export async function ensureStackFile(stackPath: string): Promise<void> {
129
128
  */
130
129
  export async function appendToStack(stackPath: string, entry: TaskStackEntry): Promise<void> {
131
130
  await ensureStackFile(stackPath)
132
- const line = JSON.stringify(entry) + '\n'
131
+ const line = `${JSON.stringify(entry)}\n`
133
132
  await fs.appendFile(stackPath, line)
134
133
  }
135
134
 
@@ -162,14 +161,18 @@ export async function readStack(stackPath: string): Promise<TaskStackEntry[]> {
162
161
  * Write full stack to file
163
162
  */
164
163
  export async function writeStack(stackPath: string, stack: TaskStackEntry[]): Promise<void> {
165
- const content = stack.map((task) => JSON.stringify(task)).join('\n') + '\n'
164
+ const content = `${stack.map((task) => JSON.stringify(task)).join('\n')}\n`
166
165
  await fs.writeFile(stackPath, content)
167
166
  }
168
167
 
169
168
  /**
170
169
  * Generate now.md content for a task
171
170
  */
172
- export function generateNowContent(task: TaskStackEntry | null, customContent: string | null, formatDurationFn: (ms: number) => string): string {
171
+ export function generateNowContent(
172
+ task: TaskStackEntry | null,
173
+ customContent: string | null,
174
+ formatDurationFn: (ms: number) => string
175
+ ): string {
173
176
  if (customContent !== undefined && customContent !== null) {
174
177
  return customContent
175
178
  }
@@ -340,7 +343,11 @@ export class TaskStack {
340
343
  /**
341
344
  * Start a new task
342
345
  */
343
- async startTask(description: string, agent: string = 'general', complexity: string = 'moderate'): Promise<TaskStackEntry> {
346
+ async startTask(
347
+ description: string,
348
+ agent: string = 'general',
349
+ complexity: string = 'moderate'
350
+ ): Promise<TaskStackEntry> {
344
351
  // Check if there's already an active task
345
352
  const active = await this.getActiveTask()
346
353
  if (active) {
@@ -524,7 +531,10 @@ export class TaskStack {
524
531
  /**
525
532
  * Update now.md to reflect current state
526
533
  */
527
- async updateNowFile(task: TaskStackEntry | null, customContent: string | null = null): Promise<void> {
534
+ async updateNowFile(
535
+ task: TaskStackEntry | null,
536
+ customContent: string | null = null
537
+ ): Promise<void> {
528
538
  await updateNowFile(this.nowPath, task, customContent, formatDuration)
529
539
  }
530
540
 
package/core/errors.ts CHANGED
@@ -13,7 +13,7 @@
13
13
  * @version 2.0.0
14
14
  */
15
15
 
16
- import { z, type ZodType } from 'zod'
16
+ import { type ZodType, z } from 'zod'
17
17
 
18
18
  // =============================================================================
19
19
  // Named Error Pattern (Zod-based)
@@ -6,10 +6,9 @@
6
6
  */
7
7
 
8
8
  import pathManager from '../infrastructure/path-manager'
9
- import * as fileHelper from '../utils/file-helper'
9
+ import type { SyncEvent, SyncEventType } from '../types'
10
10
  import { getTimestamp } from '../utils/date-helper'
11
-
12
- import type { SyncEventType, SyncEvent } from '../types'
11
+ import * as fileHelper from '../utils/file-helper'
13
12
 
14
13
  /**
15
14
  * Infer event type from path and action
@@ -84,4 +83,3 @@ class EventBus {
84
83
 
85
84
  export const eventBus = new EventBus()
86
85
  export default eventBus
87
-
@@ -4,6 +4,5 @@
4
4
  * Barrel export for events module
5
5
  */
6
6
 
7
- export { eventBus, inferEventType } from './events'
8
- export { default } from './events'
9
7
  export type { SyncEvent, SyncEventType } from '../types'
8
+ export { default, eventBus, inferEventType } from './events'