clavix 2.7.0 → 2.8.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 (165) hide show
  1. package/README.md +22 -8
  2. package/bin/clavix.js +12 -5
  3. package/dist/cli/commands/archive.d.ts +5 -4
  4. package/dist/cli/commands/archive.js +135 -161
  5. package/dist/cli/commands/config.d.ts +4 -4
  6. package/dist/cli/commands/config.js +66 -105
  7. package/dist/cli/commands/deep.d.ts +3 -3
  8. package/dist/cli/commands/deep.js +97 -103
  9. package/dist/cli/commands/execute.d.ts +4 -4
  10. package/dist/cli/commands/execute.js +57 -63
  11. package/dist/cli/commands/fast.d.ts +3 -3
  12. package/dist/cli/commands/fast.js +122 -128
  13. package/dist/cli/commands/implement.d.ts +4 -4
  14. package/dist/cli/commands/implement.js +84 -148
  15. package/dist/cli/commands/init.js +87 -126
  16. package/dist/cli/commands/list.d.ts +5 -5
  17. package/dist/cli/commands/list.js +72 -111
  18. package/dist/cli/commands/plan.d.ts +7 -7
  19. package/dist/cli/commands/plan.js +92 -131
  20. package/dist/cli/commands/prd.d.ts +4 -4
  21. package/dist/cli/commands/prd.js +76 -111
  22. package/dist/cli/commands/prompts/clear.d.ts +6 -6
  23. package/dist/cli/commands/prompts/clear.js +70 -76
  24. package/dist/cli/commands/prompts/list.js +37 -43
  25. package/dist/cli/commands/show.d.ts +4 -4
  26. package/dist/cli/commands/show.js +72 -111
  27. package/dist/cli/commands/start.d.ts +3 -3
  28. package/dist/cli/commands/start.js +63 -101
  29. package/dist/cli/commands/summarize.d.ts +4 -4
  30. package/dist/cli/commands/summarize.js +81 -120
  31. package/dist/cli/commands/task-complete.d.ts +4 -4
  32. package/dist/cli/commands/task-complete.js +86 -123
  33. package/dist/cli/commands/update.d.ts +3 -3
  34. package/dist/cli/commands/update.js +97 -130
  35. package/dist/cli/commands/version.js +13 -48
  36. package/dist/core/adapters/agents-md-generator.js +17 -50
  37. package/dist/core/adapters/amp-adapter.d.ts +1 -1
  38. package/dist/core/adapters/amp-adapter.js +13 -21
  39. package/dist/core/adapters/augment-adapter.d.ts +2 -2
  40. package/dist/core/adapters/augment-adapter.js +16 -56
  41. package/dist/core/adapters/base-adapter.d.ts +1 -1
  42. package/dist/core/adapters/base-adapter.js +11 -47
  43. package/dist/core/adapters/claude-code-adapter.d.ts +2 -2
  44. package/dist/core/adapters/claude-code-adapter.js +19 -60
  45. package/dist/core/adapters/cline-adapter.d.ts +1 -1
  46. package/dist/core/adapters/cline-adapter.js +13 -21
  47. package/dist/core/adapters/codebuddy-adapter.d.ts +2 -2
  48. package/dist/core/adapters/codebuddy-adapter.js +17 -57
  49. package/dist/core/adapters/codex-adapter.d.ts +2 -2
  50. package/dist/core/adapters/codex-adapter.js +16 -56
  51. package/dist/core/adapters/copilot-instructions-generator.js +18 -51
  52. package/dist/core/adapters/crush-adapter.d.ts +2 -2
  53. package/dist/core/adapters/crush-adapter.js +13 -20
  54. package/dist/core/adapters/cursor-adapter.d.ts +1 -1
  55. package/dist/core/adapters/cursor-adapter.js +12 -20
  56. package/dist/core/adapters/droid-adapter.d.ts +2 -2
  57. package/dist/core/adapters/droid-adapter.js +14 -21
  58. package/dist/core/adapters/gemini-adapter.d.ts +2 -2
  59. package/dist/core/adapters/gemini-adapter.js +16 -52
  60. package/dist/core/adapters/kilocode-adapter.d.ts +1 -1
  61. package/dist/core/adapters/kilocode-adapter.js +12 -20
  62. package/dist/core/adapters/octo-md-generator.js +17 -50
  63. package/dist/core/adapters/opencode-adapter.d.ts +2 -2
  64. package/dist/core/adapters/opencode-adapter.js +14 -21
  65. package/dist/core/adapters/qwen-adapter.d.ts +2 -2
  66. package/dist/core/adapters/qwen-adapter.js +16 -52
  67. package/dist/core/adapters/roocode-adapter.d.ts +2 -2
  68. package/dist/core/adapters/roocode-adapter.js +12 -19
  69. package/dist/core/adapters/warp-md-generator.js +17 -50
  70. package/dist/core/adapters/windsurf-adapter.d.ts +1 -1
  71. package/dist/core/adapters/windsurf-adapter.js +12 -20
  72. package/dist/core/agent-manager.d.ts +1 -1
  73. package/dist/core/agent-manager.js +34 -38
  74. package/dist/core/archive-manager.js +10 -46
  75. package/dist/core/config-manager.d.ts +2 -2
  76. package/dist/core/config-manager.js +3 -40
  77. package/dist/core/conversation-analyzer.d.ts +1 -1
  78. package/dist/core/conversation-analyzer.js +1 -5
  79. package/dist/core/doc-injector.js +23 -60
  80. package/dist/core/git-manager.js +11 -48
  81. package/dist/core/prd-generator.js +16 -51
  82. package/dist/core/prompt-manager.js +6 -42
  83. package/dist/core/prompt-optimizer.js +1 -5
  84. package/dist/core/question-engine.js +6 -45
  85. package/dist/core/session-manager.d.ts +1 -1
  86. package/dist/core/session-manager.js +11 -49
  87. package/dist/core/task-manager.d.ts +26 -0
  88. package/dist/core/task-manager.js +243 -101
  89. package/dist/index.d.ts +2 -1
  90. package/dist/index.js +8 -12
  91. package/dist/templates/agents/agents.md +31 -2
  92. package/dist/templates/agents/copilot-instructions.md +1 -1
  93. package/dist/templates/agents/octo.md +20 -1
  94. package/dist/templates/agents/warp.md +1 -1
  95. package/dist/templates/slash-commands/_canonical/implement.md +33 -11
  96. package/dist/types/agent.js +1 -2
  97. package/dist/types/config.js +3 -8
  98. package/dist/types/errors.js +7 -13
  99. package/dist/types/session.js +1 -2
  100. package/dist/utils/agent-error-messages.js +1 -5
  101. package/dist/utils/error-utils.js +5 -12
  102. package/dist/utils/file-system.js +20 -57
  103. package/dist/utils/legacy-command-cleanup.d.ts +1 -1
  104. package/dist/utils/legacy-command-cleanup.js +9 -45
  105. package/dist/utils/template-loader.d.ts +1 -1
  106. package/dist/utils/template-loader.js +9 -41
  107. package/dist/utils/toml-templates.js +1 -4
  108. package/package.json +12 -7
  109. package/dist/core/adapters 2/agents-md-generator.d.ts +0 -26
  110. package/dist/core/adapters 2/agents-md-generator.js +0 -102
  111. package/dist/core/adapters 2/amp-adapter.d.ts +0 -27
  112. package/dist/core/adapters 2/amp-adapter.js +0 -42
  113. package/dist/core/adapters 2/augment-adapter.d.ts +0 -22
  114. package/dist/core/adapters 2/augment-adapter.js +0 -77
  115. package/dist/core/adapters 2/base-adapter.d.ts +0 -45
  116. package/dist/core/adapters 2/base-adapter.js +0 -142
  117. package/dist/core/adapters 2/claude-code-adapter.d.ts +0 -32
  118. package/dist/core/adapters 2/claude-code-adapter.js +0 -116
  119. package/dist/core/adapters 2/cline-adapter.d.ts +0 -34
  120. package/dist/core/adapters 2/cline-adapter.js +0 -52
  121. package/dist/core/adapters 2/codebuddy-adapter.d.ts +0 -24
  122. package/dist/core/adapters 2/codebuddy-adapter.js +0 -82
  123. package/dist/core/adapters 2/codex-adapter.d.ts +0 -24
  124. package/dist/core/adapters 2/codex-adapter.js +0 -79
  125. package/dist/core/adapters 2/copilot-instructions-generator.d.ts +0 -26
  126. package/dist/core/adapters 2/copilot-instructions-generator.js +0 -104
  127. package/dist/core/adapters 2/crush-adapter.d.ts +0 -35
  128. package/dist/core/adapters 2/crush-adapter.js +0 -49
  129. package/dist/core/adapters 2/cursor-adapter.d.ts +0 -25
  130. package/dist/core/adapters 2/cursor-adapter.js +0 -40
  131. package/dist/core/adapters 2/droid-adapter.d.ts +0 -33
  132. package/dist/core/adapters 2/droid-adapter.js +0 -57
  133. package/dist/core/adapters 2/gemini-adapter.d.ts +0 -27
  134. package/dist/core/adapters 2/gemini-adapter.js +0 -90
  135. package/dist/core/adapters 2/kilocode-adapter.d.ts +0 -34
  136. package/dist/core/adapters 2/kilocode-adapter.js +0 -49
  137. package/dist/core/adapters 2/octo-md-generator.d.ts +0 -26
  138. package/dist/core/adapters 2/octo-md-generator.js +0 -102
  139. package/dist/core/adapters 2/opencode-adapter.d.ts +0 -33
  140. package/dist/core/adapters 2/opencode-adapter.js +0 -56
  141. package/dist/core/adapters 2/qwen-adapter.d.ts +0 -27
  142. package/dist/core/adapters 2/qwen-adapter.js +0 -90
  143. package/dist/core/adapters 2/roocode-adapter.d.ts +0 -40
  144. package/dist/core/adapters 2/roocode-adapter.js +0 -68
  145. package/dist/core/adapters 2/warp-md-generator.d.ts +0 -17
  146. package/dist/core/adapters 2/warp-md-generator.js +0 -88
  147. package/dist/core/adapters 2/windsurf-adapter.d.ts +0 -34
  148. package/dist/core/adapters 2/windsurf-adapter.js +0 -49
  149. package/dist/core/agent-manager 2.js +0 -126
  150. package/dist/core/agent-manager.d 2.ts +0 -51
  151. package/dist/core/archive-manager 2.js +0 -338
  152. package/dist/core/archive-manager.d 2.ts +0 -100
  153. package/dist/core/conversation-analyzer.d 2.ts +0 -86
  154. package/dist/core/doc-injector 2.js +0 -236
  155. package/dist/core/doc-injector.d 2.ts +0 -51
  156. package/dist/core/git-manager 2.js +0 -214
  157. package/dist/core/git-manager.d 2.ts +0 -100
  158. package/dist/core/prompt-optimizer 2.js +0 -963
  159. package/dist/core/prompt-optimizer.d 2.ts +0 -268
  160. package/dist/core/question-engine 2.js +0 -395
  161. package/dist/core/question-engine.d 2.ts +0 -167
  162. package/dist/core/session-manager 2.js +0 -403
  163. package/dist/core/session-manager.d 2.ts +0 -139
  164. package/dist/core/task-manager 2.js +0 -689
  165. package/dist/core/task-manager.d 2.ts +0 -155
@@ -1,167 +0,0 @@
1
- /**
2
- * QuestionEngine - Manages Socratic questioning flows for PRD generation
3
- *
4
- * This class handles:
5
- * - Loading question templates
6
- * - Sequential and conditional question flows
7
- * - Answer collection and validation
8
- * - Progress tracking
9
- */
10
- /**
11
- * Type of question input
12
- */
13
- export type QuestionType = 'text' | 'list' | 'confirm';
14
- /**
15
- * A single question in the flow
16
- */
17
- export interface Question {
18
- id: string;
19
- text: string;
20
- type: QuestionType;
21
- required: boolean;
22
- choices?: string[];
23
- default?: string | boolean;
24
- validate?: (answer: string) => boolean | string;
25
- condition?: (answers: Record<string, Answer>) => boolean;
26
- }
27
- /**
28
- * Answer to a question
29
- */
30
- export type Answer = string | boolean | string[];
31
- /**
32
- * Collection of answers keyed by question ID
33
- */
34
- export interface Answers {
35
- [questionId: string]: Answer;
36
- }
37
- /**
38
- * Question flow configuration
39
- */
40
- export interface QuestionFlow {
41
- name: string;
42
- description: string;
43
- questions: Question[];
44
- }
45
- /**
46
- * Progress information for multi-question flows
47
- */
48
- export interface QuestionProgress {
49
- current: number;
50
- total: number;
51
- percentage: number;
52
- }
53
- /**
54
- * QuestionEngine class
55
- *
56
- * Manages the flow of questions, answer collection, and validation
57
- */
58
- export declare class QuestionEngine {
59
- private currentFlow;
60
- private answers;
61
- private currentQuestionIndex;
62
- /**
63
- * Load a question flow from a template file
64
- *
65
- * @param templatePath - Path to the question template
66
- * @returns The loaded question flow
67
- */
68
- loadFlow(templatePath: string): Promise<QuestionFlow>;
69
- /**
70
- * Parse a question template into a QuestionFlow
71
- *
72
- * Template format:
73
- * ```markdown
74
- * # Flow Name
75
- *
76
- * Flow description
77
- *
78
- * ## Question 1
79
- *
80
- * **text:** What problem are you solving?
81
- * **type:** text
82
- * **required:** true
83
- * **validation:** minLength:10
84
- *
85
- * ## Question 2
86
- *
87
- * **text:** Select your technology stack
88
- * **type:** list
89
- * **choices:** React, Vue, Angular, Other
90
- * ```
91
- *
92
- * @param template - Template content
93
- * @returns Parsed QuestionFlow
94
- */
95
- private parseTemplate;
96
- /**
97
- * Parse a single metadata field for a question
98
- */
99
- private parseQuestionMetadata;
100
- /**
101
- * Finalize a question by setting defaults and generating ID
102
- */
103
- private finalizeQuestion;
104
- /**
105
- * Create a validation function from a validation string
106
- *
107
- * Supported formats:
108
- * - minLength:10 - Minimum length
109
- * - maxLength:100 - Maximum length
110
- * - pattern:^[a-z]+$ - Regex pattern
111
- * - email - Email validation
112
- * - url - URL validation
113
- */
114
- private createValidator;
115
- /**
116
- * Create a condition function from a condition string
117
- *
118
- * Supported formats:
119
- * - q1=true - Question 1 answer equals true
120
- * - q2=JWT - Question 2 answer equals "JWT"
121
- * - q3!=None - Question 3 answer not equals "None"
122
- */
123
- private createCondition;
124
- /**
125
- * Get the next question in the flow
126
- *
127
- * @returns The next question, or null if flow is complete
128
- */
129
- getNextQuestion(): Question | null;
130
- /**
131
- * Submit an answer to the current question
132
- *
133
- * @param questionId - ID of the question being answered
134
- * @param answer - The answer
135
- * @returns Validation result (true if valid, error message if invalid)
136
- */
137
- submitAnswer(questionId: string, answer: Answer): boolean | string;
138
- /**
139
- * Get all collected answers
140
- *
141
- * @returns All answers collected so far
142
- */
143
- getAnswers(): Answers;
144
- /**
145
- * Get current progress through the question flow
146
- *
147
- * @returns Progress information
148
- */
149
- getProgress(): QuestionProgress;
150
- /**
151
- * Check if the question flow is complete
152
- *
153
- * @returns True if all required questions are answered
154
- */
155
- isComplete(): boolean;
156
- /**
157
- * Reset the question flow
158
- */
159
- reset(): void;
160
- /**
161
- * Get the current question flow
162
- *
163
- * @returns The loaded question flow, or null if none loaded
164
- */
165
- getCurrentFlow(): QuestionFlow | null;
166
- }
167
- //# sourceMappingURL=question-engine.d.ts.map
@@ -1,403 +0,0 @@
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
@@ -1,139 +0,0 @@
1
- /**
2
- * SessionManager - Manages conversational sessions for clavix start/summarize
3
- *
4
- * This class handles:
5
- * - Session creation with unique IDs
6
- * - Message tracking and storage
7
- * - Session file persistence (JSON format)
8
- * - Session listing, filtering, and search
9
- * - CRUD operations for sessions
10
- *
11
- * Sessions are stored in `.clavix/sessions/` as JSON files:
12
- * `.clavix/sessions/{session-id}.json`
13
- */
14
- import { Session, SessionMetadata, SessionFilter } from '../types/session';
15
- /**
16
- * Options for creating a new session
17
- */
18
- export interface CreateSessionOptions {
19
- projectName?: string;
20
- agent?: string;
21
- description?: string;
22
- tags?: string[];
23
- }
24
- /**
25
- * SessionManager class
26
- *
27
- * Manages all session-related operations including creation, storage,
28
- * retrieval, listing, and search functionality.
29
- */
30
- export declare class SessionManager {
31
- private readonly sessionsDir;
32
- private readonly defaultSessionsDir;
33
- constructor(sessionsDir?: string);
34
- /**
35
- * Create a new session
36
- *
37
- * @param options - Session creation options
38
- * @returns The created session
39
- */
40
- createSession(options?: CreateSessionOptions): Promise<Session>;
41
- /**
42
- * Get a session by ID
43
- *
44
- * @param sessionId - The session ID
45
- * @returns The session, or null if not found
46
- */
47
- getSession(sessionId: string): Promise<Session | null>;
48
- /**
49
- * Save a session to disk
50
- *
51
- * @param session - The session to save
52
- */
53
- saveSession(session: Session): Promise<void>;
54
- /**
55
- * Update a session
56
- *
57
- * @param sessionId - The session ID
58
- * @param updates - Partial session updates
59
- * @returns The updated session, or null if not found
60
- */
61
- updateSession(sessionId: string, updates: Partial<Omit<Session, 'id' | 'created'>>): Promise<Session | null>;
62
- /**
63
- * Delete a session
64
- *
65
- * @param sessionId - The session ID
66
- * @returns True if deleted, false if not found
67
- */
68
- deleteSession(sessionId: string): Promise<boolean>;
69
- /**
70
- * Add a message to a session
71
- *
72
- * @param sessionId - The session ID
73
- * @param role - Message role (user or assistant)
74
- * @param content - Message content
75
- * @returns The updated session, or null if session not found
76
- */
77
- addMessage(sessionId: string, role: 'user' | 'assistant', content: string): Promise<Session | null>;
78
- /**
79
- * List all sessions with optional filtering
80
- *
81
- * @param filter - Optional filter criteria
82
- * @returns Array of session metadata
83
- */
84
- listSessions(filter?: SessionFilter): Promise<SessionMetadata[]>;
85
- /**
86
- * Search sessions by keyword
87
- *
88
- * Searches in project name, description, tags, and message content
89
- *
90
- * @param keyword - Search keyword
91
- * @returns Array of matching session metadata
92
- */
93
- searchSessions(keyword: string): Promise<SessionMetadata[]>;
94
- /**
95
- * Get the most recent active session
96
- *
97
- * @returns The active session, or null if none exists
98
- */
99
- getActiveSession(): Promise<Session | null>;
100
- /**
101
- * Mark a session as completed
102
- *
103
- * @param sessionId - The session ID
104
- * @returns The updated session, or null if not found
105
- */
106
- completeSession(sessionId: string): Promise<Session | null>;
107
- /**
108
- * Mark a session as archived
109
- *
110
- * @param sessionId - The session ID
111
- * @returns The updated session, or null if not found
112
- */
113
- archiveSession(sessionId: string): Promise<Session | null>;
114
- /**
115
- * Get the path to a session file
116
- */
117
- private getSessionPath;
118
- /**
119
- * Generate a default project name based on timestamp
120
- */
121
- private generateDefaultProjectName;
122
- /**
123
- * Serialize a session for file storage
124
- */
125
- private serializeSession;
126
- /**
127
- * Deserialize a session from file storage
128
- */
129
- private deserializeSession;
130
- /**
131
- * Extract metadata from a serialized session
132
- */
133
- private extractMetadata;
134
- /**
135
- * Check if session metadata matches filter criteria
136
- */
137
- private matchesFilter;
138
- }
139
- //# sourceMappingURL=session-manager.d.ts.map