clavix 7.0.0 → 7.1.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.
@@ -261,12 +261,71 @@ export default class Init extends Command {
261
261
  }
262
262
  }
263
263
  }
264
+ // Prompt for custom Agent Skills path if selected
265
+ if (selectedIntegrations.includes('agent-skills-custom')) {
266
+ this.log(chalk.cyan('\nšŸ”§ Agent Skills Custom Path Configuration'));
267
+ const { pathType } = await inquirer.prompt([
268
+ {
269
+ type: 'list',
270
+ name: 'pathType',
271
+ message: 'What type of path do you want to use?',
272
+ choices: [
273
+ {
274
+ name: 'Relative - resolved from current folder (e.g., .aider-desk/skills)',
275
+ value: 'relative',
276
+ },
277
+ {
278
+ name: 'Absolute - starts from root or home (e.g., ~/.config/my-skills or /opt/skills)',
279
+ value: 'absolute',
280
+ },
281
+ ],
282
+ },
283
+ ]);
284
+ const existingCustomPath = existingConfig?.experimental?.integrationPaths?.['agent-skills-custom'];
285
+ const { customSkillsPath } = await inquirer.prompt([
286
+ {
287
+ type: 'input',
288
+ name: 'customSkillsPath',
289
+ message: 'Enter path to skills directory:',
290
+ default: existingCustomPath ||
291
+ (pathType === 'relative' ? '.skills' : '~/.config/agents/skills'),
292
+ validate: (input) => {
293
+ const trimmed = input.trim();
294
+ if (!trimmed) {
295
+ return 'Path cannot be empty';
296
+ }
297
+ if (pathType === 'relative') {
298
+ if (path.isAbsolute(trimmed) || trimmed.startsWith('~/')) {
299
+ return 'Relative path should not start with / or ~/. Example: .aider-desk/skills';
300
+ }
301
+ }
302
+ else {
303
+ if (!path.isAbsolute(trimmed) && !trimmed.startsWith('~/')) {
304
+ return 'Absolute path should start with / or ~/. Example: ~/.config/my-skills';
305
+ }
306
+ }
307
+ return true;
308
+ },
309
+ },
310
+ ]);
311
+ integrationPaths['agent-skills-custom'] = customSkillsPath.trim();
312
+ this.log(chalk.gray(` āœ“ Using custom skills path: ${customSkillsPath.trim()}`));
313
+ }
264
314
  // Create .clavix directory structure
265
315
  this.log(chalk.cyan('\nšŸ“ Creating directory structure...'));
266
316
  await this.createDirectoryStructure();
267
317
  // Generate config
268
318
  this.log(chalk.cyan('āš™ļø Generating configuration...'));
269
319
  await this.generateConfig(selectedIntegrations, integrationPaths);
320
+ // Re-create AgentManager with updated config (includes custom integration paths)
321
+ const updatedConfig = {
322
+ ...DEFAULT_CONFIG,
323
+ integrations: selectedIntegrations,
324
+ ...(Object.keys(integrationPaths).length > 0 && {
325
+ experimental: { integrationPaths },
326
+ }),
327
+ };
328
+ const updatedAgentManager = new AgentManager(updatedConfig);
270
329
  // Generate INSTRUCTIONS.md and QUICKSTART.md
271
330
  await this.generateInstructions();
272
331
  await this.generateQuickstart();
@@ -292,9 +351,17 @@ export default class Init extends Command {
292
351
  }
293
352
  // Handle Agent Skills integrations
294
353
  if (isAgentSkillsIntegration(integrationName)) {
295
- const adapter = agentManager.requireAdapter(integrationName);
296
- const scope = integrationName === 'agent-skills-global' ? 'global' : 'project';
297
- const location = scope === 'global' ? '~/.config/agents/skills/' : '.skills/';
354
+ const adapter = updatedAgentManager.requireAdapter(integrationName);
355
+ let location;
356
+ if (integrationName === 'agent-skills-global') {
357
+ location = '~/.config/agents/skills/';
358
+ }
359
+ else if (integrationName === 'agent-skills-project') {
360
+ location = '.skills/';
361
+ }
362
+ else {
363
+ location = integrationPaths['agent-skills-custom'] || 'custom path';
364
+ }
298
365
  this.log(chalk.gray(` āœ“ Generating ${adapter.displayName}...`));
299
366
  // Validate before generating
300
367
  if (adapter.validate) {
@@ -27,8 +27,13 @@ export declare class AgentSkillsAdapter extends BaseAdapter {
27
27
  get installScope(): SkillScope;
28
28
  /**
29
29
  * Get the directory path based on scope
30
+ * For custom scope without a configured path, returns a placeholder
30
31
  */
31
32
  get directory(): string;
33
+ /**
34
+ * Check if the adapter is properly configured
35
+ */
36
+ isConfigured(): boolean;
32
37
  /**
33
38
  * Expand tilde in path to home directory
34
39
  */
@@ -31,12 +31,21 @@ export class AgentSkillsAdapter extends BaseAdapter {
31
31
  this.scope = scope;
32
32
  this.userConfig = userConfig;
33
33
  // Set name and displayName based on scope
34
- this.name = scope === 'global' ? 'agent-skills-global' : 'agent-skills-project';
35
- this.displayName = scope === 'global' ? 'Agent Skills (Global)' : 'Agent Skills (Project)';
34
+ if (scope === 'global') {
35
+ this.name = 'agent-skills-global';
36
+ this.displayName = 'Agent Skills (Global)';
37
+ }
38
+ else if (scope === 'project') {
39
+ this.name = 'agent-skills-project';
40
+ this.displayName = 'Agent Skills (Project)';
41
+ }
42
+ else {
43
+ this.name = 'agent-skills-custom';
44
+ this.displayName = 'Agent Skills (Custom Path)';
45
+ }
36
46
  // Check for custom path in user config
37
- const configKey = scope === 'global' ? 'agent-skills-global' : 'agent-skills-project';
38
- if (userConfig?.experimental?.integrationPaths?.[configKey]) {
39
- this.customPath = userConfig.experimental.integrationPaths[configKey];
47
+ if (userConfig?.experimental?.integrationPaths?.[this.name]) {
48
+ this.customPath = userConfig.experimental.integrationPaths[this.name];
40
49
  }
41
50
  }
42
51
  /**
@@ -47,13 +56,26 @@ export class AgentSkillsAdapter extends BaseAdapter {
47
56
  }
48
57
  /**
49
58
  * Get the directory path based on scope
59
+ * For custom scope without a configured path, returns a placeholder
50
60
  */
51
61
  get directory() {
52
62
  if (this.customPath) {
53
63
  return this.customPath;
54
64
  }
65
+ if (this.scope === 'custom') {
66
+ return '<custom-path-not-configured>';
67
+ }
55
68
  return this.scope === 'global' ? SKILL_PATHS.global : SKILL_PATHS.project;
56
69
  }
70
+ /**
71
+ * Check if the adapter is properly configured
72
+ */
73
+ isConfigured() {
74
+ if (this.scope === 'custom') {
75
+ return !!this.customPath;
76
+ }
77
+ return true;
78
+ }
57
79
  /**
58
80
  * Expand tilde in path to home directory
59
81
  */
@@ -68,9 +90,15 @@ export class AgentSkillsAdapter extends BaseAdapter {
68
90
  */
69
91
  getCommandPath() {
70
92
  const dir = this.directory;
71
- if (dir.startsWith('~/') || this.scope === 'global') {
93
+ // Expand ~ paths
94
+ if (dir.startsWith('~/')) {
72
95
  return this.expandPath(dir);
73
96
  }
97
+ // Absolute paths (global scope default or user-provided absolute)
98
+ if (this.scope === 'global' || path.isAbsolute(dir)) {
99
+ return dir;
100
+ }
101
+ // Relative paths (project scope or custom relative)
74
102
  return path.join(process.cwd(), dir);
75
103
  }
76
104
  /**
@@ -99,6 +127,9 @@ export class AgentSkillsAdapter extends BaseAdapter {
99
127
  * └── <reference-files>.md
100
128
  */
101
129
  async generateCommands(templates) {
130
+ if (!this.isConfigured()) {
131
+ throw new IntegrationError('Custom scope requires a custom path to be set', 'Ensure agent-skills-custom has a path configured in experimental.integrationPaths');
132
+ }
102
133
  const skillsPath = this.getCommandPath();
103
134
  try {
104
135
  // Ensure base directory exists
@@ -28,9 +28,10 @@ export class AgentManager {
28
28
  this.registerAdapter(new QwenAdapter(userConfig)); // TOML format
29
29
  this.registerAdapter(new LlxprtAdapter(userConfig)); // TOML format
30
30
  this.registerAdapter(new VibeAdapter(userConfig)); // Vibe CLI skills
31
- // Register Agent Skills adapters (both global and project scope)
31
+ // Register Agent Skills adapters (global, project, and custom scope)
32
32
  this.registerAdapter(new AgentSkillsAdapter('global', userConfig));
33
33
  this.registerAdapter(new AgentSkillsAdapter('project', userConfig));
34
+ this.registerAdapter(new AgentSkillsAdapter('custom', userConfig));
34
35
  // Register simple adapters from config (using UniversalAdapter factory)
35
36
  for (const config of getSimpleAdapters()) {
36
37
  // Skip adapters that have special handlers registered above
@@ -274,7 +274,7 @@ Result: Project permanently deleted
274
274
 
275
275
  ---
276
276
 
277
- ## Agent Transparency (v7.0.0)
277
+ ## Agent Transparency (v7.1.1)
278
278
 
279
279
  ### Agent Manual (Universal Protocols)
280
280
  {{INCLUDE:agent-protocols/AGENT_MANUAL.md}}
@@ -615,7 +615,7 @@ I'll explain what's wrong and what you might need to do:
615
615
 
616
616
  ---
617
617
 
618
- ## Agent Transparency (v7.0.0)
618
+ ## Agent Transparency (v7.1.1)
619
619
 
620
620
  ### Agent Manual (Universal Protocols)
621
621
  {{INCLUDE:agent-protocols/AGENT_MANUAL.md}}
@@ -380,7 +380,7 @@ This is a BLOCKING checkpoint. You cannot proceed to the final message until sav
380
380
  | Step | Action | Tool to Use | Verification |
381
381
  |------|--------|-------------|--------------|
382
382
  | 1 | Create directory | Write tool (create parent dirs) | Directory exists |
383
- | 2 | Generate prompt ID | Format: `{std\\|comp}-YYYYMMDD-HHMMSS-<random>` | ID is unique |
383
+ | 2 | Generate prompt ID | Format: `{std\|comp}-YYYYMMDD-HHMMSS-<random>` | ID is unique |
384
384
  | 3 | Write prompt file with frontmatter | **Write tool** | File created |
385
385
  | 4 | **VERIFY: Read back file** | **Read tool** | File readable |
386
386
 
@@ -524,7 +524,7 @@ Wait for the user to decide what to do next.
524
524
 
525
525
  ---
526
526
 
527
- ## Agent Transparency (v7.0.0)
527
+ ## Agent Transparency (v7.1.1)
528
528
 
529
529
  ### Agent Manual (Universal Protocols)
530
530
  {{INCLUDE:agent-protocols/AGENT_MANUAL.md}}
@@ -229,7 +229,7 @@ Present the plan and ask:
229
229
 
230
230
  ---
231
231
 
232
- ## Agent Transparency (v7.0.0)
232
+ ## Agent Transparency (v7.1.1)
233
233
 
234
234
  ### Agent Manual (Universal Protocols)
235
235
  {{INCLUDE:agent-protocols/AGENT_MANUAL.md}}
@@ -354,7 +354,7 @@ The validation ensures generated PRDs are immediately usable for AI consumption
354
354
 
355
355
  ---
356
356
 
357
- ## Agent Transparency (v7.0.0)
357
+ ## Agent Transparency (v7.1.1)
358
358
 
359
359
  ### Agent Manual (Universal Protocols)
360
360
  {{INCLUDE:agent-protocols/AGENT_MANUAL.md}}
@@ -415,7 +415,7 @@ I'll update the PRD and add this to the refinement history. Confirm?
415
415
 
416
416
  ---
417
417
 
418
- ## Agent Transparency (v7.0.0)
418
+ ## Agent Transparency (v7.1.1)
419
419
 
420
420
  ### Agent Manual (Universal Protocols)
421
421
  {{INCLUDE:agent-protocols/AGENT_MANUAL.md}}
@@ -447,7 +447,7 @@ consistent with the project's conventions.
447
447
 
448
448
  ---
449
449
 
450
- ## Agent Transparency (v7.0.0)
450
+ ## Agent Transparency (v7.1.1)
451
451
 
452
452
  ### Agent Manual (Universal Protocols)
453
453
  {{INCLUDE:agent-protocols/AGENT_MANUAL.md}}
@@ -230,7 +230,7 @@ The goal is natural exploration of requirements, not a rigid questionnaire. Foll
230
230
 
231
231
  ---
232
232
 
233
- ## Agent Transparency (v7.0.0)
233
+ ## Agent Transparency (v7.1.1)
234
234
 
235
235
  ### Agent Manual (Universal Protocols)
236
236
  {{INCLUDE:agent-protocols/AGENT_MANUAL.md}}
@@ -409,7 +409,7 @@ The `/clavix:summarize` command extracts requirements from exploratory conversat
409
409
 
410
410
  ---
411
411
 
412
- ## Agent Transparency (v7.0.0)
412
+ ## Agent Transparency (v7.1.1)
413
413
 
414
414
  ### Agent Manual (Universal Protocols)
415
415
  {{INCLUDE:agent-protocols/AGENT_MANUAL.md}}
@@ -123,7 +123,7 @@ Implementation: BLOCKED - I'll analyze and report, not modify or fix
123
123
 
124
124
  ----
125
125
 
126
- ## Agent Transparency (v7.0.0)
126
+ ## Agent Transparency (v7.1.1)
127
127
 
128
128
  ### Agent Manual (Universal Protocols)
129
129
  {{INCLUDE:agent-protocols/AGENT_MANUAL.md}}
@@ -9,7 +9,7 @@
9
9
  /**
10
10
  * Skill installation scope
11
11
  */
12
- export type SkillScope = 'global' | 'project';
12
+ export type SkillScope = 'global' | 'project' | 'custom';
13
13
  /**
14
14
  * Skill template with optional references
15
15
  * Used during skill generation
@@ -71,7 +71,7 @@ export interface SkillDirectory {
71
71
  * Skills configuration options
72
72
  */
73
73
  export interface SkillsConfig {
74
- /** Installation scope: 'global' or 'project' */
74
+ /** Installation scope: 'global', 'project', or 'custom' */
75
75
  scope: SkillScope;
76
76
  /** Custom directory path (overrides default based on scope) */
77
77
  customPath?: string;
@@ -21,6 +21,7 @@ export async function selectIntegrations(agentManager, preSelected = []) {
21
21
  new inquirer.Separator('=== Agent Skills (agentskills.io) ==='),
22
22
  { name: 'Agent Skills - Global (~/.config/agents/skills/)', value: 'agent-skills-global' },
23
23
  { name: 'Agent Skills - Project (.skills/)', value: 'agent-skills-project' },
24
+ { name: 'Agent Skills - Custom Path', value: 'agent-skills-custom' },
24
25
  new inquirer.Separator(),
25
26
  new inquirer.Separator('=== CLI Tools ==='),
26
27
  { name: 'Amp (.agents/commands/)', value: 'amp' },
@@ -83,7 +84,9 @@ export function ensureMandatoryIntegrations(integrations) {
83
84
  * Check if agent skills integration is selected
84
85
  */
85
86
  export function hasAgentSkillsSelected(integrations) {
86
- return (integrations.includes('agent-skills-global') || integrations.includes('agent-skills-project'));
87
+ return (integrations.includes('agent-skills-global') ||
88
+ integrations.includes('agent-skills-project') ||
89
+ integrations.includes('agent-skills-custom'));
87
90
  }
88
91
  /**
89
92
  * Get the skill scope from integration name
@@ -93,12 +96,16 @@ export function getSkillScope(integrationName) {
93
96
  return 'global';
94
97
  if (integrationName === 'agent-skills-project')
95
98
  return 'project';
99
+ if (integrationName === 'agent-skills-custom')
100
+ return 'custom';
96
101
  return null;
97
102
  }
98
103
  /**
99
104
  * Check if integration name is an agent skills integration
100
105
  */
101
106
  export function isAgentSkillsIntegration(name) {
102
- return name === 'agent-skills-global' || name === 'agent-skills-project';
107
+ return (name === 'agent-skills-global' ||
108
+ name === 'agent-skills-project' ||
109
+ name === 'agent-skills-custom');
103
110
  }
104
111
  //# sourceMappingURL=integration-selector.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clavix",
3
- "version": "7.0.0",
3
+ "version": "7.1.1",
4
4
  "description": "Agentic-first prompt workflows. Markdown templates that teach AI agents how to optimize prompts, create PRDs, and manage implementation.\n\nSLASH COMMANDS (in your AI assistant):\n /clavix:improve Optimize prompts with auto-depth\n /clavix:prd Generate PRD through questions\n /clavix:plan Create task breakdown from PRD\n /clavix:implement Execute tasks with progress tracking\n /clavix:start Begin conversational session\n /clavix:summarize Extract requirements from conversation\n /clavix:refine Refine existing PRD or prompt\n /clavix:verify Verify implementation against requirements\n /clavix:review Review teammate PRs with criteria\n /clavix:archive Archive completed projects\n\nWorks with Claude Code, Cursor, Windsurf, and 20 AI coding tools.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",