@vibe-forge/workspace-assets 3.0.0-alpha.8 → 3.1.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.
|
@@ -394,7 +394,7 @@ describe('buildAdapterAssetPlan', () => {
|
|
|
394
394
|
])
|
|
395
395
|
})
|
|
396
396
|
|
|
397
|
-
it('builds copilot native skill overlays and
|
|
397
|
+
it('builds copilot native skill overlays and native hook diagnostics', async () => {
|
|
398
398
|
const workspace = await createWorkspace()
|
|
399
399
|
|
|
400
400
|
await installPluginPackage(workspace, '@vibe-forge/plugin-logger', {
|
|
@@ -489,7 +489,7 @@ describe('buildAdapterAssetPlan', () => {
|
|
|
489
489
|
expect.objectContaining({
|
|
490
490
|
assetId: loggerHookPluginId,
|
|
491
491
|
adapter: 'copilot',
|
|
492
|
-
status: '
|
|
492
|
+
status: 'native'
|
|
493
493
|
}),
|
|
494
494
|
expect.objectContaining({
|
|
495
495
|
assetId: docsMcpId,
|
|
@@ -113,6 +113,141 @@ describe('skills CLI dependency resolution', () => {
|
|
|
113
113
|
})
|
|
114
114
|
})
|
|
115
115
|
|
|
116
|
+
it('blocks missing dependency installs when auto downloads are disabled', async () => {
|
|
117
|
+
const workspace = await createWorkspace()
|
|
118
|
+
|
|
119
|
+
await writeDocument(
|
|
120
|
+
join(workspace, '.ai/skills/app-builder/SKILL.md'),
|
|
121
|
+
[
|
|
122
|
+
'---',
|
|
123
|
+
'name: app-builder',
|
|
124
|
+
'description: Build apps',
|
|
125
|
+
'dependencies:',
|
|
126
|
+
' - name: frontend-design',
|
|
127
|
+
' source: anthropics/skills',
|
|
128
|
+
' registry: https://dependency-registry.example.test',
|
|
129
|
+
'---',
|
|
130
|
+
'Build the app.'
|
|
131
|
+
].join('\n')
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
const bundle = await resolveWorkspaceAssetBundle({
|
|
135
|
+
cwd: workspace,
|
|
136
|
+
configs: [{
|
|
137
|
+
skills: {
|
|
138
|
+
autoDownloadDependencies: false
|
|
139
|
+
}
|
|
140
|
+
}, undefined],
|
|
141
|
+
useDefaultVibeForgeMcpServer: false
|
|
142
|
+
})
|
|
143
|
+
|
|
144
|
+
await expect(buildAdapterAssetPlan({
|
|
145
|
+
adapter: 'opencode',
|
|
146
|
+
bundle,
|
|
147
|
+
options: {
|
|
148
|
+
skills: {
|
|
149
|
+
include: ['app-builder']
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
})).rejects.toThrow('Skill dependency automatic downloads are disabled; cache not found')
|
|
153
|
+
|
|
154
|
+
expect(mocks.findSkillsCli).not.toHaveBeenCalled()
|
|
155
|
+
expect(mocks.installSkillsCliRefToTemp).not.toHaveBeenCalled()
|
|
156
|
+
expect(mocks.installSkillsCliSkillToTemp).not.toHaveBeenCalled()
|
|
157
|
+
expect(bundle.skills.map(asset => asset.name)).toEqual(['app-builder'])
|
|
158
|
+
})
|
|
159
|
+
|
|
160
|
+
it('blocks bare-name dependency searches when auto downloads are disabled', async () => {
|
|
161
|
+
const workspace = await createWorkspace()
|
|
162
|
+
|
|
163
|
+
await writeDocument(
|
|
164
|
+
join(workspace, '.ai/skills/app-builder/SKILL.md'),
|
|
165
|
+
[
|
|
166
|
+
'---',
|
|
167
|
+
'name: app-builder',
|
|
168
|
+
'description: Build apps',
|
|
169
|
+
'dependencies:',
|
|
170
|
+
' - frontend-design',
|
|
171
|
+
'---',
|
|
172
|
+
'Build the app.'
|
|
173
|
+
].join('\n')
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
const bundle = await resolveWorkspaceAssetBundle({
|
|
177
|
+
cwd: workspace,
|
|
178
|
+
configs: [{
|
|
179
|
+
skills: {
|
|
180
|
+
autoDownloadDependencies: false
|
|
181
|
+
}
|
|
182
|
+
}, undefined],
|
|
183
|
+
useDefaultVibeForgeMcpServer: false
|
|
184
|
+
})
|
|
185
|
+
|
|
186
|
+
await expect(buildAdapterAssetPlan({
|
|
187
|
+
adapter: 'opencode',
|
|
188
|
+
bundle,
|
|
189
|
+
options: {
|
|
190
|
+
skills: {
|
|
191
|
+
include: ['app-builder']
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
})).rejects.toThrow(
|
|
195
|
+
'Skill dependency automatic downloads are disabled; cannot resolve frontend-design without a source'
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
expect(mocks.findSkillsCli).not.toHaveBeenCalled()
|
|
199
|
+
expect(mocks.installSkillsCliRefToTemp).not.toHaveBeenCalled()
|
|
200
|
+
expect(mocks.installSkillsCliSkillToTemp).not.toHaveBeenCalled()
|
|
201
|
+
})
|
|
202
|
+
|
|
203
|
+
it('reuses source-qualified dependency caches when auto downloads are disabled', async () => {
|
|
204
|
+
const workspace = await createWorkspace()
|
|
205
|
+
await writeDocument(
|
|
206
|
+
join(
|
|
207
|
+
workspace,
|
|
208
|
+
'.ai/caches/skill-dependencies/skills-cli/skills/latest/default/anthropics/skills/latest/frontend-design/SKILL.md'
|
|
209
|
+
),
|
|
210
|
+
'---\nname: frontend-design\ndescription: Cached UI guidance\n---\nUse the cached dependency.\n'
|
|
211
|
+
)
|
|
212
|
+
await writeDocument(
|
|
213
|
+
join(workspace, '.ai/skills/app-builder/SKILL.md'),
|
|
214
|
+
[
|
|
215
|
+
'---',
|
|
216
|
+
'name: app-builder',
|
|
217
|
+
'description: Build apps',
|
|
218
|
+
'dependencies:',
|
|
219
|
+
' - anthropics/skills@frontend-design',
|
|
220
|
+
'---',
|
|
221
|
+
'Build the app.'
|
|
222
|
+
].join('\n')
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
const bundle = await resolveWorkspaceAssetBundle({
|
|
226
|
+
cwd: workspace,
|
|
227
|
+
configs: [{
|
|
228
|
+
skills: {
|
|
229
|
+
autoDownloadDependencies: false
|
|
230
|
+
}
|
|
231
|
+
}, undefined],
|
|
232
|
+
useDefaultVibeForgeMcpServer: false
|
|
233
|
+
})
|
|
234
|
+
|
|
235
|
+
await buildAdapterAssetPlan({
|
|
236
|
+
adapter: 'opencode',
|
|
237
|
+
bundle,
|
|
238
|
+
options: {
|
|
239
|
+
skills: {
|
|
240
|
+
include: ['app-builder']
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
})
|
|
244
|
+
|
|
245
|
+
expect(mocks.findSkillsCli).not.toHaveBeenCalled()
|
|
246
|
+
expect(mocks.installSkillsCliRefToTemp).not.toHaveBeenCalled()
|
|
247
|
+
expect(mocks.installSkillsCliSkillToTemp).not.toHaveBeenCalled()
|
|
248
|
+
expect(bundle.skills.map(asset => asset.name).sort()).toEqual(['app-builder', 'frontend-design'])
|
|
249
|
+
})
|
|
250
|
+
|
|
116
251
|
it('parses registry and version from dependency specs', async () => {
|
|
117
252
|
const workspace = await createWorkspace()
|
|
118
253
|
const installedSkillDir = join(installWorkspace, '.agents', 'skills', 'frontend-design')
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vibe-forge/workspace-assets",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"description": "Workspace asset resolution and adapter asset planning for Vibe Forge",
|
|
5
5
|
"imports": {
|
|
6
6
|
"#~/*.js": {
|
|
@@ -29,10 +29,10 @@
|
|
|
29
29
|
"fast-glob": "^3.3.3",
|
|
30
30
|
"front-matter": "^4.0.2",
|
|
31
31
|
"js-yaml": "^4.1.1",
|
|
32
|
-
"@vibe-forge/
|
|
33
|
-
"@vibe-forge/
|
|
34
|
-
"@vibe-forge/
|
|
35
|
-
"@vibe-forge/definition-core": "3.
|
|
32
|
+
"@vibe-forge/types": "3.1.0",
|
|
33
|
+
"@vibe-forge/config": "3.1.0",
|
|
34
|
+
"@vibe-forge/utils": "3.1.0",
|
|
35
|
+
"@vibe-forge/definition-core": "3.1.0"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"@types/js-yaml": "^4.0.9"
|
|
@@ -78,7 +78,7 @@ export async function buildAdapterAssetPlan(params: {
|
|
|
78
78
|
params.bundle.hookPlugins.forEach((asset) => {
|
|
79
79
|
pushDiagnostic(asset, {
|
|
80
80
|
adapter: params.adapter,
|
|
81
|
-
status:
|
|
81
|
+
status: 'native',
|
|
82
82
|
reason: params.adapter === 'claude-code'
|
|
83
83
|
? 'Mapped into the Claude Code native hooks bridge.'
|
|
84
84
|
: params.adapter === 'codex'
|
|
@@ -86,7 +86,7 @@ export async function buildAdapterAssetPlan(params: {
|
|
|
86
86
|
: params.adapter === 'gemini'
|
|
87
87
|
? 'Mapped into the Gemini native hooks bridge.'
|
|
88
88
|
: params.adapter === 'copilot'
|
|
89
|
-
? '
|
|
89
|
+
? 'Mapped into the Copilot CLI native hooks bridge.'
|
|
90
90
|
: params.adapter === 'kimi'
|
|
91
91
|
? 'Mapped into the Kimi native hooks bridge.'
|
|
92
92
|
: 'Mapped into the OpenCode native hooks bridge.'
|
|
@@ -14,17 +14,33 @@ import {
|
|
|
14
14
|
withInstallLock
|
|
15
15
|
} from './skills-cli-dependency-helpers'
|
|
16
16
|
|
|
17
|
+
const resolveAutoDownloadDependenciesEnabled = (
|
|
18
|
+
projectConfig: Config | undefined,
|
|
19
|
+
userConfig: Config | undefined
|
|
20
|
+
) => userConfig?.skills?.autoDownloadDependencies ?? projectConfig?.skills?.autoDownloadDependencies ?? true
|
|
21
|
+
|
|
17
22
|
export const installSkillsCliDependency = async (params: {
|
|
18
23
|
cwd: string
|
|
19
24
|
configs: [Config?, Config?]
|
|
20
25
|
dependency: NormalizedSkillDependency
|
|
21
26
|
}) => {
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
27
|
+
const [projectConfig, userConfig] = params.configs
|
|
28
|
+
const autoDownloadDependenciesEnabled = resolveAutoDownloadDependenciesEnabled(projectConfig, userConfig)
|
|
29
|
+
const resolvedTarget = await (async () => {
|
|
30
|
+
if (params.dependency.source != null) {
|
|
31
|
+
return {
|
|
32
|
+
skill: params.dependency.name,
|
|
33
|
+
source: params.dependency.source
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (!autoDownloadDependenciesEnabled) {
|
|
38
|
+
throw new Error(
|
|
39
|
+
`Skill dependency automatic downloads are disabled; cannot resolve ${params.dependency.ref} without a source`
|
|
40
|
+
)
|
|
26
41
|
}
|
|
27
|
-
|
|
42
|
+
|
|
43
|
+
return await (async () => {
|
|
28
44
|
const searchResults = await findSkillsCli({
|
|
29
45
|
registry: params.dependency.registry,
|
|
30
46
|
query: params.dependency.name
|
|
@@ -40,6 +56,7 @@ export const installSkillsCliDependency = async (params: {
|
|
|
40
56
|
source: selected.source
|
|
41
57
|
}
|
|
42
58
|
})()
|
|
59
|
+
})()
|
|
43
60
|
|
|
44
61
|
const installDir = buildInstallDir({
|
|
45
62
|
cwd: params.cwd,
|
|
@@ -58,6 +75,10 @@ export const installSkillsCliDependency = async (params: {
|
|
|
58
75
|
}
|
|
59
76
|
}
|
|
60
77
|
|
|
78
|
+
if (!autoDownloadDependenciesEnabled) {
|
|
79
|
+
throw new Error(`Skill dependency automatic downloads are disabled; cache not found for ${params.dependency.ref}`)
|
|
80
|
+
}
|
|
81
|
+
|
|
61
82
|
const tempInstallDir = `${installDir}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`
|
|
62
83
|
await rm(tempInstallDir, { recursive: true, force: true })
|
|
63
84
|
await mkdir(tempInstallDir, { recursive: true })
|