prjct-cli 0.45.0 → 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 +75 -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
@@ -19,20 +19,14 @@ export const TaskTypeSchema = z.enum([
19
19
  'epic',
20
20
  ])
21
21
 
22
- export const PrioritySchema = z.enum([
23
- 'critical',
24
- 'high',
25
- 'medium',
26
- 'low',
27
- 'none',
28
- ])
22
+ export const PrioritySchema = z.enum(['critical', 'high', 'medium', 'low', 'none'])
29
23
 
30
24
  export const ComplexitySchema = z.enum([
31
- 'trivial', // < 1 hour
32
- 'small', // 1-4 hours
33
- 'medium', // 1-2 days
34
- 'large', // 3-5 days
35
- 'epic', // > 1 week
25
+ 'trivial', // < 1 hour
26
+ 'small', // 1-4 hours
27
+ 'medium', // 1-2 days
28
+ 'large', // 3-5 days
29
+ 'epic', // > 1 week
36
30
  ])
37
31
 
38
32
  export const RiskLevelSchema = z.enum(['none', 'low', 'medium', 'high', 'critical'])
@@ -45,7 +39,9 @@ export const UserStorySchema = z.object({
45
39
  role: z.string().describe('The user role (e.g., "mobile user")'),
46
40
  action: z.string().describe('What the user wants to do'),
47
41
  benefit: z.string().describe('The benefit they get'),
48
- formatted: z.string().describe('Formatted user story: "As a [role], I want [action] so that [benefit]"'),
42
+ formatted: z
43
+ .string()
44
+ .describe('Formatted user story: "As a [role], I want [action] so that [benefit]"'),
49
45
  })
50
46
 
51
47
  // =============================================================================
@@ -91,11 +87,15 @@ export const DependenciesSchema = z.object({
91
87
  code: z.array(CodeDependencySchema).default([]),
92
88
  api: z.array(ApiDependencySchema).default([]),
93
89
  tasks: z.array(TaskDependencySchema).default([]),
94
- infrastructure: z.array(z.object({
95
- service: z.string(),
96
- purpose: z.string(),
97
- risk: RiskLevelSchema,
98
- })).default([]),
90
+ infrastructure: z
91
+ .array(
92
+ z.object({
93
+ service: z.string(),
94
+ purpose: z.string(),
95
+ risk: RiskLevelSchema,
96
+ })
97
+ )
98
+ .default([]),
99
99
  })
100
100
 
101
101
  // =============================================================================
@@ -103,31 +103,45 @@ export const DependenciesSchema = z.object({
103
103
  // =============================================================================
104
104
 
105
105
  export const TechnicalAnalysisSchema = z.object({
106
- affectedFiles: z.array(z.object({
107
- path: z.string(),
108
- changes: z.string().describe('Expected changes'),
109
- complexity: ComplexitySchema,
110
- })).default([]),
111
-
112
- existingPatterns: z.array(z.object({
113
- pattern: z.string().describe('Pattern name'),
114
- file: z.string().describe('Reference file'),
115
- relevance: z.string().describe('Why it is relevant'),
116
- })).default([]),
106
+ affectedFiles: z
107
+ .array(
108
+ z.object({
109
+ path: z.string(),
110
+ changes: z.string().describe('Expected changes'),
111
+ complexity: ComplexitySchema,
112
+ })
113
+ )
114
+ .default([]),
115
+
116
+ existingPatterns: z
117
+ .array(
118
+ z.object({
119
+ pattern: z.string().describe('Pattern name'),
120
+ file: z.string().describe('Reference file'),
121
+ relevance: z.string().describe('Why it is relevant'),
122
+ })
123
+ )
124
+ .default([]),
117
125
 
118
126
  suggestedApproach: z.string().optional().describe('Recommended approach'),
119
127
 
120
- potentialRisks: z.array(z.object({
121
- risk: z.string(),
122
- mitigation: z.string(),
123
- severity: RiskLevelSchema,
124
- })).default([]),
125
-
126
- testingStrategy: z.object({
127
- unit: z.array(z.string()).default([]),
128
- integration: z.array(z.string()).default([]),
129
- e2e: z.array(z.string()).default([]),
130
- }).optional(),
128
+ potentialRisks: z
129
+ .array(
130
+ z.object({
131
+ risk: z.string(),
132
+ mitigation: z.string(),
133
+ severity: RiskLevelSchema,
134
+ })
135
+ )
136
+ .default([]),
137
+
138
+ testingStrategy: z
139
+ .object({
140
+ unit: z.array(z.string()).default([]),
141
+ integration: z.array(z.string()).default([]),
142
+ e2e: z.array(z.string()).default([]),
143
+ })
144
+ .optional(),
131
145
  })
132
146
 
133
147
  // =============================================================================
@@ -174,12 +188,9 @@ export const EnrichedTaskSchema = z.object({
174
188
  // Enrichment
175
189
  userStory: UserStorySchema,
176
190
  acceptanceCriteria: z.array(AcceptanceCriterionSchema).min(1),
177
- definitionOfDone: z.array(z.string()).default([
178
- 'Code reviewed',
179
- 'Tests pass',
180
- 'Documentation updated',
181
- 'Deployed to staging',
182
- ]),
191
+ definitionOfDone: z
192
+ .array(z.string())
193
+ .default(['Code reviewed', 'Tests pass', 'Documentation updated', 'Deployed to staging']),
183
194
 
184
195
  // Technical analysis
185
196
  technicalAnalysis: TechnicalAnalysisSchema,
@@ -241,13 +252,15 @@ export function isReadyForDev(task: EnrichedTask): { ready: boolean; reasons: st
241
252
  }
242
253
 
243
254
  // Check blockers
244
- const blockingDeps = task.dependencies.tasks.filter(t => t.blocking)
255
+ const blockingDeps = task.dependencies.tasks.filter((t) => t.blocking)
245
256
  if (blockingDeps.length > 0) {
246
- reasons.push(`Blocked by: ${blockingDeps.map(t => t.id).join(', ')}`)
257
+ reasons.push(`Blocked by: ${blockingDeps.map((t) => t.id).join(', ')}`)
247
258
  }
248
259
 
249
260
  // Check critical risks
250
- const criticalRisks = task.technicalAnalysis.potentialRisks.filter(r => r.severity === 'critical')
261
+ const criticalRisks = task.technicalAnalysis.potentialRisks.filter(
262
+ (r) => r.severity === 'critical'
263
+ )
251
264
  if (criticalRisks.length > 0) {
252
265
  reasons.push('Has unmitigated critical risks')
253
266
  }
@@ -23,32 +23,32 @@ export const ImpactEffortSchema = z.object({
23
23
  })
24
24
 
25
25
  export const TechStackSchema = z.object({
26
- frontend: z.string().optional(), // "Next.js 14, HeroUI"
27
- backend: z.string().optional(), // "Supabase (Auth, DB, RLS, Realtime)"
28
- payments: z.string().optional(), // "Stripe Billing"
29
- ai: z.string().optional(), // "Vercel AI SDK"
30
- deploy: z.string().optional(), // "Vercel"
26
+ frontend: z.string().optional(), // "Next.js 14, HeroUI"
27
+ backend: z.string().optional(), // "Supabase (Auth, DB, RLS, Realtime)"
28
+ payments: z.string().optional(), // "Stripe Billing"
29
+ ai: z.string().optional(), // "Vercel AI SDK"
30
+ deploy: z.string().optional(), // "Vercel"
31
31
  other: z.array(z.string()).optional(),
32
32
  })
33
33
 
34
34
  export const IdeaModuleSchema = z.object({
35
- name: z.string(), // "Multi-tenant"
36
- description: z.string(), // "Empresas con RLS estricto"
35
+ name: z.string(), // "Multi-tenant"
36
+ description: z.string(), // "Empresas con RLS estricto"
37
37
  })
38
38
 
39
39
  export const IdeaRoleSchema = z.object({
40
- name: z.string(), // "SUPER_ADMIN"
40
+ name: z.string(), // "SUPER_ADMIN"
41
41
  description: z.string().optional(),
42
42
  })
43
43
 
44
44
  export const IdeaItemSchema = z.object({
45
- id: z.string(), // idea_xxxxxxxx
46
- text: z.string(), // Title/summary
45
+ id: z.string(), // idea_xxxxxxxx
46
+ text: z.string(), // Title/summary
47
47
  details: z.string().optional(),
48
48
  priority: IdeaPrioritySchema,
49
49
  status: IdeaStatusSchema,
50
50
  tags: z.array(z.string()),
51
- addedAt: z.string(), // ISO8601
51
+ addedAt: z.string(), // ISO8601
52
52
  completedAt: z.string().optional(),
53
53
  convertedTo: z.string().optional(),
54
54
  // Source documentation
@@ -105,10 +105,10 @@ export const DEFAULT_IDEA: Omit<IdeaSchema, 'id' | 'text'> = {
105
105
  priority: 'medium',
106
106
  status: 'pending',
107
107
  tags: [],
108
- addedAt: new Date().toISOString()
108
+ addedAt: new Date().toISOString(),
109
109
  }
110
110
 
111
111
  export const DEFAULT_IDEAS: IdeasJson = {
112
112
  ideas: [],
113
- lastUpdated: ''
113
+ lastUpdated: '',
114
114
  }
@@ -12,44 +12,34 @@
12
12
  * - memory/ (context.jsonl, patterns.json)
13
13
  */
14
14
 
15
- // State (current task + queue)
16
- export * from './state'
17
-
18
- // Issues (local cache of issue tracker issues)
19
- export * from './issues'
20
-
21
- // Project metadata
22
- export * from './project'
23
-
24
15
  // Agents
25
16
  export * from './agents'
26
-
27
- // Ideas
28
- export * from './ideas'
29
-
30
- // Roadmap (features)
31
- export * from './roadmap'
32
-
33
- // Shipped items
34
- export * from './shipped'
35
-
36
17
  // Analysis
37
18
  export * from './analysis'
38
-
19
+ // Ideas
20
+ export * from './ideas'
21
+ // Issues (local cache of issue tracker issues)
22
+ export * from './issues'
39
23
  // Outcomes
40
24
  export * from './outcomes'
41
-
42
25
  // Permissions
43
26
  export * from './permissions'
44
-
27
+ // Project metadata
28
+ export * from './project'
29
+ // Roadmap (features)
30
+ export * from './roadmap'
45
31
  // Utilities (ID generators and path helpers)
46
32
  export {
47
- generateUUID,
48
- generateTaskId,
33
+ GLOBAL_STORAGE,
49
34
  generateFeatureId,
50
35
  generateIdeaId,
51
- generateShipId,
52
36
  generateSessionId,
53
- GLOBAL_STORAGE,
54
- getProjectPath
37
+ generateShipId,
38
+ generateTaskId,
39
+ generateUUID,
40
+ getProjectPath,
55
41
  } from './schemas'
42
+ // Shipped items
43
+ export * from './shipped'
44
+ // State (current task + queue)
45
+ export * from './state'
@@ -14,7 +14,14 @@ import { z } from 'zod'
14
14
  // =============================================================================
15
15
 
16
16
  export const IssueProviderSchema = z.enum(['linear', 'jira', 'github', 'monday', 'asana', 'none'])
17
- export const IssueStatusSchema = z.enum(['backlog', 'todo', 'in_progress', 'in_review', 'done', 'cancelled'])
17
+ export const IssueStatusSchema = z.enum([
18
+ 'backlog',
19
+ 'todo',
20
+ 'in_progress',
21
+ 'in_review',
22
+ 'done',
23
+ 'cancelled',
24
+ ])
18
25
  export const IssuePrioritySchema = z.enum(['none', 'urgent', 'high', 'medium', 'low'])
19
26
  export const IssueTypeSchema = z.enum(['feature', 'bug', 'improvement', 'task', 'chore', 'epic'])
20
27
 
@@ -27,8 +34,8 @@ export const IssueTypeSchema = z.enum(['feature', 'bug', 'improvement', 'task',
27
34
  */
28
35
  export const CachedIssueSchema = z.object({
29
36
  // Core identifiers
30
- id: z.string(), // Provider UUID
31
- identifier: z.string(), // Human-readable ID (e.g., "PRJ-123")
37
+ id: z.string(), // Provider UUID
38
+ identifier: z.string(), // Human-readable ID (e.g., "PRJ-123")
32
39
 
33
40
  // Issue content
34
41
  title: z.string(),
@@ -40,27 +47,33 @@ export const CachedIssueSchema = z.object({
40
47
  type: IssueTypeSchema.optional(),
41
48
 
42
49
  // Metadata
43
- assignee: z.object({
44
- id: z.string(),
45
- name: z.string(),
46
- email: z.string().optional(),
47
- }).optional(),
50
+ assignee: z
51
+ .object({
52
+ id: z.string(),
53
+ name: z.string(),
54
+ email: z.string().optional(),
55
+ })
56
+ .optional(),
48
57
  labels: z.array(z.string()).default([]),
49
- team: z.object({
50
- id: z.string(),
51
- name: z.string(),
52
- key: z.string().optional(),
53
- }).optional(),
54
- project: z.object({
55
- id: z.string(),
56
- name: z.string(),
57
- }).optional(),
58
+ team: z
59
+ .object({
60
+ id: z.string(),
61
+ name: z.string(),
62
+ key: z.string().optional(),
63
+ })
64
+ .optional(),
65
+ project: z
66
+ .object({
67
+ id: z.string(),
68
+ name: z.string(),
69
+ })
70
+ .optional(),
58
71
 
59
72
  // URLs and timestamps
60
73
  url: z.string(),
61
- createdAt: z.string(), // ISO8601 from provider
62
- updatedAt: z.string(), // ISO8601 from provider
63
- fetchedAt: z.string(), // ISO8601 when we cached it
74
+ createdAt: z.string(), // ISO8601 from provider
75
+ updatedAt: z.string(), // ISO8601 from provider
76
+ fetchedAt: z.string(), // ISO8601 when we cached it
64
77
  })
65
78
 
66
79
  // =============================================================================
@@ -76,7 +89,7 @@ export const IssuesJsonSchema = z.object({
76
89
  provider: IssueProviderSchema,
77
90
 
78
91
  // Sync metadata
79
- lastSync: z.string(), // ISO8601 of last full sync
92
+ lastSync: z.string(), // ISO8601 of last full sync
80
93
  staleAfter: z.number().default(1800000), // 30 minutes in ms
81
94
 
82
95
  // Issues map: identifier -> issue
@@ -91,10 +104,12 @@ export const SyncResultSchema = z.object({
91
104
  provider: IssueProviderSchema,
92
105
  fetched: z.number(),
93
106
  updated: z.number(),
94
- errors: z.array(z.object({
95
- issueId: z.string(),
96
- error: z.string(),
97
- })),
107
+ errors: z.array(
108
+ z.object({
109
+ issueId: z.string(),
110
+ error: z.string(),
111
+ })
112
+ ),
98
113
  timestamp: z.string(),
99
114
  })
100
115
 
@@ -18,20 +18,20 @@ import { z } from 'zod'
18
18
  * Daily stats for trend analysis
19
19
  */
20
20
  export const DailyStatsSchema = z.object({
21
- date: z.string(), // YYYY-MM-DD
22
- tokensSaved: z.number(), // Tokens saved that day
23
- syncs: z.number(), // Number of syncs
24
- avgCompressionRate: z.number(), // Average compression rate (0-1)
25
- totalDuration: z.number(), // Total sync time in ms
21
+ date: z.string(), // YYYY-MM-DD
22
+ tokensSaved: z.number(), // Tokens saved that day
23
+ syncs: z.number(), // Number of syncs
24
+ avgCompressionRate: z.number(), // Average compression rate (0-1)
25
+ totalDuration: z.number(), // Total sync time in ms
26
26
  })
27
27
 
28
28
  /**
29
29
  * Agent usage tracking
30
30
  */
31
31
  export const AgentUsageSchema = z.object({
32
- agentName: z.string(), // e.g., "backend", "frontend"
33
- usageCount: z.number(), // Times invoked
34
- tokensSaved: z.number(), // Tokens saved by this agent
32
+ agentName: z.string(), // e.g., "backend", "frontend"
33
+ usageCount: z.number(), // Times invoked
34
+ tokensSaved: z.number(), // Tokens saved by this agent
35
35
  })
36
36
 
37
37
  /**
@@ -40,13 +40,13 @@ export const AgentUsageSchema = z.object({
40
40
  export const MetricsJsonSchema = z.object({
41
41
  // Token metrics
42
42
  totalTokensSaved: z.number(),
43
- avgCompressionRate: z.number(), // 0-1 (e.g., 0.63 = 63% reduction)
43
+ avgCompressionRate: z.number(), // 0-1 (e.g., 0.63 = 63% reduction)
44
44
 
45
45
  // Sync metrics
46
46
  syncCount: z.number(),
47
- watchTriggers: z.number(), // Auto-syncs from watch mode
48
- avgSyncDuration: z.number(), // Average in ms
49
- totalSyncDuration: z.number(), // Total in ms
47
+ watchTriggers: z.number(), // Auto-syncs from watch mode
48
+ avgSyncDuration: z.number(), // Average in ms
49
+ totalSyncDuration: z.number(), // Total in ms
50
50
 
51
51
  // Agent usage
52
52
  agentUsage: z.array(AgentUsageSchema),
@@ -55,8 +55,8 @@ export const MetricsJsonSchema = z.object({
55
55
  dailyStats: z.array(DailyStatsSchema),
56
56
 
57
57
  // Metadata
58
- firstSync: z.string(), // ISO8601 - when tracking started
59
- lastUpdated: z.string(), // ISO8601
58
+ firstSync: z.string(), // ISO8601 - when tracking started
59
+ lastUpdated: z.string(), // ISO8601
60
60
  })
61
61
 
62
62
  // =============================================================================
@@ -106,20 +106,20 @@ export const DEFAULT_METRICS: MetricsJson = {
106
106
  */
107
107
  export const TOKEN_COSTS = {
108
108
  // Current models (2026)
109
- 'claude-opus-4.5': 0.005, // $5/M input - flagship
110
- 'claude-sonnet-4.5': 0.003, // $3/M input - balanced
111
- 'claude-haiku-4.5': 0.001, // $1/M input - fastest
109
+ 'claude-opus-4.5': 0.005, // $5/M input - flagship
110
+ 'claude-sonnet-4.5': 0.003, // $3/M input - balanced
111
+ 'claude-haiku-4.5': 0.001, // $1/M input - fastest
112
112
  // Legacy models
113
- 'claude-opus-4': 0.015, // $15/M input
114
- 'claude-sonnet-4': 0.003, // $3/M input
115
- 'claude-3-opus': 0.015, // $15/M input (deprecated)
116
- 'claude-3-sonnet': 0.003, // $3/M input (deprecated)
113
+ 'claude-opus-4': 0.015, // $15/M input
114
+ 'claude-sonnet-4': 0.003, // $3/M input
115
+ 'claude-3-opus': 0.015, // $15/M input (deprecated)
116
+ 'claude-3-sonnet': 0.003, // $3/M input (deprecated)
117
117
  // Other providers
118
- 'gpt-4o': 0.0025, // $2.50/M input
119
- 'gpt-4': 0.01, // $10/M input (legacy)
120
- 'gemini-pro': 0.00125, // $1.25/M input
118
+ 'gpt-4o': 0.0025, // $2.50/M input
119
+ 'gpt-4': 0.01, // $10/M input (legacy)
120
+ 'gemini-pro': 0.00125, // $1.25/M input
121
121
  // Default: Claude Sonnet (most common for Claude Code)
122
- default: 0.003, // $3/M input
122
+ default: 0.003, // $3/M input
123
123
  } as const
124
124
 
125
125
  export type ModelName = keyof typeof TOKEN_COSTS