pattyeng 1.0.6 → 1.0.7
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 +7 -1
- package/bin/pattyeng.js +5 -0
- package/lib/skills.js +36 -8
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -79,12 +79,18 @@ pattyeng upgrade
|
|
|
79
79
|
|
|
80
80
|
### `pattyeng skills list`
|
|
81
81
|
|
|
82
|
-
|
|
82
|
+
설치된 스킬 이름을 짧게 봅니다.
|
|
83
83
|
|
|
84
84
|
```bash
|
|
85
85
|
pattyeng skills list
|
|
86
86
|
```
|
|
87
87
|
|
|
88
|
+
설명까지 보고 싶으면:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
pattyeng skills list --long
|
|
92
|
+
```
|
|
93
|
+
|
|
88
94
|
---
|
|
89
95
|
|
|
90
96
|
### `pattyeng skills sync`
|
package/bin/pattyeng.js
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
+
process.stdout.on('error', (err) => {
|
|
5
|
+
if (err.code === 'EPIPE') process.exit(0);
|
|
6
|
+
throw err;
|
|
7
|
+
});
|
|
8
|
+
|
|
4
9
|
const { install } = require('../lib/install');
|
|
5
10
|
const { upgrade } = require('../lib/upgrade');
|
|
6
11
|
const { skills } = require('../lib/skills');
|
package/lib/skills.js
CHANGED
|
@@ -35,11 +35,24 @@ function readSkillMeta(skillDir) {
|
|
|
35
35
|
const nameMatch = content.match(/^name:\s*(.+)$/m);
|
|
36
36
|
const descMatch = content.match(/^description:\s*(.+)$/m);
|
|
37
37
|
return {
|
|
38
|
-
name: nameMatch
|
|
39
|
-
description: descMatch
|
|
38
|
+
name: cleanYamlScalar(nameMatch ? nameMatch[1] : path.basename(skillDir)),
|
|
39
|
+
description: descMatch ? cleanYamlScalar(descMatch[1]) : '',
|
|
40
40
|
};
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
+
function cleanYamlScalar(value) {
|
|
44
|
+
return String(value || '')
|
|
45
|
+
.trim()
|
|
46
|
+
.replace(/^['\"]|['\"]$/g, '')
|
|
47
|
+
.replace(/^>\s*/, '')
|
|
48
|
+
.trim();
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function cleanDescription(value) {
|
|
52
|
+
const cleaned = cleanYamlScalar(value).replace(/\s+/g, ' ');
|
|
53
|
+
return cleaned.length > 82 ? cleaned.slice(0, 79) + '...' : cleaned;
|
|
54
|
+
}
|
|
55
|
+
|
|
43
56
|
// Diff two SKILL.md files — returns true if different
|
|
44
57
|
function isDifferent(srcFile, destFile) {
|
|
45
58
|
if (!fs.existsSync(destFile)) return true;
|
|
@@ -64,17 +77,17 @@ async function skills(args) {
|
|
|
64
77
|
const sub = args[0];
|
|
65
78
|
|
|
66
79
|
if (!sub || sub === 'list') {
|
|
67
|
-
return listSkills();
|
|
80
|
+
return listSkills(args.includes('--long'));
|
|
68
81
|
}
|
|
69
82
|
if (sub === 'sync') {
|
|
70
83
|
return syncSkills();
|
|
71
84
|
}
|
|
72
85
|
|
|
73
|
-
log(`\n사용법:\n pattyeng skills list
|
|
86
|
+
log(`\n사용법:\n pattyeng skills list — 스킬 이름만 보기\n pattyeng skills list --long — 설명까지 보기\n pattyeng skills sync — 스킬 최신 버전으로 동기화\n`);
|
|
74
87
|
}
|
|
75
88
|
|
|
76
|
-
function listSkills() {
|
|
77
|
-
log(`\n📚
|
|
89
|
+
function listSkills(long = false) {
|
|
90
|
+
log(`\n📚 스킬 목록 (${DEST_DIR})\n`);
|
|
78
91
|
|
|
79
92
|
if (!fs.existsSync(DEST_DIR)) {
|
|
80
93
|
warn('~/.codex/skills 폴더가 없습니다. pattyeng skills sync 를 먼저 실행하세요.');
|
|
@@ -91,10 +104,25 @@ function listSkills() {
|
|
|
91
104
|
return;
|
|
92
105
|
}
|
|
93
106
|
|
|
107
|
+
const names = skills
|
|
108
|
+
.sort()
|
|
109
|
+
.map(skill => readSkillMeta(path.join(DEST_DIR, skill)).name)
|
|
110
|
+
.filter(name => !name.startsWith('.'));
|
|
111
|
+
|
|
112
|
+
if (!long) {
|
|
113
|
+
const width = Math.max(18, ...names.map(n => n.length + 2));
|
|
114
|
+
for (let i = 0; i < names.length; i += 3) {
|
|
115
|
+
log(' ' + names.slice(i, i + 3).map(n => n.padEnd(width)).join(''));
|
|
116
|
+
}
|
|
117
|
+
log(`\n 총 ${names.length}개. 설명 보기: pattyeng skills list --long\n`);
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
|
|
94
121
|
for (const skill of skills.sort()) {
|
|
95
122
|
const meta = readSkillMeta(path.join(DEST_DIR, skill));
|
|
96
|
-
|
|
97
|
-
|
|
123
|
+
if (meta.name.startsWith('.')) continue;
|
|
124
|
+
const desc = cleanDescription(meta.description);
|
|
125
|
+
log(` • ${meta.name.padEnd(20)} ${desc ? `— ${desc}` : ''}`);
|
|
98
126
|
}
|
|
99
127
|
log('');
|
|
100
128
|
}
|