@rch4com/agent-setup 1.10.0 → 1.11.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 +431 -426
- package/lib/i18n/catalog/ko.mjs +416 -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.bkit.mjs +5 -3
- package/lib/items/plugin.ecc.mjs +17 -2
- package/lib/items/plugin.mattpocock-skills.mjs +18 -8
- package/lib/items/plugin.ponytail.mjs +106 -104
- package/lib/items/plugin.superpowers.mjs +7 -4
- package/lib/items/plugin.understand-anything.mjs +13 -2
- package/lib/items/skill.diagram-design.mjs +14 -0
- package/lib/items/skill.gsd.mjs +46 -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,124 +1,124 @@
|
|
|
1
|
-
// awesome-design-md (VoltAgent) 프로바이더.
|
|
2
|
-
// 카탈로그: README `## Collection`의 `### 카테고리` + 링크 목록을 파싱한다.
|
|
3
|
-
// 링크 URL `getdesign.md/<name>/design-md`의 <name>이 곧 GitHub 폴더명이다.
|
|
4
|
-
// 파일: 폴더에는 DESIGN.md만 있다(preview.html 없음). 렌더된 미리보기는 웹페이지.
|
|
5
|
-
import { existsSync, readFileSync } from 'node:fs'
|
|
6
|
-
import { join, dirname } from 'node:path'
|
|
7
|
-
import { fileURLToPath } from 'node:url'
|
|
8
|
-
import { LocalizedError } from '../../i18n/index.mjs'
|
|
9
|
-
|
|
10
|
-
// lib/design-md/cache/<name>/DESIGN.md — 인스톨러에 동봉된 오프라인 번들.
|
|
11
|
-
const BUNDLE_DIR = join(dirname(fileURLToPath(import.meta.url)), '..', 'cache')
|
|
12
|
-
|
|
13
|
-
const REPO = 'VoltAgent/awesome-design-md'
|
|
14
|
-
const BRANCH = 'main'
|
|
15
|
-
const RAW_BASE = `https://raw.githubusercontent.com/${REPO}/${BRANCH}/design-md`
|
|
16
|
-
const README_URL = `https://raw.githubusercontent.com/${REPO}/${BRANCH}/README.md`
|
|
17
|
-
// 번들에 함께 담는 상류 고지의 출처. MIT는 사본에 저작권 고지와 허가 문구를
|
|
18
|
-
// 담을 것을 요구하므로, 파일을 내려받아 재배포하는 이상 이 URL이 필요하다.
|
|
19
|
-
const LICENSE_URL = `https://raw.githubusercontent.com/${REPO}/${BRANCH}/LICENSE`
|
|
20
|
-
const TREE_URL = `https://api.github.com/repos/${REPO}/git/trees/${BRANCH}?recursive=1`
|
|
21
|
-
// scan.mjs의 BUNDLE_CATEGORY와 같은 값이어야 한다 — 둘 다 카테고리 못 얻은
|
|
22
|
-
// 항목이 모이는 자리라, 갈라지면 같은 그룹이 헤더 두 개로 쪼개진다.
|
|
23
|
-
export const UNCATEGORIZED = '__other'
|
|
24
|
-
|
|
25
|
-
const ENTRY_RE = /^-\s*\[\*\*(.+?)\*\*\]\(\s*https?:\/\/getdesign\.md\/([^/)]+)\/design-md\s*\)\s*-\s*(.*)$/
|
|
26
|
-
|
|
27
|
-
// README `## Collection` 블록만 대상으로 카테고리·항목을 뽑는다.
|
|
28
|
-
export function parseReadme(md) {
|
|
29
|
-
const lines = md.split(/\r?\n/)
|
|
30
|
-
const entries = []
|
|
31
|
-
let inCollection = false
|
|
32
|
-
let category = UNCATEGORIZED
|
|
33
|
-
for (const line of lines) {
|
|
34
|
-
const h2 = /^##\s+(.*)$/.exec(line)
|
|
35
|
-
if (h2) {
|
|
36
|
-
inCollection = /^collection\b/i.test(h2[1].trim())
|
|
37
|
-
continue
|
|
38
|
-
}
|
|
39
|
-
if (!inCollection) continue
|
|
40
|
-
const h3 = /^###\s+(.*)$/.exec(line)
|
|
41
|
-
if (h3) {
|
|
42
|
-
category = h3[1].trim()
|
|
43
|
-
continue
|
|
44
|
-
}
|
|
45
|
-
const m = ENTRY_RE.exec(line.trim())
|
|
46
|
-
if (m) {
|
|
47
|
-
entries.push({ name: m[2].trim(), label: m[1].trim(), category, description: m[3].trim() })
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
return entries
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
// tree API에서 design-md/<name>/ 폴더명 집합을 뽑는다(orphan 보강용).
|
|
54
|
-
export function parseTreeNames(treeJson) {
|
|
55
|
-
const names = new Set()
|
|
56
|
-
for (const e of treeJson?.tree ?? []) {
|
|
57
|
-
const m = /^design-md\/([^/]+)\//.exec(e.path)
|
|
58
|
-
if (m) names.add(m[1])
|
|
59
|
-
}
|
|
60
|
-
return names
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
export const awesomeDesignMd = {
|
|
64
|
-
id: 'awesome-design-md',
|
|
65
|
-
label: 'awesome-design-md (VoltAgent)',
|
|
66
|
-
files: ['DESIGN.md'],
|
|
67
|
-
licenseUrl: LICENSE_URL,
|
|
68
|
-
// 번들과 함께 발행되는 고지 파일. 이름이 LICENSE가 아닌 이유는 발행물 검사가
|
|
69
|
-
// 최상위 LICENSE 하나만 확장자 없는 파일로 허용하기 때문이다.
|
|
70
|
-
noticeFile: 'LICENSE.md',
|
|
71
|
-
|
|
72
|
-
fileUrl(name, file = 'DESIGN.md') {
|
|
73
|
-
return `${RAW_BASE}/${encodeURIComponent(name)}/${file}`
|
|
74
|
-
},
|
|
75
|
-
|
|
76
|
-
// fileUrl과 같이 인코딩한다 — name은 원격 README에서 오므로, 그대로 이어
|
|
77
|
-
// 붙이면 URL이 아닌 문자가 미리보기 대상 문자열에 섞인다.
|
|
78
|
-
webUrl(name) {
|
|
79
|
-
return `https://getdesign.md/${encodeURIComponent(name)}/design-md`
|
|
80
|
-
},
|
|
81
|
-
|
|
82
|
-
bundlePath(name, file = 'DESIGN.md') {
|
|
83
|
-
return join(BUNDLE_DIR, this.id, name, file)
|
|
84
|
-
},
|
|
85
|
-
|
|
86
|
-
// 동봉 번들에서 읽는다(없으면 null). 오프라인 설치용.
|
|
87
|
-
bundledText(name, file = 'DESIGN.md') {
|
|
88
|
-
if (/[\\/]/.test(name)) return null
|
|
89
|
-
const p = this.bundlePath(name, file)
|
|
90
|
-
return existsSync(p) ? readFileSync(p, 'utf8') : null
|
|
91
|
-
},
|
|
92
|
-
|
|
93
|
-
async fetchFile(fetchImpl, name, file = 'DESIGN.md') {
|
|
94
|
-
const res = await fetchImpl(this.fileUrl(name, file))
|
|
95
|
-
if (!res.ok) return null
|
|
96
|
-
return res.text()
|
|
97
|
-
},
|
|
98
|
-
|
|
99
|
-
// README 파싱(주) + tree orphan 보강(선택). 이름순 정렬 반환.
|
|
100
|
-
async fetchCatalog(fetchImpl) {
|
|
101
|
-
const readmeRes = await fetchImpl(README_URL)
|
|
102
|
-
if (!readmeRes.ok) throw new LocalizedError('error.readmeFetch', { status: readmeRes.status })
|
|
103
|
-
const entries = parseReadme(await readmeRes.text())
|
|
104
|
-
const seen = new Set(entries.map((e) => e.name))
|
|
105
|
-
|
|
106
|
-
try {
|
|
107
|
-
const treeRes = await fetchImpl(TREE_URL, { headers: { 'User-Agent': 'agent-installer' } })
|
|
108
|
-
if (treeRes.ok) {
|
|
109
|
-
for (const name of parseTreeNames(await treeRes.json())) {
|
|
110
|
-
if (!seen.has(name)) {
|
|
111
|
-
entries.push({ name, label: name, category: UNCATEGORIZED, description: '' })
|
|
112
|
-
seen.add(name)
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
} catch {
|
|
117
|
-
// tree 실패는 무시 — README만으로도 카탈로그는 유효하다.
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
return entries.sort((a, b) => a.name.localeCompare(b.name))
|
|
121
|
-
},
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
export default awesomeDesignMd
|
|
1
|
+
// awesome-design-md (VoltAgent) 프로바이더.
|
|
2
|
+
// 카탈로그: README `## Collection`의 `### 카테고리` + 링크 목록을 파싱한다.
|
|
3
|
+
// 링크 URL `getdesign.md/<name>/design-md`의 <name>이 곧 GitHub 폴더명이다.
|
|
4
|
+
// 파일: 폴더에는 DESIGN.md만 있다(preview.html 없음). 렌더된 미리보기는 웹페이지.
|
|
5
|
+
import { existsSync, readFileSync } from 'node:fs'
|
|
6
|
+
import { join, dirname } from 'node:path'
|
|
7
|
+
import { fileURLToPath } from 'node:url'
|
|
8
|
+
import { LocalizedError } from '../../i18n/index.mjs'
|
|
9
|
+
|
|
10
|
+
// lib/design-md/cache/<name>/DESIGN.md — 인스톨러에 동봉된 오프라인 번들.
|
|
11
|
+
const BUNDLE_DIR = join(dirname(fileURLToPath(import.meta.url)), '..', 'cache')
|
|
12
|
+
|
|
13
|
+
const REPO = 'VoltAgent/awesome-design-md'
|
|
14
|
+
const BRANCH = 'main'
|
|
15
|
+
const RAW_BASE = `https://raw.githubusercontent.com/${REPO}/${BRANCH}/design-md`
|
|
16
|
+
const README_URL = `https://raw.githubusercontent.com/${REPO}/${BRANCH}/README.md`
|
|
17
|
+
// 번들에 함께 담는 상류 고지의 출처. MIT는 사본에 저작권 고지와 허가 문구를
|
|
18
|
+
// 담을 것을 요구하므로, 파일을 내려받아 재배포하는 이상 이 URL이 필요하다.
|
|
19
|
+
const LICENSE_URL = `https://raw.githubusercontent.com/${REPO}/${BRANCH}/LICENSE`
|
|
20
|
+
const TREE_URL = `https://api.github.com/repos/${REPO}/git/trees/${BRANCH}?recursive=1`
|
|
21
|
+
// scan.mjs의 BUNDLE_CATEGORY와 같은 값이어야 한다 — 둘 다 카테고리 못 얻은
|
|
22
|
+
// 항목이 모이는 자리라, 갈라지면 같은 그룹이 헤더 두 개로 쪼개진다.
|
|
23
|
+
export const UNCATEGORIZED = '__other'
|
|
24
|
+
|
|
25
|
+
const ENTRY_RE = /^-\s*\[\*\*(.+?)\*\*\]\(\s*https?:\/\/getdesign\.md\/([^/)]+)\/design-md\s*\)\s*-\s*(.*)$/
|
|
26
|
+
|
|
27
|
+
// README `## Collection` 블록만 대상으로 카테고리·항목을 뽑는다.
|
|
28
|
+
export function parseReadme(md) {
|
|
29
|
+
const lines = md.split(/\r?\n/)
|
|
30
|
+
const entries = []
|
|
31
|
+
let inCollection = false
|
|
32
|
+
let category = UNCATEGORIZED
|
|
33
|
+
for (const line of lines) {
|
|
34
|
+
const h2 = /^##\s+(.*)$/.exec(line)
|
|
35
|
+
if (h2) {
|
|
36
|
+
inCollection = /^collection\b/i.test(h2[1].trim())
|
|
37
|
+
continue
|
|
38
|
+
}
|
|
39
|
+
if (!inCollection) continue
|
|
40
|
+
const h3 = /^###\s+(.*)$/.exec(line)
|
|
41
|
+
if (h3) {
|
|
42
|
+
category = h3[1].trim()
|
|
43
|
+
continue
|
|
44
|
+
}
|
|
45
|
+
const m = ENTRY_RE.exec(line.trim())
|
|
46
|
+
if (m) {
|
|
47
|
+
entries.push({ name: m[2].trim(), label: m[1].trim(), category, description: m[3].trim() })
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return entries
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// tree API에서 design-md/<name>/ 폴더명 집합을 뽑는다(orphan 보강용).
|
|
54
|
+
export function parseTreeNames(treeJson) {
|
|
55
|
+
const names = new Set()
|
|
56
|
+
for (const e of treeJson?.tree ?? []) {
|
|
57
|
+
const m = /^design-md\/([^/]+)\//.exec(e.path)
|
|
58
|
+
if (m) names.add(m[1])
|
|
59
|
+
}
|
|
60
|
+
return names
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export const awesomeDesignMd = {
|
|
64
|
+
id: 'awesome-design-md',
|
|
65
|
+
label: 'awesome-design-md (VoltAgent)',
|
|
66
|
+
files: ['DESIGN.md'],
|
|
67
|
+
licenseUrl: LICENSE_URL,
|
|
68
|
+
// 번들과 함께 발행되는 고지 파일. 이름이 LICENSE가 아닌 이유는 발행물 검사가
|
|
69
|
+
// 최상위 LICENSE 하나만 확장자 없는 파일로 허용하기 때문이다.
|
|
70
|
+
noticeFile: 'LICENSE.md',
|
|
71
|
+
|
|
72
|
+
fileUrl(name, file = 'DESIGN.md') {
|
|
73
|
+
return `${RAW_BASE}/${encodeURIComponent(name)}/${file}`
|
|
74
|
+
},
|
|
75
|
+
|
|
76
|
+
// fileUrl과 같이 인코딩한다 — name은 원격 README에서 오므로, 그대로 이어
|
|
77
|
+
// 붙이면 URL이 아닌 문자가 미리보기 대상 문자열에 섞인다.
|
|
78
|
+
webUrl(name) {
|
|
79
|
+
return `https://getdesign.md/${encodeURIComponent(name)}/design-md`
|
|
80
|
+
},
|
|
81
|
+
|
|
82
|
+
bundlePath(name, file = 'DESIGN.md') {
|
|
83
|
+
return join(BUNDLE_DIR, this.id, name, file)
|
|
84
|
+
},
|
|
85
|
+
|
|
86
|
+
// 동봉 번들에서 읽는다(없으면 null). 오프라인 설치용.
|
|
87
|
+
bundledText(name, file = 'DESIGN.md') {
|
|
88
|
+
if (/[\\/]/.test(name)) return null
|
|
89
|
+
const p = this.bundlePath(name, file)
|
|
90
|
+
return existsSync(p) ? readFileSync(p, 'utf8') : null
|
|
91
|
+
},
|
|
92
|
+
|
|
93
|
+
async fetchFile(fetchImpl, name, file = 'DESIGN.md') {
|
|
94
|
+
const res = await fetchImpl(this.fileUrl(name, file))
|
|
95
|
+
if (!res.ok) return null
|
|
96
|
+
return res.text()
|
|
97
|
+
},
|
|
98
|
+
|
|
99
|
+
// README 파싱(주) + tree orphan 보강(선택). 이름순 정렬 반환.
|
|
100
|
+
async fetchCatalog(fetchImpl) {
|
|
101
|
+
const readmeRes = await fetchImpl(README_URL)
|
|
102
|
+
if (!readmeRes.ok) throw new LocalizedError('error.readmeFetch', { status: readmeRes.status })
|
|
103
|
+
const entries = parseReadme(await readmeRes.text())
|
|
104
|
+
const seen = new Set(entries.map((e) => e.name))
|
|
105
|
+
|
|
106
|
+
try {
|
|
107
|
+
const treeRes = await fetchImpl(TREE_URL, { headers: { 'User-Agent': 'agent-installer' } })
|
|
108
|
+
if (treeRes.ok) {
|
|
109
|
+
for (const name of parseTreeNames(await treeRes.json())) {
|
|
110
|
+
if (!seen.has(name)) {
|
|
111
|
+
entries.push({ name, label: name, category: UNCATEGORIZED, description: '' })
|
|
112
|
+
seen.add(name)
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
} catch {
|
|
117
|
+
// tree 실패는 무시 — README만으로도 카탈로그는 유효하다.
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return entries.sort((a, b) => a.name.localeCompare(b.name))
|
|
121
|
+
},
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export default awesomeDesignMd
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
// design.md 프로바이더 레지스트리 — 소스 확장 지점.
|
|
2
|
-
// 새 소스 추가 = 프로바이더 모듈 1개 작성 + 여기 등록.
|
|
3
|
-
import { awesomeDesignMd } from './awesome-design-md.mjs'
|
|
4
|
-
|
|
5
|
-
export const PROVIDERS = [awesomeDesignMd]
|
|
6
|
-
|
|
7
|
-
export function getProvider(id) {
|
|
8
|
-
return PROVIDERS.find((p) => p.id === id)
|
|
9
|
-
}
|
|
1
|
+
// design.md 프로바이더 레지스트리 — 소스 확장 지점.
|
|
2
|
+
// 새 소스 추가 = 프로바이더 모듈 1개 작성 + 여기 등록.
|
|
3
|
+
import { awesomeDesignMd } from './awesome-design-md.mjs'
|
|
4
|
+
|
|
5
|
+
export const PROVIDERS = [awesomeDesignMd]
|
|
6
|
+
|
|
7
|
+
export function getProvider(id) {
|
|
8
|
+
return PROVIDERS.find((p) => p.id === id)
|
|
9
|
+
}
|