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.
- package/README.md +22 -8
- package/bin/clavix.js +12 -5
- package/dist/cli/commands/archive.d.ts +5 -4
- package/dist/cli/commands/archive.js +135 -161
- package/dist/cli/commands/config.d.ts +4 -4
- package/dist/cli/commands/config.js +66 -105
- package/dist/cli/commands/deep.d.ts +3 -3
- package/dist/cli/commands/deep.js +97 -103
- package/dist/cli/commands/execute.d.ts +4 -4
- package/dist/cli/commands/execute.js +57 -63
- package/dist/cli/commands/fast.d.ts +3 -3
- package/dist/cli/commands/fast.js +122 -128
- package/dist/cli/commands/implement.d.ts +4 -4
- package/dist/cli/commands/implement.js +84 -148
- package/dist/cli/commands/init.js +87 -126
- package/dist/cli/commands/list.d.ts +5 -5
- package/dist/cli/commands/list.js +72 -111
- package/dist/cli/commands/plan.d.ts +7 -7
- package/dist/cli/commands/plan.js +92 -131
- package/dist/cli/commands/prd.d.ts +4 -4
- package/dist/cli/commands/prd.js +76 -111
- package/dist/cli/commands/prompts/clear.d.ts +6 -6
- package/dist/cli/commands/prompts/clear.js +70 -76
- package/dist/cli/commands/prompts/list.js +37 -43
- package/dist/cli/commands/show.d.ts +4 -4
- package/dist/cli/commands/show.js +72 -111
- package/dist/cli/commands/start.d.ts +3 -3
- package/dist/cli/commands/start.js +63 -101
- package/dist/cli/commands/summarize.d.ts +4 -4
- package/dist/cli/commands/summarize.js +81 -120
- package/dist/cli/commands/task-complete.d.ts +4 -4
- package/dist/cli/commands/task-complete.js +86 -123
- package/dist/cli/commands/update.d.ts +3 -3
- package/dist/cli/commands/update.js +97 -130
- package/dist/cli/commands/version.js +13 -48
- package/dist/core/adapters/agents-md-generator.js +17 -50
- package/dist/core/adapters/amp-adapter.d.ts +1 -1
- package/dist/core/adapters/amp-adapter.js +13 -21
- package/dist/core/adapters/augment-adapter.d.ts +2 -2
- package/dist/core/adapters/augment-adapter.js +16 -56
- package/dist/core/adapters/base-adapter.d.ts +1 -1
- package/dist/core/adapters/base-adapter.js +11 -47
- package/dist/core/adapters/claude-code-adapter.d.ts +2 -2
- package/dist/core/adapters/claude-code-adapter.js +19 -60
- package/dist/core/adapters/cline-adapter.d.ts +1 -1
- package/dist/core/adapters/cline-adapter.js +13 -21
- package/dist/core/adapters/codebuddy-adapter.d.ts +2 -2
- package/dist/core/adapters/codebuddy-adapter.js +17 -57
- package/dist/core/adapters/codex-adapter.d.ts +2 -2
- package/dist/core/adapters/codex-adapter.js +16 -56
- package/dist/core/adapters/copilot-instructions-generator.js +18 -51
- package/dist/core/adapters/crush-adapter.d.ts +2 -2
- package/dist/core/adapters/crush-adapter.js +13 -20
- package/dist/core/adapters/cursor-adapter.d.ts +1 -1
- package/dist/core/adapters/cursor-adapter.js +12 -20
- package/dist/core/adapters/droid-adapter.d.ts +2 -2
- package/dist/core/adapters/droid-adapter.js +14 -21
- package/dist/core/adapters/gemini-adapter.d.ts +2 -2
- package/dist/core/adapters/gemini-adapter.js +16 -52
- package/dist/core/adapters/kilocode-adapter.d.ts +1 -1
- package/dist/core/adapters/kilocode-adapter.js +12 -20
- package/dist/core/adapters/octo-md-generator.js +17 -50
- package/dist/core/adapters/opencode-adapter.d.ts +2 -2
- package/dist/core/adapters/opencode-adapter.js +14 -21
- package/dist/core/adapters/qwen-adapter.d.ts +2 -2
- package/dist/core/adapters/qwen-adapter.js +16 -52
- package/dist/core/adapters/roocode-adapter.d.ts +2 -2
- package/dist/core/adapters/roocode-adapter.js +12 -19
- package/dist/core/adapters/warp-md-generator.js +17 -50
- package/dist/core/adapters/windsurf-adapter.d.ts +1 -1
- package/dist/core/adapters/windsurf-adapter.js +12 -20
- package/dist/core/agent-manager.d.ts +1 -1
- package/dist/core/agent-manager.js +34 -38
- package/dist/core/archive-manager.js +10 -46
- package/dist/core/config-manager.d.ts +2 -2
- package/dist/core/config-manager.js +3 -40
- package/dist/core/conversation-analyzer.d.ts +1 -1
- package/dist/core/conversation-analyzer.js +1 -5
- package/dist/core/doc-injector.js +23 -60
- package/dist/core/git-manager.js +11 -48
- package/dist/core/prd-generator.js +16 -51
- package/dist/core/prompt-manager.js +6 -42
- package/dist/core/prompt-optimizer.js +1 -5
- package/dist/core/question-engine.js +6 -45
- package/dist/core/session-manager.d.ts +1 -1
- package/dist/core/session-manager.js +11 -49
- package/dist/core/task-manager.d.ts +26 -0
- package/dist/core/task-manager.js +243 -101
- package/dist/index.d.ts +2 -1
- package/dist/index.js +8 -12
- package/dist/templates/agents/agents.md +31 -2
- package/dist/templates/agents/copilot-instructions.md +1 -1
- package/dist/templates/agents/octo.md +20 -1
- package/dist/templates/agents/warp.md +1 -1
- package/dist/templates/slash-commands/_canonical/implement.md +33 -11
- package/dist/types/agent.js +1 -2
- package/dist/types/config.js +3 -8
- package/dist/types/errors.js +7 -13
- package/dist/types/session.js +1 -2
- package/dist/utils/agent-error-messages.js +1 -5
- package/dist/utils/error-utils.js +5 -12
- package/dist/utils/file-system.js +20 -57
- package/dist/utils/legacy-command-cleanup.d.ts +1 -1
- package/dist/utils/legacy-command-cleanup.js +9 -45
- package/dist/utils/template-loader.d.ts +1 -1
- package/dist/utils/template-loader.js +9 -41
- package/dist/utils/toml-templates.js +1 -4
- package/package.json +12 -7
- package/dist/core/adapters 2/agents-md-generator.d.ts +0 -26
- package/dist/core/adapters 2/agents-md-generator.js +0 -102
- package/dist/core/adapters 2/amp-adapter.d.ts +0 -27
- package/dist/core/adapters 2/amp-adapter.js +0 -42
- package/dist/core/adapters 2/augment-adapter.d.ts +0 -22
- package/dist/core/adapters 2/augment-adapter.js +0 -77
- package/dist/core/adapters 2/base-adapter.d.ts +0 -45
- package/dist/core/adapters 2/base-adapter.js +0 -142
- package/dist/core/adapters 2/claude-code-adapter.d.ts +0 -32
- package/dist/core/adapters 2/claude-code-adapter.js +0 -116
- package/dist/core/adapters 2/cline-adapter.d.ts +0 -34
- package/dist/core/adapters 2/cline-adapter.js +0 -52
- package/dist/core/adapters 2/codebuddy-adapter.d.ts +0 -24
- package/dist/core/adapters 2/codebuddy-adapter.js +0 -82
- package/dist/core/adapters 2/codex-adapter.d.ts +0 -24
- package/dist/core/adapters 2/codex-adapter.js +0 -79
- package/dist/core/adapters 2/copilot-instructions-generator.d.ts +0 -26
- package/dist/core/adapters 2/copilot-instructions-generator.js +0 -104
- package/dist/core/adapters 2/crush-adapter.d.ts +0 -35
- package/dist/core/adapters 2/crush-adapter.js +0 -49
- package/dist/core/adapters 2/cursor-adapter.d.ts +0 -25
- package/dist/core/adapters 2/cursor-adapter.js +0 -40
- package/dist/core/adapters 2/droid-adapter.d.ts +0 -33
- package/dist/core/adapters 2/droid-adapter.js +0 -57
- package/dist/core/adapters 2/gemini-adapter.d.ts +0 -27
- package/dist/core/adapters 2/gemini-adapter.js +0 -90
- package/dist/core/adapters 2/kilocode-adapter.d.ts +0 -34
- package/dist/core/adapters 2/kilocode-adapter.js +0 -49
- package/dist/core/adapters 2/octo-md-generator.d.ts +0 -26
- package/dist/core/adapters 2/octo-md-generator.js +0 -102
- package/dist/core/adapters 2/opencode-adapter.d.ts +0 -33
- package/dist/core/adapters 2/opencode-adapter.js +0 -56
- package/dist/core/adapters 2/qwen-adapter.d.ts +0 -27
- package/dist/core/adapters 2/qwen-adapter.js +0 -90
- package/dist/core/adapters 2/roocode-adapter.d.ts +0 -40
- package/dist/core/adapters 2/roocode-adapter.js +0 -68
- package/dist/core/adapters 2/warp-md-generator.d.ts +0 -17
- package/dist/core/adapters 2/warp-md-generator.js +0 -88
- package/dist/core/adapters 2/windsurf-adapter.d.ts +0 -34
- package/dist/core/adapters 2/windsurf-adapter.js +0 -49
- package/dist/core/agent-manager 2.js +0 -126
- package/dist/core/agent-manager.d 2.ts +0 -51
- package/dist/core/archive-manager 2.js +0 -338
- package/dist/core/archive-manager.d 2.ts +0 -100
- package/dist/core/conversation-analyzer.d 2.ts +0 -86
- package/dist/core/doc-injector 2.js +0 -236
- package/dist/core/doc-injector.d 2.ts +0 -51
- package/dist/core/git-manager 2.js +0 -214
- package/dist/core/git-manager.d 2.ts +0 -100
- package/dist/core/prompt-optimizer 2.js +0 -963
- package/dist/core/prompt-optimizer.d 2.ts +0 -268
- package/dist/core/question-engine 2.js +0 -395
- package/dist/core/question-engine.d 2.ts +0 -167
- package/dist/core/session-manager 2.js +0 -403
- package/dist/core/session-manager.d 2.ts +0 -139
- package/dist/core/task-manager 2.js +0 -689
- package/dist/core/task-manager.d 2.ts +0 -155
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ArchiveManager - Manages archival of completed PRD projects
|
|
3
|
-
*
|
|
4
|
-
* This class handles:
|
|
5
|
-
* - Listing active and archived PRD projects
|
|
6
|
-
* - Checking task completion status
|
|
7
|
-
* - Moving completed projects to archive
|
|
8
|
-
* - Managing archive directory structure
|
|
9
|
-
*/
|
|
10
|
-
/**
|
|
11
|
-
* Status of a PRD project's tasks
|
|
12
|
-
*/
|
|
13
|
-
export interface TaskStatus {
|
|
14
|
-
hasTasksFile: boolean;
|
|
15
|
-
total: number;
|
|
16
|
-
completed: number;
|
|
17
|
-
remaining: number;
|
|
18
|
-
percentage: number;
|
|
19
|
-
allCompleted: boolean;
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Information about a PRD project
|
|
23
|
-
*/
|
|
24
|
-
export interface PrdProject {
|
|
25
|
-
name: string;
|
|
26
|
-
path: string;
|
|
27
|
-
taskStatus: TaskStatus;
|
|
28
|
-
modifiedTime: Date;
|
|
29
|
-
isArchived: boolean;
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* ArchiveManager class
|
|
33
|
-
*
|
|
34
|
-
* Manages archival of completed PRD projects
|
|
35
|
-
*/
|
|
36
|
-
export declare class ArchiveManager {
|
|
37
|
-
private readonly taskManager;
|
|
38
|
-
private readonly outputsDir;
|
|
39
|
-
private readonly archiveDir;
|
|
40
|
-
constructor();
|
|
41
|
-
/**
|
|
42
|
-
* List all PRD projects in outputs directory
|
|
43
|
-
*
|
|
44
|
-
* @param includeArchived - Include archived projects in results
|
|
45
|
-
* @returns Array of PRD projects
|
|
46
|
-
*/
|
|
47
|
-
listPrdProjects(includeArchived?: boolean): Promise<PrdProject[]>;
|
|
48
|
-
/**
|
|
49
|
-
* List archived PRD projects
|
|
50
|
-
*
|
|
51
|
-
* @returns Array of archived PRD projects
|
|
52
|
-
*/
|
|
53
|
-
listArchivedProjects(): Promise<PrdProject[]>;
|
|
54
|
-
/**
|
|
55
|
-
* Get PRD projects that are ready to archive (all tasks completed)
|
|
56
|
-
*
|
|
57
|
-
* @returns Array of archivable PRD projects
|
|
58
|
-
*/
|
|
59
|
-
getArchivablePrds(): Promise<PrdProject[]>;
|
|
60
|
-
/**
|
|
61
|
-
* Check task completion status for a PRD project
|
|
62
|
-
*
|
|
63
|
-
* @param projectPath - Path to the PRD project directory
|
|
64
|
-
* @returns Task status information
|
|
65
|
-
*/
|
|
66
|
-
checkTasksStatus(projectPath: string): Promise<TaskStatus>;
|
|
67
|
-
/**
|
|
68
|
-
* Archive a PRD project (move to archive directory)
|
|
69
|
-
*
|
|
70
|
-
* @param projectName - Name of the project to archive
|
|
71
|
-
* @param force - Force archive even if tasks are incomplete
|
|
72
|
-
* @returns Success status and message
|
|
73
|
-
*/
|
|
74
|
-
archiveProject(projectName: string, force?: boolean): Promise<{
|
|
75
|
-
success: boolean;
|
|
76
|
-
message: string;
|
|
77
|
-
}>;
|
|
78
|
-
/**
|
|
79
|
-
* Restore an archived project back to active outputs
|
|
80
|
-
*
|
|
81
|
-
* @param projectName - Name of the archived project to restore
|
|
82
|
-
* @returns Success status and message
|
|
83
|
-
*/
|
|
84
|
-
restoreProject(projectName: string): Promise<{
|
|
85
|
-
success: boolean;
|
|
86
|
-
message: string;
|
|
87
|
-
}>;
|
|
88
|
-
/**
|
|
89
|
-
* Check if a directory contains a PRD file
|
|
90
|
-
*/
|
|
91
|
-
private hasPrdFile;
|
|
92
|
-
/**
|
|
93
|
-
* Get incomplete tasks for a project (for display purposes)
|
|
94
|
-
*
|
|
95
|
-
* @param projectPath - Path to the PRD project
|
|
96
|
-
* @returns Array of incomplete task descriptions
|
|
97
|
-
*/
|
|
98
|
-
getIncompleteTasks(projectPath: string): Promise<string[]>;
|
|
99
|
-
}
|
|
100
|
-
//# sourceMappingURL=archive-manager.d.ts.map
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ConversationAnalyzer - Analyzes conversation sessions and extracts structured requirements
|
|
3
|
-
*
|
|
4
|
-
* This class handles:
|
|
5
|
-
* - Conversation analysis and pattern extraction
|
|
6
|
-
* - Key requirement identification
|
|
7
|
-
* - Technical constraint extraction
|
|
8
|
-
* - Success criteria identification
|
|
9
|
-
* - Mini-PRD and optimized prompt generation
|
|
10
|
-
*/
|
|
11
|
-
import { Session } from '../types/session';
|
|
12
|
-
/**
|
|
13
|
-
* Analyzed conversation data
|
|
14
|
-
*/
|
|
15
|
-
export interface ConversationAnalysis {
|
|
16
|
-
summary: string;
|
|
17
|
-
keyRequirements: string[];
|
|
18
|
-
technicalConstraints: string[];
|
|
19
|
-
successCriteria: string[];
|
|
20
|
-
outOfScope: string[];
|
|
21
|
-
additionalContext: string[];
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* ConversationAnalyzer class
|
|
25
|
-
*
|
|
26
|
-
* Analyzes conversational sessions to extract structured requirements
|
|
27
|
-
* suitable for PRD generation or AI prompting
|
|
28
|
-
*/
|
|
29
|
-
export declare class ConversationAnalyzer {
|
|
30
|
-
/**
|
|
31
|
-
* Analyze a conversation session
|
|
32
|
-
*
|
|
33
|
-
* @param session - The session to analyze
|
|
34
|
-
* @returns Structured analysis of the conversation
|
|
35
|
-
*/
|
|
36
|
-
analyze(session: Session): ConversationAnalysis;
|
|
37
|
-
/**
|
|
38
|
-
* Generate a mini-PRD from analyzed conversation
|
|
39
|
-
*
|
|
40
|
-
* @param session - The session
|
|
41
|
-
* @param analysis - The conversation analysis
|
|
42
|
-
* @returns Mini-PRD content
|
|
43
|
-
*/
|
|
44
|
-
generateMiniPrd(session: Session, analysis: ConversationAnalysis): string;
|
|
45
|
-
/**
|
|
46
|
-
* Generate an optimized prompt for AI consumption
|
|
47
|
-
*
|
|
48
|
-
* @param session - The session
|
|
49
|
-
* @param analysis - The conversation analysis
|
|
50
|
-
* @returns Optimized prompt content
|
|
51
|
-
*/
|
|
52
|
-
generateOptimizedPrompt(session: Session, analysis: ConversationAnalysis): string;
|
|
53
|
-
/**
|
|
54
|
-
* Extract a summary from the conversation
|
|
55
|
-
*/
|
|
56
|
-
private extractSummary;
|
|
57
|
-
/**
|
|
58
|
-
* Extract key requirements from messages
|
|
59
|
-
*/
|
|
60
|
-
private extractKeyRequirements;
|
|
61
|
-
/**
|
|
62
|
-
* Extract technical constraints from messages
|
|
63
|
-
*/
|
|
64
|
-
private extractTechnicalConstraints;
|
|
65
|
-
/**
|
|
66
|
-
* Extract success criteria from messages
|
|
67
|
-
*/
|
|
68
|
-
private extractSuccessCriteria;
|
|
69
|
-
/**
|
|
70
|
-
* Extract out-of-scope items from messages
|
|
71
|
-
*/
|
|
72
|
-
private extractOutOfScope;
|
|
73
|
-
/**
|
|
74
|
-
* Extract additional context from messages
|
|
75
|
-
*/
|
|
76
|
-
private extractAdditionalContext;
|
|
77
|
-
/**
|
|
78
|
-
* Clean up extracted text
|
|
79
|
-
*/
|
|
80
|
-
private cleanupText;
|
|
81
|
-
/**
|
|
82
|
-
* Check if message matches any pattern
|
|
83
|
-
*/
|
|
84
|
-
private matchesAnyPattern;
|
|
85
|
-
}
|
|
86
|
-
//# sourceMappingURL=conversation-analyzer.d.ts.map
|
|
@@ -1,236 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.DocInjector = void 0;
|
|
37
|
-
const path = __importStar(require("path"));
|
|
38
|
-
const file_system_1 = require("../utils/file-system");
|
|
39
|
-
const errors_1 = require("../types/errors");
|
|
40
|
-
/**
|
|
41
|
-
* DocInjector - manages injection and updating of managed blocks in documentation files
|
|
42
|
-
*/
|
|
43
|
-
class DocInjector {
|
|
44
|
-
/**
|
|
45
|
-
* Inject or update managed block in a file
|
|
46
|
-
*/
|
|
47
|
-
static async injectBlock(filePath, content, options) {
|
|
48
|
-
const opts = {
|
|
49
|
-
startMarker: options?.startMarker || this.DEFAULT_START_MARKER,
|
|
50
|
-
endMarker: options?.endMarker || this.DEFAULT_END_MARKER,
|
|
51
|
-
content,
|
|
52
|
-
createIfMissing: options?.createIfMissing ?? true,
|
|
53
|
-
validateMarkdown: options?.validateMarkdown ?? true,
|
|
54
|
-
};
|
|
55
|
-
const fullPath = path.resolve(filePath);
|
|
56
|
-
let fileContent = '';
|
|
57
|
-
// Read existing file or create new
|
|
58
|
-
if (await file_system_1.FileSystem.exists(fullPath)) {
|
|
59
|
-
fileContent = await file_system_1.FileSystem.readFile(fullPath);
|
|
60
|
-
}
|
|
61
|
-
else if (!opts.createIfMissing) {
|
|
62
|
-
throw new errors_1.DataError(`File not found: ${filePath}`, 'Set createIfMissing: true to create the file automatically');
|
|
63
|
-
}
|
|
64
|
-
// Build the managed block
|
|
65
|
-
const blockRegex = new RegExp(`${this.escapeRegex(opts.startMarker)}[\\s\\S]*?${this.escapeRegex(opts.endMarker)}`, 'g');
|
|
66
|
-
const wrappedContent = this.wrapContent(opts.content, opts.startMarker, opts.endMarker);
|
|
67
|
-
if (blockRegex.test(fileContent)) {
|
|
68
|
-
// Replace existing block
|
|
69
|
-
await file_system_1.FileSystem.backup(fullPath);
|
|
70
|
-
fileContent = fileContent.replace(blockRegex, wrappedContent);
|
|
71
|
-
}
|
|
72
|
-
else {
|
|
73
|
-
// Append new block
|
|
74
|
-
if (fileContent && !fileContent.endsWith('\n\n')) {
|
|
75
|
-
fileContent += '\n\n';
|
|
76
|
-
}
|
|
77
|
-
fileContent += wrappedContent + '\n';
|
|
78
|
-
}
|
|
79
|
-
// Validate markdown if requested
|
|
80
|
-
if (opts.validateMarkdown) {
|
|
81
|
-
this.validateMarkdown(fileContent);
|
|
82
|
-
}
|
|
83
|
-
try {
|
|
84
|
-
// Ensure parent directory exists
|
|
85
|
-
const dir = path.dirname(fullPath);
|
|
86
|
-
await file_system_1.FileSystem.ensureDir(dir);
|
|
87
|
-
await file_system_1.FileSystem.writeFileAtomic(fullPath, fileContent);
|
|
88
|
-
}
|
|
89
|
-
catch (error) {
|
|
90
|
-
// Attempt to restore backup
|
|
91
|
-
if (await file_system_1.FileSystem.exists(`${fullPath}.backup`)) {
|
|
92
|
-
await file_system_1.FileSystem.restoreBackup(fullPath);
|
|
93
|
-
}
|
|
94
|
-
throw error;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
/**
|
|
98
|
-
* Detect if file contains managed block
|
|
99
|
-
*/
|
|
100
|
-
static async hasBlock(filePath, startMarker, endMarker) {
|
|
101
|
-
const start = startMarker || this.DEFAULT_START_MARKER;
|
|
102
|
-
const end = endMarker || this.DEFAULT_END_MARKER;
|
|
103
|
-
if (!(await file_system_1.FileSystem.exists(filePath))) {
|
|
104
|
-
return false;
|
|
105
|
-
}
|
|
106
|
-
const content = await file_system_1.FileSystem.readFile(filePath);
|
|
107
|
-
const blockRegex = new RegExp(`${this.escapeRegex(start)}[\\s\\S]*?${this.escapeRegex(end)}`, 'g');
|
|
108
|
-
return blockRegex.test(content);
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* Extract content from managed block
|
|
112
|
-
*/
|
|
113
|
-
static async extractBlock(filePath, startMarker, endMarker) {
|
|
114
|
-
const start = startMarker || this.DEFAULT_START_MARKER;
|
|
115
|
-
const end = endMarker || this.DEFAULT_END_MARKER;
|
|
116
|
-
if (!(await file_system_1.FileSystem.exists(filePath))) {
|
|
117
|
-
return null;
|
|
118
|
-
}
|
|
119
|
-
const content = await file_system_1.FileSystem.readFile(filePath);
|
|
120
|
-
const blockRegex = new RegExp(`${this.escapeRegex(start)}([\\s\\S]*?)${this.escapeRegex(end)}`, 'g');
|
|
121
|
-
const match = blockRegex.exec(content);
|
|
122
|
-
return match ? match[1].trim() : null;
|
|
123
|
-
}
|
|
124
|
-
/**
|
|
125
|
-
* Remove managed block from file
|
|
126
|
-
*/
|
|
127
|
-
static async removeBlock(filePath, startMarker, endMarker) {
|
|
128
|
-
const start = startMarker || this.DEFAULT_START_MARKER;
|
|
129
|
-
const end = endMarker || this.DEFAULT_END_MARKER;
|
|
130
|
-
if (!(await file_system_1.FileSystem.exists(filePath))) {
|
|
131
|
-
return;
|
|
132
|
-
}
|
|
133
|
-
const content = await file_system_1.FileSystem.readFile(filePath);
|
|
134
|
-
const blockRegex = new RegExp(`${this.escapeRegex(start)}[\\s\\S]*?${this.escapeRegex(end)}\\n?`, 'g');
|
|
135
|
-
if (blockRegex.test(content)) {
|
|
136
|
-
await file_system_1.FileSystem.backup(filePath);
|
|
137
|
-
const updated = content.replace(blockRegex, '');
|
|
138
|
-
await file_system_1.FileSystem.writeFileAtomic(filePath, updated);
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
/**
|
|
142
|
-
* Wrap content with markers
|
|
143
|
-
*/
|
|
144
|
-
static wrapContent(content, startMarker, endMarker) {
|
|
145
|
-
return `${startMarker}\n${content}\n${endMarker}`;
|
|
146
|
-
}
|
|
147
|
-
/**
|
|
148
|
-
* Escape special regex characters
|
|
149
|
-
*/
|
|
150
|
-
static escapeRegex(str) {
|
|
151
|
-
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
152
|
-
}
|
|
153
|
-
/**
|
|
154
|
-
* Basic markdown validation
|
|
155
|
-
*/
|
|
156
|
-
static validateMarkdown(content) {
|
|
157
|
-
// Check for balanced code blocks
|
|
158
|
-
const codeBlockMarkers = (content.match(/```/g) || []).length;
|
|
159
|
-
if (codeBlockMarkers % 2 !== 0) {
|
|
160
|
-
throw new errors_1.DataError('Invalid markdown: Unbalanced code blocks');
|
|
161
|
-
}
|
|
162
|
-
// Check for balanced brackets
|
|
163
|
-
const openBrackets = (content.match(/\[/g) || []).length;
|
|
164
|
-
const closeBrackets = (content.match(/\]/g) || []).length;
|
|
165
|
-
if (openBrackets !== closeBrackets) {
|
|
166
|
-
console.warn('Warning: Unbalanced brackets in markdown');
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
/**
|
|
170
|
-
* Create default AGENTS.md content
|
|
171
|
-
*/
|
|
172
|
-
static getDefaultAgentsContent() {
|
|
173
|
-
return `# AI Agent Instructions
|
|
174
|
-
|
|
175
|
-
This file contains instructions for AI agents working with this project.
|
|
176
|
-
|
|
177
|
-
<!-- CLAVIX:START -->
|
|
178
|
-
# Clavix - Prompt Improvement Assistant
|
|
179
|
-
|
|
180
|
-
Clavix is installed in this project. Use the following slash commands:
|
|
181
|
-
|
|
182
|
-
- \`/clavix:fast [prompt]\` - Quick prompt improvements with smart triage
|
|
183
|
-
- \`/clavix:deep [prompt]\` - Comprehensive prompt analysis
|
|
184
|
-
- \`/clavix:prd\` - Generate a PRD through guided questions
|
|
185
|
-
- \`/clavix:start\` - Start conversational mode for iterative refinement
|
|
186
|
-
- \`/clavix:summarize\` - Extract optimized prompt from conversation
|
|
187
|
-
|
|
188
|
-
**When to use:**
|
|
189
|
-
- **Fast mode**: Quick cleanup for simple prompts
|
|
190
|
-
- **Deep mode**: Comprehensive analysis for complex requirements
|
|
191
|
-
- **PRD mode**: Strategic planning with architecture and business impact
|
|
192
|
-
|
|
193
|
-
For more information, run \`clavix --help\` in your terminal.
|
|
194
|
-
<!-- CLAVIX:END -->
|
|
195
|
-
`;
|
|
196
|
-
}
|
|
197
|
-
/**
|
|
198
|
-
* Create default CLAUDE.md content for Claude Code
|
|
199
|
-
*/
|
|
200
|
-
static getDefaultClaudeContent() {
|
|
201
|
-
return `# Claude Code Instructions
|
|
202
|
-
|
|
203
|
-
<!-- CLAVIX:START -->
|
|
204
|
-
## Clavix Integration
|
|
205
|
-
|
|
206
|
-
This project uses Clavix for prompt improvement and PRD generation. The following slash commands are available:
|
|
207
|
-
|
|
208
|
-
### /clavix:fast [prompt]
|
|
209
|
-
Quick prompt improvements with smart triage. Clavix will analyze your prompt and recommend deep analysis if needed. Perfect for making "shitty prompts good" quickly.
|
|
210
|
-
|
|
211
|
-
### /clavix:deep [prompt]
|
|
212
|
-
Comprehensive prompt analysis with alternative phrasings, edge cases, implementation examples, and potential issues. Use for complex requirements or when you want thorough exploration.
|
|
213
|
-
|
|
214
|
-
### /clavix:prd
|
|
215
|
-
Launch the PRD generation workflow. Clavix will guide you through strategic questions and generate both a comprehensive PRD and a quick-reference version optimized for AI consumption.
|
|
216
|
-
|
|
217
|
-
### /clavix:start
|
|
218
|
-
Enter conversational mode for iterative prompt development. Discuss your requirements naturally, and later use \`/clavix:summarize\` to extract an optimized prompt.
|
|
219
|
-
|
|
220
|
-
### /clavix:summarize
|
|
221
|
-
Analyze the current conversation and extract key requirements into a structured prompt and mini-PRD.
|
|
222
|
-
|
|
223
|
-
**When to use which mode:**
|
|
224
|
-
- **Fast mode** (\`/clavix:fast\`): Quick cleanup for simple prompts
|
|
225
|
-
- **Deep mode** (\`/clavix:deep\`): Comprehensive analysis for complex requirements
|
|
226
|
-
- **PRD mode** (\`/clavix:prd\`): Strategic planning with architecture and business impact
|
|
227
|
-
|
|
228
|
-
**Pro tip**: Start complex features with \`/clavix:prd\` or \`/clavix:start\` to ensure clear requirements before implementation.
|
|
229
|
-
<!-- CLAVIX:END -->
|
|
230
|
-
`;
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
exports.DocInjector = DocInjector;
|
|
234
|
-
DocInjector.DEFAULT_START_MARKER = '<!-- CLAVIX:START -->';
|
|
235
|
-
DocInjector.DEFAULT_END_MARKER = '<!-- CLAVIX:END -->';
|
|
236
|
-
//# sourceMappingURL=doc-injector.js.map
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
export interface ManagedBlockOptions {
|
|
2
|
-
startMarker: string;
|
|
3
|
-
endMarker: string;
|
|
4
|
-
content: string;
|
|
5
|
-
createIfMissing?: boolean;
|
|
6
|
-
validateMarkdown?: boolean;
|
|
7
|
-
}
|
|
8
|
-
/**
|
|
9
|
-
* DocInjector - manages injection and updating of managed blocks in documentation files
|
|
10
|
-
*/
|
|
11
|
-
export declare class DocInjector {
|
|
12
|
-
private static readonly DEFAULT_START_MARKER;
|
|
13
|
-
private static readonly DEFAULT_END_MARKER;
|
|
14
|
-
/**
|
|
15
|
-
* Inject or update managed block in a file
|
|
16
|
-
*/
|
|
17
|
-
static injectBlock(filePath: string, content: string, options?: Partial<ManagedBlockOptions>): Promise<void>;
|
|
18
|
-
/**
|
|
19
|
-
* Detect if file contains managed block
|
|
20
|
-
*/
|
|
21
|
-
static hasBlock(filePath: string, startMarker?: string, endMarker?: string): Promise<boolean>;
|
|
22
|
-
/**
|
|
23
|
-
* Extract content from managed block
|
|
24
|
-
*/
|
|
25
|
-
static extractBlock(filePath: string, startMarker?: string, endMarker?: string): Promise<string | null>;
|
|
26
|
-
/**
|
|
27
|
-
* Remove managed block from file
|
|
28
|
-
*/
|
|
29
|
-
static removeBlock(filePath: string, startMarker?: string, endMarker?: string): Promise<void>;
|
|
30
|
-
/**
|
|
31
|
-
* Wrap content with markers
|
|
32
|
-
*/
|
|
33
|
-
private static wrapContent;
|
|
34
|
-
/**
|
|
35
|
-
* Escape special regex characters
|
|
36
|
-
*/
|
|
37
|
-
private static escapeRegex;
|
|
38
|
-
/**
|
|
39
|
-
* Basic markdown validation
|
|
40
|
-
*/
|
|
41
|
-
private static validateMarkdown;
|
|
42
|
-
/**
|
|
43
|
-
* Create default AGENTS.md content
|
|
44
|
-
*/
|
|
45
|
-
static getDefaultAgentsContent(): string;
|
|
46
|
-
/**
|
|
47
|
-
* Create default CLAUDE.md content for Claude Code
|
|
48
|
-
*/
|
|
49
|
-
static getDefaultClaudeContent(): string;
|
|
50
|
-
}
|
|
51
|
-
//# sourceMappingURL=doc-injector.d.ts.map
|
|
@@ -1,214 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* GitManager - Manages git auto-commit functionality for task implementation
|
|
4
|
-
*
|
|
5
|
-
* This class handles:
|
|
6
|
-
* - Checking git repository status
|
|
7
|
-
* - Creating commits based on user preferences
|
|
8
|
-
* - Generating commit messages
|
|
9
|
-
* - Handling commit strategies (per task, per phase, per N tasks)
|
|
10
|
-
*/
|
|
11
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.CommitScheduler = exports.GitManager = void 0;
|
|
13
|
-
const child_process_1 = require("child_process");
|
|
14
|
-
const util_1 = require("util");
|
|
15
|
-
const execAsync = (0, util_1.promisify)(child_process_1.exec);
|
|
16
|
-
/**
|
|
17
|
-
* GitManager class
|
|
18
|
-
*
|
|
19
|
-
* Handles git operations for the implement command
|
|
20
|
-
*/
|
|
21
|
-
class GitManager {
|
|
22
|
-
/**
|
|
23
|
-
* Check if current directory is a git repository
|
|
24
|
-
*/
|
|
25
|
-
async isGitRepository() {
|
|
26
|
-
try {
|
|
27
|
-
await execAsync('git rev-parse --git-dir');
|
|
28
|
-
return true;
|
|
29
|
-
}
|
|
30
|
-
catch {
|
|
31
|
-
return false;
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
/**
|
|
35
|
-
* Check if there are uncommitted changes
|
|
36
|
-
*/
|
|
37
|
-
async hasUncommittedChanges() {
|
|
38
|
-
try {
|
|
39
|
-
const { stdout } = await execAsync('git status --porcelain');
|
|
40
|
-
return stdout.trim().length > 0;
|
|
41
|
-
}
|
|
42
|
-
catch {
|
|
43
|
-
return false;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* Create a commit with the given tasks
|
|
48
|
-
*/
|
|
49
|
-
async createCommit(options) {
|
|
50
|
-
try {
|
|
51
|
-
// Check for changes first
|
|
52
|
-
if (!(await this.hasUncommittedChanges())) {
|
|
53
|
-
return false; // No changes to commit
|
|
54
|
-
}
|
|
55
|
-
// Stage all changes
|
|
56
|
-
await execAsync('git add .');
|
|
57
|
-
// Generate commit message
|
|
58
|
-
const message = this.generateCommitMessage(options);
|
|
59
|
-
// Create commit
|
|
60
|
-
await execAsync(`git commit -m "${this.escapeCommitMessage(message)}"`);
|
|
61
|
-
return true;
|
|
62
|
-
}
|
|
63
|
-
catch (error) {
|
|
64
|
-
// If commit fails, log but don't throw
|
|
65
|
-
console.error('Git commit failed:', error);
|
|
66
|
-
return false;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* Generate commit message from tasks
|
|
71
|
-
*/
|
|
72
|
-
generateCommitMessage(options) {
|
|
73
|
-
const { tasks, phase, projectName } = options;
|
|
74
|
-
let message = '';
|
|
75
|
-
// Header
|
|
76
|
-
if (phase) {
|
|
77
|
-
message += `clavix: ${phase}\n\n`;
|
|
78
|
-
}
|
|
79
|
-
else if (tasks.length === 1) {
|
|
80
|
-
message += `clavix: ${tasks[0]}\n\n`;
|
|
81
|
-
}
|
|
82
|
-
else {
|
|
83
|
-
message += `clavix: implement ${tasks.length} tasks\n\n`;
|
|
84
|
-
}
|
|
85
|
-
// Task list
|
|
86
|
-
message += 'Completed tasks:\n';
|
|
87
|
-
tasks.forEach((task) => {
|
|
88
|
-
message += `- ${task}\n`;
|
|
89
|
-
});
|
|
90
|
-
// Footer
|
|
91
|
-
message += '\n';
|
|
92
|
-
if (projectName) {
|
|
93
|
-
message += `Project: ${projectName}\n`;
|
|
94
|
-
}
|
|
95
|
-
message += 'Generated by Clavix /clavix:implement';
|
|
96
|
-
return message;
|
|
97
|
-
}
|
|
98
|
-
/**
|
|
99
|
-
* Escape commit message for shell
|
|
100
|
-
*/
|
|
101
|
-
escapeCommitMessage(message) {
|
|
102
|
-
return message.replace(/"/g, '\\"').replace(/\n/g, '\\n');
|
|
103
|
-
}
|
|
104
|
-
/**
|
|
105
|
-
* Get the current branch name
|
|
106
|
-
*/
|
|
107
|
-
async getCurrentBranch() {
|
|
108
|
-
try {
|
|
109
|
-
const { stdout } = await execAsync('git rev-parse --abbrev-ref HEAD');
|
|
110
|
-
return stdout.trim();
|
|
111
|
-
}
|
|
112
|
-
catch {
|
|
113
|
-
return 'unknown';
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
/**
|
|
117
|
-
* Check if working directory is clean
|
|
118
|
-
*/
|
|
119
|
-
async isWorkingDirectoryClean() {
|
|
120
|
-
return !(await this.hasUncommittedChanges());
|
|
121
|
-
}
|
|
122
|
-
/**
|
|
123
|
-
* Get short status for display
|
|
124
|
-
*/
|
|
125
|
-
async getStatus() {
|
|
126
|
-
try {
|
|
127
|
-
const { stdout } = await execAsync('git status --short');
|
|
128
|
-
return stdout.trim();
|
|
129
|
-
}
|
|
130
|
-
catch {
|
|
131
|
-
return 'Unable to get git status';
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
/**
|
|
135
|
-
* Validate git setup before implementing
|
|
136
|
-
*/
|
|
137
|
-
async validateGitSetup() {
|
|
138
|
-
const isRepo = await this.isGitRepository();
|
|
139
|
-
const hasChanges = await this.hasUncommittedChanges();
|
|
140
|
-
const currentBranch = isRepo ? await this.getCurrentBranch() : '';
|
|
141
|
-
return {
|
|
142
|
-
isRepo,
|
|
143
|
-
hasChanges,
|
|
144
|
-
currentBranch,
|
|
145
|
-
};
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
exports.GitManager = GitManager;
|
|
149
|
-
/**
|
|
150
|
-
* Helper class to track when to commit based on strategy
|
|
151
|
-
*/
|
|
152
|
-
class CommitScheduler {
|
|
153
|
-
constructor(strategy) {
|
|
154
|
-
this.strategy = strategy;
|
|
155
|
-
this.completedTasksInPhase = 0;
|
|
156
|
-
this.completedTasksTotal = 0;
|
|
157
|
-
this.completedTasksSinceLastCommit = 0;
|
|
158
|
-
this.currentPhase = '';
|
|
159
|
-
}
|
|
160
|
-
/**
|
|
161
|
-
* Mark a task as completed and check if commit should be made
|
|
162
|
-
*/
|
|
163
|
-
taskCompleted(taskPhase) {
|
|
164
|
-
this.completedTasksTotal++;
|
|
165
|
-
this.completedTasksSinceLastCommit++;
|
|
166
|
-
if (taskPhase !== this.currentPhase) {
|
|
167
|
-
this.completedTasksInPhase = 0;
|
|
168
|
-
this.currentPhase = taskPhase;
|
|
169
|
-
}
|
|
170
|
-
this.completedTasksInPhase++;
|
|
171
|
-
return this.shouldCommit();
|
|
172
|
-
}
|
|
173
|
-
/**
|
|
174
|
-
* Mark a phase as completed
|
|
175
|
-
*/
|
|
176
|
-
phaseCompleted() {
|
|
177
|
-
// Reset phase counter
|
|
178
|
-
this.completedTasksInPhase = 0;
|
|
179
|
-
// If strategy is per-phase, we should commit
|
|
180
|
-
return this.strategy === 'per-phase';
|
|
181
|
-
}
|
|
182
|
-
/**
|
|
183
|
-
* Check if a commit should be made now
|
|
184
|
-
*/
|
|
185
|
-
shouldCommit() {
|
|
186
|
-
switch (this.strategy) {
|
|
187
|
-
case 'per-task':
|
|
188
|
-
return true;
|
|
189
|
-
case 'per-5-tasks':
|
|
190
|
-
return this.completedTasksSinceLastCommit >= 5;
|
|
191
|
-
case 'per-phase':
|
|
192
|
-
// Will be handled by phaseCompleted()
|
|
193
|
-
return false;
|
|
194
|
-
case 'none':
|
|
195
|
-
return false;
|
|
196
|
-
default:
|
|
197
|
-
return false;
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
/**
|
|
201
|
-
* Reset commit counter (after a commit is made)
|
|
202
|
-
*/
|
|
203
|
-
resetCommitCounter() {
|
|
204
|
-
this.completedTasksSinceLastCommit = 0;
|
|
205
|
-
}
|
|
206
|
-
/**
|
|
207
|
-
* Get accumulated task count for commit message
|
|
208
|
-
*/
|
|
209
|
-
getTaskCountSinceLastCommit() {
|
|
210
|
-
return this.completedTasksSinceLastCommit;
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
exports.CommitScheduler = CommitScheduler;
|
|
214
|
-
//# sourceMappingURL=git-manager.js.map
|