clavix 2.3.0 → 2.4.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 (180) hide show
  1. package/dist/cli/commands/init.js +1 -1
  2. package/dist/core 2/adapters/agents-md-generator.d.ts +26 -0
  3. package/dist/core 2/adapters/agents-md-generator.js +102 -0
  4. package/dist/core 2/adapters/amp-adapter.d.ts +27 -0
  5. package/dist/core 2/adapters/amp-adapter.js +42 -0
  6. package/dist/core 2/adapters/augment-adapter.d.ts +22 -0
  7. package/dist/core 2/adapters/augment-adapter.js +77 -0
  8. package/dist/core 2/adapters/base-adapter.d.ts +45 -0
  9. package/dist/core 2/adapters/base-adapter.js +142 -0
  10. package/dist/core 2/adapters/claude-code-adapter.d.ts +32 -0
  11. package/dist/core 2/adapters/claude-code-adapter.js +116 -0
  12. package/dist/core 2/adapters/cline-adapter.d.ts +34 -0
  13. package/dist/core 2/adapters/cline-adapter.js +52 -0
  14. package/dist/core 2/adapters/codebuddy-adapter.d.ts +24 -0
  15. package/dist/core 2/adapters/codebuddy-adapter.js +82 -0
  16. package/dist/core 2/adapters/codex-adapter.d.ts +24 -0
  17. package/dist/core 2/adapters/codex-adapter.js +79 -0
  18. package/dist/core 2/adapters/copilot-instructions-generator.d.ts +26 -0
  19. package/dist/core 2/adapters/copilot-instructions-generator.js +104 -0
  20. package/dist/core 2/adapters/crush-adapter.d.ts +35 -0
  21. package/dist/core 2/adapters/crush-adapter.js +49 -0
  22. package/dist/core 2/adapters/cursor-adapter.d.ts +25 -0
  23. package/dist/core 2/adapters/cursor-adapter.js +40 -0
  24. package/dist/core 2/adapters/droid-adapter.d.ts +33 -0
  25. package/dist/core 2/adapters/droid-adapter.js +57 -0
  26. package/dist/core 2/adapters/gemini-adapter.d.ts +27 -0
  27. package/dist/core 2/adapters/gemini-adapter.js +90 -0
  28. package/dist/core 2/adapters/kilocode-adapter.d.ts +34 -0
  29. package/dist/core 2/adapters/kilocode-adapter.js +49 -0
  30. package/dist/core 2/adapters/octo-md-generator.d.ts +26 -0
  31. package/dist/core 2/adapters/octo-md-generator.js +102 -0
  32. package/dist/core 2/adapters/opencode-adapter.d.ts +33 -0
  33. package/dist/core 2/adapters/opencode-adapter.js +56 -0
  34. package/dist/core 2/adapters/qwen-adapter.d.ts +27 -0
  35. package/dist/core 2/adapters/qwen-adapter.js +90 -0
  36. package/dist/core 2/adapters/roocode-adapter.d.ts +40 -0
  37. package/dist/core 2/adapters/roocode-adapter.js +68 -0
  38. package/dist/core 2/adapters/warp-md-generator.d.ts +17 -0
  39. package/dist/core 2/adapters/warp-md-generator.js +88 -0
  40. package/dist/core 2/adapters/windsurf-adapter.d.ts +34 -0
  41. package/dist/core 2/adapters/windsurf-adapter.js +49 -0
  42. package/dist/core 2/agent-manager.d.ts +51 -0
  43. package/dist/core 2/agent-manager.js +126 -0
  44. package/dist/core 2/archive-manager.d.ts +100 -0
  45. package/dist/core 2/archive-manager.js +338 -0
  46. package/dist/core 2/conversation-analyzer.d.ts +86 -0
  47. package/dist/core 2/doc-injector.d.ts +51 -0
  48. package/dist/core 2/doc-injector.js +236 -0
  49. package/dist/core 2/git-manager.d.ts +100 -0
  50. package/dist/core 2/git-manager.js +214 -0
  51. package/dist/core 2/prompt-optimizer.d.ts +268 -0
  52. package/dist/core 2/prompt-optimizer.js +963 -0
  53. package/dist/core 2/question-engine.d.ts +167 -0
  54. package/dist/core 2/question-engine.js +395 -0
  55. package/dist/core 2/session-manager.d.ts +139 -0
  56. package/dist/core 2/session-manager.js +403 -0
  57. package/dist/core 2/task-manager.d.ts +155 -0
  58. package/dist/core 2/task-manager.js +689 -0
  59. package/dist/utils/template-loader.js +24 -22
  60. package/package.json +1 -1
  61. package/dist/templates/slash-commands/augment/archive.md +0 -291
  62. package/dist/templates/slash-commands/augment/deep.md +0 -207
  63. package/dist/templates/slash-commands/augment/fast.md +0 -183
  64. package/dist/templates/slash-commands/augment/implement.md +0 -267
  65. package/dist/templates/slash-commands/augment/plan.md +0 -173
  66. package/dist/templates/slash-commands/augment/prd.md +0 -178
  67. package/dist/templates/slash-commands/augment/start.md +0 -142
  68. package/dist/templates/slash-commands/augment/summarize.md +0 -179
  69. package/dist/templates/slash-commands/claude-code/archive.md +0 -291
  70. package/dist/templates/slash-commands/claude-code/deep.md +0 -207
  71. package/dist/templates/slash-commands/claude-code/fast.md +0 -183
  72. package/dist/templates/slash-commands/claude-code/implement.md +0 -267
  73. package/dist/templates/slash-commands/claude-code/plan.md +0 -173
  74. package/dist/templates/slash-commands/claude-code/prd.md +0 -178
  75. package/dist/templates/slash-commands/claude-code/start.md +0 -142
  76. package/dist/templates/slash-commands/claude-code/summarize.md +0 -179
  77. package/dist/templates/slash-commands/cline/archive.md +0 -291
  78. package/dist/templates/slash-commands/cline/deep.md +0 -207
  79. package/dist/templates/slash-commands/cline/fast.md +0 -183
  80. package/dist/templates/slash-commands/cline/implement.md +0 -267
  81. package/dist/templates/slash-commands/cline/plan.md +0 -173
  82. package/dist/templates/slash-commands/cline/prd.md +0 -178
  83. package/dist/templates/slash-commands/cline/start.md +0 -142
  84. package/dist/templates/slash-commands/cline/summarize.md +0 -179
  85. package/dist/templates/slash-commands/codebuddy/archive.md +0 -291
  86. package/dist/templates/slash-commands/codebuddy/deep.md +0 -207
  87. package/dist/templates/slash-commands/codebuddy/fast.md +0 -183
  88. package/dist/templates/slash-commands/codebuddy/implement.md +0 -267
  89. package/dist/templates/slash-commands/codebuddy/plan.md +0 -173
  90. package/dist/templates/slash-commands/codebuddy/prd.md +0 -178
  91. package/dist/templates/slash-commands/codebuddy/start.md +0 -142
  92. package/dist/templates/slash-commands/codebuddy/summarize.md +0 -179
  93. package/dist/templates/slash-commands/codex/archive.md +0 -291
  94. package/dist/templates/slash-commands/codex/deep.md +0 -207
  95. package/dist/templates/slash-commands/codex/fast.md +0 -183
  96. package/dist/templates/slash-commands/codex/implement.md +0 -267
  97. package/dist/templates/slash-commands/codex/plan.md +0 -173
  98. package/dist/templates/slash-commands/codex/prd.md +0 -178
  99. package/dist/templates/slash-commands/codex/start.md +0 -142
  100. package/dist/templates/slash-commands/codex/summarize.md +0 -179
  101. package/dist/templates/slash-commands/crush/archive.md +0 -291
  102. package/dist/templates/slash-commands/crush/deep.md +0 -207
  103. package/dist/templates/slash-commands/crush/fast.md +0 -183
  104. package/dist/templates/slash-commands/crush/implement.md +0 -267
  105. package/dist/templates/slash-commands/crush/plan.md +0 -173
  106. package/dist/templates/slash-commands/crush/prd.md +0 -178
  107. package/dist/templates/slash-commands/crush/start.md +0 -142
  108. package/dist/templates/slash-commands/crush/summarize.md +0 -179
  109. package/dist/templates/slash-commands/cursor/archive.md +0 -291
  110. package/dist/templates/slash-commands/cursor/deep.md +0 -207
  111. package/dist/templates/slash-commands/cursor/fast.md +0 -183
  112. package/dist/templates/slash-commands/cursor/implement.md +0 -267
  113. package/dist/templates/slash-commands/cursor/plan.md +0 -173
  114. package/dist/templates/slash-commands/cursor/prd.md +0 -178
  115. package/dist/templates/slash-commands/cursor/start.md +0 -142
  116. package/dist/templates/slash-commands/cursor/summarize.md +0 -179
  117. package/dist/templates/slash-commands/droid/archive.md +0 -291
  118. package/dist/templates/slash-commands/droid/deep.md +0 -207
  119. package/dist/templates/slash-commands/droid/fast.md +0 -183
  120. package/dist/templates/slash-commands/droid/implement.md +0 -267
  121. package/dist/templates/slash-commands/droid/plan.md +0 -173
  122. package/dist/templates/slash-commands/droid/prd.md +0 -178
  123. package/dist/templates/slash-commands/droid/start.md +0 -142
  124. package/dist/templates/slash-commands/droid/summarize.md +0 -179
  125. package/dist/templates/slash-commands/gemini/archive.toml +0 -290
  126. package/dist/templates/slash-commands/gemini/deep.toml +0 -206
  127. package/dist/templates/slash-commands/gemini/fast.toml +0 -182
  128. package/dist/templates/slash-commands/gemini/implement.toml +0 -266
  129. package/dist/templates/slash-commands/gemini/plan.toml +0 -170
  130. package/dist/templates/slash-commands/gemini/prd.toml +0 -177
  131. package/dist/templates/slash-commands/gemini/start.toml +0 -141
  132. package/dist/templates/slash-commands/gemini/summarize.toml +0 -178
  133. package/dist/templates/slash-commands/kilocode/archive.md +0 -291
  134. package/dist/templates/slash-commands/kilocode/deep.md +0 -207
  135. package/dist/templates/slash-commands/kilocode/fast.md +0 -183
  136. package/dist/templates/slash-commands/kilocode/implement.md +0 -267
  137. package/dist/templates/slash-commands/kilocode/plan.md +0 -173
  138. package/dist/templates/slash-commands/kilocode/prd.md +0 -178
  139. package/dist/templates/slash-commands/kilocode/start.md +0 -142
  140. package/dist/templates/slash-commands/kilocode/summarize.md +0 -179
  141. package/dist/templates/slash-commands/opencode/archive.md +0 -291
  142. package/dist/templates/slash-commands/opencode/deep.md +0 -207
  143. package/dist/templates/slash-commands/opencode/fast.md +0 -183
  144. package/dist/templates/slash-commands/opencode/implement.md +0 -267
  145. package/dist/templates/slash-commands/opencode/plan.md +0 -173
  146. package/dist/templates/slash-commands/opencode/prd.md +0 -178
  147. package/dist/templates/slash-commands/opencode/start.md +0 -142
  148. package/dist/templates/slash-commands/opencode/summarize.md +0 -179
  149. package/dist/templates/slash-commands/qwen/archive.toml +0 -290
  150. package/dist/templates/slash-commands/qwen/deep.toml +0 -206
  151. package/dist/templates/slash-commands/qwen/fast.toml +0 -182
  152. package/dist/templates/slash-commands/qwen/implement.toml +0 -266
  153. package/dist/templates/slash-commands/qwen/plan.toml +0 -170
  154. package/dist/templates/slash-commands/qwen/prd.toml +0 -177
  155. package/dist/templates/slash-commands/qwen/start.toml +0 -141
  156. package/dist/templates/slash-commands/qwen/summarize.toml +0 -178
  157. package/dist/templates/slash-commands/roocode/archive.md +0 -291
  158. package/dist/templates/slash-commands/roocode/deep.md +0 -207
  159. package/dist/templates/slash-commands/roocode/fast.md +0 -183
  160. package/dist/templates/slash-commands/roocode/implement.md +0 -267
  161. package/dist/templates/slash-commands/roocode/plan.md +0 -173
  162. package/dist/templates/slash-commands/roocode/prd.md +0 -178
  163. package/dist/templates/slash-commands/roocode/start.md +0 -142
  164. package/dist/templates/slash-commands/roocode/summarize.md +0 -179
  165. package/dist/templates/slash-commands/windsurf/archive.md +0 -291
  166. package/dist/templates/slash-commands/windsurf/deep.md +0 -207
  167. package/dist/templates/slash-commands/windsurf/fast.md +0 -183
  168. package/dist/templates/slash-commands/windsurf/implement.md +0 -267
  169. package/dist/templates/slash-commands/windsurf/plan.md +0 -173
  170. package/dist/templates/slash-commands/windsurf/prd.md +0 -178
  171. package/dist/templates/slash-commands/windsurf/start.md +0 -142
  172. package/dist/templates/slash-commands/windsurf/summarize.md +0 -179
  173. /package/dist/templates/slash-commands/{amp → _canonical}/archive.md +0 -0
  174. /package/dist/templates/slash-commands/{amp → _canonical}/deep.md +0 -0
  175. /package/dist/templates/slash-commands/{amp → _canonical}/fast.md +0 -0
  176. /package/dist/templates/slash-commands/{amp → _canonical}/implement.md +0 -0
  177. /package/dist/templates/slash-commands/{amp → _canonical}/plan.md +0 -0
  178. /package/dist/templates/slash-commands/{amp → _canonical}/prd.md +0 -0
  179. /package/dist/templates/slash-commands/{amp → _canonical}/start.md +0 -0
  180. /package/dist/templates/slash-commands/{amp → _canonical}/summarize.md +0 -0
@@ -0,0 +1,403 @@
1
+ "use strict";
2
+ /**
3
+ * SessionManager - Manages conversational sessions for clavix start/summarize
4
+ *
5
+ * This class handles:
6
+ * - Session creation with unique IDs
7
+ * - Message tracking and storage
8
+ * - Session file persistence (JSON format)
9
+ * - Session listing, filtering, and search
10
+ * - CRUD operations for sessions
11
+ *
12
+ * Sessions are stored in `.clavix/sessions/` as JSON files:
13
+ * `.clavix/sessions/{session-id}.json`
14
+ */
15
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
16
+ if (k2 === undefined) k2 = k;
17
+ var desc = Object.getOwnPropertyDescriptor(m, k);
18
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
19
+ desc = { enumerable: true, get: function() { return m[k]; } };
20
+ }
21
+ Object.defineProperty(o, k2, desc);
22
+ }) : (function(o, m, k, k2) {
23
+ if (k2 === undefined) k2 = k;
24
+ o[k2] = m[k];
25
+ }));
26
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
27
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
28
+ }) : function(o, v) {
29
+ o["default"] = v;
30
+ });
31
+ var __importStar = (this && this.__importStar) || (function () {
32
+ var ownKeys = function(o) {
33
+ ownKeys = Object.getOwnPropertyNames || function (o) {
34
+ var ar = [];
35
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
36
+ return ar;
37
+ };
38
+ return ownKeys(o);
39
+ };
40
+ return function (mod) {
41
+ if (mod && mod.__esModule) return mod;
42
+ var result = {};
43
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
44
+ __setModuleDefault(result, mod);
45
+ return result;
46
+ };
47
+ })();
48
+ Object.defineProperty(exports, "__esModule", { value: true });
49
+ exports.SessionManager = void 0;
50
+ const fs = __importStar(require("fs-extra"));
51
+ const path = __importStar(require("path"));
52
+ const file_system_1 = require("../utils/file-system");
53
+ // Use require for uuid to avoid Jest ESM issues
54
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
55
+ const { v4: uuidv4 } = require('uuid');
56
+ /**
57
+ * SessionManager class
58
+ *
59
+ * Manages all session-related operations including creation, storage,
60
+ * retrieval, listing, and search functionality.
61
+ */
62
+ class SessionManager {
63
+ constructor(sessionsDir) {
64
+ this.defaultSessionsDir = '.clavix/sessions';
65
+ this.sessionsDir = sessionsDir || this.defaultSessionsDir;
66
+ }
67
+ /**
68
+ * Create a new session
69
+ *
70
+ * @param options - Session creation options
71
+ * @returns The created session
72
+ */
73
+ async createSession(options = {}) {
74
+ const now = new Date();
75
+ const session = {
76
+ id: uuidv4(),
77
+ projectName: options.projectName || this.generateDefaultProjectName(),
78
+ agent: options.agent || 'Claude Code',
79
+ created: now,
80
+ updated: now,
81
+ status: 'active',
82
+ messages: [],
83
+ tags: options.tags,
84
+ description: options.description,
85
+ };
86
+ await this.saveSession(session);
87
+ return session;
88
+ }
89
+ /**
90
+ * Get a session by ID
91
+ *
92
+ * @param sessionId - The session ID
93
+ * @returns The session, or null if not found
94
+ */
95
+ async getSession(sessionId) {
96
+ try {
97
+ const sessionPath = this.getSessionPath(sessionId);
98
+ const exists = await fs.pathExists(sessionPath);
99
+ if (!exists) {
100
+ return null;
101
+ }
102
+ const serialized = await fs.readJSON(sessionPath);
103
+ return this.deserializeSession(serialized);
104
+ }
105
+ catch {
106
+ return null;
107
+ }
108
+ }
109
+ /**
110
+ * Save a session to disk
111
+ *
112
+ * @param session - The session to save
113
+ */
114
+ async saveSession(session) {
115
+ await file_system_1.FileSystem.ensureDir(this.sessionsDir);
116
+ const sessionPath = this.getSessionPath(session.id);
117
+ const serialized = this.serializeSession(session);
118
+ // Use atomic write to prevent corruption
119
+ await file_system_1.FileSystem.writeFileAtomic(sessionPath, JSON.stringify(serialized, null, 2));
120
+ }
121
+ /**
122
+ * Update a session
123
+ *
124
+ * @param sessionId - The session ID
125
+ * @param updates - Partial session updates
126
+ * @returns The updated session, or null if not found
127
+ */
128
+ async updateSession(sessionId, updates) {
129
+ const session = await this.getSession(sessionId);
130
+ if (!session) {
131
+ return null;
132
+ }
133
+ const updatedSession = {
134
+ ...session,
135
+ ...updates,
136
+ id: session.id,
137
+ created: session.created,
138
+ updated: new Date(),
139
+ };
140
+ await this.saveSession(updatedSession);
141
+ return updatedSession;
142
+ }
143
+ /**
144
+ * Delete a session
145
+ *
146
+ * @param sessionId - The session ID
147
+ * @returns True if deleted, false if not found
148
+ */
149
+ async deleteSession(sessionId) {
150
+ const sessionPath = this.getSessionPath(sessionId);
151
+ const exists = await fs.pathExists(sessionPath);
152
+ if (!exists) {
153
+ return false;
154
+ }
155
+ await fs.remove(sessionPath);
156
+ return true;
157
+ }
158
+ /**
159
+ * Add a message to a session
160
+ *
161
+ * @param sessionId - The session ID
162
+ * @param role - Message role (user or assistant)
163
+ * @param content - Message content
164
+ * @returns The updated session, or null if session not found
165
+ */
166
+ async addMessage(sessionId, role, content) {
167
+ const session = await this.getSession(sessionId);
168
+ if (!session) {
169
+ return null;
170
+ }
171
+ const message = {
172
+ role,
173
+ content,
174
+ timestamp: new Date(),
175
+ };
176
+ session.messages.push(message);
177
+ session.updated = new Date();
178
+ await this.saveSession(session);
179
+ return session;
180
+ }
181
+ /**
182
+ * List all sessions with optional filtering
183
+ *
184
+ * @param filter - Optional filter criteria
185
+ * @returns Array of session metadata
186
+ */
187
+ async listSessions(filter) {
188
+ await file_system_1.FileSystem.ensureDir(this.sessionsDir);
189
+ const files = await fs.readdir(this.sessionsDir);
190
+ const sessionFiles = files.filter((f) => f.endsWith('.json'));
191
+ const sessions = [];
192
+ for (const file of sessionFiles) {
193
+ try {
194
+ const sessionPath = path.join(this.sessionsDir, file);
195
+ const serialized = await fs.readJSON(sessionPath);
196
+ const metadata = this.extractMetadata(serialized);
197
+ // Apply filters
198
+ if (filter && !this.matchesFilter(metadata, filter)) {
199
+ continue;
200
+ }
201
+ sessions.push(metadata);
202
+ }
203
+ catch {
204
+ // Skip corrupted session files
205
+ continue;
206
+ }
207
+ }
208
+ // Sort by updated date (most recent first)
209
+ sessions.sort((a, b) => {
210
+ return new Date(b.updated).getTime() - new Date(a.updated).getTime();
211
+ });
212
+ return sessions;
213
+ }
214
+ /**
215
+ * Search sessions by keyword
216
+ *
217
+ * Searches in project name, description, tags, and message content
218
+ *
219
+ * @param keyword - Search keyword
220
+ * @returns Array of matching session metadata
221
+ */
222
+ async searchSessions(keyword) {
223
+ await file_system_1.FileSystem.ensureDir(this.sessionsDir);
224
+ const files = await fs.readdir(this.sessionsDir);
225
+ const sessionFiles = files.filter((f) => f.endsWith('.json'));
226
+ const matches = [];
227
+ const lowerKeyword = keyword.toLowerCase();
228
+ for (const file of sessionFiles) {
229
+ try {
230
+ const sessionPath = path.join(this.sessionsDir, file);
231
+ const serialized = await fs.readJSON(sessionPath);
232
+ // Search in project name
233
+ if (serialized.projectName.toLowerCase().includes(lowerKeyword)) {
234
+ matches.push(this.extractMetadata(serialized));
235
+ continue;
236
+ }
237
+ // Search in description
238
+ if (serialized.description?.toLowerCase().includes(lowerKeyword)) {
239
+ matches.push(this.extractMetadata(serialized));
240
+ continue;
241
+ }
242
+ // Search in tags
243
+ if (serialized.tags?.some((tag) => tag.toLowerCase().includes(lowerKeyword))) {
244
+ matches.push(this.extractMetadata(serialized));
245
+ continue;
246
+ }
247
+ // Search in message content
248
+ const hasMessageMatch = serialized.messages.some((msg) => msg.content.toLowerCase().includes(lowerKeyword));
249
+ if (hasMessageMatch) {
250
+ matches.push(this.extractMetadata(serialized));
251
+ }
252
+ }
253
+ catch {
254
+ // Skip corrupted session files
255
+ continue;
256
+ }
257
+ }
258
+ // Sort by updated date (most recent first)
259
+ matches.sort((a, b) => {
260
+ return new Date(b.updated).getTime() - new Date(a.updated).getTime();
261
+ });
262
+ return matches;
263
+ }
264
+ /**
265
+ * Get the most recent active session
266
+ *
267
+ * @returns The active session, or null if none exists
268
+ */
269
+ async getActiveSession() {
270
+ const activeSessions = await this.listSessions({ status: 'active' });
271
+ if (activeSessions.length === 0) {
272
+ return null;
273
+ }
274
+ // Return the most recently updated active session
275
+ return this.getSession(activeSessions[0].id);
276
+ }
277
+ /**
278
+ * Mark a session as completed
279
+ *
280
+ * @param sessionId - The session ID
281
+ * @returns The updated session, or null if not found
282
+ */
283
+ async completeSession(sessionId) {
284
+ return this.updateSession(sessionId, { status: 'completed' });
285
+ }
286
+ /**
287
+ * Mark a session as archived
288
+ *
289
+ * @param sessionId - The session ID
290
+ * @returns The updated session, or null if not found
291
+ */
292
+ async archiveSession(sessionId) {
293
+ return this.updateSession(sessionId, { status: 'archived' });
294
+ }
295
+ /**
296
+ * Get the path to a session file
297
+ */
298
+ getSessionPath(sessionId) {
299
+ return path.join(this.sessionsDir, `${sessionId}.json`);
300
+ }
301
+ /**
302
+ * Generate a default project name based on timestamp
303
+ */
304
+ generateDefaultProjectName() {
305
+ const date = new Date();
306
+ const timestamp = date.toISOString().split('T')[0]; // YYYY-MM-DD
307
+ return `session-${timestamp}`;
308
+ }
309
+ /**
310
+ * Serialize a session for file storage
311
+ */
312
+ serializeSession(session) {
313
+ return {
314
+ id: session.id,
315
+ projectName: session.projectName,
316
+ agent: session.agent,
317
+ created: session.created.toISOString(),
318
+ updated: session.updated.toISOString(),
319
+ status: session.status,
320
+ messages: session.messages.map((msg) => ({
321
+ role: msg.role,
322
+ content: msg.content,
323
+ timestamp: msg.timestamp.toISOString(),
324
+ })),
325
+ tags: session.tags,
326
+ description: session.description,
327
+ };
328
+ }
329
+ /**
330
+ * Deserialize a session from file storage
331
+ */
332
+ deserializeSession(serialized) {
333
+ return {
334
+ id: serialized.id,
335
+ projectName: serialized.projectName,
336
+ agent: serialized.agent,
337
+ created: new Date(serialized.created),
338
+ updated: new Date(serialized.updated),
339
+ status: serialized.status,
340
+ messages: serialized.messages.map((msg) => ({
341
+ role: msg.role,
342
+ content: msg.content,
343
+ timestamp: new Date(msg.timestamp),
344
+ })),
345
+ tags: serialized.tags,
346
+ description: serialized.description,
347
+ };
348
+ }
349
+ /**
350
+ * Extract metadata from a serialized session
351
+ */
352
+ extractMetadata(serialized) {
353
+ return {
354
+ id: serialized.id,
355
+ projectName: serialized.projectName,
356
+ agent: serialized.agent,
357
+ created: serialized.created,
358
+ updated: serialized.updated,
359
+ status: serialized.status,
360
+ messageCount: serialized.messages.length,
361
+ tags: serialized.tags,
362
+ description: serialized.description,
363
+ };
364
+ }
365
+ /**
366
+ * Check if session metadata matches filter criteria
367
+ */
368
+ matchesFilter(metadata, filter) {
369
+ // Status filter
370
+ if (filter.status && metadata.status !== filter.status) {
371
+ return false;
372
+ }
373
+ // Project name filter
374
+ if (filter.projectName && metadata.projectName !== filter.projectName) {
375
+ return false;
376
+ }
377
+ // Agent filter
378
+ if (filter.agent && metadata.agent !== filter.agent) {
379
+ return false;
380
+ }
381
+ // Tags filter (session must have ALL specified tags)
382
+ if (filter.tags && filter.tags.length > 0) {
383
+ if (!metadata.tags || metadata.tags.length === 0) {
384
+ return false;
385
+ }
386
+ const hasAllTags = filter.tags.every((tag) => metadata.tags.includes(tag));
387
+ if (!hasAllTags) {
388
+ return false;
389
+ }
390
+ }
391
+ // Date range filters
392
+ const updatedDate = new Date(metadata.updated);
393
+ if (filter.startDate && updatedDate < filter.startDate) {
394
+ return false;
395
+ }
396
+ if (filter.endDate && updatedDate > filter.endDate) {
397
+ return false;
398
+ }
399
+ return true;
400
+ }
401
+ }
402
+ exports.SessionManager = SessionManager;
403
+ //# sourceMappingURL=session-manager.js.map
@@ -0,0 +1,155 @@
1
+ /**
2
+ * TaskManager - Manages PRD-based task generation and execution
3
+ *
4
+ * This class handles:
5
+ * - Analyzing PRD documents
6
+ * - Generating CLEAR-optimized task breakdowns
7
+ * - Reading/writing tasks.md with checkbox format
8
+ * - Tracking task completion state
9
+ * - Managing session resume capability
10
+ */
11
+ export type PrdSourceType = 'auto' | 'full' | 'quick' | 'mini' | 'prompt';
12
+ /**
13
+ * Represents a single task in the implementation plan
14
+ */
15
+ export interface Task {
16
+ id: string;
17
+ description: string;
18
+ phase: string;
19
+ completed: boolean;
20
+ prdReference?: string;
21
+ }
22
+ /**
23
+ * Represents a phase/section of tasks
24
+ */
25
+ export interface TaskPhase {
26
+ name: string;
27
+ tasks: Task[];
28
+ }
29
+ /**
30
+ * Options for task generation
31
+ */
32
+ export interface TaskGenerationOptions {
33
+ maxTasksPerPhase?: number;
34
+ includeReferences?: boolean;
35
+ clearMode?: 'fast' | 'deep';
36
+ source?: PrdSourceType;
37
+ }
38
+ /**
39
+ * Result of task generation
40
+ */
41
+ export interface TaskGenerationResult {
42
+ phases: TaskPhase[];
43
+ totalTasks: number;
44
+ outputPath: string;
45
+ sourcePath: string;
46
+ sourceType: Exclude<PrdSourceType, 'auto'>;
47
+ }
48
+ /**
49
+ * TaskManager class
50
+ *
51
+ * Generates and manages implementation tasks from PRD documents
52
+ */
53
+ export declare class TaskManager {
54
+ private readonly optimizer;
55
+ constructor();
56
+ /**
57
+ * Generate tasks.md from PRD
58
+ *
59
+ * @param prdPath - Path to the PRD directory
60
+ * @param options - Generation options
61
+ * @returns Task generation result
62
+ */
63
+ generateTasksFromPrd(prdPath: string, options?: TaskGenerationOptions): Promise<TaskGenerationResult>;
64
+ /**
65
+ * Find the PRD file in a directory
66
+ */
67
+ private resolvePrdFile;
68
+ /**
69
+ * Analyze PRD content and generate task breakdown
70
+ */
71
+ private analyzePrdAndGenerateTasks;
72
+ private getSectionByAliases;
73
+ private generatePhasesFromCoreFeatures;
74
+ private extractListItems;
75
+ private buildFeatureTaskDescriptions;
76
+ private formatInlineText;
77
+ private toTitleCase;
78
+ private injectTechnicalConstraintsTask;
79
+ private appendSuccessCriteriaPhase;
80
+ /**
81
+ * Parse PRD into sections
82
+ */
83
+ private parsePrdSections;
84
+ /**
85
+ * Normalize section name for consistent lookup
86
+ */
87
+ private normalizeSectionName;
88
+ /**
89
+ * Generate tasks from requirements section
90
+ */
91
+ private generateTasksFromRequirements;
92
+ /**
93
+ * Generate a phase from a feature description
94
+ */
95
+ private generatePhaseFromFeature;
96
+ /**
97
+ * Convert behavior description to task description
98
+ */
99
+ private convertBehaviorToTask;
100
+ /**
101
+ * Generate default phases when no structure found
102
+ */
103
+ private generateDefaultPhases;
104
+ /**
105
+ * Sanitize ID for use in task IDs
106
+ */
107
+ private sanitizeId;
108
+ /**
109
+ * Optimize task description using CLEAR principles
110
+ */
111
+ private optimizeTaskDescription;
112
+ /**
113
+ * Write tasks to tasks.md file
114
+ */
115
+ private writeTasksFile;
116
+ /**
117
+ * Read tasks from tasks.md file
118
+ */
119
+ readTasksFile(tasksPath: string): Promise<TaskPhase[]>;
120
+ /**
121
+ * Parse tasks.md content into TaskPhase objects
122
+ */
123
+ private parseTasksFile;
124
+ /**
125
+ * Find the first incomplete task
126
+ */
127
+ findFirstIncompleteTask(phases: TaskPhase[]): Task | null;
128
+ /**
129
+ * Mark a task as completed in the tasks.md file
130
+ */
131
+ markTaskCompleted(tasksPath: string, taskId: string): Promise<void>;
132
+ /**
133
+ * Escape special regex characters
134
+ */
135
+ private escapeRegex;
136
+ /**
137
+ * Get task completion statistics
138
+ */
139
+ getTaskStats(phases: TaskPhase[]): {
140
+ total: number;
141
+ completed: number;
142
+ remaining: number;
143
+ percentage: number;
144
+ };
145
+ /**
146
+ * Find PRD directory from current working directory
147
+ */
148
+ findPrdDirectory(projectName?: string): Promise<string>;
149
+ /**
150
+ * Check if directory has a PRD file
151
+ */
152
+ hasPrdFile(dirPath: string): Promise<boolean>;
153
+ detectAvailableSources(dirPath: string): Promise<Array<Exclude<PrdSourceType, 'auto'>>>;
154
+ }
155
+ //# sourceMappingURL=task-manager.d.ts.map