@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,7 +1,8 @@
1
- import { basename, dirname } from 'node:path'
1
+ import { dirname } from 'node:path'
2
2
 
3
3
  import type {
4
4
  AdapterAssetPlan,
5
+ AdapterOverlayEntry,
5
6
  AssetDiagnostic,
6
7
  WorkspaceAssetAdapter,
7
8
  WorkspaceAssetBundle,
@@ -9,25 +10,7 @@ import type {
9
10
  WorkspaceSkillSelection
10
11
  } from '@vibe-forge/types'
11
12
 
12
- import { filterSkillAssets } from './document-assets'
13
- import { isOpenCodeOverlayAsset } from './internal-types'
14
-
15
- const resolveMcpServerSelection = (
16
- bundle: WorkspaceAssetBundle,
17
- selection: WorkspaceMcpSelection | undefined
18
- ) => {
19
- const include = selection?.include ?? (
20
- bundle.defaultIncludeMcpServers.length > 0 ? bundle.defaultIncludeMcpServers : undefined
21
- )
22
- const exclude = selection?.exclude ?? (
23
- bundle.defaultExcludeMcpServers.length > 0 ? bundle.defaultExcludeMcpServers : undefined
24
- )
25
-
26
- return {
27
- include,
28
- exclude
29
- }
30
- }
13
+ import { resolveSelectedMcpNames, resolveSelectedSkillAssets } from './selection-internal'
31
14
 
32
15
  export function buildAdapterAssetPlan(params: {
33
16
  adapter: WorkspaceAssetAdapter
@@ -39,136 +22,134 @@ export function buildAdapterAssetPlan(params: {
39
22
  }
40
23
  }): AdapterAssetPlan {
41
24
  const diagnostics: AssetDiagnostic[] = []
42
- const promptAssetIdSet = new Set(params.options.promptAssetIds ?? [])
43
- const mcpSelection = resolveMcpServerSelection(params.bundle, params.options.mcpServers)
44
- const selectedMcpServerNames = Object.keys(params.bundle.mcpServers).filter((name) => {
45
- if (mcpSelection.include != null && !mcpSelection.include.includes(name)) return false
46
- if (mcpSelection.exclude?.includes(name)) return false
47
- return true
48
- })
49
- const mcpServers = Object.fromEntries(
50
- selectedMcpServerNames.map((name) => [name, params.bundle.mcpServers[name].payload.config])
51
- )
52
25
 
53
- for (const assetId of promptAssetIdSet) {
26
+ for (const assetId of params.options.promptAssetIds ?? []) {
27
+ const asset = params.bundle.assets.find(item => item.id === assetId)
28
+ if (asset == null || asset.kind === 'mcpServer') continue
54
29
  diagnostics.push({
55
30
  assetId,
56
31
  adapter: params.adapter,
57
32
  status: 'prompt',
58
- reason: 'Mapped into the generated system prompt.'
33
+ reason: 'Mapped into the generated system prompt.',
34
+ packageId: asset.packageId,
35
+ scope: asset.scope,
36
+ instancePath: asset.instancePath,
37
+ origin: asset.origin,
38
+ resolvedBy: asset.resolvedBy,
39
+ taskOverlaySource: asset.taskOverlaySource
59
40
  })
60
41
  }
61
42
 
62
- for (const name of selectedMcpServerNames) {
43
+ const selectedMcpNames = resolveSelectedMcpNames(params.bundle, params.options.mcpServers)
44
+ const mcpServers = Object.fromEntries(
45
+ selectedMcpNames.map(name => [name, params.bundle.mcpServers[name].payload.config])
46
+ )
47
+
48
+ selectedMcpNames.forEach((name) => {
49
+ const asset = params.bundle.mcpServers[name]
63
50
  diagnostics.push({
64
- assetId: params.bundle.mcpServers[name].id,
51
+ assetId: asset.id,
65
52
  adapter: params.adapter,
66
53
  status: params.adapter === 'claude-code' ? 'native' : 'translated',
67
54
  reason: params.adapter === 'claude-code'
68
- ? 'Mapped into native MCP settings.'
69
- : 'Translated into adapter-specific MCP configuration.'
55
+ ? 'Mapped into adapter MCP settings.'
56
+ : 'Translated into adapter-specific MCP configuration.',
57
+ packageId: asset.packageId,
58
+ scope: asset.scope,
59
+ instancePath: asset.instancePath,
60
+ origin: asset.origin,
61
+ resolvedBy: asset.resolvedBy,
62
+ taskOverlaySource: asset.taskOverlaySource
70
63
  })
71
- }
64
+ })
72
65
 
73
- for (const hookPlugin of params.bundle.hookPlugins) {
74
- const nativeHookReason = params.adapter === 'claude-code'
75
- ? 'Mapped into the isolated Claude Code native hooks bridge under .ai/.mock/.claude/settings.json.'
76
- : params.adapter === 'codex'
77
- ? 'Mapped into the isolated Codex native hooks bridge for SessionStart, UserPromptSubmit, PreToolUse, PostToolUse, and Stop.'
78
- : 'Mapped into the isolated OpenCode native hook plugin bridge under .ai/.mock/.config/opencode/plugins.'
66
+ params.bundle.hookPlugins.forEach((asset) => {
79
67
  diagnostics.push({
80
- assetId: hookPlugin.id,
68
+ assetId: asset.id,
81
69
  adapter: params.adapter,
82
70
  status: 'native',
83
- reason: nativeHookReason
71
+ reason: params.adapter === 'claude-code'
72
+ ? 'Mapped into the Claude Code native hooks bridge.'
73
+ : params.adapter === 'codex'
74
+ ? 'Mapped into the Codex native hooks bridge.'
75
+ : 'Mapped into the OpenCode native hooks bridge.',
76
+ packageId: asset.packageId,
77
+ scope: asset.scope,
78
+ instancePath: asset.instancePath,
79
+ origin: asset.origin,
80
+ resolvedBy: asset.resolvedBy,
81
+ taskOverlaySource: asset.taskOverlaySource
84
82
  })
85
- }
83
+ })
86
84
 
87
- const overlays: AdapterAssetPlan['overlays'] = []
85
+ const selectedSkillAssets = resolveSelectedSkillAssets(params.bundle.skills, params.options.skills)
88
86
  if (params.adapter === 'opencode') {
89
- const skillAssets = filterSkillAssets(params.bundle.skills, params.options.skills)
90
- for (const skillAsset of skillAssets) {
91
- overlays.push({
92
- assetId: skillAsset.id,
93
- kind: 'skill',
94
- sourcePath: dirname(skillAsset.payload.definition.path),
95
- targetPath: `skills/${basename(dirname(skillAsset.payload.definition.path))}`
96
- })
87
+ selectedSkillAssets.forEach((asset) => {
97
88
  diagnostics.push({
98
- assetId: skillAsset.id,
99
- adapter: 'opencode',
100
- status: 'native',
101
- reason: 'Mirrored into OPENCODE_CONFIG_DIR as a native skill.'
102
- })
103
- }
104
-
105
- for (const asset of params.bundle.assets) {
106
- if (!isOpenCodeOverlayAsset(asset)) continue
107
- if (!asset.targets.includes('opencode')) continue
108
-
109
- overlays.push({
110
89
  assetId: asset.id,
111
- kind: asset.kind,
112
- sourcePath: asset.payload.sourcePath,
113
- targetPath: asset.payload.targetSubpath
90
+ adapter: params.adapter,
91
+ status: 'native',
92
+ reason: 'Mirrored into OPENCODE_CONFIG_DIR as a native skill.',
93
+ packageId: asset.packageId,
94
+ scope: asset.scope,
95
+ instancePath: asset.instancePath,
96
+ origin: asset.origin,
97
+ resolvedBy: asset.resolvedBy,
98
+ taskOverlaySource: asset.taskOverlaySource
114
99
  })
100
+ })
101
+ params.bundle.opencodeOverlayAssets.forEach((asset) => {
115
102
  diagnostics.push({
116
103
  assetId: asset.id,
117
- adapter: 'opencode',
104
+ adapter: params.adapter,
118
105
  status: 'native',
119
- reason: 'Mirrored into OPENCODE_CONFIG_DIR as a native OpenCode asset.'
106
+ reason: 'Mirrored into OPENCODE_CONFIG_DIR as a native OpenCode asset.',
107
+ packageId: asset.packageId,
108
+ scope: asset.scope,
109
+ instancePath: asset.instancePath,
110
+ origin: asset.origin,
111
+ resolvedBy: asset.resolvedBy,
112
+ taskOverlaySource: asset.taskOverlaySource
120
113
  })
121
- }
122
- }
123
-
124
- if (params.adapter !== 'claude-code') {
125
- for (const asset of params.bundle.assets) {
126
- if (asset.kind !== 'nativePlugin' || !asset.enabled || !asset.targets.includes('claude-code')) continue
114
+ })
115
+ } else if (params.adapter === 'codex') {
116
+ params.bundle.opencodeOverlayAssets.forEach((asset) => {
127
117
  diagnostics.push({
128
118
  assetId: asset.id,
129
119
  adapter: params.adapter,
130
120
  status: 'skipped',
131
- reason: 'Claude marketplace plugin settings do not have a native mapping for this adapter.'
121
+ reason: 'No stable native Codex mapping exists for this asset kind in V1.',
122
+ packageId: asset.packageId,
123
+ scope: asset.scope,
124
+ instancePath: asset.instancePath,
125
+ origin: asset.origin,
126
+ resolvedBy: asset.resolvedBy,
127
+ taskOverlaySource: asset.taskOverlaySource
132
128
  })
133
- }
129
+ })
134
130
  }
135
131
 
136
- if (params.adapter === 'codex') {
137
- for (const asset of params.bundle.assets) {
138
- if (!['nativePlugin', 'agent', 'command', 'mode'].includes(asset.kind)) continue
139
- if (asset.targets.includes('codex')) continue
140
- if (asset.kind === 'nativePlugin' && asset.targets.includes('claude-code')) continue
141
- diagnostics.push({
132
+ const overlays: AdapterOverlayEntry[] = params.adapter === 'opencode'
133
+ ? [
134
+ ...selectedSkillAssets.map((asset): AdapterOverlayEntry => ({
142
135
  assetId: asset.id,
143
- adapter: 'codex',
144
- status: 'skipped',
145
- reason: 'No stable native Codex mapping exists for this asset kind in V1.'
146
- })
147
- }
148
- }
136
+ kind: 'skill',
137
+ sourcePath: dirname(asset.sourcePath),
138
+ targetPath: `skills/${asset.displayName.replaceAll('/', '__')}`
139
+ })),
140
+ ...params.bundle.opencodeOverlayAssets.map((asset): AdapterOverlayEntry => ({
141
+ assetId: asset.id,
142
+ kind: asset.kind,
143
+ sourcePath: asset.sourcePath,
144
+ targetPath: asset.payload.targetSubpath
145
+ }))
146
+ ]
147
+ : []
149
148
 
150
149
  return {
151
150
  adapter: params.adapter,
152
151
  diagnostics,
153
152
  mcpServers,
154
- overlays,
155
- native: params.adapter === 'claude-code'
156
- ? {
157
- enabledPlugins: params.bundle.enabledPlugins,
158
- extraKnownMarketplaces: params.bundle.extraKnownMarketplaces
159
- }
160
- : params.adapter === 'codex' && params.bundle.hookPlugins.length > 0
161
- ? {
162
- codexHooks: {
163
- supportedEvents: [
164
- 'SessionStart',
165
- 'UserPromptSubmit',
166
- 'PreToolUse',
167
- 'PostToolUse',
168
- 'Stop'
169
- ]
170
- }
171
- }
172
- : {}
153
+ overlays
173
154
  }
174
155
  }