@tetherto/mdk-skill 0.0.0 → 0.12.1
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/LICENSE +202 -0
- package/README.md +133 -0
- package/dist/skills/mdk/SKILL.md +114 -0
- package/dist/skills/mdk/references/architecture.md +89 -0
- package/dist/skills/mdk/references/glossary.md +27 -0
- package/dist/skills/mdk/references/mdk-contract.schema.json +138 -0
- package/dist/skills/mdk/references/package-index.md +53 -0
- package/dist/skills/mdk/references/protocol.md +95 -0
- package/dist/skills/mdk-create-app/SKILL.md +231 -0
- package/dist/skills/mdk-deployment/SKILL.md +161 -0
- package/dist/skills/mdk-gateway-plugin/SKILL.md +192 -0
- package/dist/skills/mdk-gateway-plugin/references/controller-patterns.md +99 -0
- package/dist/skills/mdk-gateway-plugin/references/plugin-authoring.md +121 -0
- package/dist/skills/mdk-publish-security/SKILL.md +177 -0
- package/dist/skills/mdk-publish-security/references/vuln-classes.md +151 -0
- package/dist/skills/mdk-publish-security/scripts/scan-packages.mjs +544 -0
- package/dist/skills/mdk-site-sizing/SKILL.md +160 -0
- package/dist/skills/mdk-site-sizing/eval/held-out.json +104 -0
- package/dist/skills/mdk-site-sizing/eval/profiles/cap-100devices-2workers-mixed.json +24 -0
- package/dist/skills/mdk-site-sizing/eval/profiles/cap-100devices-2workers.json +23 -0
- package/dist/skills/mdk-site-sizing/eval/profiles/cap-10devices-1workers.json +23 -0
- package/dist/skills/mdk-site-sizing/eval/profiles/cap-15devices-2workers.json +24 -0
- package/dist/skills/mdk-site-sizing/eval/profiles/cap-200devices-4workers.json +23 -0
- package/dist/skills/mdk-site-sizing/eval/profiles/cap-500devices-4workers.json +23 -0
- package/dist/skills/mdk-site-sizing/eval/profiles/cap-50devices-2workers.json +23 -0
- package/dist/skills/mdk-site-sizing/references/envelope.json +284 -0
- package/dist/skills/mdk-site-sizing/references/envelope.md +42 -0
- package/dist/skills/mdk-site-sizing/scripts/compile-envelope.mjs +45 -0
- package/dist/skills/mdk-site-sizing/scripts/eval-held-out.mjs +50 -0
- package/dist/skills/mdk-site-sizing/scripts/lib.mjs +591 -0
- package/dist/skills/mdk-site-sizing/scripts/parse-site.mjs +25 -0
- package/dist/skills/mdk-site-sizing/scripts/size-site.mjs +49 -0
- package/dist/skills/mdk-ui-component/SKILL.md +207 -0
- package/dist/skills/mdk-ui-component/references/page-recipe.md +78 -0
- package/dist/skills/mdk-ui-component/references/ui-registry.json +1 -0
- package/dist/skills/mdk-worker-plugin/SKILL.md +198 -0
- package/dist/skills/mdk-worker-plugin/assets/mdk-contract.template.json +45 -0
- package/dist/skills/mdk-worker-plugin/assets/worker-template/README.md +93 -0
- package/dist/skills/mdk-worker-plugin/assets/worker-template/mdk-contract.json +26 -0
- package/dist/skills/mdk-worker-plugin/assets/worker-template/mock/server.js +93 -0
- package/dist/skills/mdk-worker-plugin/assets/worker-template/package.json +23 -0
- package/dist/skills/mdk-worker-plugin/assets/worker-template/smoke.config.js +41 -0
- package/dist/skills/mdk-worker-plugin/assets/worker-template/src/client.js +47 -0
- package/dist/skills/mdk-worker-plugin/assets/worker-template/src/commands/reboot.js +5 -0
- package/dist/skills/mdk-worker-plugin/assets/worker-template/src/commands/set-power-mode.js +10 -0
- package/dist/skills/mdk-worker-plugin/assets/worker-template/src/telemetry/hashrate-rt.js +5 -0
- package/dist/skills/mdk-worker-plugin/assets/worker-template/src/telemetry/power-mode.js +5 -0
- package/dist/skills/mdk-worker-plugin/assets/worker-template/src/telemetry/power.js +5 -0
- package/dist/skills/mdk-worker-plugin/assets/worker-template/src/telemetry/temperature.js +5 -0
- package/dist/skills/mdk-worker-plugin/references/contract-authoring.md +135 -0
- package/dist/skills/mdk-worker-plugin/references/device-families.md +96 -0
- package/dist/skills/mdk-worker-plugin/references/local-testing.md +134 -0
- package/dist/skills/mdk-worker-plugin/references/mdk-contract.schema.json +138 -0
- package/dist/skills/mdk-worker-plugin/references/worker-base-api.md +152 -0
- package/dist/skills/mdk-worker-plugin/scripts/validate-contract.mjs +129 -0
- package/dist/skills/mdk-worker-plugin/scripts/worker-smoke.mjs +256 -0
- package/package.json +47 -1
- package/src/assemble.mjs +11 -0
- package/src/index.d.ts +57 -0
- package/src/index.mjs +254 -0
- package/src/install.mjs +57 -0
- package/src/sources.map.json +34 -0
package/src/index.mjs
ADDED
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
// Programmatic entry point for @tetherto/mdk-skill.
|
|
2
|
+
//
|
|
3
|
+
// Consumers (e.g. the MDK CLI) import this module and call `installSkills()`
|
|
4
|
+
// to copy the assembled Agent Skills into a project's client directories.
|
|
5
|
+
// When published to npm the package ships a prebuilt `dist/skills/`; inside
|
|
6
|
+
// the monorepo the skills are assembled on demand from the source artifacts.
|
|
7
|
+
|
|
8
|
+
import fs from 'node:fs'
|
|
9
|
+
import path from 'node:path'
|
|
10
|
+
import { fileURLToPath } from 'node:url'
|
|
11
|
+
|
|
12
|
+
const SRC_DIR = path.dirname(fileURLToPath(import.meta.url))
|
|
13
|
+
const PKG_DIR = path.dirname(SRC_DIR)
|
|
14
|
+
const REPO_ROOT = path.resolve(PKG_DIR, '..', '..')
|
|
15
|
+
const DIST = path.join(PKG_DIR, 'dist', 'skills')
|
|
16
|
+
|
|
17
|
+
const SKILL_MD_MAX_LINES = 500
|
|
18
|
+
|
|
19
|
+
// Frontmatter key every suite skill carries (`metadata.suite`). installSkills
|
|
20
|
+
// only replaces an existing skill dir that has it, and only sweeps a stale one
|
|
21
|
+
// (no longer shipped) that has it, so a user's own skill is never deleted.
|
|
22
|
+
const SUITE_MARKER = /^\s+suite:\s*["']?mdk-developer-skill["']?\s*$/m
|
|
23
|
+
|
|
24
|
+
export const CLIENT_DIRS = {
|
|
25
|
+
cursor: ['.cursor', 'skills'],
|
|
26
|
+
claude: ['.claude', 'skills']
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Flat sibling skills — clients discover <skills-dir>/<name>/SKILL.md one
|
|
30
|
+
// level deep, so nested sub-skills would never trigger.
|
|
31
|
+
const REQUIRED = [
|
|
32
|
+
'mdk/SKILL.md',
|
|
33
|
+
'mdk/references/architecture.md',
|
|
34
|
+
'mdk/references/package-index.md',
|
|
35
|
+
'mdk/references/protocol.md',
|
|
36
|
+
'mdk/references/glossary.md',
|
|
37
|
+
'mdk/references/mdk-contract.schema.json',
|
|
38
|
+
'mdk-gateway-plugin/SKILL.md',
|
|
39
|
+
'mdk-create-app/SKILL.md',
|
|
40
|
+
'mdk-ui-component/SKILL.md',
|
|
41
|
+
'mdk-ui-component/references/ui-registry.json',
|
|
42
|
+
'mdk-deployment/SKILL.md',
|
|
43
|
+
'mdk-site-sizing/SKILL.md',
|
|
44
|
+
'mdk-site-sizing/references/envelope.json',
|
|
45
|
+
'mdk-site-sizing/scripts/size-site.mjs',
|
|
46
|
+
'mdk-site-sizing/scripts/eval-held-out.mjs',
|
|
47
|
+
'mdk-worker-plugin/SKILL.md',
|
|
48
|
+
'mdk-worker-plugin/references/mdk-contract.schema.json',
|
|
49
|
+
'mdk-worker-plugin/references/contract-authoring.md',
|
|
50
|
+
'mdk-worker-plugin/references/worker-base-api.md',
|
|
51
|
+
'mdk-worker-plugin/references/device-families.md',
|
|
52
|
+
'mdk-worker-plugin/references/local-testing.md',
|
|
53
|
+
'mdk-worker-plugin/assets/mdk-contract.template.json',
|
|
54
|
+
'mdk-worker-plugin/assets/worker-template/mdk-contract.json',
|
|
55
|
+
'mdk-worker-plugin/assets/worker-template/src/client.js',
|
|
56
|
+
'mdk-worker-plugin/assets/worker-template/mock/server.js',
|
|
57
|
+
'mdk-worker-plugin/assets/worker-template/smoke.config.js',
|
|
58
|
+
'mdk-worker-plugin/scripts/validate-contract.mjs',
|
|
59
|
+
'mdk-worker-plugin/scripts/worker-smoke.mjs'
|
|
60
|
+
]
|
|
61
|
+
|
|
62
|
+
function copyEntry (entry) {
|
|
63
|
+
const src = path.resolve(REPO_ROOT, entry.source)
|
|
64
|
+
const dest = path.resolve(DIST, entry.dest)
|
|
65
|
+
if (!fs.existsSync(src)) throw new Error(`source missing: ${entry.source}`)
|
|
66
|
+
|
|
67
|
+
const excluded = new Set(entry.exclude || [])
|
|
68
|
+
fs.cpSync(src, dest, {
|
|
69
|
+
recursive: true,
|
|
70
|
+
filter: (from) => !excluded.has(path.basename(from))
|
|
71
|
+
})
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function walk (dir, out = []) {
|
|
75
|
+
for (const name of fs.readdirSync(dir)) {
|
|
76
|
+
const p = path.join(dir, name)
|
|
77
|
+
if (fs.statSync(p).isDirectory()) walk(p, out)
|
|
78
|
+
else out.push(p)
|
|
79
|
+
}
|
|
80
|
+
return out
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function injectVersion (files, version) {
|
|
84
|
+
for (const file of files) {
|
|
85
|
+
if (!file.endsWith('.md')) continue
|
|
86
|
+
const body = fs.readFileSync(file, 'utf8')
|
|
87
|
+
if (!body.includes('{{MDK_VERSION}}')) continue
|
|
88
|
+
fs.writeFileSync(file, body.replaceAll('{{MDK_VERSION}}', version))
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function check (files) {
|
|
93
|
+
for (const rel of REQUIRED) {
|
|
94
|
+
if (!fs.existsSync(path.join(DIST, rel))) throw new Error(`required artifact missing after assembly: ${rel}`)
|
|
95
|
+
}
|
|
96
|
+
for (const file of files) {
|
|
97
|
+
if (path.basename(file) !== 'SKILL.md') continue
|
|
98
|
+
const lines = fs.readFileSync(file, 'utf8').split('\n').length
|
|
99
|
+
if (lines > SKILL_MD_MAX_LINES) {
|
|
100
|
+
throw new Error(`${path.relative(DIST, file)} is ${lines} lines (budget ${SKILL_MD_MAX_LINES}) — move content to references/`)
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** True when the source map and repo root are available to assemble from. */
|
|
106
|
+
export function canAssemble () {
|
|
107
|
+
return (
|
|
108
|
+
fs.existsSync(path.join(SRC_DIR, 'sources.map.json')) &&
|
|
109
|
+
fs.existsSync(path.join(REPO_ROOT, 'package.json'))
|
|
110
|
+
)
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/** True when `dist/skills/` already holds at least one assembled skill. */
|
|
114
|
+
export function isAssembled () {
|
|
115
|
+
try {
|
|
116
|
+
return fs.existsSync(DIST) && fs.readdirSync(DIST).length > 0
|
|
117
|
+
} catch {
|
|
118
|
+
return false
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Assemble the skill suite from source artifacts into `dist/skills/`.
|
|
124
|
+
* Only usable inside the monorepo (or the published package's own tree).
|
|
125
|
+
* Returns the number of files assembled and the MDK version stamped in.
|
|
126
|
+
*/
|
|
127
|
+
export function assemble () {
|
|
128
|
+
const map = JSON.parse(fs.readFileSync(path.join(SRC_DIR, 'sources.map.json'), 'utf8'))
|
|
129
|
+
const mdkVersion = JSON.parse(fs.readFileSync(path.join(REPO_ROOT, 'package.json'), 'utf8')).version
|
|
130
|
+
|
|
131
|
+
fs.rmSync(DIST, { recursive: true, force: true })
|
|
132
|
+
fs.mkdirSync(DIST, { recursive: true })
|
|
133
|
+
|
|
134
|
+
for (const entry of map.entries) copyEntry(entry)
|
|
135
|
+
|
|
136
|
+
const files = walk(DIST)
|
|
137
|
+
injectVersion(files, mdkVersion)
|
|
138
|
+
check(files)
|
|
139
|
+
|
|
140
|
+
return { files: files.length, version: mdkVersion }
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function isSuiteSkill (dir) {
|
|
144
|
+
let body
|
|
145
|
+
try {
|
|
146
|
+
body = fs.readFileSync(path.join(dir, 'SKILL.md'), 'utf8')
|
|
147
|
+
} catch {
|
|
148
|
+
return false
|
|
149
|
+
}
|
|
150
|
+
const fm = body.match(/^---\r?\n([\s\S]*?)\r?\n---/)
|
|
151
|
+
return Boolean(fm && SUITE_MARKER.test(fm[1]))
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function lstatOrNull (p) {
|
|
155
|
+
try {
|
|
156
|
+
return fs.lstatSync(p)
|
|
157
|
+
} catch (err) {
|
|
158
|
+
if (err.code === 'ENOENT') return null
|
|
159
|
+
throw err
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Create <root>/<segments...> one level at a time, refusing any segment that is
|
|
164
|
+
// a symlink, so a planted `.claude -> /elsewhere` cannot redirect the install
|
|
165
|
+
// (and its deletes) outside the project.
|
|
166
|
+
function ensureRealDir (root, segments) {
|
|
167
|
+
let dir = root
|
|
168
|
+
for (const seg of segments) {
|
|
169
|
+
dir = path.join(dir, seg)
|
|
170
|
+
const st = lstatOrNull(dir)
|
|
171
|
+
if (!st) fs.mkdirSync(dir)
|
|
172
|
+
else if (st.isSymbolicLink()) throw new Error(`refusing to install through symlink ${dir}`)
|
|
173
|
+
else if (!st.isDirectory()) throw new Error(`${dir} exists and is not a directory`)
|
|
174
|
+
}
|
|
175
|
+
return dir
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Remove MDK-shipped skill dirs in `targetDir` that the current suite no longer
|
|
180
|
+
* ships (renamed or dropped between MDK versions). Installs are copies, so
|
|
181
|
+
* without this a rerun would leave the stale dir behind and the agent would
|
|
182
|
+
* keep loading it. Dirs without the suite marker, and symlinks, are left alone.
|
|
183
|
+
*/
|
|
184
|
+
function sweepStale (targetDir, shipped) {
|
|
185
|
+
const removed = []
|
|
186
|
+
for (const entry of fs.readdirSync(targetDir, { withFileTypes: true })) {
|
|
187
|
+
if (!entry.isDirectory() || shipped.has(entry.name)) continue
|
|
188
|
+
const dir = path.join(targetDir, entry.name)
|
|
189
|
+
if (!isSuiteSkill(dir)) continue
|
|
190
|
+
fs.rmSync(dir, { recursive: true, force: true })
|
|
191
|
+
removed.push(entry.name)
|
|
192
|
+
}
|
|
193
|
+
return removed
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Install the assembled skills into a project's client skills directories.
|
|
198
|
+
* Stale MDK-shipped skills (present in the target but absent from the current
|
|
199
|
+
* suite) are removed; user-authored skills are never touched.
|
|
200
|
+
*
|
|
201
|
+
* @param {object} [options]
|
|
202
|
+
* @param {'cursor'|'claude'|'all'} [options.client='all']
|
|
203
|
+
* @param {string} [options.target=process.cwd()] Project root to install into.
|
|
204
|
+
* @param {boolean} [options.assembleIfMissing=true] Assemble first if `dist/skills/` is empty.
|
|
205
|
+
* @param {(msg: string) => void} [options.onWarn=console.warn] Called for each skill dir left untouched.
|
|
206
|
+
* @returns {{ skills: string[], installed: Array<{ client: string, dir: string, removed: string[] }>, skipped: Array<{ client: string, skill: string, dir: string, reason: string }> }}
|
|
207
|
+
*
|
|
208
|
+
* Throws if `.cursor`/`.claude` or `skills` under the target is a symlink. An
|
|
209
|
+
* existing `<skills-dir>/<name>` is replaced only when its SKILL.md carries the
|
|
210
|
+
* suite marker (`metadata.suite: mdk-developer-skill`); a symlink or a foreign
|
|
211
|
+
* skill with the same name is skipped with a warning.
|
|
212
|
+
*/
|
|
213
|
+
export function installSkills ({ client = 'all', target = process.cwd(), assembleIfMissing = true, onWarn = console.warn } = {}) {
|
|
214
|
+
const clients = client === 'all' ? Object.keys(CLIENT_DIRS) : [client]
|
|
215
|
+
for (const c of clients) {
|
|
216
|
+
if (!CLIENT_DIRS[c]) throw new Error(`unknown client '${client}' — use cursor | claude | all`)
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
if (!isAssembled()) {
|
|
220
|
+
if (assembleIfMissing && canAssemble()) assemble()
|
|
221
|
+
else throw new Error(`no assembled skills found at ${DIST} — run \`npm run assemble\` in @tetherto/mdk-skill`)
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
const skills = fs.readdirSync(DIST, { withFileTypes: true }).filter((e) => e.isDirectory())
|
|
225
|
+
if (!skills.length) throw new Error(`no skills found in ${DIST}`)
|
|
226
|
+
|
|
227
|
+
fs.mkdirSync(path.resolve(target), { recursive: true })
|
|
228
|
+
const projectRoot = fs.realpathSync(path.resolve(target))
|
|
229
|
+
const shipped = new Set(skills.map((s) => s.name))
|
|
230
|
+
const installed = []
|
|
231
|
+
const skipped = []
|
|
232
|
+
for (const c of clients) {
|
|
233
|
+
const targetDir = ensureRealDir(projectRoot, CLIENT_DIRS[c])
|
|
234
|
+
const removed = sweepStale(targetDir, shipped)
|
|
235
|
+
for (const skill of skills) {
|
|
236
|
+
const dest = path.join(targetDir, skill.name)
|
|
237
|
+
const st = lstatOrNull(dest)
|
|
238
|
+
let reason = null
|
|
239
|
+
if (st?.isSymbolicLink()) reason = 'is a symlink'
|
|
240
|
+
else if (st && !st.isDirectory()) reason = 'is not a directory'
|
|
241
|
+
else if (st && !isSuiteSkill(dest)) reason = 'is not an MDK suite skill (no metadata.suite: mdk-developer-skill)'
|
|
242
|
+
if (reason) {
|
|
243
|
+
skipped.push({ client: c, skill: skill.name, dir: dest, reason })
|
|
244
|
+
onWarn(`mdk-skill: skipped ${dest}: ${reason}; remove or rename it to install ${skill.name}`)
|
|
245
|
+
continue
|
|
246
|
+
}
|
|
247
|
+
if (st) fs.rmSync(dest, { recursive: true, force: true })
|
|
248
|
+
fs.cpSync(path.join(DIST, skill.name), dest, { recursive: true })
|
|
249
|
+
}
|
|
250
|
+
installed.push({ client: c, dir: targetDir, removed })
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
return { skills: skills.map((s) => s.name), installed, skipped }
|
|
254
|
+
}
|
package/src/install.mjs
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// CLI wrapper around the programmatic `installSkills()` (see index.mjs).
|
|
3
|
+
//
|
|
4
|
+
// node src/install.mjs [--client cursor|claude|all] [--target <project-root>]
|
|
5
|
+
//
|
|
6
|
+
// The project root defaults to the enclosing git repo of cwd, so this works
|
|
7
|
+
// both inside the monorepo and when consumed from npm.
|
|
8
|
+
|
|
9
|
+
import fs from 'node:fs'
|
|
10
|
+
import path from 'node:path'
|
|
11
|
+
import { parseArgs } from 'node:util'
|
|
12
|
+
import { installSkills } from './index.mjs'
|
|
13
|
+
|
|
14
|
+
function findProjectRoot (startDir) {
|
|
15
|
+
let dir = startDir
|
|
16
|
+
for (;;) {
|
|
17
|
+
if (fs.existsSync(path.join(dir, '.git'))) return dir
|
|
18
|
+
const parent = path.dirname(dir)
|
|
19
|
+
if (parent === dir) return startDir
|
|
20
|
+
dir = parent
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const USAGE = 'usage: node src/install.mjs [--client cursor|claude|all] [--target <project-root>]'
|
|
25
|
+
|
|
26
|
+
let values
|
|
27
|
+
try {
|
|
28
|
+
({ values } = parseArgs({
|
|
29
|
+
options: {
|
|
30
|
+
client: { type: 'string', default: 'all' },
|
|
31
|
+
target: { type: 'string' },
|
|
32
|
+
help: { type: 'boolean', short: 'h' }
|
|
33
|
+
}
|
|
34
|
+
}))
|
|
35
|
+
} catch (err) {
|
|
36
|
+
console.error(`ERR_ARGS: ${err.message}\n${USAGE}`)
|
|
37
|
+
process.exit(2)
|
|
38
|
+
}
|
|
39
|
+
if (values.help) {
|
|
40
|
+
console.log(USAGE)
|
|
41
|
+
process.exit(0)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const { client, target } = values
|
|
45
|
+
const projectRoot = target ? path.resolve(process.cwd(), target) : findProjectRoot(process.cwd())
|
|
46
|
+
|
|
47
|
+
try {
|
|
48
|
+
const { skills, installed } = installSkills({ client, target: projectRoot })
|
|
49
|
+
for (const { dir, removed } of installed) {
|
|
50
|
+
console.log(`installed ${skills.length} skill(s) -> ${path.relative(process.cwd(), dir) || '.'}`)
|
|
51
|
+
if (removed.length) console.log(`removed ${removed.length} stale skill(s): ${removed.join(', ')}`)
|
|
52
|
+
}
|
|
53
|
+
console.log('done — installed skill dirs are generated artifacts; keep them gitignored')
|
|
54
|
+
} catch (err) {
|
|
55
|
+
console.error(`ERR_INSTALL: ${err instanceof Error ? err.message : String(err)}`)
|
|
56
|
+
process.exit(1)
|
|
57
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$comment": "Source -> dist/skills/ artifact mapping, applied in order by assemble.mjs (later entries layer onto earlier copies). Skills are flat siblings — clients discover <skills-dir>/<name>/SKILL.md one level deep. Regenerate with `node packages/mdk-skill/src/assemble.mjs`; never hand-edit dist/.",
|
|
3
|
+
"entries": [
|
|
4
|
+
{
|
|
5
|
+
"source": "packages/mdk-skill/src/skills",
|
|
6
|
+
"dest": ".",
|
|
7
|
+
"note": "Hand-authored suite content: router + mdk-worker-plugin, mdk-gateway-plugin, mdk-ui-component, mdk-deployment, mdk-site-sizing (full workflows). One file in this tree is generated, not hand-authored: skills/mdk-ui-component/references/ui-registry.json is copied verbatim from ui/packages/react-devkit/dist/registry.json by docs/scripts/sync-ui-registry.mjs. Regenerate it with `npm run generate:ui-registry` from the repo root; never hand-edit it. mdk-site-sizing/references/envelope.json is compiled from eval/profiles (or harness results) by skills/mdk-site-sizing/scripts/compile-envelope.mjs."
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"source": "backend/core/mdk-worker/mdk-contract.schema.json",
|
|
11
|
+
"dest": "mdk/references/mdk-contract.schema.json",
|
|
12
|
+
"note": "Verbatim copy of the runtime contract schema owned by backend/core/mdk-worker, so agents author against exactly what generate-catalogue.js and the Kernel validate. Change the schema there, never in a bundle."
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"source": "backend/core/mdk-worker/mdk-contract.schema.json",
|
|
16
|
+
"dest": "mdk-worker-plugin/references/mdk-contract.schema.json",
|
|
17
|
+
"note": "Second copy so the device-worker skill is self-contained when installed alone; same source, cannot drift apart."
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"source": "packages/cli/templates/worker",
|
|
21
|
+
"dest": "mdk-worker-plugin/assets/worker-template",
|
|
22
|
+
"exclude": [
|
|
23
|
+
"node_modules",
|
|
24
|
+
"package-lock.json"
|
|
25
|
+
],
|
|
26
|
+
"note": "Verbatim copy of the CLI worker scaffold (mdk create worker) so the skill template cannot drift from what agents are told to run."
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"source": "packages/mdk-skill/src/worker-template-extras/smoke.config.js",
|
|
30
|
+
"dest": "mdk-worker-plugin/assets/worker-template/smoke.config.js",
|
|
31
|
+
"note": "Smoke-harness glue layered onto the template copy."
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
}
|