@vibe-forge/workspace-assets 0.9.1-alpha.0 → 0.9.2-alpha.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/AGENTS.md +4 -1
- package/LICENSE +21 -0
- package/__tests__/__snapshots__/workspace-assets-rich.snapshot.json +360 -355
- package/__tests__/adapter-asset-plan.spec.ts +76 -38
- package/__tests__/bundle.spec.ts +195 -43
- package/__tests__/prompt-builders.spec.ts +206 -0
- package/__tests__/prompt-selection.spec.ts +362 -14
- package/__tests__/selection-internal.spec.ts +42 -0
- package/__tests__/snapshot.ts +78 -128
- package/__tests__/test-helpers.ts +13 -0
- package/__tests__/workspace-assets.snapshot.spec.ts +84 -103
- package/package.json +11 -10
- package/src/adapter-asset-plan.ts +92 -111
- package/src/bundle-internal.ts +548 -0
- package/src/bundle.ts +17 -166
- package/src/internal-types.ts +1 -39
- package/src/prompt-builders.ts +184 -0
- package/src/prompt-selection.ts +144 -104
- package/src/selection-internal.ts +275 -0
- package/src/document-assets.ts +0 -191
- package/src/helpers.ts +0 -35
- package/src/plugin-assets.ts +0 -175
package/__tests__/snapshot.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import process from 'node:process'
|
|
2
2
|
|
|
3
|
+
import { resolveDocumentName, resolveSpecIdentifier } from '@vibe-forge/definition-core'
|
|
3
4
|
import type {
|
|
4
5
|
AdapterAssetPlan,
|
|
5
6
|
AssetDiagnostic,
|
|
@@ -14,27 +15,17 @@ import type {
|
|
|
14
15
|
WorkspaceAssetBundle,
|
|
15
16
|
WorkspaceAssetKind
|
|
16
17
|
} from '@vibe-forge/types'
|
|
17
|
-
import { resolveDocumentName, resolveSpecIdentifier } from '@vibe-forge/utils'
|
|
18
|
-
|
|
19
|
-
import { isOpenCodeOverlayAsset } from '#~/internal-types.js'
|
|
20
18
|
|
|
21
19
|
const sortStrings = (values: string[]) => [...values].sort((left, right) => left.localeCompare(right))
|
|
22
20
|
|
|
23
|
-
const isConfigNativePluginAsset = (
|
|
24
|
-
asset: Extract<WorkspaceAsset, { kind: 'nativePlugin' }>
|
|
25
|
-
): asset is Extract<WorkspaceAsset, { kind: 'nativePlugin' }> & {
|
|
26
|
-
payload: {
|
|
27
|
-
name: string
|
|
28
|
-
enabled: boolean
|
|
29
|
-
}
|
|
30
|
-
} => !isOpenCodeOverlayAsset(asset)
|
|
31
|
-
|
|
32
21
|
const sanitizeValue = (
|
|
33
22
|
value: string,
|
|
34
23
|
cwd: string
|
|
35
24
|
) => (
|
|
36
25
|
value
|
|
26
|
+
.replaceAll(`/private${cwd}`, '<workspace>')
|
|
37
27
|
.replaceAll(cwd, '<workspace>')
|
|
28
|
+
.replaceAll(`/private${process.execPath}`, '<node-path>')
|
|
38
29
|
.replaceAll(process.execPath, '<node-path>')
|
|
39
30
|
)
|
|
40
31
|
|
|
@@ -99,104 +90,75 @@ const summarizeDefinition = (
|
|
|
99
90
|
body: definition.body.trim()
|
|
100
91
|
})
|
|
101
92
|
|
|
102
|
-
const
|
|
103
|
-
asset:
|
|
93
|
+
const buildSnapshotAssetId = (
|
|
94
|
+
asset: WorkspaceAsset,
|
|
104
95
|
cwd: string
|
|
96
|
+
) => (
|
|
97
|
+
`${asset.kind}:${asset.origin}:${asset.instancePath ?? 'workspace'}:${asset.displayName}:${
|
|
98
|
+
sanitizeValue(asset.sourcePath, cwd)
|
|
99
|
+
}`
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
const summarizeBaseAsset = (
|
|
103
|
+
asset: WorkspaceAsset,
|
|
104
|
+
cwd: string,
|
|
105
|
+
assetIdMap?: Map<string, string>
|
|
105
106
|
) => ({
|
|
106
|
-
id: asset.id,
|
|
107
|
+
id: assetIdMap?.get(asset.id) ?? buildSnapshotAssetId(asset, cwd),
|
|
107
108
|
kind: asset.kind,
|
|
109
|
+
name: asset.name,
|
|
110
|
+
displayName: asset.displayName,
|
|
108
111
|
origin: asset.origin,
|
|
109
112
|
scope: asset.scope,
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
+
sourcePath: sanitizeValue(asset.sourcePath, cwd),
|
|
114
|
+
instancePath: asset.instancePath,
|
|
115
|
+
packageId: asset.packageId,
|
|
116
|
+
resolvedBy: asset.resolvedBy,
|
|
117
|
+
taskOverlaySource: asset.taskOverlaySource
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
const summarizeDocumentAsset = (
|
|
121
|
+
asset: Extract<WorkspaceAsset, { kind: 'rule' | 'spec' | 'entity' | 'skill' }>,
|
|
122
|
+
cwd: string,
|
|
123
|
+
assetIdMap?: Map<string, string>
|
|
124
|
+
) => ({
|
|
125
|
+
...summarizeBaseAsset(asset, cwd, assetIdMap),
|
|
113
126
|
definition: summarizeDefinition(asset.kind, asset.payload.definition, cwd)
|
|
114
127
|
})
|
|
115
128
|
|
|
116
129
|
const summarizeMcpServer = (
|
|
117
130
|
asset: Extract<WorkspaceAsset, { kind: 'mcpServer' }>,
|
|
118
|
-
cwd: string
|
|
131
|
+
cwd: string,
|
|
132
|
+
assetIdMap?: Map<string, string>
|
|
119
133
|
) => ({
|
|
120
|
-
|
|
121
|
-
origin: asset.origin,
|
|
122
|
-
scope: asset.scope,
|
|
123
|
-
pluginId: asset.pluginId,
|
|
124
|
-
enabled: asset.enabled,
|
|
125
|
-
targets: sortStrings(asset.targets),
|
|
126
|
-
name: asset.payload.name,
|
|
134
|
+
...summarizeBaseAsset(asset, cwd, assetIdMap),
|
|
127
135
|
config: normalizeValue(asset.payload.config, cwd)
|
|
128
136
|
})
|
|
129
137
|
|
|
130
138
|
const summarizeHookPlugin = (
|
|
131
139
|
asset: Extract<WorkspaceAsset, { kind: 'hookPlugin' }>,
|
|
132
|
-
cwd: string
|
|
140
|
+
cwd: string,
|
|
141
|
+
assetIdMap?: Map<string, string>
|
|
133
142
|
) => ({
|
|
134
|
-
|
|
135
|
-
origin: asset.origin,
|
|
136
|
-
scope: asset.scope,
|
|
137
|
-
pluginId: asset.pluginId,
|
|
138
|
-
enabled: asset.enabled,
|
|
139
|
-
targets: sortStrings(asset.targets),
|
|
143
|
+
...summarizeBaseAsset(asset, cwd, assetIdMap),
|
|
140
144
|
packageName: asset.payload.packageName,
|
|
141
145
|
config: normalizeValue(asset.payload.config, cwd)
|
|
142
146
|
})
|
|
143
147
|
|
|
144
|
-
const
|
|
145
|
-
asset: Extract<WorkspaceAsset, { kind: 'nativePlugin' }>,
|
|
146
|
-
cwd: string
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
scope: asset.scope,
|
|
154
|
-
pluginId: asset.pluginId,
|
|
155
|
-
enabled: asset.enabled,
|
|
156
|
-
targets: sortStrings(asset.targets),
|
|
157
|
-
entryName: asset.payload.entryName,
|
|
158
|
-
sourcePath: sanitizeValue(asset.payload.sourcePath, cwd),
|
|
159
|
-
targetSubpath: asset.payload.targetSubpath
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
return {
|
|
164
|
-
id: asset.id,
|
|
165
|
-
kind: asset.kind,
|
|
166
|
-
origin: asset.origin,
|
|
167
|
-
scope: asset.scope,
|
|
168
|
-
pluginId: asset.pluginId,
|
|
169
|
-
enabled: asset.enabled,
|
|
170
|
-
targets: sortStrings(asset.targets),
|
|
171
|
-
name: isConfigNativePluginAsset(asset) ? asset.payload.name : undefined
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
const summarizeOverlayAsset = (
|
|
176
|
-
asset:
|
|
177
|
-
| Extract<WorkspaceAsset, { kind: 'agent' | 'command' | 'mode' }>
|
|
178
|
-
| Extract<WorkspaceAsset, { kind: 'nativePlugin' }>,
|
|
179
|
-
cwd: string
|
|
180
|
-
) => {
|
|
181
|
-
if (!isOpenCodeOverlayAsset(asset)) {
|
|
182
|
-
return summarizeNativePlugin(asset, cwd)
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
return {
|
|
186
|
-
id: asset.id,
|
|
187
|
-
kind: asset.kind,
|
|
188
|
-
origin: asset.origin,
|
|
189
|
-
scope: asset.scope,
|
|
190
|
-
pluginId: asset.pluginId,
|
|
191
|
-
enabled: asset.enabled,
|
|
192
|
-
targets: sortStrings(asset.targets),
|
|
193
|
-
entryName: asset.payload.entryName,
|
|
194
|
-
sourcePath: sanitizeValue(asset.payload.sourcePath, cwd),
|
|
195
|
-
targetSubpath: asset.payload.targetSubpath
|
|
196
|
-
}
|
|
197
|
-
}
|
|
148
|
+
const summarizeOpenCodeOverlayAsset = (
|
|
149
|
+
asset: Extract<WorkspaceAsset, { kind: 'agent' | 'command' | 'mode' | 'nativePlugin' }>,
|
|
150
|
+
cwd: string,
|
|
151
|
+
assetIdMap?: Map<string, string>
|
|
152
|
+
) => ({
|
|
153
|
+
...summarizeBaseAsset(asset, cwd, assetIdMap),
|
|
154
|
+
entryName: asset.payload.entryName,
|
|
155
|
+
targetSubpath: asset.payload.targetSubpath
|
|
156
|
+
})
|
|
198
157
|
|
|
199
|
-
const summarizeDiagnostics = (
|
|
158
|
+
const summarizeDiagnostics = (
|
|
159
|
+
diagnostics: AssetDiagnostic[],
|
|
160
|
+
assetIdMap: Map<string, string>
|
|
161
|
+
) => (
|
|
200
162
|
[...diagnostics]
|
|
201
163
|
.sort((left, right) => {
|
|
202
164
|
const assetIdDiff = left.assetId.localeCompare(right.assetId)
|
|
@@ -204,29 +166,31 @@ const summarizeDiagnostics = (diagnostics: AssetDiagnostic[]) => (
|
|
|
204
166
|
return left.status.localeCompare(right.status)
|
|
205
167
|
})
|
|
206
168
|
.map(diagnostic => ({
|
|
207
|
-
assetId: diagnostic.assetId,
|
|
169
|
+
assetId: assetIdMap.get(diagnostic.assetId) ?? diagnostic.assetId,
|
|
208
170
|
adapter: diagnostic.adapter,
|
|
209
171
|
status: diagnostic.status,
|
|
210
|
-
reason: diagnostic.reason
|
|
172
|
+
reason: diagnostic.reason,
|
|
173
|
+
scope: diagnostic.scope,
|
|
174
|
+
packageId: diagnostic.packageId
|
|
211
175
|
}))
|
|
212
176
|
)
|
|
213
177
|
|
|
214
178
|
const summarizePlan = (
|
|
215
179
|
plan: AdapterAssetPlan,
|
|
216
|
-
cwd: string
|
|
180
|
+
cwd: string,
|
|
181
|
+
assetIdMap: Map<string, string>
|
|
217
182
|
) => ({
|
|
218
183
|
adapter: plan.adapter,
|
|
219
184
|
mcpServers: normalizeValue(plan.mcpServers, cwd),
|
|
220
185
|
overlays: [...plan.overlays]
|
|
221
186
|
.sort((left, right) => left.assetId.localeCompare(right.assetId))
|
|
222
187
|
.map(entry => ({
|
|
223
|
-
assetId: entry.assetId,
|
|
188
|
+
assetId: assetIdMap.get(entry.assetId) ?? entry.assetId,
|
|
224
189
|
kind: entry.kind,
|
|
225
190
|
sourcePath: sanitizeValue(entry.sourcePath, cwd),
|
|
226
191
|
targetPath: entry.targetPath
|
|
227
192
|
})),
|
|
228
|
-
|
|
229
|
-
diagnostics: summarizeDiagnostics(plan.diagnostics)
|
|
193
|
+
diagnostics: summarizeDiagnostics(plan.diagnostics, assetIdMap)
|
|
230
194
|
})
|
|
231
195
|
|
|
232
196
|
const summarizeSelection = (
|
|
@@ -237,7 +201,8 @@ const summarizeSelection = (
|
|
|
237
201
|
mcpServers?: Filter
|
|
238
202
|
promptAssetIds?: string[]
|
|
239
203
|
},
|
|
240
|
-
cwd: string
|
|
204
|
+
cwd: string,
|
|
205
|
+
assetIdMap: Map<string, string>
|
|
241
206
|
) => ({
|
|
242
207
|
resolution: {
|
|
243
208
|
rules: resolution.rules.map(rule => summarizeDefinition('rule', rule, cwd)),
|
|
@@ -246,13 +211,15 @@ const summarizeSelection = (
|
|
|
246
211
|
skills: resolution.skills.map(skill => summarizeDefinition('skill', skill, cwd)),
|
|
247
212
|
specs: resolution.specs.map(spec => summarizeDefinition('spec', spec, cwd)),
|
|
248
213
|
targetBody: resolution.targetBody.trim(),
|
|
249
|
-
promptAssetIds: sortStrings(resolution.promptAssetIds)
|
|
214
|
+
promptAssetIds: sortStrings(resolution.promptAssetIds.map(assetId => assetIdMap.get(assetId) ?? assetId))
|
|
250
215
|
},
|
|
251
216
|
options: {
|
|
252
217
|
systemPrompt: options.systemPrompt?.trim(),
|
|
253
218
|
tools: sortFilter(options.tools),
|
|
254
219
|
mcpServers: sortFilter(options.mcpServers),
|
|
255
|
-
promptAssetIds: options.promptAssetIds == null
|
|
220
|
+
promptAssetIds: options.promptAssetIds == null
|
|
221
|
+
? undefined
|
|
222
|
+
: sortStrings(options.promptAssetIds.map(assetId => assetIdMap.get(assetId) ?? assetId))
|
|
256
223
|
}
|
|
257
224
|
})
|
|
258
225
|
|
|
@@ -271,56 +238,39 @@ export const serializeWorkspaceAssetsSnapshot = (params: {
|
|
|
271
238
|
plans: AdapterAssetPlan[]
|
|
272
239
|
}) => {
|
|
273
240
|
const { bundle, cwd } = params
|
|
274
|
-
const
|
|
275
|
-
asset
|
|
276
|
-
): asset is
|
|
277
|
-
| Extract<WorkspaceAsset, { kind: 'agent' | 'command' | 'mode' }>
|
|
278
|
-
| Extract<WorkspaceAsset, { kind: 'nativePlugin' }> => (
|
|
279
|
-
asset.kind === 'agent' ||
|
|
280
|
-
asset.kind === 'command' ||
|
|
281
|
-
asset.kind === 'mode' ||
|
|
282
|
-
(asset.kind === 'nativePlugin' && isOpenCodeOverlayAsset(asset))
|
|
283
|
-
)
|
|
284
|
-
)
|
|
285
|
-
const claudeNativePlugins = bundle.assets.filter((
|
|
286
|
-
asset
|
|
287
|
-
): asset is Extract<WorkspaceAsset, { kind: 'nativePlugin' }> => (
|
|
288
|
-
asset.kind === 'nativePlugin' && !isOpenCodeOverlayAsset(asset)
|
|
289
|
-
))
|
|
241
|
+
const assetIdMap = new Map(bundle.assets.map(asset => [asset.id, buildSnapshotAssetId(asset, cwd)]))
|
|
290
242
|
|
|
291
243
|
const snapshot = {
|
|
292
244
|
bundle: {
|
|
293
245
|
cwd: '<workspace>',
|
|
294
|
-
|
|
295
|
-
|
|
246
|
+
pluginConfigs: normalizeValue(bundle.pluginConfigs, cwd),
|
|
247
|
+
pluginInstances: normalizeValue(bundle.pluginInstances, cwd),
|
|
296
248
|
defaultIncludeMcpServers: sortStrings(bundle.defaultIncludeMcpServers),
|
|
297
249
|
defaultExcludeMcpServers: sortStrings(bundle.defaultExcludeMcpServers),
|
|
298
|
-
rules: bundle.rules.map(rule => summarizeDocumentAsset(rule, cwd)),
|
|
299
|
-
specs: bundle.specs.map(spec => summarizeDocumentAsset(spec, cwd)),
|
|
300
|
-
entities: bundle.entities.map(entity => summarizeDocumentAsset(entity, cwd)),
|
|
301
|
-
skills: bundle.skills.map(skill => summarizeDocumentAsset(skill, cwd)),
|
|
250
|
+
rules: bundle.rules.map(rule => summarizeDocumentAsset(rule, cwd, assetIdMap)),
|
|
251
|
+
specs: bundle.specs.map(spec => summarizeDocumentAsset(spec, cwd, assetIdMap)),
|
|
252
|
+
entities: bundle.entities.map(entity => summarizeDocumentAsset(entity, cwd, assetIdMap)),
|
|
253
|
+
skills: bundle.skills.map(skill => summarizeDocumentAsset(skill, cwd, assetIdMap)),
|
|
302
254
|
mcpServers: Object.values(bundle.mcpServers)
|
|
303
255
|
.sort((left, right) => left.payload.name.localeCompare(right.payload.name))
|
|
304
|
-
.map(server => summarizeMcpServer(server, cwd)),
|
|
256
|
+
.map(server => summarizeMcpServer(server, cwd, assetIdMap)),
|
|
305
257
|
hookPlugins: bundle.hookPlugins
|
|
306
258
|
.sort((left, right) => left.id.localeCompare(right.id))
|
|
307
|
-
.map(plugin => summarizeHookPlugin(plugin, cwd)),
|
|
308
|
-
|
|
309
|
-
.sort((left, right) => left.id.localeCompare(right.id))
|
|
310
|
-
.map(asset => summarizeNativePlugin(asset, cwd)),
|
|
311
|
-
opencodeOverlayAssets: overlayAssets
|
|
259
|
+
.map(plugin => summarizeHookPlugin(plugin, cwd, assetIdMap)),
|
|
260
|
+
opencodeOverlayAssets: bundle.opencodeOverlayAssets
|
|
312
261
|
.sort((left, right) => left.id.localeCompare(right.id))
|
|
313
|
-
.map(asset =>
|
|
262
|
+
.map(asset => summarizeOpenCodeOverlayAsset(asset, cwd, assetIdMap))
|
|
314
263
|
},
|
|
315
264
|
selection: summarizeSelection(
|
|
316
265
|
params.selection.resolution,
|
|
317
266
|
params.selection.options,
|
|
318
|
-
cwd
|
|
267
|
+
cwd,
|
|
268
|
+
assetIdMap
|
|
319
269
|
),
|
|
320
270
|
plans: Object.fromEntries(
|
|
321
271
|
[...params.plans]
|
|
322
272
|
.sort((left, right) => left.adapter.localeCompare(right.adapter))
|
|
323
|
-
.map(plan => [plan.adapter, summarizePlan(plan, cwd)])
|
|
273
|
+
.map(plan => [plan.adapter, summarizePlan(plan, cwd, assetIdMap)])
|
|
324
274
|
)
|
|
325
275
|
}
|
|
326
276
|
|
|
@@ -17,6 +17,19 @@ export const writeDocument = async (filePath: string, content: string) => {
|
|
|
17
17
|
await writeFile(filePath, content)
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
export const installPluginPackage = async (
|
|
21
|
+
workspace: string,
|
|
22
|
+
packageName: string,
|
|
23
|
+
files: Record<string, string>
|
|
24
|
+
) => {
|
|
25
|
+
const packageDir = join(workspace, 'node_modules', ...packageName.split('/'))
|
|
26
|
+
await Promise.all(
|
|
27
|
+
Object.entries(files).map(async ([relativePath, content]) => {
|
|
28
|
+
await writeDocument(join(packageDir, relativePath), content)
|
|
29
|
+
})
|
|
30
|
+
)
|
|
31
|
+
}
|
|
32
|
+
|
|
20
33
|
afterEach(async () => {
|
|
21
34
|
await Promise.all(tempDirs.splice(0).map(dir => rm(dir, { recursive: true, force: true })))
|
|
22
35
|
})
|
|
@@ -8,7 +8,7 @@ import type { Config } from '@vibe-forge/types'
|
|
|
8
8
|
import { buildAdapterAssetPlan, resolvePromptAssetSelection, resolveWorkspaceAssetBundle } from '#~/index.js'
|
|
9
9
|
|
|
10
10
|
import { serializeWorkspaceAssetsSnapshot } from './snapshot'
|
|
11
|
-
import { createWorkspace, writeDocument } from './test-helpers'
|
|
11
|
+
import { createWorkspace, installPluginPackage, writeDocument } from './test-helpers'
|
|
12
12
|
|
|
13
13
|
const resolveSnapshotPath = (name: string) => (
|
|
14
14
|
fileURLToPath(new URL(`./__snapshots__/${name}.snapshot.json`, import.meta.url))
|
|
@@ -19,43 +19,33 @@ describe('workspace assets snapshots', () => {
|
|
|
19
19
|
const workspace = await createWorkspace()
|
|
20
20
|
|
|
21
21
|
const projectConfig: Config = {
|
|
22
|
-
plugins:
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
plugins: [
|
|
23
|
+
{
|
|
24
|
+
id: 'logger'
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
id: 'demo',
|
|
28
|
+
scope: 'demo'
|
|
25
29
|
}
|
|
26
|
-
|
|
27
|
-
enabledPlugins: {
|
|
28
|
-
logger: true,
|
|
29
|
-
demo: true,
|
|
30
|
-
legacy: false,
|
|
31
|
-
telemetry: true
|
|
32
|
-
},
|
|
30
|
+
],
|
|
33
31
|
mcpServers: {
|
|
34
32
|
docs: {
|
|
35
33
|
command: 'npx',
|
|
36
34
|
args: ['docs-server']
|
|
37
35
|
}
|
|
38
36
|
},
|
|
39
|
-
defaultIncludeMcpServers: ['docs', 'browser']
|
|
40
|
-
extraKnownMarketplaces: {
|
|
41
|
-
internal: {
|
|
42
|
-
source: {
|
|
43
|
-
source: 'git',
|
|
44
|
-
url: 'https://plugins.internal.example.com'
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
}
|
|
37
|
+
defaultIncludeMcpServers: ['docs', 'demo/browser']
|
|
48
38
|
}
|
|
49
39
|
|
|
50
40
|
const userConfig: Config = {
|
|
51
|
-
plugins:
|
|
52
|
-
|
|
53
|
-
|
|
41
|
+
plugins: [
|
|
42
|
+
{
|
|
43
|
+
id: 'telemetry',
|
|
44
|
+
options: {
|
|
45
|
+
mode: 'summary'
|
|
46
|
+
}
|
|
54
47
|
}
|
|
55
|
-
|
|
56
|
-
enabledPlugins: {
|
|
57
|
-
telemetry: true
|
|
58
|
-
},
|
|
48
|
+
],
|
|
59
49
|
mcpServers: {
|
|
60
50
|
notes: {
|
|
61
51
|
command: 'node',
|
|
@@ -65,33 +55,79 @@ describe('workspace assets snapshots', () => {
|
|
|
65
55
|
defaultExcludeMcpServers: ['notes']
|
|
66
56
|
}
|
|
67
57
|
|
|
68
|
-
await
|
|
69
|
-
|
|
70
|
-
|
|
58
|
+
await installPluginPackage(workspace, '@vibe-forge/plugin-demo', {
|
|
59
|
+
'package.json': JSON.stringify(
|
|
60
|
+
{
|
|
61
|
+
name: '@vibe-forge/plugin-demo',
|
|
62
|
+
version: '1.0.0'
|
|
63
|
+
},
|
|
64
|
+
null,
|
|
65
|
+
2
|
|
66
|
+
),
|
|
67
|
+
'hooks.js': 'module.exports = {}\n',
|
|
68
|
+
'rules/security.md': [
|
|
71
69
|
'---',
|
|
72
|
-
'description:
|
|
73
|
-
'always: true',
|
|
70
|
+
'description: 插件安全规则',
|
|
74
71
|
'---',
|
|
75
|
-
'
|
|
76
|
-
].join('\n')
|
|
77
|
-
|
|
78
|
-
await writeDocument(
|
|
79
|
-
join(workspace, '.ai/plugins/demo/rules/review.md'),
|
|
80
|
-
[
|
|
72
|
+
'上线前要检查权限与密钥暴露。'
|
|
73
|
+
].join('\n'),
|
|
74
|
+
'specs/release/index.md': [
|
|
81
75
|
'---',
|
|
82
|
-
'description:
|
|
83
|
-
'always: true',
|
|
76
|
+
'description: 插件发布流程',
|
|
84
77
|
'---',
|
|
85
|
-
'
|
|
86
|
-
].join('\n')
|
|
87
|
-
|
|
78
|
+
'插件 release 不应直接替代项目 release。'
|
|
79
|
+
].join('\n'),
|
|
80
|
+
'skills/audit/SKILL.md': [
|
|
81
|
+
'---',
|
|
82
|
+
'description: 审计输出',
|
|
83
|
+
'---',
|
|
84
|
+
'检查最终输出是否覆盖风险项。'
|
|
85
|
+
].join('\n'),
|
|
86
|
+
'mcp/browser.json': JSON.stringify(
|
|
87
|
+
{
|
|
88
|
+
name: 'browser',
|
|
89
|
+
command: 'npx',
|
|
90
|
+
args: ['browser-mcp']
|
|
91
|
+
},
|
|
92
|
+
null,
|
|
93
|
+
2
|
|
94
|
+
),
|
|
95
|
+
'opencode/agents/release-helper.md': '# release-helper\n',
|
|
96
|
+
'opencode/commands/review.md': '# review\n',
|
|
97
|
+
'opencode/modes/strict.md': '# strict\n',
|
|
98
|
+
'opencode/plugins/demo-plugin.js': 'export default {}\n'
|
|
99
|
+
})
|
|
100
|
+
await installPluginPackage(workspace, '@vibe-forge/plugin-logger', {
|
|
101
|
+
'package.json': JSON.stringify(
|
|
102
|
+
{
|
|
103
|
+
name: '@vibe-forge/plugin-logger',
|
|
104
|
+
version: '1.0.0'
|
|
105
|
+
},
|
|
106
|
+
null,
|
|
107
|
+
2
|
|
108
|
+
),
|
|
109
|
+
'hooks.js': 'module.exports = {}\n'
|
|
110
|
+
})
|
|
111
|
+
await installPluginPackage(workspace, '@vibe-forge/plugin-telemetry', {
|
|
112
|
+
'package.json': JSON.stringify(
|
|
113
|
+
{
|
|
114
|
+
name: '@vibe-forge/plugin-telemetry',
|
|
115
|
+
version: '1.0.0'
|
|
116
|
+
},
|
|
117
|
+
null,
|
|
118
|
+
2
|
|
119
|
+
),
|
|
120
|
+
'hooks.js': 'module.exports = {}\n'
|
|
121
|
+
})
|
|
122
|
+
|
|
88
123
|
await writeDocument(
|
|
89
|
-
join(workspace, '.ai/
|
|
124
|
+
join(workspace, '.ai/rules/review.md'),
|
|
90
125
|
[
|
|
91
126
|
'---',
|
|
92
|
-
'description:
|
|
127
|
+
'description: 项目评审规则',
|
|
128
|
+
'always: true',
|
|
93
129
|
'---',
|
|
94
|
-
'
|
|
130
|
+
'必须检查发布改动的回归风险。'
|
|
95
131
|
].join('\n')
|
|
96
132
|
)
|
|
97
133
|
await writeDocument(
|
|
@@ -106,9 +142,9 @@ describe('workspace assets snapshots', () => {
|
|
|
106
142
|
'mcpServers:',
|
|
107
143
|
' include:',
|
|
108
144
|
' - docs',
|
|
109
|
-
' - browser',
|
|
145
|
+
' - demo/browser',
|
|
110
146
|
' exclude:',
|
|
111
|
-
' - browser',
|
|
147
|
+
' - demo/browser',
|
|
112
148
|
'tools:',
|
|
113
149
|
' include:',
|
|
114
150
|
' - Read',
|
|
@@ -117,15 +153,6 @@ describe('workspace assets snapshots', () => {
|
|
|
117
153
|
'执行正式发布,并整理变更摘要。'
|
|
118
154
|
].join('\n')
|
|
119
155
|
)
|
|
120
|
-
await writeDocument(
|
|
121
|
-
join(workspace, '.ai/plugins/demo/specs/release/index.md'),
|
|
122
|
-
[
|
|
123
|
-
'---',
|
|
124
|
-
'description: 插件发布流程',
|
|
125
|
-
'---',
|
|
126
|
-
'插件 release 不应覆盖项目 release。'
|
|
127
|
-
].join('\n')
|
|
128
|
-
)
|
|
129
156
|
await writeDocument(
|
|
130
157
|
join(workspace, '.ai/entities/architect/README.md'),
|
|
131
158
|
[
|
|
@@ -144,52 +171,6 @@ describe('workspace assets snapshots', () => {
|
|
|
144
171
|
'先阅读 README.md,再补充结论。'
|
|
145
172
|
].join('\n')
|
|
146
173
|
)
|
|
147
|
-
await writeDocument(
|
|
148
|
-
join(workspace, '.ai/plugins/demo/skills/research/SKILL.md'),
|
|
149
|
-
[
|
|
150
|
-
'---',
|
|
151
|
-
'description: 插件 research',
|
|
152
|
-
'---',
|
|
153
|
-
'插件 research 不应覆盖项目 skill。'
|
|
154
|
-
].join('\n')
|
|
155
|
-
)
|
|
156
|
-
await writeDocument(
|
|
157
|
-
join(workspace, '.ai/plugins/demo/skills/audit/SKILL.md'),
|
|
158
|
-
[
|
|
159
|
-
'---',
|
|
160
|
-
'description: 审计输出',
|
|
161
|
-
'---',
|
|
162
|
-
'检查最终输出是否覆盖风险项。'
|
|
163
|
-
].join('\n')
|
|
164
|
-
)
|
|
165
|
-
await writeDocument(
|
|
166
|
-
join(workspace, '.ai/plugins/demo/mcp/browser.json'),
|
|
167
|
-
JSON.stringify(
|
|
168
|
-
{
|
|
169
|
-
name: 'browser',
|
|
170
|
-
command: 'npx',
|
|
171
|
-
args: ['browser-mcp']
|
|
172
|
-
},
|
|
173
|
-
null,
|
|
174
|
-
2
|
|
175
|
-
)
|
|
176
|
-
)
|
|
177
|
-
await writeDocument(
|
|
178
|
-
join(workspace, '.ai/plugins/demo/opencode/plugins/demo-plugin.js'),
|
|
179
|
-
'export default {};\n'
|
|
180
|
-
)
|
|
181
|
-
await writeDocument(
|
|
182
|
-
join(workspace, '.ai/plugins/demo/opencode/agents/release-helper.md'),
|
|
183
|
-
'# release-helper\n'
|
|
184
|
-
)
|
|
185
|
-
await writeDocument(
|
|
186
|
-
join(workspace, '.ai/plugins/demo/opencode/commands/review.md'),
|
|
187
|
-
'# review\n'
|
|
188
|
-
)
|
|
189
|
-
await writeDocument(
|
|
190
|
-
join(workspace, '.ai/plugins/demo/opencode/modes/strict.md'),
|
|
191
|
-
'# strict\n'
|
|
192
|
-
)
|
|
193
174
|
|
|
194
175
|
const bundle = await resolveWorkspaceAssetBundle({
|
|
195
176
|
cwd: workspace,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vibe-forge/workspace-assets",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.2-alpha.0",
|
|
4
4
|
"description": "Workspace asset resolution and adapter asset planning for Vibe Forge",
|
|
5
5
|
"imports": {
|
|
6
6
|
"#~/*.js": {
|
|
@@ -25,18 +25,19 @@
|
|
|
25
25
|
},
|
|
26
26
|
"./package.json": "./package.json"
|
|
27
27
|
},
|
|
28
|
-
"scripts": {
|
|
29
|
-
"test": "pnpm -C ../.. exec vitest run --workspace vitest.workspace.ts --project bundler packages/workspace-assets/__tests__"
|
|
30
|
-
},
|
|
31
28
|
"dependencies": {
|
|
32
|
-
"@vibe-forge/config": "workspace:^",
|
|
33
|
-
"@vibe-forge/definition-loader": "workspace:^",
|
|
34
|
-
"@vibe-forge/types": "workspace:^",
|
|
35
|
-
"@vibe-forge/utils": "workspace:^",
|
|
36
29
|
"fast-glob": "^3.3.3",
|
|
37
|
-
"
|
|
30
|
+
"front-matter": "^4.0.2",
|
|
31
|
+
"js-yaml": "^4.1.1",
|
|
32
|
+
"@vibe-forge/utils": "^0.9.0",
|
|
33
|
+
"@vibe-forge/definition-core": "^0.9.0",
|
|
34
|
+
"@vibe-forge/types": "^0.9.0",
|
|
35
|
+
"@vibe-forge/config": "^0.9.1-alpha.0"
|
|
38
36
|
},
|
|
39
37
|
"devDependencies": {
|
|
40
38
|
"@types/js-yaml": "^4.0.9"
|
|
39
|
+
},
|
|
40
|
+
"scripts": {
|
|
41
|
+
"test": "pnpm -C ../.. exec vitest run --workspace vitest.workspace.ts --project bundler packages/workspace-assets/__tests__"
|
|
41
42
|
}
|
|
42
|
-
}
|
|
43
|
+
}
|