clavix 4.12.0 → 5.0.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.
- package/README.md +69 -61
- package/dist/cli/commands/init.js +54 -153
- package/dist/cli/commands/update.js +19 -21
- package/dist/templates/agents/agents.md +28 -26
- package/dist/templates/agents/copilot-instructions.md +42 -36
- package/dist/templates/agents/octo.md +41 -36
- package/dist/templates/agents/warp.md +24 -24
- package/dist/templates/instructions/README.md +8 -5
- package/dist/templates/slash-commands/_canonical/archive.md +83 -121
- package/dist/templates/slash-commands/_canonical/execute.md +32 -42
- package/dist/templates/slash-commands/_canonical/implement.md +32 -44
- package/dist/templates/slash-commands/_canonical/improve.md +13 -52
- package/dist/templates/slash-commands/_canonical/plan.md +8 -20
- package/dist/templates/slash-commands/_canonical/verify.md +9 -9
- package/dist/templates/slash-commands/_components/agent-protocols/assertion-checkpoints.md +1 -1
- package/dist/templates/slash-commands/_components/agent-protocols/cli-reference.md +84 -180
- package/dist/templates/slash-commands/_components/agent-protocols/decision-rules.md +5 -6
- package/dist/templates/slash-commands/_components/agent-protocols/error-handling.md +2 -2
- package/dist/templates/slash-commands/_components/agent-protocols/file-formats.md +41 -59
- package/dist/templates/slash-commands/_components/agent-protocols/state-awareness.md +5 -7
- package/dist/templates/slash-commands/_components/sections/file-saving-protocol.md +20 -27
- package/dist/templates/slash-commands/_components/troubleshooting/file-not-saved.md +4 -5
- package/dist/templates/slash-commands/_components/troubleshooting/vibecoder-recovery.md +2 -2
- package/dist/utils/agent-error-messages.js +13 -12
- package/package.json +2 -2
- package/dist/cli/commands/analyze.d.ts +0 -17
- package/dist/cli/commands/analyze.js +0 -133
- package/dist/cli/commands/archive.d.ts +0 -36
- package/dist/cli/commands/archive.js +0 -266
- package/dist/cli/commands/deep.d.ts +0 -17
- package/dist/cli/commands/deep.js +0 -170
- package/dist/cli/commands/execute.d.ts +0 -15
- package/dist/cli/commands/execute.js +0 -168
- package/dist/cli/commands/fast.d.ts +0 -18
- package/dist/cli/commands/fast.js +0 -219
- package/dist/cli/commands/implement.d.ts +0 -24
- package/dist/cli/commands/implement.js +0 -289
- package/dist/cli/commands/improve.d.ts +0 -32
- package/dist/cli/commands/improve.js +0 -250
- package/dist/cli/commands/list.d.ts +0 -17
- package/dist/cli/commands/list.js +0 -217
- package/dist/cli/commands/plan.d.ts +0 -21
- package/dist/cli/commands/plan.js +0 -297
- package/dist/cli/commands/prd.d.ts +0 -24
- package/dist/cli/commands/prd.js +0 -321
- package/dist/cli/commands/prompts/clear.d.ts +0 -16
- package/dist/cli/commands/prompts/clear.js +0 -222
- package/dist/cli/commands/prompts/list.d.ts +0 -8
- package/dist/cli/commands/prompts/list.js +0 -88
- package/dist/cli/commands/show.d.ts +0 -21
- package/dist/cli/commands/show.js +0 -191
- package/dist/cli/commands/start.d.ts +0 -40
- package/dist/cli/commands/start.js +0 -210
- package/dist/cli/commands/summarize.d.ts +0 -17
- package/dist/cli/commands/summarize.js +0 -196
- package/dist/cli/commands/task-complete.d.ts +0 -27
- package/dist/cli/commands/task-complete.js +0 -269
- package/dist/cli/commands/verify.d.ts +0 -28
- package/dist/cli/commands/verify.js +0 -349
- package/dist/core/archive-manager.d.ts +0 -100
- package/dist/core/archive-manager.js +0 -302
- package/dist/core/basic-checklist-generator.d.ts +0 -35
- package/dist/core/basic-checklist-generator.js +0 -344
- package/dist/core/checklist-parser.d.ts +0 -48
- package/dist/core/checklist-parser.js +0 -238
- package/dist/core/config-manager.d.ts +0 -149
- package/dist/core/config-manager.js +0 -230
- package/dist/core/conversation-analyzer.d.ts +0 -86
- package/dist/core/conversation-analyzer.js +0 -387
- package/dist/core/conversation-quality-tracker.d.ts +0 -81
- package/dist/core/conversation-quality-tracker.js +0 -195
- package/dist/core/git-manager.d.ts +0 -126
- package/dist/core/git-manager.js +0 -282
- package/dist/core/intelligence/confidence-calculator.d.ts +0 -93
- package/dist/core/intelligence/confidence-calculator.js +0 -124
- package/dist/core/intelligence/index.d.ts +0 -11
- package/dist/core/intelligence/index.js +0 -15
- package/dist/core/intelligence/intent-detector.d.ts +0 -54
- package/dist/core/intelligence/intent-detector.js +0 -723
- package/dist/core/intelligence/pattern-library.d.ts +0 -104
- package/dist/core/intelligence/pattern-library.js +0 -330
- package/dist/core/intelligence/patterns/actionability-enhancer.d.ts +0 -27
- package/dist/core/intelligence/patterns/actionability-enhancer.js +0 -192
- package/dist/core/intelligence/patterns/alternative-phrasing-generator.d.ts +0 -29
- package/dist/core/intelligence/patterns/alternative-phrasing-generator.js +0 -239
- package/dist/core/intelligence/patterns/ambiguity-detector.d.ts +0 -22
- package/dist/core/intelligence/patterns/ambiguity-detector.js +0 -196
- package/dist/core/intelligence/patterns/assumption-explicitizer.d.ts +0 -30
- package/dist/core/intelligence/patterns/assumption-explicitizer.js +0 -296
- package/dist/core/intelligence/patterns/base-pattern.d.ts +0 -192
- package/dist/core/intelligence/patterns/base-pattern.js +0 -103
- package/dist/core/intelligence/patterns/completeness-validator.d.ts +0 -27
- package/dist/core/intelligence/patterns/completeness-validator.js +0 -221
- package/dist/core/intelligence/patterns/conciseness-filter.d.ts +0 -20
- package/dist/core/intelligence/patterns/conciseness-filter.js +0 -92
- package/dist/core/intelligence/patterns/context-precision.d.ts +0 -32
- package/dist/core/intelligence/patterns/context-precision.js +0 -389
- package/dist/core/intelligence/patterns/conversation-summarizer.d.ts +0 -30
- package/dist/core/intelligence/patterns/conversation-summarizer.js +0 -277
- package/dist/core/intelligence/patterns/dependency-identifier.d.ts +0 -23
- package/dist/core/intelligence/patterns/dependency-identifier.js +0 -166
- package/dist/core/intelligence/patterns/domain-context-enricher.d.ts +0 -21
- package/dist/core/intelligence/patterns/domain-context-enricher.js +0 -198
- package/dist/core/intelligence/patterns/edge-case-identifier.d.ts +0 -30
- package/dist/core/intelligence/patterns/edge-case-identifier.js +0 -269
- package/dist/core/intelligence/patterns/error-tolerance-enhancer.d.ts +0 -22
- package/dist/core/intelligence/patterns/error-tolerance-enhancer.js +0 -179
- package/dist/core/intelligence/patterns/implicit-requirement-extractor.d.ts +0 -24
- package/dist/core/intelligence/patterns/implicit-requirement-extractor.js +0 -259
- package/dist/core/intelligence/patterns/objective-clarifier.d.ts +0 -22
- package/dist/core/intelligence/patterns/objective-clarifier.js +0 -126
- package/dist/core/intelligence/patterns/output-format-enforcer.d.ts +0 -22
- package/dist/core/intelligence/patterns/output-format-enforcer.js +0 -151
- package/dist/core/intelligence/patterns/prd-structure-enforcer.d.ts +0 -23
- package/dist/core/intelligence/patterns/prd-structure-enforcer.js +0 -183
- package/dist/core/intelligence/patterns/prerequisite-identifier.d.ts +0 -23
- package/dist/core/intelligence/patterns/prerequisite-identifier.js +0 -221
- package/dist/core/intelligence/patterns/requirement-prioritizer.d.ts +0 -24
- package/dist/core/intelligence/patterns/requirement-prioritizer.js +0 -134
- package/dist/core/intelligence/patterns/scope-definer.d.ts +0 -26
- package/dist/core/intelligence/patterns/scope-definer.js +0 -236
- package/dist/core/intelligence/patterns/step-decomposer.d.ts +0 -31
- package/dist/core/intelligence/patterns/step-decomposer.js +0 -242
- package/dist/core/intelligence/patterns/structure-organizer.d.ts +0 -31
- package/dist/core/intelligence/patterns/structure-organizer.js +0 -218
- package/dist/core/intelligence/patterns/success-criteria-enforcer.d.ts +0 -22
- package/dist/core/intelligence/patterns/success-criteria-enforcer.js +0 -165
- package/dist/core/intelligence/patterns/success-metrics-enforcer.d.ts +0 -24
- package/dist/core/intelligence/patterns/success-metrics-enforcer.js +0 -165
- package/dist/core/intelligence/patterns/technical-context-enricher.d.ts +0 -25
- package/dist/core/intelligence/patterns/technical-context-enricher.js +0 -165
- package/dist/core/intelligence/patterns/topic-coherence-analyzer.d.ts +0 -26
- package/dist/core/intelligence/patterns/topic-coherence-analyzer.js +0 -300
- package/dist/core/intelligence/patterns/user-persona-enricher.d.ts +0 -24
- package/dist/core/intelligence/patterns/user-persona-enricher.js +0 -141
- package/dist/core/intelligence/patterns/validation-checklist-creator.d.ts +0 -31
- package/dist/core/intelligence/patterns/validation-checklist-creator.js +0 -242
- package/dist/core/intelligence/quality-assessor.d.ts +0 -71
- package/dist/core/intelligence/quality-assessor.js +0 -525
- package/dist/core/intelligence/types.d.ts +0 -111
- package/dist/core/intelligence/types.js +0 -3
- package/dist/core/intelligence/universal-optimizer.d.ts +0 -91
- package/dist/core/intelligence/universal-optimizer.js +0 -399
- package/dist/core/prd-generator.d.ts +0 -76
- package/dist/core/prd-generator.js +0 -173
- package/dist/core/prompt-manager.d.ts +0 -110
- package/dist/core/prompt-manager.js +0 -274
- package/dist/core/prompt-optimizer.d.ts +0 -268
- package/dist/core/prompt-optimizer.js +0 -959
- package/dist/core/question-engine.d.ts +0 -167
- package/dist/core/question-engine.js +0 -356
- package/dist/core/session-manager.d.ts +0 -139
- package/dist/core/session-manager.js +0 -365
- package/dist/core/task-manager.d.ts +0 -211
- package/dist/core/task-manager.js +0 -981
- package/dist/core/verification-hooks.d.ts +0 -67
- package/dist/core/verification-hooks.js +0 -309
- package/dist/core/verification-manager.d.ts +0 -107
- package/dist/core/verification-manager.js +0 -415
- package/dist/types/session.d.ts +0 -78
- package/dist/types/session.js +0 -8
- package/dist/types/verification.d.ts +0 -205
- package/dist/types/verification.js +0 -9
|
@@ -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,356 +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
|
-
import fs from 'fs-extra';
|
|
11
|
-
import * as path from 'path';
|
|
12
|
-
/**
|
|
13
|
-
* QuestionEngine class
|
|
14
|
-
*
|
|
15
|
-
* Manages the flow of questions, answer collection, and validation
|
|
16
|
-
*/
|
|
17
|
-
export class QuestionEngine {
|
|
18
|
-
currentFlow = null;
|
|
19
|
-
answers = {};
|
|
20
|
-
currentQuestionIndex = 0;
|
|
21
|
-
/**
|
|
22
|
-
* Load a question flow from a template file
|
|
23
|
-
*
|
|
24
|
-
* @param templatePath - Path to the question template
|
|
25
|
-
* @returns The loaded question flow
|
|
26
|
-
*/
|
|
27
|
-
async loadFlow(templatePath) {
|
|
28
|
-
const fullPath = path.resolve(templatePath);
|
|
29
|
-
if (!await fs.pathExists(fullPath)) {
|
|
30
|
-
throw new Error(`Question template not found: ${templatePath}`);
|
|
31
|
-
}
|
|
32
|
-
const content = await fs.readFile(fullPath, 'utf-8');
|
|
33
|
-
const flow = this.parseTemplate(content);
|
|
34
|
-
this.currentFlow = flow;
|
|
35
|
-
this.answers = {};
|
|
36
|
-
this.currentQuestionIndex = 0;
|
|
37
|
-
return flow;
|
|
38
|
-
}
|
|
39
|
-
/**
|
|
40
|
-
* Parse a question template into a QuestionFlow
|
|
41
|
-
*
|
|
42
|
-
* Template format:
|
|
43
|
-
* ```markdown
|
|
44
|
-
* # Flow Name
|
|
45
|
-
*
|
|
46
|
-
* Flow description
|
|
47
|
-
*
|
|
48
|
-
* ## Question 1
|
|
49
|
-
*
|
|
50
|
-
* **text:** What problem are you solving?
|
|
51
|
-
* **type:** text
|
|
52
|
-
* **required:** true
|
|
53
|
-
* **validation:** minLength:10
|
|
54
|
-
*
|
|
55
|
-
* ## Question 2
|
|
56
|
-
*
|
|
57
|
-
* **text:** Select your technology stack
|
|
58
|
-
* **type:** list
|
|
59
|
-
* **choices:** React, Vue, Angular, Other
|
|
60
|
-
* ```
|
|
61
|
-
*
|
|
62
|
-
* @param template - Template content
|
|
63
|
-
* @returns Parsed QuestionFlow
|
|
64
|
-
*/
|
|
65
|
-
parseTemplate(template) {
|
|
66
|
-
const lines = template.split('\n');
|
|
67
|
-
const questions = [];
|
|
68
|
-
let name = 'Default Flow';
|
|
69
|
-
let description = '';
|
|
70
|
-
let currentQuestion = null;
|
|
71
|
-
for (let i = 0; i < lines.length; i++) {
|
|
72
|
-
const line = lines[i].trim();
|
|
73
|
-
// Skip empty lines
|
|
74
|
-
if (!line) {
|
|
75
|
-
continue;
|
|
76
|
-
}
|
|
77
|
-
// Extract flow name from first h1
|
|
78
|
-
if (line.startsWith('# ') && name === 'Default Flow') {
|
|
79
|
-
name = line.substring(2).trim();
|
|
80
|
-
continue;
|
|
81
|
-
}
|
|
82
|
-
// Extract description (first non-heading paragraph)
|
|
83
|
-
if (line && !line.startsWith('#') && !line.startsWith('**') && !description) {
|
|
84
|
-
description = line;
|
|
85
|
-
continue;
|
|
86
|
-
}
|
|
87
|
-
// Start new question on h2
|
|
88
|
-
if (line.startsWith('## ')) {
|
|
89
|
-
// Save previous question if exists
|
|
90
|
-
if (currentQuestion && currentQuestion.text) {
|
|
91
|
-
questions.push(this.finalizeQuestion(currentQuestion, questions.length));
|
|
92
|
-
}
|
|
93
|
-
// Start new question
|
|
94
|
-
currentQuestion = {};
|
|
95
|
-
continue;
|
|
96
|
-
}
|
|
97
|
-
// Parse question metadata: **key:** value
|
|
98
|
-
const metadataMatch = line.match(/^\*\*(\w+):\*\*\s*(.+)$/);
|
|
99
|
-
if (metadataMatch && currentQuestion) {
|
|
100
|
-
const [, key, value] = metadataMatch;
|
|
101
|
-
this.parseQuestionMetadata(currentQuestion, key, value);
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
// Save last question
|
|
105
|
-
if (currentQuestion && currentQuestion.text) {
|
|
106
|
-
questions.push(this.finalizeQuestion(currentQuestion, questions.length));
|
|
107
|
-
}
|
|
108
|
-
return { name, description, questions };
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* Parse a single metadata field for a question
|
|
112
|
-
*/
|
|
113
|
-
parseQuestionMetadata(question, key, value) {
|
|
114
|
-
switch (key.toLowerCase()) {
|
|
115
|
-
case 'text':
|
|
116
|
-
question.text = value;
|
|
117
|
-
break;
|
|
118
|
-
case 'type':
|
|
119
|
-
if (value === 'text' || value === 'list' || value === 'confirm') {
|
|
120
|
-
question.type = value;
|
|
121
|
-
}
|
|
122
|
-
break;
|
|
123
|
-
case 'required':
|
|
124
|
-
question.required = value.toLowerCase() === 'true';
|
|
125
|
-
break;
|
|
126
|
-
case 'choices':
|
|
127
|
-
question.choices = value.split(',').map((c) => c.trim());
|
|
128
|
-
break;
|
|
129
|
-
case 'default':
|
|
130
|
-
if (question.type === 'confirm') {
|
|
131
|
-
question.default = value.toLowerCase() === 'true';
|
|
132
|
-
}
|
|
133
|
-
else {
|
|
134
|
-
question.default = value;
|
|
135
|
-
}
|
|
136
|
-
break;
|
|
137
|
-
case 'validation':
|
|
138
|
-
question.validate = this.createValidator(value);
|
|
139
|
-
break;
|
|
140
|
-
case 'condition':
|
|
141
|
-
question.condition = this.createCondition(value);
|
|
142
|
-
break;
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
/**
|
|
146
|
-
* Finalize a question by setting defaults and generating ID
|
|
147
|
-
*/
|
|
148
|
-
finalizeQuestion(partial, index) {
|
|
149
|
-
return {
|
|
150
|
-
id: `q${index + 1}`,
|
|
151
|
-
text: partial.text || '',
|
|
152
|
-
type: partial.type || 'text',
|
|
153
|
-
required: partial.required !== undefined ? partial.required : true,
|
|
154
|
-
choices: partial.choices,
|
|
155
|
-
default: partial.default,
|
|
156
|
-
validate: partial.validate,
|
|
157
|
-
condition: partial.condition,
|
|
158
|
-
};
|
|
159
|
-
}
|
|
160
|
-
/**
|
|
161
|
-
* Create a validation function from a validation string
|
|
162
|
-
*
|
|
163
|
-
* Supported formats:
|
|
164
|
-
* - minLength:10 - Minimum length
|
|
165
|
-
* - maxLength:100 - Maximum length
|
|
166
|
-
* - pattern:^[a-z]+$ - Regex pattern
|
|
167
|
-
* - email - Email validation
|
|
168
|
-
* - url - URL validation
|
|
169
|
-
*/
|
|
170
|
-
createValidator(validationStr) {
|
|
171
|
-
const parts = validationStr.split(':');
|
|
172
|
-
const type = parts[0].toLowerCase();
|
|
173
|
-
const param = parts[1];
|
|
174
|
-
return (answer) => {
|
|
175
|
-
switch (type) {
|
|
176
|
-
case 'minlength':
|
|
177
|
-
if (answer.length < parseInt(param, 10)) {
|
|
178
|
-
return `Minimum length is ${param} characters`;
|
|
179
|
-
}
|
|
180
|
-
break;
|
|
181
|
-
case 'maxlength':
|
|
182
|
-
if (answer.length > parseInt(param, 10)) {
|
|
183
|
-
return `Maximum length is ${param} characters`;
|
|
184
|
-
}
|
|
185
|
-
break;
|
|
186
|
-
case 'pattern':
|
|
187
|
-
if (!new RegExp(param).test(answer)) {
|
|
188
|
-
return 'Answer does not match required format';
|
|
189
|
-
}
|
|
190
|
-
break;
|
|
191
|
-
case 'email':
|
|
192
|
-
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(answer)) {
|
|
193
|
-
return 'Please enter a valid email address';
|
|
194
|
-
}
|
|
195
|
-
break;
|
|
196
|
-
case 'url':
|
|
197
|
-
try {
|
|
198
|
-
new URL(answer);
|
|
199
|
-
}
|
|
200
|
-
catch {
|
|
201
|
-
return 'Please enter a valid URL';
|
|
202
|
-
}
|
|
203
|
-
break;
|
|
204
|
-
}
|
|
205
|
-
return true;
|
|
206
|
-
};
|
|
207
|
-
}
|
|
208
|
-
/**
|
|
209
|
-
* Create a condition function from a condition string
|
|
210
|
-
*
|
|
211
|
-
* Supported formats:
|
|
212
|
-
* - q1=true - Question 1 answer equals true
|
|
213
|
-
* - q2=JWT - Question 2 answer equals "JWT"
|
|
214
|
-
* - q3!=None - Question 3 answer not equals "None"
|
|
215
|
-
*/
|
|
216
|
-
createCondition(conditionStr) {
|
|
217
|
-
const match = conditionStr.match(/^(\w+)\s*(=|!=)\s*(.+)$/);
|
|
218
|
-
if (!match) {
|
|
219
|
-
return () => true;
|
|
220
|
-
}
|
|
221
|
-
const [, questionId, operator, expectedValue] = match;
|
|
222
|
-
return (answers) => {
|
|
223
|
-
const actualValue = answers[questionId];
|
|
224
|
-
// Convert expected value to proper type
|
|
225
|
-
let expected = expectedValue;
|
|
226
|
-
if (expectedValue.toLowerCase() === 'true') {
|
|
227
|
-
expected = true;
|
|
228
|
-
}
|
|
229
|
-
else if (expectedValue.toLowerCase() === 'false') {
|
|
230
|
-
expected = false;
|
|
231
|
-
}
|
|
232
|
-
if (operator === '=') {
|
|
233
|
-
return actualValue === expected;
|
|
234
|
-
}
|
|
235
|
-
else {
|
|
236
|
-
return actualValue !== expected;
|
|
237
|
-
}
|
|
238
|
-
};
|
|
239
|
-
}
|
|
240
|
-
/**
|
|
241
|
-
* Get the next question in the flow
|
|
242
|
-
*
|
|
243
|
-
* @returns The next question, or null if flow is complete
|
|
244
|
-
*/
|
|
245
|
-
getNextQuestion() {
|
|
246
|
-
if (!this.currentFlow) {
|
|
247
|
-
throw new Error('No question flow loaded');
|
|
248
|
-
}
|
|
249
|
-
// Find the next unanswered question that meets its condition
|
|
250
|
-
while (this.currentQuestionIndex < this.currentFlow.questions.length) {
|
|
251
|
-
const question = this.currentFlow.questions[this.currentQuestionIndex];
|
|
252
|
-
// Skip if already answered
|
|
253
|
-
if (question.id in this.answers) {
|
|
254
|
-
this.currentQuestionIndex++;
|
|
255
|
-
continue;
|
|
256
|
-
}
|
|
257
|
-
// Check if question condition is met (if it has one)
|
|
258
|
-
if (question.condition && !question.condition(this.answers)) {
|
|
259
|
-
this.currentQuestionIndex++;
|
|
260
|
-
continue;
|
|
261
|
-
}
|
|
262
|
-
return question;
|
|
263
|
-
}
|
|
264
|
-
return null;
|
|
265
|
-
}
|
|
266
|
-
/**
|
|
267
|
-
* Submit an answer to the current question
|
|
268
|
-
*
|
|
269
|
-
* @param questionId - ID of the question being answered
|
|
270
|
-
* @param answer - The answer
|
|
271
|
-
* @returns Validation result (true if valid, error message if invalid)
|
|
272
|
-
*/
|
|
273
|
-
submitAnswer(questionId, answer) {
|
|
274
|
-
if (!this.currentFlow) {
|
|
275
|
-
throw new Error('No question flow loaded');
|
|
276
|
-
}
|
|
277
|
-
const question = this.currentFlow.questions.find((q) => q.id === questionId);
|
|
278
|
-
if (!question) {
|
|
279
|
-
throw new Error(`Question not found: ${questionId}`);
|
|
280
|
-
}
|
|
281
|
-
// Validate required fields (but allow false for boolean answers)
|
|
282
|
-
if (question.required && (answer === '' || answer === null || answer === undefined)) {
|
|
283
|
-
return 'This question is required';
|
|
284
|
-
}
|
|
285
|
-
// Run custom validation if provided
|
|
286
|
-
if (question.validate) {
|
|
287
|
-
const validationResult = question.validate(String(answer));
|
|
288
|
-
if (validationResult !== true) {
|
|
289
|
-
return validationResult;
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
// Store the answer
|
|
293
|
-
this.answers[questionId] = answer;
|
|
294
|
-
this.currentQuestionIndex++;
|
|
295
|
-
return true;
|
|
296
|
-
}
|
|
297
|
-
/**
|
|
298
|
-
* Get all collected answers
|
|
299
|
-
*
|
|
300
|
-
* @returns All answers collected so far
|
|
301
|
-
*/
|
|
302
|
-
getAnswers() {
|
|
303
|
-
return { ...this.answers };
|
|
304
|
-
}
|
|
305
|
-
/**
|
|
306
|
-
* Get current progress through the question flow
|
|
307
|
-
*
|
|
308
|
-
* @returns Progress information
|
|
309
|
-
*/
|
|
310
|
-
getProgress() {
|
|
311
|
-
if (!this.currentFlow) {
|
|
312
|
-
return { current: 0, total: 0, percentage: 0 };
|
|
313
|
-
}
|
|
314
|
-
const total = this.currentFlow.questions.length;
|
|
315
|
-
const current = Object.keys(this.answers).length;
|
|
316
|
-
const percentage = total > 0 ? Math.round((current / total) * 100) : 0;
|
|
317
|
-
return { current, total, percentage };
|
|
318
|
-
}
|
|
319
|
-
/**
|
|
320
|
-
* Check if the question flow is complete
|
|
321
|
-
*
|
|
322
|
-
* @returns True if all required questions are answered
|
|
323
|
-
*/
|
|
324
|
-
isComplete() {
|
|
325
|
-
if (!this.currentFlow) {
|
|
326
|
-
return false;
|
|
327
|
-
}
|
|
328
|
-
// Check if all required questions have answers
|
|
329
|
-
for (const question of this.currentFlow.questions) {
|
|
330
|
-
// Skip if condition not met
|
|
331
|
-
if (question.condition && !question.condition(this.answers)) {
|
|
332
|
-
continue;
|
|
333
|
-
}
|
|
334
|
-
if (question.required && !(question.id in this.answers)) {
|
|
335
|
-
return false;
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
return true;
|
|
339
|
-
}
|
|
340
|
-
/**
|
|
341
|
-
* Reset the question flow
|
|
342
|
-
*/
|
|
343
|
-
reset() {
|
|
344
|
-
this.answers = {};
|
|
345
|
-
this.currentQuestionIndex = 0;
|
|
346
|
-
}
|
|
347
|
-
/**
|
|
348
|
-
* Get the current question flow
|
|
349
|
-
*
|
|
350
|
-
* @returns The loaded question flow, or null if none loaded
|
|
351
|
-
*/
|
|
352
|
-
getCurrentFlow() {
|
|
353
|
-
return this.currentFlow;
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
//# sourceMappingURL=question-engine.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.js';
|
|
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
|