@rch4com/agent-setup 1.10.0 → 1.10.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/LICENSE +21 -21
- package/README.md +199 -199
- package/install.mjs +163 -163
- package/lib/args.mjs +276 -276
- package/lib/bootstrap/adapter.mjs +96 -96
- package/lib/bootstrap/apply.mjs +380 -380
- package/lib/bootstrap/flow.mjs +140 -140
- package/lib/bootstrap/record.mjs +154 -154
- package/lib/bootstrap/templates.mjs +148 -148
- package/lib/bootstrap/text.mjs +19 -19
- package/lib/catalog.mjs +234 -234
- package/lib/claude-plugins.mjs +64 -64
- package/lib/clis.mjs +111 -111
- package/lib/context.mjs +66 -66
- package/lib/deps.mjs +17 -17
- package/lib/design-md/catalog.json +454 -454
- package/lib/design-md/catalog.mjs +266 -266
- package/lib/design-md/flow.mjs +192 -192
- package/lib/design-md/open.mjs +51 -51
- package/lib/design-md/providers/awesome-design-md.mjs +124 -124
- package/lib/design-md/providers/index.mjs +9 -9
- package/lib/design-md/scan.mjs +295 -295
- package/lib/engine.mjs +115 -115
- package/lib/gitignore.mjs +18 -18
- package/lib/i18n/catalog/en.mjs +426 -426
- package/lib/i18n/catalog/ko.mjs +411 -411
- package/lib/i18n/detect.mjs +39 -39
- package/lib/i18n/index.mjs +93 -93
- package/lib/items/mcp.codebase-memory.mjs +6 -6
- package/lib/items/mcp.notion.mjs +6 -6
- package/lib/items/mcp.supabase.mjs +6 -6
- package/lib/items/mcp.vercel.mjs +6 -6
- package/lib/items/plugin.mattpocock-skills.mjs +8 -8
- package/lib/items/plugin.ponytail.mjs +104 -104
- package/lib/items/skill.gsd.mjs +44 -44
- package/lib/items/skill.gstack.mjs +54 -54
- package/lib/jsonfile.mjs +40 -40
- package/lib/status.mjs +93 -93
- package/lib/tomlfile.mjs +60 -60
- package/lib/tui/detail.mjs +127 -127
- package/lib/tui/progress.mjs +160 -160
- package/lib/tui/render.mjs +268 -268
- package/lib/tui/rows.mjs +317 -317
- package/lib/tui/run.mjs +396 -396
- package/lib/tui/state.mjs +249 -249
- package/lib/update.mjs +85 -85
- package/lib/width.mjs +115 -115
- package/package.json +36 -36
|
@@ -1,96 +1,96 @@
|
|
|
1
|
-
// 스킬 어댑터 — .agents/skills를 도구별 경로에서 보이게 한다.
|
|
2
|
-
// Windows는 Junction을 쓴다. 관리자 권한이 필요 없고, MSYS(Git Bash)의 ln -s가
|
|
3
|
-
// 링크 대신 복사를 만드는 문제도 우회한다.
|
|
4
|
-
import { cpSync, lstatSync, mkdirSync, readlinkSync, rmSync, symlinkSync, writeFileSync } from 'node:fs'
|
|
5
|
-
import { dirname, join, relative, resolve } from 'node:path'
|
|
6
|
-
import { repoPath, repoPathStrict } from '../context.mjs'
|
|
7
|
-
import { createT, msg } from '../i18n/index.mjs'
|
|
8
|
-
import { pathExists } from './apply.mjs'
|
|
9
|
-
|
|
10
|
-
const MARKER = '.agent-kit-managed-copy'
|
|
11
|
-
const SOURCE_REL = '.agents/skills'
|
|
12
|
-
|
|
13
|
-
// 심볼릭 링크/Junction이면 가리키는 절대 경로를, 아니면 null을 돌려준다.
|
|
14
|
-
function linkTarget(target) {
|
|
15
|
-
try {
|
|
16
|
-
if (!lstatSync(target).isSymbolicLink()) return null
|
|
17
|
-
return resolve(dirname(target), readlinkSync(target))
|
|
18
|
-
} catch {
|
|
19
|
-
return null
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
function createLink(source, target) {
|
|
24
|
-
if (process.platform === 'win32') {
|
|
25
|
-
// Junction은 절대 경로를 요구한다.
|
|
26
|
-
symlinkSync(source, target, 'junction')
|
|
27
|
-
} else {
|
|
28
|
-
symlinkSync(relative(dirname(target), source), target)
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
function createCopy(source, target) {
|
|
33
|
-
mkdirSync(target, { recursive: true })
|
|
34
|
-
cpSync(source, target, { recursive: true })
|
|
35
|
-
writeFileSync(join(target, MARKER), '', { encoding: 'utf8' })
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export function configureAdapter(root, { tool, path: rel }, { dryRun = false, skillMode = 'auto', log, t = createT('en') }) {
|
|
39
|
-
// 기존 상태를 살펴보는 데에는 어휘적 경로를 쓴다. target이 저장소 밖을 가리키는
|
|
40
|
-
// 링크일 수 있는데, 그 경우도 "보존 + 경고"가 정답이라 지켜야 할 쓰기가 없다.
|
|
41
|
-
// repoPathStrict를 여기서 쓰면 이탈 링크에서 예외가 던져져 경고 대신 죽는다.
|
|
42
|
-
const target = repoPath(root, rel)
|
|
43
|
-
|
|
44
|
-
const linked = linkTarget(target)
|
|
45
|
-
if (linked !== null) {
|
|
46
|
-
if (linked === repoPath(root, SOURCE_REL)) {
|
|
47
|
-
log(t('log.skill.linkOk', { tool, path: rel }))
|
|
48
|
-
return { ok: true, action: 'skip', path: rel }
|
|
49
|
-
}
|
|
50
|
-
log(t('log.skill.warnForeignLink', { path: rel }))
|
|
51
|
-
return { ok: true, action: 'warn', path: rel, message: msg('msg.foreignLink') }
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const managedCopy = pathExists(target) && pathExists(join(target, MARKER))
|
|
55
|
-
if (pathExists(target) && !managedCopy) {
|
|
56
|
-
log(t('log.skill.warnUnmanaged', { path: rel }))
|
|
57
|
-
return { ok: true, action: 'warn', path: rel, message: msg('msg.unmanagedExisting') }
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// 여기부터는 실제로 링크/복사본을 만드는 경로다. 엄격 검사는 dry-run 여부와
|
|
61
|
-
// 무관하게 항상 하고(dry-run에서도 이탈 경로를 걸러내려면), 실제 파일시스템
|
|
62
|
-
// 쓰기만 !dryRun으로 막는다 — apply.mjs의 ensureDirs와 같은 형태.
|
|
63
|
-
// source(.agents/skills)는 실제로 읽어 복사하는 대상이므로 여기서 함께 검사한다.
|
|
64
|
-
const source = repoPathStrict(root, SOURCE_REL)
|
|
65
|
-
const strictTarget = repoPathStrict(root, rel)
|
|
66
|
-
|
|
67
|
-
if (dryRun) {
|
|
68
|
-
log(t('log.skill.plan', { tool, path: rel, mode: skillMode }))
|
|
69
|
-
return { ok: true, action: 'skip', path: rel }
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
if (managedCopy) {
|
|
73
|
-
log(t('log.skill.copySync', { tool, path: rel }))
|
|
74
|
-
// 마커가 확인된 복사본만 지운다.
|
|
75
|
-
rmSync(strictTarget, { recursive: true, force: true })
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
mkdirSync(dirname(strictTarget), { recursive: true })
|
|
79
|
-
|
|
80
|
-
if (skillMode !== 'copy') {
|
|
81
|
-
try {
|
|
82
|
-
createLink(source, strictTarget)
|
|
83
|
-
log(t('log.skill.linkCreate', { tool, path: rel, target: SOURCE_REL }))
|
|
84
|
-
return { ok: true, action: 'link', path: rel }
|
|
85
|
-
} catch (err) {
|
|
86
|
-
if (skillMode === 'link') {
|
|
87
|
-
return { ok: false, action: 'link', path: rel, message: msg('msg.linkFailed', { message: err.message }) }
|
|
88
|
-
}
|
|
89
|
-
log(t('log.skill.linkFellBack', { tool }))
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
createCopy(source, strictTarget)
|
|
94
|
-
log(t('log.skill.copyCreate', { tool, path: rel }))
|
|
95
|
-
return { ok: true, action: 'copy', path: rel }
|
|
96
|
-
}
|
|
1
|
+
// 스킬 어댑터 — .agents/skills를 도구별 경로에서 보이게 한다.
|
|
2
|
+
// Windows는 Junction을 쓴다. 관리자 권한이 필요 없고, MSYS(Git Bash)의 ln -s가
|
|
3
|
+
// 링크 대신 복사를 만드는 문제도 우회한다.
|
|
4
|
+
import { cpSync, lstatSync, mkdirSync, readlinkSync, rmSync, symlinkSync, writeFileSync } from 'node:fs'
|
|
5
|
+
import { dirname, join, relative, resolve } from 'node:path'
|
|
6
|
+
import { repoPath, repoPathStrict } from '../context.mjs'
|
|
7
|
+
import { createT, msg } from '../i18n/index.mjs'
|
|
8
|
+
import { pathExists } from './apply.mjs'
|
|
9
|
+
|
|
10
|
+
const MARKER = '.agent-kit-managed-copy'
|
|
11
|
+
const SOURCE_REL = '.agents/skills'
|
|
12
|
+
|
|
13
|
+
// 심볼릭 링크/Junction이면 가리키는 절대 경로를, 아니면 null을 돌려준다.
|
|
14
|
+
function linkTarget(target) {
|
|
15
|
+
try {
|
|
16
|
+
if (!lstatSync(target).isSymbolicLink()) return null
|
|
17
|
+
return resolve(dirname(target), readlinkSync(target))
|
|
18
|
+
} catch {
|
|
19
|
+
return null
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function createLink(source, target) {
|
|
24
|
+
if (process.platform === 'win32') {
|
|
25
|
+
// Junction은 절대 경로를 요구한다.
|
|
26
|
+
symlinkSync(source, target, 'junction')
|
|
27
|
+
} else {
|
|
28
|
+
symlinkSync(relative(dirname(target), source), target)
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function createCopy(source, target) {
|
|
33
|
+
mkdirSync(target, { recursive: true })
|
|
34
|
+
cpSync(source, target, { recursive: true })
|
|
35
|
+
writeFileSync(join(target, MARKER), '', { encoding: 'utf8' })
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function configureAdapter(root, { tool, path: rel }, { dryRun = false, skillMode = 'auto', log, t = createT('en') }) {
|
|
39
|
+
// 기존 상태를 살펴보는 데에는 어휘적 경로를 쓴다. target이 저장소 밖을 가리키는
|
|
40
|
+
// 링크일 수 있는데, 그 경우도 "보존 + 경고"가 정답이라 지켜야 할 쓰기가 없다.
|
|
41
|
+
// repoPathStrict를 여기서 쓰면 이탈 링크에서 예외가 던져져 경고 대신 죽는다.
|
|
42
|
+
const target = repoPath(root, rel)
|
|
43
|
+
|
|
44
|
+
const linked = linkTarget(target)
|
|
45
|
+
if (linked !== null) {
|
|
46
|
+
if (linked === repoPath(root, SOURCE_REL)) {
|
|
47
|
+
log(t('log.skill.linkOk', { tool, path: rel }))
|
|
48
|
+
return { ok: true, action: 'skip', path: rel }
|
|
49
|
+
}
|
|
50
|
+
log(t('log.skill.warnForeignLink', { path: rel }))
|
|
51
|
+
return { ok: true, action: 'warn', path: rel, message: msg('msg.foreignLink') }
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const managedCopy = pathExists(target) && pathExists(join(target, MARKER))
|
|
55
|
+
if (pathExists(target) && !managedCopy) {
|
|
56
|
+
log(t('log.skill.warnUnmanaged', { path: rel }))
|
|
57
|
+
return { ok: true, action: 'warn', path: rel, message: msg('msg.unmanagedExisting') }
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// 여기부터는 실제로 링크/복사본을 만드는 경로다. 엄격 검사는 dry-run 여부와
|
|
61
|
+
// 무관하게 항상 하고(dry-run에서도 이탈 경로를 걸러내려면), 실제 파일시스템
|
|
62
|
+
// 쓰기만 !dryRun으로 막는다 — apply.mjs의 ensureDirs와 같은 형태.
|
|
63
|
+
// source(.agents/skills)는 실제로 읽어 복사하는 대상이므로 여기서 함께 검사한다.
|
|
64
|
+
const source = repoPathStrict(root, SOURCE_REL)
|
|
65
|
+
const strictTarget = repoPathStrict(root, rel)
|
|
66
|
+
|
|
67
|
+
if (dryRun) {
|
|
68
|
+
log(t('log.skill.plan', { tool, path: rel, mode: skillMode }))
|
|
69
|
+
return { ok: true, action: 'skip', path: rel }
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (managedCopy) {
|
|
73
|
+
log(t('log.skill.copySync', { tool, path: rel }))
|
|
74
|
+
// 마커가 확인된 복사본만 지운다.
|
|
75
|
+
rmSync(strictTarget, { recursive: true, force: true })
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
mkdirSync(dirname(strictTarget), { recursive: true })
|
|
79
|
+
|
|
80
|
+
if (skillMode !== 'copy') {
|
|
81
|
+
try {
|
|
82
|
+
createLink(source, strictTarget)
|
|
83
|
+
log(t('log.skill.linkCreate', { tool, path: rel, target: SOURCE_REL }))
|
|
84
|
+
return { ok: true, action: 'link', path: rel }
|
|
85
|
+
} catch (err) {
|
|
86
|
+
if (skillMode === 'link') {
|
|
87
|
+
return { ok: false, action: 'link', path: rel, message: msg('msg.linkFailed', { message: err.message }) }
|
|
88
|
+
}
|
|
89
|
+
log(t('log.skill.linkFellBack', { tool }))
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
createCopy(source, strictTarget)
|
|
94
|
+
log(t('log.skill.copyCreate', { tool, path: rel }))
|
|
95
|
+
return { ok: true, action: 'copy', path: rel }
|
|
96
|
+
}
|