clavix 2.3.1 → 2.4.1

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 (187) hide show
  1. package/README.md +0 -116
  2. package/bin/clavix.js +7 -0
  3. package/dist/cli/commands/implement.js +25 -33
  4. package/dist/cli/commands/plan.js +22 -27
  5. package/dist/cli/commands/prd.js +7 -12
  6. package/dist/cli/commands/start.js +4 -9
  7. package/dist/cli/commands/summarize.js +15 -22
  8. package/dist/core 2/adapters/agents-md-generator.d.ts +26 -0
  9. package/dist/core 2/adapters/agents-md-generator.js +102 -0
  10. package/dist/core 2/adapters/amp-adapter.d.ts +27 -0
  11. package/dist/core 2/adapters/amp-adapter.js +42 -0
  12. package/dist/core 2/adapters/augment-adapter.d.ts +22 -0
  13. package/dist/core 2/adapters/augment-adapter.js +77 -0
  14. package/dist/core 2/adapters/base-adapter.d.ts +45 -0
  15. package/dist/core 2/adapters/base-adapter.js +142 -0
  16. package/dist/core 2/adapters/claude-code-adapter.d.ts +32 -0
  17. package/dist/core 2/adapters/claude-code-adapter.js +116 -0
  18. package/dist/core 2/adapters/cline-adapter.d.ts +34 -0
  19. package/dist/core 2/adapters/cline-adapter.js +52 -0
  20. package/dist/core 2/adapters/codebuddy-adapter.d.ts +24 -0
  21. package/dist/core 2/adapters/codebuddy-adapter.js +82 -0
  22. package/dist/core 2/adapters/codex-adapter.d.ts +24 -0
  23. package/dist/core 2/adapters/codex-adapter.js +79 -0
  24. package/dist/core 2/adapters/copilot-instructions-generator.d.ts +26 -0
  25. package/dist/core 2/adapters/copilot-instructions-generator.js +104 -0
  26. package/dist/core 2/adapters/crush-adapter.d.ts +35 -0
  27. package/dist/core 2/adapters/crush-adapter.js +49 -0
  28. package/dist/core 2/adapters/cursor-adapter.d.ts +25 -0
  29. package/dist/core 2/adapters/cursor-adapter.js +40 -0
  30. package/dist/core 2/adapters/droid-adapter.d.ts +33 -0
  31. package/dist/core 2/adapters/droid-adapter.js +57 -0
  32. package/dist/core 2/adapters/gemini-adapter.d.ts +27 -0
  33. package/dist/core 2/adapters/gemini-adapter.js +90 -0
  34. package/dist/core 2/adapters/kilocode-adapter.d.ts +34 -0
  35. package/dist/core 2/adapters/kilocode-adapter.js +49 -0
  36. package/dist/core 2/adapters/octo-md-generator.d.ts +26 -0
  37. package/dist/core 2/adapters/octo-md-generator.js +102 -0
  38. package/dist/core 2/adapters/opencode-adapter.d.ts +33 -0
  39. package/dist/core 2/adapters/opencode-adapter.js +56 -0
  40. package/dist/core 2/adapters/qwen-adapter.d.ts +27 -0
  41. package/dist/core 2/adapters/qwen-adapter.js +90 -0
  42. package/dist/core 2/adapters/roocode-adapter.d.ts +40 -0
  43. package/dist/core 2/adapters/roocode-adapter.js +68 -0
  44. package/dist/core 2/adapters/warp-md-generator.d.ts +17 -0
  45. package/dist/core 2/adapters/warp-md-generator.js +88 -0
  46. package/dist/core 2/adapters/windsurf-adapter.d.ts +34 -0
  47. package/dist/core 2/adapters/windsurf-adapter.js +49 -0
  48. package/dist/core 2/agent-manager.d.ts +51 -0
  49. package/dist/core 2/agent-manager.js +126 -0
  50. package/dist/core 2/archive-manager.d.ts +100 -0
  51. package/dist/core 2/archive-manager.js +338 -0
  52. package/dist/core 2/conversation-analyzer.d.ts +86 -0
  53. package/dist/core 2/doc-injector.d.ts +51 -0
  54. package/dist/core 2/doc-injector.js +236 -0
  55. package/dist/core 2/git-manager.d.ts +100 -0
  56. package/dist/core 2/git-manager.js +214 -0
  57. package/dist/core 2/prompt-optimizer.d.ts +268 -0
  58. package/dist/core 2/prompt-optimizer.js +963 -0
  59. package/dist/core 2/question-engine.d.ts +167 -0
  60. package/dist/core 2/question-engine.js +395 -0
  61. package/dist/core 2/session-manager.d.ts +139 -0
  62. package/dist/core 2/session-manager.js +403 -0
  63. package/dist/core 2/task-manager.d.ts +155 -0
  64. package/dist/core 2/task-manager.js +689 -0
  65. package/dist/index.js +6 -0
  66. package/dist/utils/template-loader.js +24 -22
  67. package/package.json +1 -1
  68. package/dist/templates/slash-commands/augment/archive.md +0 -291
  69. package/dist/templates/slash-commands/augment/deep.md +0 -207
  70. package/dist/templates/slash-commands/augment/fast.md +0 -183
  71. package/dist/templates/slash-commands/augment/implement.md +0 -267
  72. package/dist/templates/slash-commands/augment/plan.md +0 -173
  73. package/dist/templates/slash-commands/augment/prd.md +0 -178
  74. package/dist/templates/slash-commands/augment/start.md +0 -142
  75. package/dist/templates/slash-commands/augment/summarize.md +0 -179
  76. package/dist/templates/slash-commands/claude-code/archive.md +0 -291
  77. package/dist/templates/slash-commands/claude-code/deep.md +0 -207
  78. package/dist/templates/slash-commands/claude-code/fast.md +0 -183
  79. package/dist/templates/slash-commands/claude-code/implement.md +0 -267
  80. package/dist/templates/slash-commands/claude-code/plan.md +0 -173
  81. package/dist/templates/slash-commands/claude-code/prd.md +0 -178
  82. package/dist/templates/slash-commands/claude-code/start.md +0 -142
  83. package/dist/templates/slash-commands/claude-code/summarize.md +0 -179
  84. package/dist/templates/slash-commands/cline/archive.md +0 -291
  85. package/dist/templates/slash-commands/cline/deep.md +0 -207
  86. package/dist/templates/slash-commands/cline/fast.md +0 -183
  87. package/dist/templates/slash-commands/cline/implement.md +0 -267
  88. package/dist/templates/slash-commands/cline/plan.md +0 -173
  89. package/dist/templates/slash-commands/cline/prd.md +0 -178
  90. package/dist/templates/slash-commands/cline/start.md +0 -142
  91. package/dist/templates/slash-commands/cline/summarize.md +0 -179
  92. package/dist/templates/slash-commands/codebuddy/archive.md +0 -291
  93. package/dist/templates/slash-commands/codebuddy/deep.md +0 -207
  94. package/dist/templates/slash-commands/codebuddy/fast.md +0 -183
  95. package/dist/templates/slash-commands/codebuddy/implement.md +0 -267
  96. package/dist/templates/slash-commands/codebuddy/plan.md +0 -173
  97. package/dist/templates/slash-commands/codebuddy/prd.md +0 -178
  98. package/dist/templates/slash-commands/codebuddy/start.md +0 -142
  99. package/dist/templates/slash-commands/codebuddy/summarize.md +0 -179
  100. package/dist/templates/slash-commands/codex/archive.md +0 -291
  101. package/dist/templates/slash-commands/codex/deep.md +0 -207
  102. package/dist/templates/slash-commands/codex/fast.md +0 -183
  103. package/dist/templates/slash-commands/codex/implement.md +0 -267
  104. package/dist/templates/slash-commands/codex/plan.md +0 -173
  105. package/dist/templates/slash-commands/codex/prd.md +0 -178
  106. package/dist/templates/slash-commands/codex/start.md +0 -142
  107. package/dist/templates/slash-commands/codex/summarize.md +0 -179
  108. package/dist/templates/slash-commands/crush/archive.md +0 -291
  109. package/dist/templates/slash-commands/crush/deep.md +0 -207
  110. package/dist/templates/slash-commands/crush/fast.md +0 -183
  111. package/dist/templates/slash-commands/crush/implement.md +0 -267
  112. package/dist/templates/slash-commands/crush/plan.md +0 -173
  113. package/dist/templates/slash-commands/crush/prd.md +0 -178
  114. package/dist/templates/slash-commands/crush/start.md +0 -142
  115. package/dist/templates/slash-commands/crush/summarize.md +0 -179
  116. package/dist/templates/slash-commands/cursor/archive.md +0 -291
  117. package/dist/templates/slash-commands/cursor/deep.md +0 -207
  118. package/dist/templates/slash-commands/cursor/fast.md +0 -183
  119. package/dist/templates/slash-commands/cursor/implement.md +0 -267
  120. package/dist/templates/slash-commands/cursor/plan.md +0 -173
  121. package/dist/templates/slash-commands/cursor/prd.md +0 -178
  122. package/dist/templates/slash-commands/cursor/start.md +0 -142
  123. package/dist/templates/slash-commands/cursor/summarize.md +0 -179
  124. package/dist/templates/slash-commands/droid/archive.md +0 -291
  125. package/dist/templates/slash-commands/droid/deep.md +0 -207
  126. package/dist/templates/slash-commands/droid/fast.md +0 -183
  127. package/dist/templates/slash-commands/droid/implement.md +0 -267
  128. package/dist/templates/slash-commands/droid/plan.md +0 -173
  129. package/dist/templates/slash-commands/droid/prd.md +0 -178
  130. package/dist/templates/slash-commands/droid/start.md +0 -142
  131. package/dist/templates/slash-commands/droid/summarize.md +0 -179
  132. package/dist/templates/slash-commands/gemini/archive.toml +0 -290
  133. package/dist/templates/slash-commands/gemini/deep.toml +0 -206
  134. package/dist/templates/slash-commands/gemini/fast.toml +0 -182
  135. package/dist/templates/slash-commands/gemini/implement.toml +0 -266
  136. package/dist/templates/slash-commands/gemini/plan.toml +0 -170
  137. package/dist/templates/slash-commands/gemini/prd.toml +0 -177
  138. package/dist/templates/slash-commands/gemini/start.toml +0 -141
  139. package/dist/templates/slash-commands/gemini/summarize.toml +0 -178
  140. package/dist/templates/slash-commands/kilocode/archive.md +0 -291
  141. package/dist/templates/slash-commands/kilocode/deep.md +0 -207
  142. package/dist/templates/slash-commands/kilocode/fast.md +0 -183
  143. package/dist/templates/slash-commands/kilocode/implement.md +0 -267
  144. package/dist/templates/slash-commands/kilocode/plan.md +0 -173
  145. package/dist/templates/slash-commands/kilocode/prd.md +0 -178
  146. package/dist/templates/slash-commands/kilocode/start.md +0 -142
  147. package/dist/templates/slash-commands/kilocode/summarize.md +0 -179
  148. package/dist/templates/slash-commands/opencode/archive.md +0 -291
  149. package/dist/templates/slash-commands/opencode/deep.md +0 -207
  150. package/dist/templates/slash-commands/opencode/fast.md +0 -183
  151. package/dist/templates/slash-commands/opencode/implement.md +0 -267
  152. package/dist/templates/slash-commands/opencode/plan.md +0 -173
  153. package/dist/templates/slash-commands/opencode/prd.md +0 -178
  154. package/dist/templates/slash-commands/opencode/start.md +0 -142
  155. package/dist/templates/slash-commands/opencode/summarize.md +0 -179
  156. package/dist/templates/slash-commands/qwen/archive.toml +0 -290
  157. package/dist/templates/slash-commands/qwen/deep.toml +0 -206
  158. package/dist/templates/slash-commands/qwen/fast.toml +0 -182
  159. package/dist/templates/slash-commands/qwen/implement.toml +0 -266
  160. package/dist/templates/slash-commands/qwen/plan.toml +0 -170
  161. package/dist/templates/slash-commands/qwen/prd.toml +0 -177
  162. package/dist/templates/slash-commands/qwen/start.toml +0 -141
  163. package/dist/templates/slash-commands/qwen/summarize.toml +0 -178
  164. package/dist/templates/slash-commands/roocode/archive.md +0 -291
  165. package/dist/templates/slash-commands/roocode/deep.md +0 -207
  166. package/dist/templates/slash-commands/roocode/fast.md +0 -183
  167. package/dist/templates/slash-commands/roocode/implement.md +0 -267
  168. package/dist/templates/slash-commands/roocode/plan.md +0 -173
  169. package/dist/templates/slash-commands/roocode/prd.md +0 -178
  170. package/dist/templates/slash-commands/roocode/start.md +0 -142
  171. package/dist/templates/slash-commands/roocode/summarize.md +0 -179
  172. package/dist/templates/slash-commands/windsurf/archive.md +0 -291
  173. package/dist/templates/slash-commands/windsurf/deep.md +0 -207
  174. package/dist/templates/slash-commands/windsurf/fast.md +0 -183
  175. package/dist/templates/slash-commands/windsurf/implement.md +0 -267
  176. package/dist/templates/slash-commands/windsurf/plan.md +0 -173
  177. package/dist/templates/slash-commands/windsurf/prd.md +0 -178
  178. package/dist/templates/slash-commands/windsurf/start.md +0 -142
  179. package/dist/templates/slash-commands/windsurf/summarize.md +0 -179
  180. /package/dist/templates/slash-commands/{amp → _canonical}/archive.md +0 -0
  181. /package/dist/templates/slash-commands/{amp → _canonical}/deep.md +0 -0
  182. /package/dist/templates/slash-commands/{amp → _canonical}/fast.md +0 -0
  183. /package/dist/templates/slash-commands/{amp → _canonical}/implement.md +0 -0
  184. /package/dist/templates/slash-commands/{amp → _canonical}/plan.md +0 -0
  185. /package/dist/templates/slash-commands/{amp → _canonical}/prd.md +0 -0
  186. /package/dist/templates/slash-commands/{amp → _canonical}/start.md +0 -0
  187. /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