@paths.design/caws-cli 3.2.4 ā 3.3.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/dist/commands/diagnose.d.ts +52 -0
- package/dist/commands/diagnose.d.ts.map +1 -0
- package/dist/commands/diagnose.js +472 -0
- package/dist/commands/status.d.ts +38 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +276 -0
- package/dist/commands/templates.d.ts +74 -0
- package/dist/commands/templates.d.ts.map +1 -0
- package/dist/commands/templates.js +235 -0
- package/dist/error-handler.d.ts +27 -2
- package/dist/error-handler.d.ts.map +1 -1
- package/dist/error-handler.js +187 -16
- package/dist/generators/jest-config.d.ts +32 -0
- package/dist/generators/jest-config.d.ts.map +1 -0
- package/dist/generators/jest-config.js +242 -0
- package/dist/index-new.d.ts +5 -0
- package/dist/index-new.d.ts.map +1 -0
- package/dist/index-new.js +317 -0
- package/dist/index.js +174 -4
- package/dist/index.js.backup +4711 -0
- package/dist/scaffold/index.d.ts.map +1 -1
- package/dist/scaffold/index.js +13 -0
- package/dist/utils/typescript-detector.d.ts +32 -0
- package/dist/utils/typescript-detector.d.ts.map +1 -0
- package/dist/utils/typescript-detector.js +185 -0
- package/package.json +4 -4
- package/templates/OIDC_SETUP.md +300 -0
- package/templates/agents.md +912 -686
- package/templates/apps/tools/caws/prompt-lint.js.backup +274 -0
- package/templates/apps/tools/caws/provenance.js.backup +73 -0
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview CAWS Status Command
|
|
3
|
+
* Display project health overview
|
|
4
|
+
* @author @darianrosebrook
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const fs = require('fs-extra');
|
|
8
|
+
const path = require('path');
|
|
9
|
+
const yaml = require('js-yaml');
|
|
10
|
+
const chalk = require('chalk');
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Load working specification
|
|
14
|
+
* @param {string} specPath - Path to working spec
|
|
15
|
+
* @returns {Promise<Object|null>} Parsed spec or null
|
|
16
|
+
*/
|
|
17
|
+
async function loadWorkingSpec(specPath = '.caws/working-spec.yaml') {
|
|
18
|
+
try {
|
|
19
|
+
if (!(await fs.pathExists(specPath))) {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const content = await fs.readFile(specPath, 'utf8');
|
|
24
|
+
return yaml.load(content);
|
|
25
|
+
} catch (error) {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Check Git hooks status
|
|
32
|
+
* @returns {Promise<Object>} Hooks status
|
|
33
|
+
*/
|
|
34
|
+
async function checkGitHooks() {
|
|
35
|
+
const hooksDir = '.git/hooks';
|
|
36
|
+
|
|
37
|
+
if (!(await fs.pathExists(hooksDir))) {
|
|
38
|
+
return {
|
|
39
|
+
installed: false,
|
|
40
|
+
count: 0,
|
|
41
|
+
active: [],
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const cawsHooks = ['pre-commit', 'post-commit', 'pre-push', 'commit-msg'];
|
|
46
|
+
const activeHooks = [];
|
|
47
|
+
|
|
48
|
+
for (const hook of cawsHooks) {
|
|
49
|
+
const hookPath = path.join(hooksDir, hook);
|
|
50
|
+
if (await fs.pathExists(hookPath)) {
|
|
51
|
+
const content = await fs.readFile(hookPath, 'utf8');
|
|
52
|
+
if (content.includes('CAWS')) {
|
|
53
|
+
activeHooks.push(hook);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return {
|
|
59
|
+
installed: activeHooks.length > 0,
|
|
60
|
+
count: activeHooks.length,
|
|
61
|
+
active: activeHooks,
|
|
62
|
+
total: cawsHooks.length,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Load provenance chain
|
|
68
|
+
* @returns {Promise<Object>} Provenance status
|
|
69
|
+
*/
|
|
70
|
+
async function loadProvenanceChain() {
|
|
71
|
+
const chainPath = '.caws/provenance/chain.json';
|
|
72
|
+
|
|
73
|
+
if (!(await fs.pathExists(chainPath))) {
|
|
74
|
+
return {
|
|
75
|
+
exists: false,
|
|
76
|
+
count: 0,
|
|
77
|
+
lastUpdate: null,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
try {
|
|
82
|
+
const chain = JSON.parse(await fs.readFile(chainPath, 'utf8'));
|
|
83
|
+
const lastEntry = chain.length > 0 ? chain[chain.length - 1] : null;
|
|
84
|
+
|
|
85
|
+
return {
|
|
86
|
+
exists: true,
|
|
87
|
+
count: chain.length,
|
|
88
|
+
lastUpdate: lastEntry?.timestamp || null,
|
|
89
|
+
lastCommit: lastEntry?.commit?.hash || null,
|
|
90
|
+
};
|
|
91
|
+
} catch (error) {
|
|
92
|
+
return {
|
|
93
|
+
exists: true,
|
|
94
|
+
count: 0,
|
|
95
|
+
lastUpdate: null,
|
|
96
|
+
error: error.message,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Check quality gates status (simplified)
|
|
103
|
+
* @returns {Promise<Object>} Quality gates status
|
|
104
|
+
*/
|
|
105
|
+
async function checkQualityGates() {
|
|
106
|
+
// For now, return a placeholder
|
|
107
|
+
// In full implementation, this would run actual gate checks
|
|
108
|
+
return {
|
|
109
|
+
checked: false,
|
|
110
|
+
message: 'Run: node apps/tools/caws/gates.js for full gate status',
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Get time since last update
|
|
116
|
+
* @param {string} timestamp - ISO timestamp
|
|
117
|
+
* @returns {string} Human-readable time
|
|
118
|
+
*/
|
|
119
|
+
function getTimeSince(timestamp) {
|
|
120
|
+
if (!timestamp) return 'never';
|
|
121
|
+
|
|
122
|
+
const now = new Date();
|
|
123
|
+
const then = new Date(timestamp);
|
|
124
|
+
const diffMs = now - then;
|
|
125
|
+
|
|
126
|
+
const diffMins = Math.floor(diffMs / 60000);
|
|
127
|
+
const diffHours = Math.floor(diffMs / 3600000);
|
|
128
|
+
const diffDays = Math.floor(diffMs / 86400000);
|
|
129
|
+
|
|
130
|
+
if (diffMins < 1) return 'just now';
|
|
131
|
+
if (diffMins < 60) return `${diffMins} minute${diffMins > 1 ? 's' : ''} ago`;
|
|
132
|
+
if (diffHours < 24) return `${diffHours} hour${diffHours > 1 ? 's' : ''} ago`;
|
|
133
|
+
return `${diffDays} day${diffDays > 1 ? 's' : ''} ago`;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Display project status
|
|
138
|
+
* @param {Object} data - Status data
|
|
139
|
+
*/
|
|
140
|
+
function displayStatus(data) {
|
|
141
|
+
const { spec, hooks, provenance, gates } = data;
|
|
142
|
+
|
|
143
|
+
console.log(chalk.bold.cyan('\nš CAWS Project Status'));
|
|
144
|
+
console.log(chalk.cyan('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n'));
|
|
145
|
+
|
|
146
|
+
// Working Spec Status
|
|
147
|
+
if (spec) {
|
|
148
|
+
console.log(chalk.green('ā
Working Spec'));
|
|
149
|
+
console.log(chalk.gray(` ID: ${spec.id} | Tier: ${spec.risk_tier} | Mode: ${spec.mode}`));
|
|
150
|
+
console.log(chalk.gray(` Title: ${spec.title}`));
|
|
151
|
+
} else {
|
|
152
|
+
console.log(chalk.red('ā Working Spec'));
|
|
153
|
+
console.log(chalk.gray(' No working spec found'));
|
|
154
|
+
console.log(chalk.yellow(' š” Run: caws init . to create one'));
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
console.log('');
|
|
158
|
+
|
|
159
|
+
// Git Hooks Status
|
|
160
|
+
if (hooks.installed) {
|
|
161
|
+
console.log(chalk.green(`ā
Git Hooks`));
|
|
162
|
+
console.log(chalk.gray(` ${hooks.count}/${hooks.total} active: ${hooks.active.join(', ')}`));
|
|
163
|
+
} else {
|
|
164
|
+
console.log(chalk.yellow('ā ļø Git Hooks'));
|
|
165
|
+
console.log(chalk.gray(' No CAWS git hooks installed'));
|
|
166
|
+
console.log(chalk.yellow(' š” Run: caws hooks install'));
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
console.log('');
|
|
170
|
+
|
|
171
|
+
// Provenance Status
|
|
172
|
+
if (provenance.exists) {
|
|
173
|
+
console.log(chalk.green('ā
Provenance'));
|
|
174
|
+
console.log(chalk.gray(` Chain: ${provenance.count} entries`));
|
|
175
|
+
if (provenance.lastUpdate) {
|
|
176
|
+
console.log(chalk.gray(` Last update: ${getTimeSince(provenance.lastUpdate)}`));
|
|
177
|
+
}
|
|
178
|
+
} else {
|
|
179
|
+
console.log(chalk.yellow('ā ļø Provenance'));
|
|
180
|
+
console.log(chalk.gray(' Provenance tracking not initialized'));
|
|
181
|
+
console.log(chalk.yellow(' š” Run: caws provenance init'));
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
console.log('');
|
|
185
|
+
|
|
186
|
+
// Quality Gates Status
|
|
187
|
+
console.log(chalk.blue('ā¹ļø Quality Gates'));
|
|
188
|
+
console.log(chalk.gray(` ${gates.message}`));
|
|
189
|
+
|
|
190
|
+
// Suggestions
|
|
191
|
+
const suggestions = generateSuggestions(data);
|
|
192
|
+
if (suggestions.length > 0) {
|
|
193
|
+
console.log(chalk.bold.yellow('\nš” Suggestions:'));
|
|
194
|
+
suggestions.forEach((suggestion) => {
|
|
195
|
+
console.log(chalk.yellow(` ${suggestion}`));
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// Quick Links
|
|
200
|
+
console.log(chalk.bold.blue('\nš Quick Links:'));
|
|
201
|
+
if (spec) {
|
|
202
|
+
console.log(chalk.blue(' View spec: .caws/working-spec.yaml'));
|
|
203
|
+
}
|
|
204
|
+
if (hooks.installed) {
|
|
205
|
+
console.log(chalk.blue(' View hooks: .git/hooks/'));
|
|
206
|
+
}
|
|
207
|
+
if (provenance.exists) {
|
|
208
|
+
console.log(chalk.blue(' View provenance: caws provenance show --format=dashboard'));
|
|
209
|
+
}
|
|
210
|
+
console.log(chalk.blue(' Full documentation: docs/agents/full-guide.md'));
|
|
211
|
+
|
|
212
|
+
console.log('');
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Generate actionable suggestions based on status
|
|
217
|
+
* @param {Object} data - Status data
|
|
218
|
+
* @returns {string[]} Array of suggestions
|
|
219
|
+
*/
|
|
220
|
+
function generateSuggestions(data) {
|
|
221
|
+
const suggestions = [];
|
|
222
|
+
|
|
223
|
+
if (!data.spec) {
|
|
224
|
+
suggestions.push('Initialize CAWS: caws init .');
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
if (!data.hooks.installed) {
|
|
228
|
+
suggestions.push('Install Git hooks: caws hooks install');
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
if (!data.provenance.exists) {
|
|
232
|
+
suggestions.push('Initialize provenance tracking: caws provenance init');
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
if (data.spec && !data.hooks.installed && !data.provenance.exists) {
|
|
236
|
+
suggestions.push('Complete setup: caws scaffold');
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
return suggestions;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Status command handler
|
|
244
|
+
* @param {Object} options - Command options
|
|
245
|
+
*/
|
|
246
|
+
async function statusCommand(options = {}) {
|
|
247
|
+
try {
|
|
248
|
+
// Load all status data
|
|
249
|
+
const spec = await loadWorkingSpec(options.spec || '.caws/working-spec.yaml');
|
|
250
|
+
const hooks = await checkGitHooks();
|
|
251
|
+
const provenance = await loadProvenanceChain();
|
|
252
|
+
const gates = await checkQualityGates();
|
|
253
|
+
|
|
254
|
+
// Display status
|
|
255
|
+
displayStatus({
|
|
256
|
+
spec,
|
|
257
|
+
hooks,
|
|
258
|
+
provenance,
|
|
259
|
+
gates,
|
|
260
|
+
});
|
|
261
|
+
} catch (error) {
|
|
262
|
+
console.error(chalk.red('ā Error checking project status:'), error.message);
|
|
263
|
+
console.error(chalk.yellow('\nš” Try: caws validate to check your setup'));
|
|
264
|
+
process.exit(1);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
module.exports = {
|
|
269
|
+
statusCommand,
|
|
270
|
+
loadWorkingSpec,
|
|
271
|
+
checkGitHooks,
|
|
272
|
+
loadProvenanceChain,
|
|
273
|
+
checkQualityGates,
|
|
274
|
+
displayStatus,
|
|
275
|
+
generateSuggestions,
|
|
276
|
+
};
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Templates command handler
|
|
3
|
+
* @param {string} subcommand - Subcommand (list, info)
|
|
4
|
+
* @param {Object} options - Command options
|
|
5
|
+
*/
|
|
6
|
+
export function templatesCommand(subcommand?: string, options?: any): Promise<void>;
|
|
7
|
+
/**
|
|
8
|
+
* List all available templates
|
|
9
|
+
*/
|
|
10
|
+
export function listTemplates(): void;
|
|
11
|
+
/**
|
|
12
|
+
* Show detailed template information
|
|
13
|
+
* @param {string} templateId - Template ID
|
|
14
|
+
*/
|
|
15
|
+
export function showTemplateInfo(templateId: string): void;
|
|
16
|
+
/**
|
|
17
|
+
* Check which templates actually exist
|
|
18
|
+
* @returns {Object} Available templates
|
|
19
|
+
*/
|
|
20
|
+
export function getAvailableTemplates(): any;
|
|
21
|
+
/**
|
|
22
|
+
* Built-in template definitions
|
|
23
|
+
*/
|
|
24
|
+
export const BUILTIN_TEMPLATES: {
|
|
25
|
+
'typescript-library': {
|
|
26
|
+
name: string;
|
|
27
|
+
description: string;
|
|
28
|
+
category: string;
|
|
29
|
+
tier: number;
|
|
30
|
+
features: string[];
|
|
31
|
+
path: string;
|
|
32
|
+
};
|
|
33
|
+
'typescript-api': {
|
|
34
|
+
name: string;
|
|
35
|
+
description: string;
|
|
36
|
+
category: string;
|
|
37
|
+
tier: number;
|
|
38
|
+
features: string[];
|
|
39
|
+
path: string;
|
|
40
|
+
};
|
|
41
|
+
'typescript-monorepo': {
|
|
42
|
+
name: string;
|
|
43
|
+
description: string;
|
|
44
|
+
category: string;
|
|
45
|
+
tier: number;
|
|
46
|
+
features: string[];
|
|
47
|
+
path: string;
|
|
48
|
+
};
|
|
49
|
+
'javascript-package': {
|
|
50
|
+
name: string;
|
|
51
|
+
description: string;
|
|
52
|
+
category: string;
|
|
53
|
+
tier: number;
|
|
54
|
+
features: string[];
|
|
55
|
+
path: string;
|
|
56
|
+
};
|
|
57
|
+
'react-component-lib': {
|
|
58
|
+
name: string;
|
|
59
|
+
description: string;
|
|
60
|
+
category: string;
|
|
61
|
+
tier: number;
|
|
62
|
+
features: string[];
|
|
63
|
+
path: string;
|
|
64
|
+
};
|
|
65
|
+
'vscode-extension': {
|
|
66
|
+
name: string;
|
|
67
|
+
description: string;
|
|
68
|
+
category: string;
|
|
69
|
+
tier: number;
|
|
70
|
+
features: string[];
|
|
71
|
+
path: string;
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
//# sourceMappingURL=templates.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/commands/templates.js"],"names":[],"mappings":"AAoMA;;;;GAIG;AACH,8CAHW,MAAM,gCA4BhB;AAvHD;;GAEG;AACH,sCAuCC;AAED;;;GAGG;AACH,6CAFW,MAAM,QAyChB;AA9GD;;;GAGG;AACH,6CAiBC;AA/FD;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiDE"}
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview CAWS Templates Command
|
|
3
|
+
* Discover and manage project templates
|
|
4
|
+
* @author @darianrosebrook
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const fs = require('fs-extra');
|
|
8
|
+
const path = require('path');
|
|
9
|
+
const chalk = require('chalk');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Built-in template definitions
|
|
13
|
+
*/
|
|
14
|
+
const BUILTIN_TEMPLATES = {
|
|
15
|
+
'typescript-library': {
|
|
16
|
+
name: 'TypeScript Library',
|
|
17
|
+
description: 'Production-ready TypeScript library with Jest testing',
|
|
18
|
+
category: 'TypeScript',
|
|
19
|
+
tier: 2,
|
|
20
|
+
features: ['TypeScript', 'Jest', 'ESLint', 'Prettier', 'Publishing'],
|
|
21
|
+
path: 'templates/typescript/library',
|
|
22
|
+
},
|
|
23
|
+
'typescript-api': {
|
|
24
|
+
name: 'TypeScript API',
|
|
25
|
+
description: 'REST API with Express and TypeScript',
|
|
26
|
+
category: 'TypeScript',
|
|
27
|
+
tier: 1,
|
|
28
|
+
features: ['TypeScript', 'Express', 'Jest', 'OpenAPI', 'Docker'],
|
|
29
|
+
path: 'templates/typescript/api',
|
|
30
|
+
},
|
|
31
|
+
'typescript-monorepo': {
|
|
32
|
+
name: 'TypeScript Monorepo',
|
|
33
|
+
description: 'Multi-package TypeScript monorepo with Turbo',
|
|
34
|
+
category: 'TypeScript',
|
|
35
|
+
tier: 2,
|
|
36
|
+
features: ['TypeScript', 'Turborepo', 'Jest', 'Changesets'],
|
|
37
|
+
path: 'templates/typescript/monorepo',
|
|
38
|
+
},
|
|
39
|
+
'javascript-package': {
|
|
40
|
+
name: 'JavaScript Package',
|
|
41
|
+
description: 'NPM package with modern JavaScript',
|
|
42
|
+
category: 'JavaScript',
|
|
43
|
+
tier: 3,
|
|
44
|
+
features: ['JavaScript', 'Jest', 'ESLint', 'Publishing'],
|
|
45
|
+
path: 'templates/javascript/package',
|
|
46
|
+
},
|
|
47
|
+
'react-component-lib': {
|
|
48
|
+
name: 'React Component Library',
|
|
49
|
+
description: 'Reusable React component library with Storybook',
|
|
50
|
+
category: 'React',
|
|
51
|
+
tier: 2,
|
|
52
|
+
features: ['React', 'TypeScript', 'Storybook', 'Jest', 'Publishing'],
|
|
53
|
+
path: 'templates/react/component-library',
|
|
54
|
+
},
|
|
55
|
+
'vscode-extension': {
|
|
56
|
+
name: 'VS Code Extension',
|
|
57
|
+
description: 'VS Code extension with TypeScript',
|
|
58
|
+
category: 'Extension',
|
|
59
|
+
tier: 2,
|
|
60
|
+
features: ['TypeScript', 'VS Code API', 'Jest', 'Publishing'],
|
|
61
|
+
path: 'templates/vscode-extension',
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Get template directory path
|
|
67
|
+
* @returns {string|null} Template directory path or null
|
|
68
|
+
*/
|
|
69
|
+
function getTemplateDir() {
|
|
70
|
+
const possiblePaths = [
|
|
71
|
+
path.join(__dirname, '../../templates'),
|
|
72
|
+
path.join(process.cwd(), 'packages/caws-cli/templates'),
|
|
73
|
+
path.join(process.cwd(), 'templates'),
|
|
74
|
+
];
|
|
75
|
+
|
|
76
|
+
for (const testPath of possiblePaths) {
|
|
77
|
+
if (fs.existsSync(testPath)) {
|
|
78
|
+
return testPath;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Check which templates actually exist
|
|
87
|
+
* @returns {Object} Available templates
|
|
88
|
+
*/
|
|
89
|
+
function getAvailableTemplates() {
|
|
90
|
+
const templateDir = getTemplateDir();
|
|
91
|
+
const available = {};
|
|
92
|
+
|
|
93
|
+
for (const [id, template] of Object.entries(BUILTIN_TEMPLATES)) {
|
|
94
|
+
const templatePath = templateDir
|
|
95
|
+
? path.join(templateDir, template.path.replace('templates/', ''))
|
|
96
|
+
: null;
|
|
97
|
+
|
|
98
|
+
available[id] = {
|
|
99
|
+
...template,
|
|
100
|
+
available: templatePath ? fs.existsSync(templatePath) : false,
|
|
101
|
+
fullPath: templatePath,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return available;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* List all available templates
|
|
110
|
+
*/
|
|
111
|
+
function listTemplates() {
|
|
112
|
+
const templates = getAvailableTemplates();
|
|
113
|
+
const categories = {};
|
|
114
|
+
|
|
115
|
+
// Group by category
|
|
116
|
+
for (const [id, template] of Object.entries(templates)) {
|
|
117
|
+
if (!categories[template.category]) {
|
|
118
|
+
categories[template.category] = [];
|
|
119
|
+
}
|
|
120
|
+
categories[template.category].push({ id, ...template });
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
console.log(chalk.bold.cyan('\nš¦ Available CAWS Templates\n'));
|
|
124
|
+
|
|
125
|
+
// Display by category
|
|
126
|
+
for (const [category, categoryTemplates] of Object.entries(categories)) {
|
|
127
|
+
console.log(chalk.bold.white(`${category}:`));
|
|
128
|
+
|
|
129
|
+
for (const template of categoryTemplates) {
|
|
130
|
+
const status = template.available ? chalk.green('ā
') : chalk.gray('ā³');
|
|
131
|
+
console.log(`${status} ${chalk.bold(template.id.padEnd(25))} - ${template.description}`);
|
|
132
|
+
console.log(chalk.gray(` Usage: caws init --template=${template.id} my-project`));
|
|
133
|
+
console.log(chalk.gray(` Features: ${template.features.join(', ')}`));
|
|
134
|
+
console.log('');
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const totalAvailable = Object.values(templates).filter((t) => t.available).length;
|
|
139
|
+
const totalTemplates = Object.keys(templates).length;
|
|
140
|
+
|
|
141
|
+
if (totalAvailable < totalTemplates) {
|
|
142
|
+
console.log(chalk.yellow(`\nā³ ${totalTemplates - totalAvailable} templates coming soon`));
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
console.log(chalk.blue('\nš Learn more:'));
|
|
146
|
+
console.log(chalk.blue(' caws templates --help'));
|
|
147
|
+
console.log(chalk.blue(' docs/guides/template-usage.md'));
|
|
148
|
+
|
|
149
|
+
console.log('');
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Show detailed template information
|
|
154
|
+
* @param {string} templateId - Template ID
|
|
155
|
+
*/
|
|
156
|
+
function showTemplateInfo(templateId) {
|
|
157
|
+
const templates = getAvailableTemplates();
|
|
158
|
+
const template = templates[templateId];
|
|
159
|
+
|
|
160
|
+
if (!template) {
|
|
161
|
+
console.error(chalk.red(`\nā Template not found: ${templateId}`));
|
|
162
|
+
console.error(chalk.yellow('\nš” Available templates:'));
|
|
163
|
+
console.error(chalk.yellow(` ${Object.keys(templates).join(', ')}`));
|
|
164
|
+
console.error(chalk.yellow('\nš” Try: caws templates list'));
|
|
165
|
+
process.exit(1);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
console.log(chalk.bold.cyan(`\nš¦ Template: ${template.name}\n`));
|
|
169
|
+
console.log(chalk.white(`Description: ${template.description}`));
|
|
170
|
+
console.log(chalk.white(`Category: ${template.category}`));
|
|
171
|
+
console.log(chalk.white(`Risk Tier: ${template.tier}`));
|
|
172
|
+
console.log(
|
|
173
|
+
chalk.white(
|
|
174
|
+
`Status: ${template.available ? chalk.green('Available') : chalk.yellow('Coming Soon')}`
|
|
175
|
+
)
|
|
176
|
+
);
|
|
177
|
+
|
|
178
|
+
console.log(chalk.bold.white('\nFeatures:'));
|
|
179
|
+
template.features.forEach((feature) => {
|
|
180
|
+
console.log(chalk.gray(` ⢠${feature}`));
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
console.log(chalk.bold.white('\nUsage:'));
|
|
184
|
+
console.log(chalk.cyan(` caws init --template=${templateId} my-project`));
|
|
185
|
+
console.log(chalk.cyan(` cd my-project`));
|
|
186
|
+
console.log(chalk.cyan(` npm install`));
|
|
187
|
+
console.log(chalk.cyan(` npm test`));
|
|
188
|
+
|
|
189
|
+
if (template.available && template.fullPath) {
|
|
190
|
+
console.log(chalk.bold.white('\nTemplate Location:'));
|
|
191
|
+
console.log(chalk.gray(` ${template.fullPath}`));
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
console.log('');
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Templates command handler
|
|
199
|
+
* @param {string} subcommand - Subcommand (list, info)
|
|
200
|
+
* @param {Object} options - Command options
|
|
201
|
+
*/
|
|
202
|
+
async function templatesCommand(subcommand = 'list', options = {}) {
|
|
203
|
+
try {
|
|
204
|
+
switch (subcommand) {
|
|
205
|
+
case 'list':
|
|
206
|
+
listTemplates();
|
|
207
|
+
break;
|
|
208
|
+
|
|
209
|
+
case 'info':
|
|
210
|
+
if (!options.name) {
|
|
211
|
+
console.error(chalk.red('\nā Template name required'));
|
|
212
|
+
console.error(chalk.yellow('š” Usage: caws templates info <template-name>'));
|
|
213
|
+
console.error(chalk.yellow('š” Try: caws templates list to see available templates'));
|
|
214
|
+
process.exit(1);
|
|
215
|
+
}
|
|
216
|
+
showTemplateInfo(options.name);
|
|
217
|
+
break;
|
|
218
|
+
|
|
219
|
+
default:
|
|
220
|
+
listTemplates();
|
|
221
|
+
}
|
|
222
|
+
} catch (error) {
|
|
223
|
+
console.error(chalk.red('\nā Error:'), error.message);
|
|
224
|
+
console.error(chalk.yellow('\nš” Try: caws templates list'));
|
|
225
|
+
process.exit(1);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
module.exports = {
|
|
230
|
+
templatesCommand,
|
|
231
|
+
listTemplates,
|
|
232
|
+
showTemplateInfo,
|
|
233
|
+
getAvailableTemplates,
|
|
234
|
+
BUILTIN_TEMPLATES,
|
|
235
|
+
};
|
package/dist/error-handler.d.ts
CHANGED
|
@@ -32,9 +32,10 @@ export function safeAsync(operation: Function, context?: string): Promise<any>;
|
|
|
32
32
|
/**
|
|
33
33
|
* Handle CLI errors with consistent formatting and user guidance
|
|
34
34
|
* @param {Error} error - Error to handle
|
|
35
|
+
* @param {Object} context - Error context (command, option, etc.)
|
|
35
36
|
* @param {boolean} exit - Whether to exit the process (default: true)
|
|
36
37
|
*/
|
|
37
|
-
export function handleCliError(error: Error, exit?: boolean): void;
|
|
38
|
+
export function handleCliError(error: Error, context?: any, exit?: boolean): void;
|
|
38
39
|
/**
|
|
39
40
|
* Validate required environment and dependencies
|
|
40
41
|
* @returns {Object} Validation result with any errors
|
|
@@ -44,7 +45,31 @@ export function validateEnvironment(): any;
|
|
|
44
45
|
* Get recovery suggestions based on error category
|
|
45
46
|
* @param {Error} error - Original error
|
|
46
47
|
* @param {string} category - Error category
|
|
48
|
+
* @param {Object} context - Additional context (command, options, etc.)
|
|
47
49
|
* @returns {string[]} Array of recovery suggestions
|
|
48
50
|
*/
|
|
49
|
-
export function getRecoverySuggestions(error: Error, category: string): string[];
|
|
51
|
+
export function getRecoverySuggestions(error: Error, category: string, context?: any): string[];
|
|
52
|
+
/**
|
|
53
|
+
* Get documentation link for error category
|
|
54
|
+
* @param {string} category - Error category
|
|
55
|
+
* @param {Object} context - Additional context
|
|
56
|
+
* @returns {string} Documentation URL
|
|
57
|
+
*/
|
|
58
|
+
export function getDocumentationLink(category: string, context?: any): string;
|
|
59
|
+
/**
|
|
60
|
+
* Find similar command using Levenshtein distance
|
|
61
|
+
* @param {string} input - User's input command
|
|
62
|
+
* @param {string[]} validCommands - List of valid commands
|
|
63
|
+
* @returns {string|null} Most similar command or null
|
|
64
|
+
*/
|
|
65
|
+
export function findSimilarCommand(input: string, validCommands: string[]): string | null;
|
|
66
|
+
/**
|
|
67
|
+
* Command-specific error suggestions
|
|
68
|
+
*/
|
|
69
|
+
export const COMMAND_SUGGESTIONS: {
|
|
70
|
+
'unknown option': (option: any, command: any) => any[];
|
|
71
|
+
'unknown command': (command: any) => string[];
|
|
72
|
+
'template not found': () => string[];
|
|
73
|
+
'not a caws project': () => string[];
|
|
74
|
+
};
|
|
50
75
|
//# sourceMappingURL=error-handler.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error-handler.d.ts","sourceRoot":"","sources":["../src/error-handler.js"],"names":[],"mappings":"AA0GA;;GAEG;AACH;IACE,+DAKC;IAFC,cAAqD;IACrD,mBAA2F;CAE9F;;;;;;;;;;;AA9ED;;;;GAIG;AACH,wCAHW,KAAK,GAAC,MAAM,GACV,MAAM,CA+DlB;AAcD;;;;;GAKG;AACH,yDAHW,MAAM,GACJ,OAAO,CAAC,GAAG,CAAC,CAexB;
|
|
1
|
+
{"version":3,"file":"error-handler.d.ts","sourceRoot":"","sources":["../src/error-handler.js"],"names":[],"mappings":"AA0GA;;GAEG;AACH;IACE,+DAKC;IAFC,cAAqD;IACrD,mBAA2F;CAE9F;;;;;;;;;;;AA9ED;;;;GAIG;AACH,wCAHW,KAAK,GAAC,MAAM,GACV,MAAM,CA+DlB;AAcD;;;;;GAKG;AACH,yDAHW,MAAM,GACJ,OAAO,CAAC,GAAG,CAAC,CAexB;AA4ND;;;;;GAKG;AACH,sCAJW,KAAK,wBAEL,OAAO,QAsBjB;AAED;;;GAGG;AACH,2CAqBC;AAtJD;;;;;;GAMG;AACH,8CALW,KAAK,YACL,MAAM,kBAEJ,MAAM,EAAE,CAwDpB;AAED;;;;;GAKG;AACH,+CAJW,MAAM,kBAEJ,MAAM,CA4BlB;AAxJD;;;;;GAKG;AACH,0CAJW,MAAM,iBACN,MAAM,EAAE,GACN,MAAM,GAAC,IAAI,CAiBvB;AArFD;;GAEG;AACH;;;;;EA2DE"}
|