@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
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import {
|
|
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 {
|
|
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
|
|
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
|
-
|
|
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:
|
|
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
|
|
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
|
-
|
|
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:
|
|
68
|
+
assetId: asset.id,
|
|
81
69
|
adapter: params.adapter,
|
|
82
70
|
status: 'native',
|
|
83
|
-
reason:
|
|
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
|
|
85
|
+
const selectedSkillAssets = resolveSelectedSkillAssets(params.bundle.skills, params.options.skills)
|
|
88
86
|
if (params.adapter === 'opencode') {
|
|
89
|
-
|
|
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
|
-
|
|
112
|
-
|
|
113
|
-
|
|
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:
|
|
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: '
|
|
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
|
-
|
|
137
|
-
|
|
138
|
-
|
|
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
|
-
|
|
144
|
-
|
|
145
|
-
|
|
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
|
}
|