clavix 5.1.1 → 5.3.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 -5
- package/dist/cli/commands/diagnose.d.ts +15 -0
- package/dist/cli/commands/diagnose.js +295 -0
- package/dist/cli/commands/init.d.ts +4 -0
- package/dist/cli/commands/init.js +130 -24
- package/dist/cli/commands/update.js +1 -1
- package/dist/constants.d.ts +18 -0
- package/dist/constants.js +24 -0
- package/dist/core/adapter-registry.d.ts +39 -0
- package/dist/core/adapter-registry.js +208 -0
- package/dist/core/adapters/agents-md-generator.d.ts +0 -10
- package/dist/core/adapters/agents-md-generator.js +7 -41
- package/dist/core/adapters/base-adapter.d.ts +1 -0
- package/dist/core/adapters/base-adapter.js +3 -1
- package/dist/core/adapters/copilot-instructions-generator.d.ts +0 -10
- package/dist/core/adapters/copilot-instructions-generator.js +7 -41
- package/dist/core/adapters/gemini-adapter.d.ts +2 -18
- package/dist/core/adapters/gemini-adapter.js +7 -48
- package/dist/core/adapters/llxprt-adapter.d.ts +2 -18
- package/dist/core/adapters/llxprt-adapter.js +7 -48
- package/dist/core/adapters/octo-md-generator.d.ts +0 -10
- package/dist/core/adapters/octo-md-generator.js +7 -41
- package/dist/core/adapters/qwen-adapter.d.ts +2 -18
- package/dist/core/adapters/qwen-adapter.js +7 -46
- package/dist/core/adapters/toml-formatting-adapter.d.ts +50 -0
- package/dist/core/adapters/toml-formatting-adapter.js +74 -0
- package/dist/core/adapters/universal-adapter.d.ts +49 -0
- package/dist/core/adapters/universal-adapter.js +88 -0
- package/dist/core/adapters/warp-md-generator.d.ts +3 -4
- package/dist/core/adapters/warp-md-generator.js +10 -30
- package/dist/core/command-transformer.d.ts +11 -12
- package/dist/core/command-transformer.js +11 -12
- package/dist/core/doc-injector.d.ts +0 -4
- package/dist/core/doc-injector.js +9 -15
- package/dist/core/template-assembler.d.ts +1 -1
- package/dist/core/template-assembler.js +1 -1
- package/dist/templates/agents/agents.md +9 -4
- package/dist/templates/agents/copilot-instructions.md +7 -4
- package/dist/templates/agents/octo.md +7 -3
- package/dist/templates/agents/warp.md +8 -4
- package/dist/templates/instructions/core/file-operations.md +15 -11
- package/dist/templates/slash-commands/_canonical/plan.md +1 -2
- package/dist/templates/slash-commands/_components/MANIFEST.md +81 -0
- package/dist/templates/slash-commands/_components/agent-protocols/AGENT_MANUAL.md +1 -1
- package/dist/templates/slash-commands/_components/agent-protocols/cli-reference.md +15 -17
- package/dist/types/adapter-config.d.ts +73 -0
- package/dist/types/adapter-config.js +24 -0
- package/dist/types/config.d.ts +0 -80
- package/dist/types/config.js +3 -2
- package/dist/utils/error-utils.d.ts +4 -0
- package/dist/utils/error-utils.js +6 -0
- package/dist/utils/file-system.js +7 -12
- package/dist/utils/legacy-command-cleanup.d.ts +14 -0
- package/dist/utils/legacy-command-cleanup.js +14 -0
- package/dist/utils/logger.d.ts +32 -0
- package/dist/utils/logger.js +56 -0
- package/dist/utils/string-utils.d.ts +10 -0
- package/dist/utils/string-utils.js +12 -0
- package/dist/utils/version.d.ts +20 -0
- package/dist/utils/version.js +43 -0
- package/oclif.manifest.json +130 -0
- package/package.json +2 -2
- package/dist/cli/commands/config.d.ts +0 -30
- package/dist/cli/commands/config.js +0 -456
- package/dist/templates/slash-commands/_components/agent-protocols/decision-rules.md +0 -232
- package/dist/templates/slash-commands/_components/agent-protocols/error-handling.md +0 -177
package/README.md
CHANGED
|
@@ -12,7 +12,8 @@
|
|
|
12
12
|
|
|
13
13
|
| Version | Highlights | Details |
|
|
14
14
|
| --- | --- | --- |
|
|
15
|
-
| **v5.
|
|
15
|
+
| **v5.2.1** (Latest) | Diagnose command, DRY architecture, feature matrix | [Changelog](CHANGELOG.md) |
|
|
16
|
+
| **v5.0.0** | Agentic-first architecture - lean template delivery | [Changelog](CHANGELOG.md#500---2025-01-27) |
|
|
16
17
|
| **v4.12.0** | Final v4 release with full CLI commands | [Changelog](docs/archive/v4-changelog.md) |
|
|
17
18
|
|
|
18
19
|
**Requirements:** Node.js >= 18.0.0
|
|
@@ -49,6 +50,15 @@ Clavix v5 follows an **agentic-first architecture**:
|
|
|
49
50
|
| CLI agents | Claude Code, Droid CLI, CodeBuddy CLI, OpenCode, Gemini CLI, Qwen Code, LLXPRT, Amp, Crush CLI, Codex CLI, Augment CLI |
|
|
50
51
|
| Universal adapters | AGENTS.md, GitHub Copilot, OCTO.md, WARP.md |
|
|
51
52
|
|
|
53
|
+
### Feature Matrix
|
|
54
|
+
|
|
55
|
+
| Feature | Claude Code | Cursor/Windsurf | Gemini/Qwen | Generic Agents |
|
|
56
|
+
|---------|-------------|-----------------|-------------|----------------|
|
|
57
|
+
| Slash commands | ✅ Native | ✅ Native | ✅ TOML | ❌ Read-only |
|
|
58
|
+
| Doc injection | ✅ CLAUDE.md | ✅ .cursor/rules | ✅ N/A | ✅ AGENTS.md |
|
|
59
|
+
| Namespace dirs | ✅ clavix/ | ✅ clavix/ | ✅ clavix/ | N/A |
|
|
60
|
+
| Auto-detection | ✅ Yes | ✅ Yes | ✅ Yes | N/A |
|
|
61
|
+
|
|
52
62
|
Full list and configuration: [docs/integrations.md](docs/integrations.md)
|
|
53
63
|
|
|
54
64
|
## Quickstart
|
|
@@ -77,6 +87,7 @@ The AI agent reads the improve template and:
|
|
|
77
87
|
|
|
78
88
|
### 3. Choose Your Workflow
|
|
79
89
|
|
|
90
|
+
**Core Workflows:**
|
|
80
91
|
| Command | When to Use |
|
|
81
92
|
|---------|-------------|
|
|
82
93
|
| `/clavix:improve` | Optimize a single prompt (auto-selects depth) |
|
|
@@ -84,7 +95,13 @@ The AI agent reads the improve template and:
|
|
|
84
95
|
| `/clavix:start` | Explore ideas conversationally first |
|
|
85
96
|
| `/clavix:plan` | Generate tasks from a PRD |
|
|
86
97
|
| `/clavix:implement` | Execute tasks with progress tracking |
|
|
87
|
-
| `/clavix:
|
|
98
|
+
| `/clavix:summarize` | Extract requirements from conversation |
|
|
99
|
+
|
|
100
|
+
**Project Management:**
|
|
101
|
+
| Utility | Purpose |
|
|
102
|
+
|---------|---------|
|
|
103
|
+
| `/clavix:verify` | Check implementation against PRD requirements |
|
|
104
|
+
| `/clavix:archive` | Archive completed projects to `.clavix/archive/` |
|
|
88
105
|
|
|
89
106
|
See [Choosing the Right Workflow](docs/guides/choosing-workflow.md) for detailed guidance.
|
|
90
107
|
|
|
@@ -96,13 +113,13 @@ clavix update # After npm update clavix
|
|
|
96
113
|
|
|
97
114
|
## CLI Commands
|
|
98
115
|
|
|
99
|
-
Clavix v5 has
|
|
116
|
+
Clavix v5 has 4 CLI commands (for setup and diagnostics, not workflows):
|
|
100
117
|
|
|
101
118
|
| Command | Purpose |
|
|
102
119
|
|---------|---------|
|
|
103
|
-
| `clavix init` | Initialize Clavix in a project |
|
|
120
|
+
| `clavix init` | Initialize or reconfigure Clavix in a project |
|
|
104
121
|
| `clavix update` | Update templates after package update |
|
|
105
|
-
| `clavix
|
|
122
|
+
| `clavix diagnose` | Check installation and report issues |
|
|
106
123
|
| `clavix version` | Show version |
|
|
107
124
|
|
|
108
125
|
**All workflows** (`/clavix:improve`, `/clavix:prd`, etc.) are **slash commands** that AI agents execute by reading markdown templates.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
export default class Diagnose extends Command {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
run(): Promise<void>;
|
|
6
|
+
private checkVersion;
|
|
7
|
+
private checkClavixDir;
|
|
8
|
+
private checkConfig;
|
|
9
|
+
private static readonly DOC_GENERATORS;
|
|
10
|
+
private getDocGeneratorFile;
|
|
11
|
+
private getDocGeneratorName;
|
|
12
|
+
private checkIntegrations;
|
|
13
|
+
private checkTemplates;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=diagnose.d.ts.map
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import * as path from 'path';
|
|
4
|
+
import { fileURLToPath } from 'url';
|
|
5
|
+
import { dirname } from 'path';
|
|
6
|
+
import fs from 'fs-extra';
|
|
7
|
+
import { AgentManager } from '../../core/agent-manager.js';
|
|
8
|
+
import { FileSystem } from '../../utils/file-system.js';
|
|
9
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
10
|
+
const __dirname = dirname(__filename);
|
|
11
|
+
export default class Diagnose extends Command {
|
|
12
|
+
static description = 'Diagnose Clavix installation and configuration';
|
|
13
|
+
static examples = [
|
|
14
|
+
'<%= config.bin %> <%= command.id %>',
|
|
15
|
+
'<%= config.bin %> <%= command.id %> # Check setup and report issues',
|
|
16
|
+
];
|
|
17
|
+
async run() {
|
|
18
|
+
this.log(chalk.bold.cyan('\n🔍 Clavix Diagnostic Report\n'));
|
|
19
|
+
const results = [];
|
|
20
|
+
// 1. Check version
|
|
21
|
+
results.push(await this.checkVersion());
|
|
22
|
+
// 2. Check .clavix directory
|
|
23
|
+
results.push(await this.checkClavixDir());
|
|
24
|
+
// 3. Check config.json
|
|
25
|
+
results.push(await this.checkConfig());
|
|
26
|
+
// 4. Check integrations
|
|
27
|
+
results.push(...(await this.checkIntegrations()));
|
|
28
|
+
// 5. Check templates
|
|
29
|
+
results.push(await this.checkTemplates());
|
|
30
|
+
// Note: Slash commands are checked per-integration in checkIntegrations()
|
|
31
|
+
// No separate checkSlashCommands() - commands are in adapter-specific directories
|
|
32
|
+
// Print results
|
|
33
|
+
this.log(chalk.gray('─'.repeat(50)));
|
|
34
|
+
this.log(chalk.bold('\nResults:\n'));
|
|
35
|
+
let passCount = 0;
|
|
36
|
+
let warnCount = 0;
|
|
37
|
+
let failCount = 0;
|
|
38
|
+
for (const result of results) {
|
|
39
|
+
const icon = result.status === 'pass'
|
|
40
|
+
? chalk.green('✓')
|
|
41
|
+
: result.status === 'warn'
|
|
42
|
+
? chalk.yellow('⚠')
|
|
43
|
+
: chalk.red('✗');
|
|
44
|
+
const color = result.status === 'pass'
|
|
45
|
+
? chalk.green
|
|
46
|
+
: result.status === 'warn'
|
|
47
|
+
? chalk.yellow
|
|
48
|
+
: chalk.red;
|
|
49
|
+
this.log(` ${icon} ${color(result.message)}`);
|
|
50
|
+
if (result.details) {
|
|
51
|
+
this.log(chalk.gray(` ${result.details}`));
|
|
52
|
+
}
|
|
53
|
+
if (result.status === 'pass')
|
|
54
|
+
passCount++;
|
|
55
|
+
else if (result.status === 'warn')
|
|
56
|
+
warnCount++;
|
|
57
|
+
else
|
|
58
|
+
failCount++;
|
|
59
|
+
}
|
|
60
|
+
// Summary
|
|
61
|
+
this.log('\n' + chalk.gray('─'.repeat(50)));
|
|
62
|
+
this.log(chalk.bold(`\nSummary: ${chalk.green(passCount + ' passed')}, ${chalk.yellow(warnCount + ' warnings')}, ${chalk.red(failCount + ' failed')}\n`));
|
|
63
|
+
// Recommendations
|
|
64
|
+
if (failCount > 0) {
|
|
65
|
+
this.log(chalk.yellow('Recommendations:'));
|
|
66
|
+
this.log(chalk.gray(' • Run `clavix init` to initialize or repair installation'));
|
|
67
|
+
this.log(chalk.gray(' • Run `clavix update` to sync templates\n'));
|
|
68
|
+
}
|
|
69
|
+
else if (warnCount > 0) {
|
|
70
|
+
this.log(chalk.cyan('Tip: Run `clavix update` to resolve warnings\n'));
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
this.log(chalk.green('✨ All checks passed! Clavix is ready to use.\n'));
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
async checkVersion() {
|
|
77
|
+
try {
|
|
78
|
+
const packageJsonPath = path.join(__dirname, '../../../package.json');
|
|
79
|
+
const packageJson = await fs.readJson(packageJsonPath);
|
|
80
|
+
return {
|
|
81
|
+
status: 'pass',
|
|
82
|
+
message: `Version: v${packageJson.version}`,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
return {
|
|
87
|
+
status: 'fail',
|
|
88
|
+
message: 'Could not determine version',
|
|
89
|
+
details: 'package.json not found',
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
async checkClavixDir() {
|
|
94
|
+
const clavixDir = path.join(process.cwd(), '.clavix');
|
|
95
|
+
if (!(await FileSystem.exists(clavixDir))) {
|
|
96
|
+
return {
|
|
97
|
+
status: 'fail',
|
|
98
|
+
message: '.clavix directory not found',
|
|
99
|
+
details: 'Run `clavix init` to initialize',
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
// Check for essential subdirectory (outputs is always created)
|
|
103
|
+
// Note: 'instructions' is only created when generic integrations are used
|
|
104
|
+
// Note: 'commands' doesn't exist - commands go to adapter-specific directories
|
|
105
|
+
const outputsDir = path.join(clavixDir, 'outputs');
|
|
106
|
+
if (!(await FileSystem.exists(outputsDir))) {
|
|
107
|
+
return {
|
|
108
|
+
status: 'warn',
|
|
109
|
+
message: '.clavix directory incomplete',
|
|
110
|
+
details: 'Missing: outputs',
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
return {
|
|
114
|
+
status: 'pass',
|
|
115
|
+
message: '.clavix directory OK',
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
async checkConfig() {
|
|
119
|
+
const configPath = path.join(process.cwd(), '.clavix', 'config.json');
|
|
120
|
+
if (!(await FileSystem.exists(configPath))) {
|
|
121
|
+
return {
|
|
122
|
+
status: 'fail',
|
|
123
|
+
message: 'config.json not found',
|
|
124
|
+
details: 'Run `clavix init` to create configuration',
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
try {
|
|
128
|
+
const config = await fs.readJson(configPath);
|
|
129
|
+
if (!config.version) {
|
|
130
|
+
return {
|
|
131
|
+
status: 'warn',
|
|
132
|
+
message: 'config.json missing version field',
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
if (!config.integrations || config.integrations.length === 0) {
|
|
136
|
+
return {
|
|
137
|
+
status: 'warn',
|
|
138
|
+
message: 'No integrations configured',
|
|
139
|
+
details: 'Run `clavix init` to add integrations',
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
return {
|
|
143
|
+
status: 'pass',
|
|
144
|
+
message: `config.json OK (${config.integrations.length} integration(s))`,
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
catch (error) {
|
|
148
|
+
return {
|
|
149
|
+
status: 'fail',
|
|
150
|
+
message: 'config.json is invalid',
|
|
151
|
+
details: `${error}`,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
// Doc generators are integrations that generate documentation files, not adapters
|
|
156
|
+
static DOC_GENERATORS = [
|
|
157
|
+
'agents-md',
|
|
158
|
+
'octo-md',
|
|
159
|
+
'warp-md',
|
|
160
|
+
'copilot-instructions',
|
|
161
|
+
];
|
|
162
|
+
getDocGeneratorFile(integration) {
|
|
163
|
+
switch (integration) {
|
|
164
|
+
case 'agents-md':
|
|
165
|
+
return 'AGENTS.md';
|
|
166
|
+
case 'octo-md':
|
|
167
|
+
return 'OCTO.md';
|
|
168
|
+
case 'warp-md':
|
|
169
|
+
return 'WARP.md';
|
|
170
|
+
case 'copilot-instructions':
|
|
171
|
+
return path.join('.github', 'copilot-instructions.md');
|
|
172
|
+
default:
|
|
173
|
+
return '';
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
getDocGeneratorName(integration) {
|
|
177
|
+
switch (integration) {
|
|
178
|
+
case 'agents-md':
|
|
179
|
+
return 'AGENTS.md';
|
|
180
|
+
case 'octo-md':
|
|
181
|
+
return 'OCTO.md';
|
|
182
|
+
case 'warp-md':
|
|
183
|
+
return 'WARP.md';
|
|
184
|
+
case 'copilot-instructions':
|
|
185
|
+
return 'GitHub Copilot';
|
|
186
|
+
default:
|
|
187
|
+
return integration;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
async checkIntegrations() {
|
|
191
|
+
const results = [];
|
|
192
|
+
const configPath = path.join(process.cwd(), '.clavix', 'config.json');
|
|
193
|
+
if (!(await FileSystem.exists(configPath))) {
|
|
194
|
+
return results;
|
|
195
|
+
}
|
|
196
|
+
try {
|
|
197
|
+
const config = await fs.readJson(configPath);
|
|
198
|
+
const agentManager = new AgentManager();
|
|
199
|
+
for (const integrationName of config.integrations || []) {
|
|
200
|
+
// Handle doc generators specially (they don't have adapters)
|
|
201
|
+
if (Diagnose.DOC_GENERATORS.includes(integrationName)) {
|
|
202
|
+
const docFile = this.getDocGeneratorFile(integrationName);
|
|
203
|
+
const docPath = path.join(process.cwd(), docFile);
|
|
204
|
+
if (await FileSystem.exists(docPath)) {
|
|
205
|
+
results.push({
|
|
206
|
+
status: 'pass',
|
|
207
|
+
message: `${this.getDocGeneratorName(integrationName)}: Generated`,
|
|
208
|
+
details: docFile,
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
results.push({
|
|
213
|
+
status: 'warn',
|
|
214
|
+
message: `${this.getDocGeneratorName(integrationName)}: Not generated`,
|
|
215
|
+
details: `Run \`clavix update\` to generate`,
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
220
|
+
// Handle adapters (integrations with command generation)
|
|
221
|
+
const adapter = agentManager.getAdapter(integrationName);
|
|
222
|
+
if (!adapter) {
|
|
223
|
+
results.push({
|
|
224
|
+
status: 'warn',
|
|
225
|
+
message: `Unknown integration: ${integrationName}`,
|
|
226
|
+
details: 'May be removed in a future version',
|
|
227
|
+
});
|
|
228
|
+
continue;
|
|
229
|
+
}
|
|
230
|
+
// Check if adapter's command directory exists
|
|
231
|
+
const commandPath = adapter.getCommandPath();
|
|
232
|
+
const commandDirExists = await FileSystem.exists(commandPath);
|
|
233
|
+
if (commandDirExists) {
|
|
234
|
+
const files = await FileSystem.listFiles(commandPath);
|
|
235
|
+
const commandCount = files.filter((f) => f.endsWith('.md') || f.endsWith('.toml') || f.endsWith('.mdc')).length;
|
|
236
|
+
results.push({
|
|
237
|
+
status: 'pass',
|
|
238
|
+
message: `${adapter.displayName}: ${commandCount} command(s)`,
|
|
239
|
+
details: commandPath,
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
results.push({
|
|
244
|
+
status: 'warn',
|
|
245
|
+
message: `${adapter.displayName}: commands not generated`,
|
|
246
|
+
details: `Run \`clavix update\` to generate`,
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
catch {
|
|
252
|
+
// Config read error handled elsewhere
|
|
253
|
+
}
|
|
254
|
+
return results;
|
|
255
|
+
}
|
|
256
|
+
async checkTemplates() {
|
|
257
|
+
const templateDir = path.join(__dirname, '../../templates');
|
|
258
|
+
if (!(await FileSystem.exists(templateDir))) {
|
|
259
|
+
return {
|
|
260
|
+
status: 'fail',
|
|
261
|
+
message: 'Template directory not found',
|
|
262
|
+
details: 'Package may be corrupted',
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
// Check for canonical templates
|
|
266
|
+
const canonicalDir = path.join(templateDir, 'slash-commands', '_canonical');
|
|
267
|
+
if (!(await FileSystem.exists(canonicalDir))) {
|
|
268
|
+
return {
|
|
269
|
+
status: 'warn',
|
|
270
|
+
message: 'Canonical templates missing',
|
|
271
|
+
details: 'Try reinstalling clavix',
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
const requiredTemplates = ['improve.md', 'prd.md', 'plan.md', 'implement.md'];
|
|
275
|
+
const missing = [];
|
|
276
|
+
for (const template of requiredTemplates) {
|
|
277
|
+
const templatePath = path.join(canonicalDir, template);
|
|
278
|
+
if (!(await FileSystem.exists(templatePath))) {
|
|
279
|
+
missing.push(template);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
if (missing.length > 0) {
|
|
283
|
+
return {
|
|
284
|
+
status: 'warn',
|
|
285
|
+
message: 'Some canonical templates missing',
|
|
286
|
+
details: missing.join(', '),
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
return {
|
|
290
|
+
status: 'pass',
|
|
291
|
+
message: 'Package templates OK',
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
//# sourceMappingURL=diagnose.js.map
|
|
@@ -3,6 +3,10 @@ export default class Init extends Command {
|
|
|
3
3
|
static description: string;
|
|
4
4
|
static examples: string[];
|
|
5
5
|
run(): Promise<void>;
|
|
6
|
+
/**
|
|
7
|
+
* Regenerate commands for existing integrations (update mode)
|
|
8
|
+
*/
|
|
9
|
+
private regenerateCommands;
|
|
6
10
|
private createDirectoryStructure;
|
|
7
11
|
private generateConfig;
|
|
8
12
|
private generateInstructions;
|
|
@@ -21,24 +21,9 @@ export default class Init extends Command {
|
|
|
21
21
|
async run() {
|
|
22
22
|
console.log(chalk.bold.cyan('\n🚀 Clavix Initialization\n'));
|
|
23
23
|
try {
|
|
24
|
-
// Check if already initialized
|
|
25
|
-
if (await FileSystem.exists('.clavix')) {
|
|
26
|
-
const { reinit } = await inquirer.prompt([
|
|
27
|
-
{
|
|
28
|
-
type: 'confirm',
|
|
29
|
-
name: 'reinit',
|
|
30
|
-
message: 'Clavix is already initialized. Reinitialize?',
|
|
31
|
-
default: false,
|
|
32
|
-
},
|
|
33
|
-
]);
|
|
34
|
-
if (!reinit) {
|
|
35
|
-
console.log(chalk.yellow('\n✓ Initialization cancelled\n'));
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
// Load existing config if re-initializing
|
|
40
24
|
const agentManager = new AgentManager();
|
|
41
25
|
let existingIntegrations = [];
|
|
26
|
+
// Load existing config if present
|
|
42
27
|
if (await FileSystem.exists('.clavix/config.json')) {
|
|
43
28
|
try {
|
|
44
29
|
const configContent = await FileSystem.readFile('.clavix/config.json');
|
|
@@ -49,6 +34,45 @@ export default class Init extends Command {
|
|
|
49
34
|
// Ignore parse errors, will use empty array
|
|
50
35
|
}
|
|
51
36
|
}
|
|
37
|
+
// Check if already initialized
|
|
38
|
+
if (await FileSystem.exists('.clavix')) {
|
|
39
|
+
// Show current state
|
|
40
|
+
console.log(chalk.cyan('You have existing Clavix configuration:'));
|
|
41
|
+
if (existingIntegrations.length > 0) {
|
|
42
|
+
const displayNames = existingIntegrations.map((name) => {
|
|
43
|
+
const adapter = agentManager.getAdapter(name);
|
|
44
|
+
return adapter?.displayName || name;
|
|
45
|
+
});
|
|
46
|
+
console.log(chalk.gray(` Integrations: ${displayNames.join(', ')}\n`));
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
console.log(chalk.gray(' Integrations: (none configured)\n'));
|
|
50
|
+
}
|
|
51
|
+
const { action } = await inquirer.prompt([
|
|
52
|
+
{
|
|
53
|
+
type: 'list',
|
|
54
|
+
name: 'action',
|
|
55
|
+
message: 'What would you like to do?',
|
|
56
|
+
choices: [
|
|
57
|
+
{ name: 'Reconfigure integrations', value: 'reconfigure' },
|
|
58
|
+
{ name: 'Update existing (regenerate commands)', value: 'update' },
|
|
59
|
+
{ name: 'Cancel', value: 'cancel' },
|
|
60
|
+
],
|
|
61
|
+
},
|
|
62
|
+
]);
|
|
63
|
+
if (action === 'cancel') {
|
|
64
|
+
console.log(chalk.yellow('\n✓ Initialization cancelled\n'));
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
if (action === 'update') {
|
|
68
|
+
// Just regenerate commands for existing integrations
|
|
69
|
+
console.log(chalk.cyan('\n📝 Regenerating commands...\n'));
|
|
70
|
+
await this.regenerateCommands(agentManager, existingIntegrations);
|
|
71
|
+
console.log(chalk.green('\n✅ Commands updated successfully!\n'));
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
// Continue with reconfiguration flow below
|
|
75
|
+
}
|
|
52
76
|
// Select integrations using shared utility
|
|
53
77
|
console.log(chalk.gray('Select AI development tools to support:\n'));
|
|
54
78
|
console.log(chalk.gray('(Space to select, Enter to confirm)\n'));
|
|
@@ -83,6 +107,32 @@ export default class Init extends Command {
|
|
|
83
107
|
if (cleanupAction === 'cleanup') {
|
|
84
108
|
console.log(chalk.gray('\n🗑️ Cleaning up deselected integrations...'));
|
|
85
109
|
for (const integrationName of deselectedIntegrations) {
|
|
110
|
+
// Handle doc generators (AGENTS.md, OCTO.md, WARP.md, copilot-instructions)
|
|
111
|
+
if (integrationName === 'agents-md') {
|
|
112
|
+
await DocInjector.removeBlock('AGENTS.md');
|
|
113
|
+
console.log(chalk.gray(' ✓ Cleaned AGENTS.md Clavix block'));
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
if (integrationName === 'octo-md') {
|
|
117
|
+
await DocInjector.removeBlock('OCTO.md');
|
|
118
|
+
console.log(chalk.gray(' ✓ Cleaned OCTO.md Clavix block'));
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
if (integrationName === 'warp-md') {
|
|
122
|
+
await DocInjector.removeBlock('WARP.md');
|
|
123
|
+
console.log(chalk.gray(' ✓ Cleaned WARP.md Clavix block'));
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
if (integrationName === 'copilot-instructions') {
|
|
127
|
+
await DocInjector.removeBlock('.github/copilot-instructions.md');
|
|
128
|
+
console.log(chalk.gray(' ✓ Cleaned copilot-instructions.md Clavix block'));
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
// Handle Claude Code (has CLAUDE.md doc injection)
|
|
132
|
+
if (integrationName === 'claude-code') {
|
|
133
|
+
await DocInjector.removeBlock('CLAUDE.md');
|
|
134
|
+
console.log(chalk.gray(' ✓ Cleaned CLAUDE.md Clavix block'));
|
|
135
|
+
}
|
|
86
136
|
const adapter = agentManager.getAdapter(integrationName);
|
|
87
137
|
if (adapter) {
|
|
88
138
|
const removed = await adapter.removeAllCommands();
|
|
@@ -247,8 +297,69 @@ export default class Init extends Command {
|
|
|
247
297
|
throw toError(error);
|
|
248
298
|
}
|
|
249
299
|
}
|
|
300
|
+
/**
|
|
301
|
+
* Regenerate commands for existing integrations (update mode)
|
|
302
|
+
*/
|
|
303
|
+
async regenerateCommands(agentManager, integrations) {
|
|
304
|
+
for (const integrationName of integrations) {
|
|
305
|
+
// Handle doc generators (not adapters)
|
|
306
|
+
if (integrationName === 'agents-md') {
|
|
307
|
+
console.log(chalk.gray(' ✓ Regenerating AGENTS.md...'));
|
|
308
|
+
await AgentsMdGenerator.generate();
|
|
309
|
+
continue;
|
|
310
|
+
}
|
|
311
|
+
if (integrationName === 'copilot-instructions') {
|
|
312
|
+
console.log(chalk.gray(' ✓ Regenerating .github/copilot-instructions.md...'));
|
|
313
|
+
await CopilotInstructionsGenerator.generate();
|
|
314
|
+
continue;
|
|
315
|
+
}
|
|
316
|
+
if (integrationName === 'octo-md') {
|
|
317
|
+
console.log(chalk.gray(' ✓ Regenerating OCTO.md...'));
|
|
318
|
+
await OctoMdGenerator.generate();
|
|
319
|
+
continue;
|
|
320
|
+
}
|
|
321
|
+
if (integrationName === 'warp-md') {
|
|
322
|
+
console.log(chalk.gray(' ✓ Regenerating WARP.md...'));
|
|
323
|
+
await WarpMdGenerator.generate();
|
|
324
|
+
continue;
|
|
325
|
+
}
|
|
326
|
+
// Handle regular adapters
|
|
327
|
+
const adapter = agentManager.getAdapter(integrationName);
|
|
328
|
+
if (!adapter) {
|
|
329
|
+
console.log(chalk.yellow(` ⚠ Unknown integration: ${integrationName}`));
|
|
330
|
+
continue;
|
|
331
|
+
}
|
|
332
|
+
console.log(chalk.gray(` ✓ Regenerating ${adapter.displayName} commands...`));
|
|
333
|
+
// Remove existing commands before regenerating
|
|
334
|
+
const removed = await adapter.removeAllCommands();
|
|
335
|
+
if (removed > 0) {
|
|
336
|
+
console.log(chalk.gray(` Removed ${removed} existing command(s)`));
|
|
337
|
+
}
|
|
338
|
+
// Generate slash commands
|
|
339
|
+
const templates = await this.generateSlashCommands(adapter);
|
|
340
|
+
// Handle legacy command cleanup (silent in update mode)
|
|
341
|
+
const commandNames = templates.map((template) => template.name);
|
|
342
|
+
const legacyFiles = await collectLegacyCommandFiles(adapter, commandNames);
|
|
343
|
+
if (legacyFiles.length > 0) {
|
|
344
|
+
for (const file of legacyFiles) {
|
|
345
|
+
await FileSystem.remove(file);
|
|
346
|
+
}
|
|
347
|
+
console.log(chalk.gray(` Cleaned ${legacyFiles.length} legacy file(s)`));
|
|
348
|
+
}
|
|
349
|
+
// Re-inject documentation blocks (Claude Code only)
|
|
350
|
+
if (integrationName === 'claude-code') {
|
|
351
|
+
console.log(chalk.gray(' ✓ Updating CLAUDE.md documentation...'));
|
|
352
|
+
await this.injectDocumentation(adapter);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
// Regenerate instructions folder if needed
|
|
356
|
+
if (InstructionsGenerator.needsGeneration(integrations)) {
|
|
357
|
+
console.log(chalk.gray('\n📁 Updating .clavix/instructions/ reference folder...'));
|
|
358
|
+
await InstructionsGenerator.generate();
|
|
359
|
+
}
|
|
360
|
+
}
|
|
250
361
|
async createDirectoryStructure() {
|
|
251
|
-
const dirs = ['.clavix', '.clavix/
|
|
362
|
+
const dirs = ['.clavix', '.clavix/outputs', '.clavix/templates'];
|
|
252
363
|
for (const dir of dirs) {
|
|
253
364
|
await FileSystem.ensureDir(dir);
|
|
254
365
|
}
|
|
@@ -274,7 +385,6 @@ Welcome to Clavix! This directory contains your local Clavix configuration and d
|
|
|
274
385
|
├── config.json # Your Clavix configuration
|
|
275
386
|
├── INSTRUCTIONS.md # This file
|
|
276
387
|
├── instructions/ # Workflow instruction files for AI agents
|
|
277
|
-
├── sessions/ # Conversational mode session files
|
|
278
388
|
├── outputs/
|
|
279
389
|
│ ├── <project-name>/ # Per-project outputs
|
|
280
390
|
│ │ ├── full-prd.md
|
|
@@ -293,7 +403,7 @@ Welcome to Clavix! This directory contains your local Clavix configuration and d
|
|
|
293
403
|
|---------|---------|
|
|
294
404
|
| \`clavix init\` | Initialize Clavix in a project |
|
|
295
405
|
| \`clavix update\` | Update templates after package update |
|
|
296
|
-
| \`clavix
|
|
406
|
+
| \`clavix diagnose\` | Check installation health |
|
|
297
407
|
| \`clavix version\` | Show version |
|
|
298
408
|
|
|
299
409
|
### Workflow Commands (Slash Commands)
|
|
@@ -363,11 +473,7 @@ PRD Creation → Task Planning → Implementation → Archive
|
|
|
363
473
|
|
|
364
474
|
Create custom templates in \`.clavix/templates/\` to override defaults.
|
|
365
475
|
|
|
366
|
-
|
|
367
|
-
\`\`\`bash
|
|
368
|
-
clavix config edit # Opens config.json in $EDITOR
|
|
369
|
-
clavix config set key=value
|
|
370
|
-
\`\`\`
|
|
476
|
+
To reconfigure integrations, run \`clavix init\` again.
|
|
371
477
|
|
|
372
478
|
## Need Help?
|
|
373
479
|
|
|
@@ -220,7 +220,7 @@ This project uses Clavix for prompt improvement and PRD generation.
|
|
|
220
220
|
|---------|---------|
|
|
221
221
|
| \`clavix init\` | Initialize Clavix in a project |
|
|
222
222
|
| \`clavix update\` | Update templates after package update |
|
|
223
|
-
| \`clavix
|
|
223
|
+
| \`clavix diagnose\` | Check installation health |
|
|
224
224
|
| \`clavix version\` | Show version |
|
|
225
225
|
|
|
226
226
|
### Workflow Commands (Slash Commands)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Clavix constants and magic values
|
|
3
|
+
* Centralizes hardcoded values for maintainability
|
|
4
|
+
*/
|
|
5
|
+
export declare const BACKUP_EXTENSION = ".backup";
|
|
6
|
+
export declare const SEPARATOR_WIDTH = 50;
|
|
7
|
+
export declare const SEPARATOR_CHAR = "\u2500";
|
|
8
|
+
export declare const CLAVIX_BLOCK_START = "<!-- CLAVIX:START -->";
|
|
9
|
+
export declare const CLAVIX_BLOCK_END = "<!-- CLAVIX:END -->";
|
|
10
|
+
export declare const WINDSURF_CHAR_LIMIT = 12000;
|
|
11
|
+
export declare const DEPTH_STANDARD = "standard";
|
|
12
|
+
export declare const DEPTH_COMPREHENSIVE = "comprehensive";
|
|
13
|
+
export declare const CLAVIX_CONFIG_DIR = ".clavix";
|
|
14
|
+
export declare const CLAVIX_CONFIG_FILE = "config.json";
|
|
15
|
+
export declare const CLAVIX_OUTPUTS_DIR = "outputs";
|
|
16
|
+
export declare const CLAVIX_PROMPTS_DIR = "prompts";
|
|
17
|
+
export declare const CLAVIX_TEMPLATES_DIR = "templates";
|
|
18
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Clavix constants and magic values
|
|
3
|
+
* Centralizes hardcoded values for maintainability
|
|
4
|
+
*/
|
|
5
|
+
// File system
|
|
6
|
+
export const BACKUP_EXTENSION = '.backup';
|
|
7
|
+
// CLI formatting
|
|
8
|
+
export const SEPARATOR_WIDTH = 50;
|
|
9
|
+
export const SEPARATOR_CHAR = '─';
|
|
10
|
+
// Clavix managed block markers
|
|
11
|
+
export const CLAVIX_BLOCK_START = '<!-- CLAVIX:START -->';
|
|
12
|
+
export const CLAVIX_BLOCK_END = '<!-- CLAVIX:END -->';
|
|
13
|
+
// Adapter-specific limits
|
|
14
|
+
export const WINDSURF_CHAR_LIMIT = 12000;
|
|
15
|
+
// Depth terminology (canonical)
|
|
16
|
+
export const DEPTH_STANDARD = 'standard';
|
|
17
|
+
export const DEPTH_COMPREHENSIVE = 'comprehensive';
|
|
18
|
+
// File patterns
|
|
19
|
+
export const CLAVIX_CONFIG_DIR = '.clavix';
|
|
20
|
+
export const CLAVIX_CONFIG_FILE = 'config.json';
|
|
21
|
+
export const CLAVIX_OUTPUTS_DIR = 'outputs';
|
|
22
|
+
export const CLAVIX_PROMPTS_DIR = 'prompts';
|
|
23
|
+
export const CLAVIX_TEMPLATES_DIR = 'templates';
|
|
24
|
+
//# sourceMappingURL=constants.js.map
|