specweave 0.13.6 → 0.14.0

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 (35) hide show
  1. package/CLAUDE.md +189 -0
  2. package/dist/cli/commands/init.js +1 -1
  3. package/dist/cli/commands/init.js.map +1 -1
  4. package/dist/cli/commands/status-line.d.ts +14 -0
  5. package/dist/cli/commands/status-line.d.ts.map +1 -0
  6. package/dist/cli/commands/status-line.js +75 -0
  7. package/dist/cli/commands/status-line.js.map +1 -0
  8. package/dist/core/status-line/status-line-manager.d.ts +62 -0
  9. package/dist/core/status-line/status-line-manager.d.ts.map +1 -0
  10. package/dist/core/status-line/status-line-manager.js +169 -0
  11. package/dist/core/status-line/status-line-manager.js.map +1 -0
  12. package/dist/core/status-line/types.d.ts +50 -0
  13. package/dist/core/status-line/types.d.ts.map +1 -0
  14. package/dist/core/status-line/types.js +17 -0
  15. package/dist/core/status-line/types.js.map +1 -0
  16. package/dist/utils/project-mapper.d.ts +74 -0
  17. package/dist/utils/project-mapper.d.ts.map +1 -0
  18. package/dist/utils/project-mapper.js +273 -0
  19. package/dist/utils/project-mapper.js.map +1 -0
  20. package/dist/utils/spec-splitter.d.ts +68 -0
  21. package/dist/utils/spec-splitter.d.ts.map +1 -0
  22. package/dist/utils/spec-splitter.js +314 -0
  23. package/dist/utils/spec-splitter.js.map +1 -0
  24. package/package.json +1 -1
  25. package/plugins/specweave/hooks/lib/update-status-line.sh +138 -0
  26. package/plugins/specweave/hooks/post-task-completion.sh +10 -0
  27. package/plugins/specweave/skills/multi-project-spec-mapper/SKILL.md +399 -0
  28. package/plugins/specweave-ado/lib/ado-multi-project-sync.js +453 -0
  29. package/plugins/specweave-ado/lib/ado-multi-project-sync.ts +633 -0
  30. package/plugins/specweave-docs/skills/docusaurus/SKILL.md +17 -3
  31. package/plugins/specweave-docs-preview/commands/preview.md +29 -4
  32. package/plugins/specweave-github/lib/github-multi-project-sync.js +340 -0
  33. package/plugins/specweave-github/lib/github-multi-project-sync.ts +461 -0
  34. package/plugins/specweave-jira/lib/jira-multi-project-sync.js +244 -0
  35. package/plugins/specweave-jira/lib/jira-multi-project-sync.ts +358 -0
@@ -0,0 +1,169 @@
1
+ /**
2
+ * Status Line Manager
3
+ *
4
+ * Ultra-fast status line rendering with intelligent caching.
5
+ * Target: <1ms render time for 99% of requests.
6
+ *
7
+ * Architecture:
8
+ * - Hook pre-computes cache (async, 10-50ms)
9
+ * - Renderer reads cache (sync, <1ms)
10
+ * - mtime-based invalidation (handles external edits)
11
+ */
12
+ import * as fs from 'fs';
13
+ import * as path from 'path';
14
+ import { DEFAULT_STATUS_LINE_CONFIG, } from './types.js';
15
+ export class StatusLineManager {
16
+ constructor(rootDir = process.cwd(), config = {}) {
17
+ this.rootDir = rootDir;
18
+ this.cacheFile = path.join(rootDir, '.specweave/state/status-line.json');
19
+ this.config = { ...DEFAULT_STATUS_LINE_CONFIG, ...config };
20
+ }
21
+ /**
22
+ * Render status line (FAST PATH: <1ms)
23
+ *
24
+ * Returns formatted status line string or null if no active increment.
25
+ */
26
+ render() {
27
+ if (!this.config.enabled) {
28
+ return null;
29
+ }
30
+ const cache = this.getCache();
31
+ if (!cache) {
32
+ return null; // No active increment or cache stale
33
+ }
34
+ return this.formatStatusLine(cache);
35
+ }
36
+ /**
37
+ * Get cache with freshness validation (0.5-1ms)
38
+ *
39
+ * Returns null if:
40
+ * - Cache file missing
41
+ * - Cache too old (>maxCacheAge)
42
+ * - tasks.md modified since cache update
43
+ */
44
+ getCache() {
45
+ try {
46
+ // Step 1: Read cache file (0.3ms)
47
+ if (!fs.existsSync(this.cacheFile)) {
48
+ return null;
49
+ }
50
+ const content = fs.readFileSync(this.cacheFile, 'utf8');
51
+ const cache = JSON.parse(content);
52
+ // Step 2: Validate cache has required fields
53
+ if (!cache.incrementId || cache.totalTasks === undefined) {
54
+ return null;
55
+ }
56
+ // Step 3: Check freshness (0.2-0.5ms)
57
+ if (!this.isCacheFresh(cache)) {
58
+ return null;
59
+ }
60
+ return cache;
61
+ }
62
+ catch (error) {
63
+ // Cache read/parse error = treat as cache miss
64
+ return null;
65
+ }
66
+ }
67
+ /**
68
+ * Check if cache is fresh (0.2-0.5ms)
69
+ *
70
+ * Two-level check:
71
+ * 1. Age check (ultra-fast, no I/O)
72
+ * 2. mtime check (fast, single stat() call)
73
+ */
74
+ isCacheFresh(cache) {
75
+ // Check 1: Recent update? (no I/O, ultra-fast)
76
+ const age = Date.now() - new Date(cache.lastUpdate).getTime();
77
+ if (age < this.config.maxCacheAge) {
78
+ return true; // Cache is fresh (<5s old)
79
+ }
80
+ // Check 2: Has tasks.md changed? (single stat() call)
81
+ try {
82
+ const tasksFile = path.join(this.rootDir, '.specweave/increments', cache.incrementId, 'tasks.md');
83
+ const stats = fs.statSync(tasksFile);
84
+ const currentMtime = Math.floor(stats.mtimeMs / 1000);
85
+ return currentMtime === cache.lastModified;
86
+ }
87
+ catch {
88
+ // File missing or stat() failed = invalidate cache
89
+ return false;
90
+ }
91
+ }
92
+ /**
93
+ * Format status line from cache (0.1ms)
94
+ */
95
+ formatStatusLine(cache) {
96
+ const parts = [];
97
+ // Increment name (truncated)
98
+ const name = this.truncate(cache.incrementName, this.config.maxIncrementNameLength);
99
+ parts.push(`[${name}]`);
100
+ // Progress bar
101
+ if (this.config.showProgressBar) {
102
+ const bar = this.renderProgressBar(cache.completedTasks, cache.totalTasks);
103
+ parts.push(bar);
104
+ }
105
+ // Tasks count and percentage
106
+ if (this.config.showPercentage) {
107
+ parts.push(`${cache.completedTasks}/${cache.totalTasks} (${cache.percentage}%)`);
108
+ }
109
+ else {
110
+ parts.push(`${cache.completedTasks}/${cache.totalTasks}`);
111
+ }
112
+ // Current task
113
+ if (this.config.showCurrentTask && cache.currentTask) {
114
+ const taskTitle = this.truncate(cache.currentTask.title, this.config.maxTaskTitleLength);
115
+ parts.push(`• ${cache.currentTask.id}: ${taskTitle}`);
116
+ }
117
+ return parts.join(' ');
118
+ }
119
+ /**
120
+ * Render ASCII progress bar (0.05ms)
121
+ */
122
+ renderProgressBar(completed, total) {
123
+ if (total === 0) {
124
+ return '░'.repeat(this.config.progressBarWidth);
125
+ }
126
+ const percentage = completed / total;
127
+ const filled = Math.floor(percentage * this.config.progressBarWidth);
128
+ const empty = this.config.progressBarWidth - filled;
129
+ return '█'.repeat(filled) + '░'.repeat(empty);
130
+ }
131
+ /**
132
+ * Truncate string with ellipsis (0.01ms)
133
+ */
134
+ truncate(str, maxLength) {
135
+ if (str.length <= maxLength) {
136
+ return str;
137
+ }
138
+ return str.substring(0, maxLength - 1) + '…';
139
+ }
140
+ /**
141
+ * Get raw cache data (for testing/debugging)
142
+ */
143
+ getCacheData() {
144
+ try {
145
+ if (!fs.existsSync(this.cacheFile)) {
146
+ return null;
147
+ }
148
+ const content = fs.readFileSync(this.cacheFile, 'utf8');
149
+ return JSON.parse(content);
150
+ }
151
+ catch {
152
+ return null;
153
+ }
154
+ }
155
+ /**
156
+ * Clear cache (for testing/manual reset)
157
+ */
158
+ clearCache() {
159
+ try {
160
+ if (fs.existsSync(this.cacheFile)) {
161
+ fs.unlinkSync(this.cacheFile);
162
+ }
163
+ }
164
+ catch {
165
+ // Ignore errors
166
+ }
167
+ }
168
+ }
169
+ //# sourceMappingURL=status-line-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status-line-manager.js","sourceRoot":"","sources":["../../../src/core/status-line/status-line-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Status Line Types
3
+ *
4
+ * Type definitions for the fast status line caching system.
5
+ * Supports <1ms rendering with intelligent cache invalidation.
6
+ */
7
+ export interface StatusLineCache {
8
+ /** Active increment ID (e.g., "0017-sync-architecture-fix") */
9
+ incrementId: string;
10
+ /** Short increment name (e.g., "sync-architecture-fix") */
11
+ incrementName: string;
12
+ /** Total number of tasks in tasks.md */
13
+ totalTasks: number;
14
+ /** Number of completed tasks ([x]) */
15
+ completedTasks: number;
16
+ /** Completion percentage (0-100) */
17
+ percentage: number;
18
+ /** Current task being worked on */
19
+ currentTask: TaskInfo | null;
20
+ /** ISO timestamp of last cache update */
21
+ lastUpdate: string;
22
+ /** Unix timestamp of tasks.md mtime (for invalidation) */
23
+ lastModified: number;
24
+ }
25
+ export interface TaskInfo {
26
+ /** Task ID (e.g., "T-016") */
27
+ id: string;
28
+ /** Task title (e.g., "Update documentation") */
29
+ title: string;
30
+ }
31
+ export interface StatusLineConfig {
32
+ /** Enable status line rendering */
33
+ enabled: boolean;
34
+ /** Maximum age of cache before forcing refresh (ms) */
35
+ maxCacheAge: number;
36
+ /** Width of progress bar (characters) */
37
+ progressBarWidth: number;
38
+ /** Maximum length for increment name */
39
+ maxIncrementNameLength: number;
40
+ /** Maximum length for task title */
41
+ maxTaskTitleLength: number;
42
+ /** Show progress bar */
43
+ showProgressBar: boolean;
44
+ /** Show percentage */
45
+ showPercentage: boolean;
46
+ /** Show current task */
47
+ showCurrentTask: boolean;
48
+ }
49
+ export declare const DEFAULT_STATUS_LINE_CONFIG: StatusLineConfig;
50
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/core/status-line/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,eAAe;IAC9B,+DAA+D;IAC/D,WAAW,EAAE,MAAM,CAAC;IAEpB,2DAA2D;IAC3D,aAAa,EAAE,MAAM,CAAC;IAEtB,wCAAwC;IACxC,UAAU,EAAE,MAAM,CAAC;IAEnB,sCAAsC;IACtC,cAAc,EAAE,MAAM,CAAC;IAEvB,oCAAoC;IACpC,UAAU,EAAE,MAAM,CAAC;IAEnB,mCAAmC;IACnC,WAAW,EAAE,QAAQ,GAAG,IAAI,CAAC;IAE7B,yCAAyC;IACzC,UAAU,EAAE,MAAM,CAAC;IAEnB,0DAA0D;IAC1D,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,QAAQ;IACvB,8BAA8B;IAC9B,EAAE,EAAE,MAAM,CAAC;IAEX,gDAAgD;IAChD,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,gBAAgB;IAC/B,mCAAmC;IACnC,OAAO,EAAE,OAAO,CAAC;IAEjB,uDAAuD;IACvD,WAAW,EAAE,MAAM,CAAC;IAEpB,yCAAyC;IACzC,gBAAgB,EAAE,MAAM,CAAC;IAEzB,wCAAwC;IACxC,sBAAsB,EAAE,MAAM,CAAC;IAE/B,oCAAoC;IACpC,kBAAkB,EAAE,MAAM,CAAC;IAE3B,wBAAwB;IACxB,eAAe,EAAE,OAAO,CAAC;IAEzB,sBAAsB;IACtB,cAAc,EAAE,OAAO,CAAC;IAExB,wBAAwB;IACxB,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,eAAO,MAAM,0BAA0B,EAAE,gBASxC,CAAC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Status Line Types
3
+ *
4
+ * Type definitions for the fast status line caching system.
5
+ * Supports <1ms rendering with intelligent cache invalidation.
6
+ */
7
+ export const DEFAULT_STATUS_LINE_CONFIG = {
8
+ enabled: true,
9
+ maxCacheAge: 5000, // 5 seconds
10
+ progressBarWidth: 8,
11
+ maxIncrementNameLength: 20,
12
+ maxTaskTitleLength: 30,
13
+ showProgressBar: true,
14
+ showPercentage: true,
15
+ showCurrentTask: true,
16
+ };
17
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/core/status-line/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA8DH,MAAM,CAAC,MAAM,0BAA0B,GAAqB;IAC1D,OAAO,EAAE,IAAI;IACb,WAAW,EAAE,IAAI,EAAE,YAAY;IAC/B,gBAAgB,EAAE,CAAC;IACnB,sBAAsB,EAAE,EAAE;IAC1B,kBAAkB,EAAE,EAAE;IACtB,eAAe,EAAE,IAAI;IACrB,cAAc,EAAE,IAAI;IACpB,eAAe,EAAE,IAAI;CACtB,CAAC"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Project Mapper - Intelligent User Story to Project Classification
3
+ *
4
+ * Analyzes user story content, tech stack mentions, and component architecture
5
+ * to intelligently map user stories to the correct projects (FE, BE, MOBILE, etc.)
6
+ *
7
+ * @module project-mapper
8
+ */
9
+ export interface ProjectMapping {
10
+ projectId: string;
11
+ confidence: number;
12
+ reasoning: string[];
13
+ }
14
+ export interface UserStory {
15
+ id: string;
16
+ title: string;
17
+ description: string;
18
+ acceptanceCriteria: string[];
19
+ technicalContext?: string;
20
+ }
21
+ export interface ProjectRule {
22
+ id: string;
23
+ name: string;
24
+ keywords: string[];
25
+ techStack: string[];
26
+ componentTypes: string[];
27
+ excludeKeywords?: string[];
28
+ }
29
+ /**
30
+ * Default project mapping rules
31
+ * These can be customized via .specweave/config.json
32
+ */
33
+ export declare const DEFAULT_PROJECT_RULES: ProjectRule[];
34
+ /**
35
+ * Analyze user story content and map to projects
36
+ *
37
+ * @param userStory User story to analyze
38
+ * @param projectRules Project mapping rules (defaults to DEFAULT_PROJECT_RULES)
39
+ * @returns Array of project mappings sorted by confidence (highest first)
40
+ */
41
+ export declare function mapUserStoryToProjects(userStory: UserStory, projectRules?: ProjectRule[]): ProjectMapping[];
42
+ /**
43
+ * Determine primary project for a user story
44
+ * (highest confidence mapping)
45
+ *
46
+ * @param userStory User story to analyze
47
+ * @param projectRules Project mapping rules
48
+ * @returns Primary project mapping or null if no confident match
49
+ */
50
+ export declare function getPrimaryProject(userStory: UserStory, projectRules?: ProjectRule[]): ProjectMapping | null;
51
+ /**
52
+ * Split spec into project-specific specs based on user story mappings
53
+ *
54
+ * @param userStories Array of user stories
55
+ * @param projectRules Project mapping rules
56
+ * @returns Map of projectId → user stories
57
+ */
58
+ export declare function splitSpecByProject(userStories: UserStory[], projectRules?: ProjectRule[]): Map<string, UserStory[]>;
59
+ /**
60
+ * Suggest JIRA item type hierarchy based on user story scope
61
+ *
62
+ * @param userStory User story to analyze
63
+ * @returns Suggested JIRA item type (Epic, Story, Task, Subtask)
64
+ */
65
+ export declare function suggestJiraItemType(userStory: UserStory): 'Epic' | 'Story' | 'Task' | 'Subtask';
66
+ /**
67
+ * Format project mapping report (for display to user)
68
+ *
69
+ * @param userStory User story
70
+ * @param mappings Project mappings
71
+ * @returns Formatted markdown report
72
+ */
73
+ export declare function formatProjectMappingReport(userStory: UserStory, mappings: ProjectMapping[]): string;
74
+ //# sourceMappingURL=project-mapper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-mapper.d.ts","sourceRoot":"","sources":["../../src/utils/project-mapper.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5B;AAED;;;GAGG;AACH,eAAO,MAAM,qBAAqB,EAAE,WAAW,EAwF9C,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,SAAS,EACpB,YAAY,GAAE,WAAW,EAA0B,GAClD,cAAc,EAAE,CAiFlB;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,SAAS,EACpB,YAAY,GAAE,WAAW,EAA0B,GAClD,cAAc,GAAG,IAAI,CAOvB;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,SAAS,EAAE,EACxB,YAAY,GAAE,WAAW,EAA0B,GAClD,GAAG,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,CAmB1B;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,CAoB/F;AAeD;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CACxC,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,cAAc,EAAE,GACzB,MAAM,CA4BR"}
@@ -0,0 +1,273 @@
1
+ /**
2
+ * Project Mapper - Intelligent User Story to Project Classification
3
+ *
4
+ * Analyzes user story content, tech stack mentions, and component architecture
5
+ * to intelligently map user stories to the correct projects (FE, BE, MOBILE, etc.)
6
+ *
7
+ * @module project-mapper
8
+ */
9
+ /**
10
+ * Default project mapping rules
11
+ * These can be customized via .specweave/config.json
12
+ */
13
+ export const DEFAULT_PROJECT_RULES = [
14
+ {
15
+ id: 'FE',
16
+ name: 'Frontend (Web)',
17
+ keywords: [
18
+ 'ui', 'ux', 'web', 'browser', 'chart', 'graph', 'visualization',
19
+ 'dashboard', 'button', 'form', 'input', 'page', 'view', 'screen',
20
+ 'modal', 'dropdown', 'navigation', 'menu', 'search', 'filter',
21
+ 'responsive', 'desktop', 'tablet', 'css', 'styling', 'theme',
22
+ 'dark mode', 'light mode', 'component', 'state management'
23
+ ],
24
+ techStack: [
25
+ 'react', 'vue', 'angular', 'next.js', 'gatsby', 'svelte',
26
+ 'typescript', 'javascript', 'html', 'css', 'scss', 'tailwind',
27
+ 'mui', 'material-ui', 'antd', 'chakra', 'redux', 'zustand',
28
+ 'recharts', 'd3', 'chart.js', 'plotly'
29
+ ],
30
+ componentTypes: [
31
+ 'component', 'hook', 'context', 'provider', 'hoc', 'page',
32
+ 'layout', 'template', 'widget'
33
+ ]
34
+ },
35
+ {
36
+ id: 'BE',
37
+ name: 'Backend (API)',
38
+ keywords: [
39
+ 'api', 'endpoint', 'rest', 'graphql', 'database', 'query',
40
+ 'migration', 'schema', 'model', 'service', 'controller',
41
+ 'authentication', 'authorization', 'jwt', 'session', 'token',
42
+ 'validation', 'sanitization', 'rate limiting', 'caching',
43
+ 'redis', 'queue', 'job', 'worker', 'webhook', 'integration',
44
+ 'third-party', 'external api', 'data processing', 'batch',
45
+ 'cron', 'scheduler', 'background'
46
+ ],
47
+ techStack: [
48
+ 'node.js', 'express', 'fastify', 'nestjs', 'koa',
49
+ 'python', 'fastapi', 'django', 'flask',
50
+ 'java', 'spring boot',
51
+ '.net', 'asp.net',
52
+ 'go', 'gin',
53
+ 'rust', 'actix',
54
+ 'postgresql', 'mysql', 'mongodb', 'redis',
55
+ 'prisma', 'typeorm', 'sequelize', 'sqlalchemy'
56
+ ],
57
+ componentTypes: [
58
+ 'controller', 'service', 'repository', 'middleware',
59
+ 'route', 'handler', 'util', 'helper', 'validator'
60
+ ]
61
+ },
62
+ {
63
+ id: 'MOBILE',
64
+ name: 'Mobile (iOS/Android)',
65
+ keywords: [
66
+ 'mobile', 'ios', 'android', 'app', 'native', 'cross-platform',
67
+ 'push notification', 'offline', 'sync', 'device', 'camera',
68
+ 'gps', 'location', 'gesture', 'touch', 'swipe', 'navigation',
69
+ 'tab bar', 'bottom sheet', 'drawer', 'stack', 'screen transition',
70
+ 'deep linking', 'universal link', 'app store', 'play store'
71
+ ],
72
+ techStack: [
73
+ 'react native', 'expo', 'flutter', 'swift', 'swiftui',
74
+ 'kotlin', 'jetpack compose', 'xamarin', 'cordova', 'ionic',
75
+ 'react-navigation', 'react-native-reanimated', 'asyncstorage'
76
+ ],
77
+ componentTypes: [
78
+ 'screen', 'navigator', 'modal', 'bottom-sheet', 'drawer'
79
+ ],
80
+ excludeKeywords: ['web']
81
+ },
82
+ {
83
+ id: 'INFRA',
84
+ name: 'Infrastructure',
85
+ keywords: [
86
+ 'deployment', 'ci/cd', 'docker', 'kubernetes', 'helm',
87
+ 'terraform', 'cloudformation', 'infrastructure', 'devops',
88
+ 'monitoring', 'logging', 'metrics', 'alerting', 'slo', 'sli',
89
+ 'scalability', 'load balancing', 'cdn', 'dns', 'ssl', 'tls',
90
+ 'security', 'firewall', 'vpc', 'network', 'backup', 'disaster recovery'
91
+ ],
92
+ techStack: [
93
+ 'aws', 'azure', 'gcp', 'kubernetes', 'docker', 'terraform',
94
+ 'ansible', 'jenkins', 'github actions', 'gitlab ci', 'circleci',
95
+ 'prometheus', 'grafana', 'datadog', 'new relic', 'sentry'
96
+ ],
97
+ componentTypes: [
98
+ 'pipeline', 'manifest', 'helm chart', 'terraform module'
99
+ ]
100
+ }
101
+ ];
102
+ /**
103
+ * Analyze user story content and map to projects
104
+ *
105
+ * @param userStory User story to analyze
106
+ * @param projectRules Project mapping rules (defaults to DEFAULT_PROJECT_RULES)
107
+ * @returns Array of project mappings sorted by confidence (highest first)
108
+ */
109
+ export function mapUserStoryToProjects(userStory, projectRules = DEFAULT_PROJECT_RULES) {
110
+ const mappings = [];
111
+ // Combine all user story text for analysis
112
+ const fullText = [
113
+ userStory.title,
114
+ userStory.description,
115
+ ...userStory.acceptanceCriteria,
116
+ userStory.technicalContext || ''
117
+ ].join(' ').toLowerCase();
118
+ for (const rule of projectRules) {
119
+ const reasoning = [];
120
+ let score = 0;
121
+ let maxScore = 0;
122
+ // Keyword matching (40% weight)
123
+ const keywordMatches = rule.keywords.filter(keyword => fullText.includes(keyword.toLowerCase()));
124
+ const keywordScore = keywordMatches.length * 0.4;
125
+ score += keywordScore;
126
+ maxScore += rule.keywords.length * 0.4;
127
+ if (keywordMatches.length > 0) {
128
+ reasoning.push(`Keywords: ${keywordMatches.slice(0, 5).join(', ')}`);
129
+ }
130
+ // Tech stack matching (40% weight)
131
+ const techStackMatches = rule.techStack.filter(tech => fullText.includes(tech.toLowerCase()));
132
+ const techScore = techStackMatches.length * 0.4;
133
+ score += techScore;
134
+ maxScore += rule.techStack.length * 0.4;
135
+ if (techStackMatches.length > 0) {
136
+ reasoning.push(`Tech stack: ${techStackMatches.slice(0, 5).join(', ')}`);
137
+ }
138
+ // Component type matching (20% weight)
139
+ const componentMatches = rule.componentTypes.filter(component => fullText.includes(component.toLowerCase()));
140
+ const componentScore = componentMatches.length * 0.2;
141
+ score += componentScore;
142
+ maxScore += rule.componentTypes.length * 0.2;
143
+ if (componentMatches.length > 0) {
144
+ reasoning.push(`Components: ${componentMatches.slice(0, 3).join(', ')}`);
145
+ }
146
+ // Exclude keywords (penalty)
147
+ if (rule.excludeKeywords) {
148
+ const excludeMatches = rule.excludeKeywords.filter(keyword => fullText.includes(keyword.toLowerCase()));
149
+ if (excludeMatches.length > 0) {
150
+ score *= 0.5; // 50% penalty
151
+ reasoning.push(`Penalty: ${excludeMatches.join(', ')} (not primary focus)`);
152
+ }
153
+ }
154
+ // Normalize confidence (0.0-1.0)
155
+ const confidence = maxScore > 0 ? Math.min(score / (maxScore * 0.3), 1.0) : 0;
156
+ // Only include mappings with confidence > 0.1
157
+ if (confidence > 0.1) {
158
+ mappings.push({
159
+ projectId: rule.id,
160
+ confidence,
161
+ reasoning
162
+ });
163
+ }
164
+ }
165
+ // Sort by confidence (highest first)
166
+ mappings.sort((a, b) => b.confidence - a.confidence);
167
+ return mappings;
168
+ }
169
+ /**
170
+ * Determine primary project for a user story
171
+ * (highest confidence mapping)
172
+ *
173
+ * @param userStory User story to analyze
174
+ * @param projectRules Project mapping rules
175
+ * @returns Primary project mapping or null if no confident match
176
+ */
177
+ export function getPrimaryProject(userStory, projectRules = DEFAULT_PROJECT_RULES) {
178
+ const mappings = mapUserStoryToProjects(userStory, projectRules);
179
+ // Require at least 30% confidence for primary project
180
+ return mappings.length > 0 && mappings[0].confidence >= 0.3
181
+ ? mappings[0]
182
+ : null;
183
+ }
184
+ /**
185
+ * Split spec into project-specific specs based on user story mappings
186
+ *
187
+ * @param userStories Array of user stories
188
+ * @param projectRules Project mapping rules
189
+ * @returns Map of projectId → user stories
190
+ */
191
+ export function splitSpecByProject(userStories, projectRules = DEFAULT_PROJECT_RULES) {
192
+ const projectSpecs = new Map();
193
+ for (const userStory of userStories) {
194
+ const primaryProject = getPrimaryProject(userStory, projectRules);
195
+ if (primaryProject) {
196
+ const existing = projectSpecs.get(primaryProject.projectId) || [];
197
+ existing.push(userStory);
198
+ projectSpecs.set(primaryProject.projectId, existing);
199
+ }
200
+ else {
201
+ // No confident match - assign to "SHARED" or primary project
202
+ const shared = projectSpecs.get('SHARED') || [];
203
+ shared.push(userStory);
204
+ projectSpecs.set('SHARED', shared);
205
+ }
206
+ }
207
+ return projectSpecs;
208
+ }
209
+ /**
210
+ * Suggest JIRA item type hierarchy based on user story scope
211
+ *
212
+ * @param userStory User story to analyze
213
+ * @returns Suggested JIRA item type (Epic, Story, Task, Subtask)
214
+ */
215
+ export function suggestJiraItemType(userStory) {
216
+ const storyPoints = estimateStoryPoints(userStory);
217
+ // Epic: > 13 story points (large feature area)
218
+ if (storyPoints > 13) {
219
+ return 'Epic';
220
+ }
221
+ // Story: 3-13 story points (standard user story)
222
+ if (storyPoints >= 3) {
223
+ return 'Story';
224
+ }
225
+ // Task: 1-2 story points (small implementation task)
226
+ if (storyPoints >= 1) {
227
+ return 'Task';
228
+ }
229
+ // Subtask: < 1 story point (granular work)
230
+ return 'Subtask';
231
+ }
232
+ /**
233
+ * Estimate story points based on acceptance criteria count and complexity
234
+ *
235
+ * @param userStory User story to estimate
236
+ * @returns Estimated story points (1-21)
237
+ */
238
+ function estimateStoryPoints(userStory) {
239
+ const acCount = userStory.acceptanceCriteria.length;
240
+ // Simple heuristic: 1 AC ≈ 1 story point, max 21
241
+ return Math.min(acCount, 21);
242
+ }
243
+ /**
244
+ * Format project mapping report (for display to user)
245
+ *
246
+ * @param userStory User story
247
+ * @param mappings Project mappings
248
+ * @returns Formatted markdown report
249
+ */
250
+ export function formatProjectMappingReport(userStory, mappings) {
251
+ const lines = [];
252
+ lines.push(`## ${userStory.id}: ${userStory.title}`);
253
+ lines.push('');
254
+ if (mappings.length === 0) {
255
+ lines.push('❌ **No project match** (assign to SHARED)');
256
+ return lines.join('\n');
257
+ }
258
+ lines.push(`✅ **Primary Project**: ${mappings[0].projectId} (${(mappings[0].confidence * 100).toFixed(0)}% confidence)`);
259
+ lines.push('');
260
+ lines.push('**Reasoning**:');
261
+ for (const reason of mappings[0].reasoning) {
262
+ lines.push(`- ${reason}`);
263
+ }
264
+ if (mappings.length > 1) {
265
+ lines.push('');
266
+ lines.push('**Secondary Matches**:');
267
+ for (const mapping of mappings.slice(1, 3)) {
268
+ lines.push(`- ${mapping.projectId} (${(mapping.confidence * 100).toFixed(0)}%)`);
269
+ }
270
+ }
271
+ return lines.join('\n');
272
+ }
273
+ //# sourceMappingURL=project-mapper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-mapper.js","sourceRoot":"","sources":["../../src/utils/project-mapper.ts"],"names":[],"mappings":"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"}