@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.
@@ -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 summarizeDocumentAsset = (
103
- asset: Extract<WorkspaceAsset, { kind: 'rule' | 'spec' | 'entity' | 'skill' }>,
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
- pluginId: asset.pluginId,
111
- enabled: asset.enabled,
112
- targets: sortStrings(asset.targets),
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
- id: asset.id,
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
- id: asset.id,
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 summarizeNativePlugin = (
145
- asset: Extract<WorkspaceAsset, { kind: 'nativePlugin' }>,
146
- cwd: string
147
- ) => {
148
- if (isOpenCodeOverlayAsset(asset)) {
149
- return {
150
- id: asset.id,
151
- kind: asset.kind,
152
- origin: asset.origin,
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 = (diagnostics: AssetDiagnostic[]) => (
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
- native: normalizeValue(plan.native, cwd),
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 ? undefined : sortStrings(options.promptAssetIds)
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 overlayAssets = bundle.assets.filter((
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
- enabledPlugins: normalizeValue(bundle.enabledPlugins, cwd),
295
- extraKnownMarketplaces: normalizeValue(bundle.extraKnownMarketplaces, cwd),
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
- claudeNativePlugins: claudeNativePlugins
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 => summarizeOverlayAsset(asset, cwd))
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
- logger: {
24
- level: 'info'
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
- telemetry: {
53
- mode: 'summary'
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 writeDocument(
69
- join(workspace, '.ai/rules/review.md'),
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
- '这是插件内的 review 规则,不应覆盖项目规则。'
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/plugins/demo/rules/security.md'),
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.1-alpha.0",
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
- "js-yaml": "^4.1.1"
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
+ }