agentic-team-templates 0.14.0 → 0.15.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentic-team-templates",
3
- "version": "0.14.0",
3
+ "version": "0.15.0",
4
4
  "description": "AI coding assistant templates for Cursor IDE. Pre-configured rules and guidelines that help AI assistants write better code. - use at your own risk",
5
5
  "keywords": [
6
6
  "cursor",
package/src/index.js CHANGED
@@ -118,6 +118,36 @@ const TEMPLATES = {
118
118
  }
119
119
  };
120
120
 
121
+ // Shorthand aliases for language expert templates
122
+ const TEMPLATE_ALIASES = {
123
+ 'js': 'javascript-expert',
124
+ 'javascript': 'javascript-expert',
125
+ 'ts': 'javascript-expert',
126
+ 'typescript': 'javascript-expert',
127
+ 'go': 'golang-expert',
128
+ 'golang': 'golang-expert',
129
+ 'py': 'python-expert',
130
+ 'python': 'python-expert',
131
+ 'rs': 'rust-expert',
132
+ 'rust': 'rust-expert',
133
+ 'swift': 'swift-expert',
134
+ 'kotlin': 'kotlin-expert',
135
+ 'kt': 'kotlin-expert',
136
+ 'java': 'java-expert',
137
+ 'cpp': 'cpp-expert',
138
+ 'csharp': 'csharp-expert',
139
+ 'cs': 'csharp-expert',
140
+ };
141
+
142
+ /**
143
+ * Resolve a template alias to its canonical name
144
+ * @param {string} name - Template name or alias
145
+ * @returns {string} Canonical template name
146
+ */
147
+ function resolveTemplateAlias(name) {
148
+ return TEMPLATE_ALIASES[name] || name;
149
+ }
150
+
121
151
  const SHARED_RULES = [
122
152
  'code-quality.md',
123
153
  'communication.md',
@@ -215,7 +245,19 @@ ${colors.yellow('IDE Targets:')}
215
245
  claude CLAUDE.md file (Claude Code, Cursor with Claude)
216
246
  codex .github/copilot-instructions.md (GitHub Copilot)
217
247
 
248
+ ${colors.yellow('Shorthand Aliases:')}
249
+ js, ts, javascript, typescript → javascript-expert
250
+ go, golang → golang-expert
251
+ py, python → python-expert
252
+ rs, rust → rust-expert
253
+ swift → swift-expert
254
+ kotlin, kt → kotlin-expert
255
+ java → java-expert
256
+ cpp → cpp-expert
257
+ csharp, cs → csharp-expert
258
+
218
259
  ${colors.yellow('Examples:')}
260
+ npx cursor-templates js
219
261
  npx cursor-templates web-frontend
220
262
  npx cursor-templates web-frontend --ide=cursor
221
263
  npx cursor-templates web-frontend --ide=claude --ide=codex
@@ -237,13 +279,24 @@ ${colors.dim('CLAUDE.md: missing sections are intelligently merged (not overwrit
237
279
  }
238
280
 
239
281
  function printTemplates() {
282
+ // Build reverse map: canonical name -> list of aliases
283
+ const aliasesByTemplate = {};
284
+ for (const [alias, canonical] of Object.entries(TEMPLATE_ALIASES)) {
285
+ if (!aliasesByTemplate[canonical]) {
286
+ aliasesByTemplate[canonical] = [];
287
+ }
288
+ aliasesByTemplate[canonical].push(alias);
289
+ }
290
+
240
291
  console.log(colors.yellow('Available Templates:\n'));
241
-
292
+
242
293
  for (const [name, info] of Object.entries(TEMPLATES)) {
243
- console.log(` ${colors.green(name)}`);
294
+ const aliases = aliasesByTemplate[name];
295
+ const aliasSuffix = aliases ? ` ${colors.dim(`(aliases: ${aliases.join(', ')})`)}` : '';
296
+ console.log(` ${colors.green(name)}${aliasSuffix}`);
244
297
  console.log(` ${info.description}\n`);
245
298
  }
246
-
299
+
247
300
  console.log(colors.blue('Shared rules (always included):'));
248
301
  for (const rule of SHARED_RULES) {
249
302
  console.log(` - ${rule.replace('.md', '')}`);
@@ -1378,10 +1431,13 @@ export async function run(args) {
1378
1431
  }
1379
1432
 
1380
1433
  printBanner();
1381
-
1434
+
1382
1435
  // Check for updates (non-blocking, fails silently)
1383
1436
  await checkForUpdates();
1384
1437
 
1438
+ // Resolve template aliases to canonical names
1439
+ const resolvedTemplates = templates.map(resolveTemplateAlias);
1440
+
1385
1441
  // Use default IDEs if none specified
1386
1442
  const targetIdes = ides.length > 0 ? ides : DEFAULT_IDES;
1387
1443
 
@@ -1391,7 +1447,7 @@ export async function run(args) {
1391
1447
  console.error(colors.red('Error: Cannot use --remove and --reset together\n'));
1392
1448
  process.exit(1);
1393
1449
  }
1394
- if (templates.length > 0) {
1450
+ if (resolvedTemplates.length > 0) {
1395
1451
  console.error(colors.red('Error: --reset does not accept template arguments\n'));
1396
1452
  console.error(colors.dim('Use --remove <templates...> to remove specific templates.\n'));
1397
1453
  process.exit(1);
@@ -1410,14 +1466,14 @@ export async function run(args) {
1410
1466
 
1411
1467
  // Handle remove mode
1412
1468
  if (removeMode) {
1413
- if (templates.length === 0) {
1469
+ if (resolvedTemplates.length === 0) {
1414
1470
  console.error(colors.red('Error: No templates specified for removal\n'));
1415
1471
  console.error(colors.dim('Usage: npx cursor-templates --remove <templates...>\n'));
1416
1472
  printTemplates();
1417
1473
  process.exit(1);
1418
1474
  }
1419
1475
 
1420
- for (const template of templates) {
1476
+ for (const template of resolvedTemplates) {
1421
1477
  if (!TEMPLATES[template]) {
1422
1478
  console.error(colors.red(`Error: Unknown template '${template}'\n`));
1423
1479
  printTemplates();
@@ -1432,18 +1488,18 @@ export async function run(args) {
1432
1488
  console.log(colors.yellow('FORCE MODE - Modified files will be removed\n'));
1433
1489
  }
1434
1490
 
1435
- await remove(process.cwd(), templates, dryRun, force, skipConfirm, targetIdes);
1491
+ await remove(process.cwd(), resolvedTemplates, dryRun, force, skipConfirm, targetIdes);
1436
1492
  return;
1437
1493
  }
1438
1494
 
1439
1495
  // Install mode (default)
1440
- if (templates.length === 0) {
1496
+ if (resolvedTemplates.length === 0) {
1441
1497
  console.error(colors.red('Error: No templates specified\n'));
1442
1498
  printHelp();
1443
1499
  process.exit(1);
1444
1500
  }
1445
1501
 
1446
- for (const template of templates) {
1502
+ for (const template of resolvedTemplates) {
1447
1503
  if (!TEMPLATES[template]) {
1448
1504
  console.error(colors.red(`Error: Unknown template '${template}'\n`));
1449
1505
  printTemplates();
@@ -1460,7 +1516,7 @@ export async function run(args) {
1460
1516
  }
1461
1517
 
1462
1518
  // Install to current directory
1463
- install(process.cwd(), templates, dryRun, force, targetIdes);
1519
+ install(process.cwd(), resolvedTemplates, dryRun, force, targetIdes);
1464
1520
  }
1465
1521
 
1466
1522
  // Export internals for testing
@@ -1470,11 +1526,13 @@ export const _internals = {
1470
1526
  REPO_URL,
1471
1527
  CHANGELOG_URL,
1472
1528
  TEMPLATES,
1529
+ TEMPLATE_ALIASES,
1473
1530
  SHARED_RULES,
1474
1531
  SUPPORTED_IDES,
1475
1532
  DEFAULT_IDES,
1476
1533
  compareVersions,
1477
1534
  checkForUpdates,
1535
+ resolveTemplateAlias,
1478
1536
  filesMatch,
1479
1537
  parseMarkdownSections,
1480
1538
  generateSectionSignature,
package/src/index.test.js CHANGED
@@ -8,10 +8,12 @@ const {
8
8
  PACKAGE_NAME,
9
9
  CURRENT_VERSION,
10
10
  TEMPLATES,
11
+ TEMPLATE_ALIASES,
11
12
  SHARED_RULES,
12
13
  SUPPORTED_IDES,
13
14
  DEFAULT_IDES,
14
15
  compareVersions,
16
+ resolveTemplateAlias,
15
17
  filesMatch,
16
18
  parseMarkdownSections,
17
19
  generateSectionSignature,
@@ -150,6 +152,50 @@ describe('Constants', () => {
150
152
  expect(DEFAULT_IDES).toEqual(SUPPORTED_IDES);
151
153
  });
152
154
  });
155
+
156
+ describe('TEMPLATE_ALIASES', () => {
157
+ it('all alias values should be valid TEMPLATES keys', () => {
158
+ for (const [alias, canonical] of Object.entries(TEMPLATE_ALIASES)) {
159
+ expect(TEMPLATES).toHaveProperty(canonical,
160
+ expect.anything(),
161
+ );
162
+ }
163
+ });
164
+
165
+ it('should include expected shorthand aliases', () => {
166
+ expect(TEMPLATE_ALIASES['js']).toBe('javascript-expert');
167
+ expect(TEMPLATE_ALIASES['ts']).toBe('javascript-expert');
168
+ expect(TEMPLATE_ALIASES['go']).toBe('golang-expert');
169
+ expect(TEMPLATE_ALIASES['py']).toBe('python-expert');
170
+ expect(TEMPLATE_ALIASES['rs']).toBe('rust-expert');
171
+ expect(TEMPLATE_ALIASES['kt']).toBe('kotlin-expert');
172
+ });
173
+ });
174
+
175
+ describe('resolveTemplateAlias', () => {
176
+ it('should resolve known aliases to canonical names', () => {
177
+ expect(resolveTemplateAlias('js')).toBe('javascript-expert');
178
+ expect(resolveTemplateAlias('typescript')).toBe('javascript-expert');
179
+ expect(resolveTemplateAlias('go')).toBe('golang-expert');
180
+ expect(resolveTemplateAlias('golang')).toBe('golang-expert');
181
+ expect(resolveTemplateAlias('py')).toBe('python-expert');
182
+ expect(resolveTemplateAlias('rs')).toBe('rust-expert');
183
+ expect(resolveTemplateAlias('kotlin')).toBe('kotlin-expert');
184
+ expect(resolveTemplateAlias('kt')).toBe('kotlin-expert');
185
+ });
186
+
187
+ it('should pass through unknown names unchanged', () => {
188
+ expect(resolveTemplateAlias('web-frontend')).toBe('web-frontend');
189
+ expect(resolveTemplateAlias('blockchain')).toBe('blockchain');
190
+ expect(resolveTemplateAlias('nonexistent')).toBe('nonexistent');
191
+ });
192
+
193
+ it('should pass through canonical template names unchanged', () => {
194
+ expect(resolveTemplateAlias('javascript-expert')).toBe('javascript-expert');
195
+ expect(resolveTemplateAlias('golang-expert')).toBe('golang-expert');
196
+ expect(resolveTemplateAlias('python-expert')).toBe('python-expert');
197
+ });
198
+ });
153
199
  });
154
200
 
155
201
  // ============================================================================
@@ -1019,7 +1065,50 @@ describe('CLI Argument Parsing', () => {
1019
1065
  it('should accept -y shorthand for yes', async () => {
1020
1066
  await run(['web-frontend']);
1021
1067
  await run(['--reset', '-y']);
1022
-
1068
+
1069
+ expect(exitSpy).not.toHaveBeenCalled();
1070
+ });
1071
+
1072
+ it('should resolve shorthand alias "js" to javascript-expert', async () => {
1073
+ await run(['js', '--dry-run']);
1074
+
1075
+ expect(exitSpy).not.toHaveBeenCalled();
1076
+ });
1077
+
1078
+ it('should resolve shorthand alias "go" to golang-expert', async () => {
1079
+ await run(['go', '--dry-run']);
1080
+
1081
+ expect(exitSpy).not.toHaveBeenCalled();
1082
+ });
1083
+
1084
+ it('should resolve shorthand alias "py" to python-expert', async () => {
1085
+ await run(['py', '--dry-run']);
1086
+
1087
+ expect(exitSpy).not.toHaveBeenCalled();
1088
+ });
1089
+
1090
+ it('should resolve shorthand alias "rs" to rust-expert', async () => {
1091
+ await run(['rs', '--dry-run']);
1092
+
1093
+ expect(exitSpy).not.toHaveBeenCalled();
1094
+ });
1095
+
1096
+ it('should resolve shorthand alias "kt" to kotlin-expert', async () => {
1097
+ await run(['kt', '--dry-run']);
1098
+
1099
+ expect(exitSpy).not.toHaveBeenCalled();
1100
+ });
1101
+
1102
+ it('should resolve aliases in --remove mode', async () => {
1103
+ await run(['go']);
1104
+ await run(['--remove', 'go', '--yes']);
1105
+
1106
+ expect(exitSpy).not.toHaveBeenCalled();
1107
+ });
1108
+
1109
+ it('should still accept canonical template names', async () => {
1110
+ await run(['javascript-expert', '--dry-run']);
1111
+
1023
1112
  expect(exitSpy).not.toHaveBeenCalled();
1024
1113
  });
1025
1114
  });