release-skill 0.2.0 → 0.2.2
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/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.codebuddy-plugin/plugin.json +10 -0
- package/.codex-plugin/plugin.json +2 -2
- package/.kimi-plugin/plugin.json +1 -1
- package/CHANGELOG.md +35 -0
- package/INSTALL.md +186 -4
- package/INSTALL.zh-CN.md +166 -4
- package/README.md +116 -13
- package/README.zh-CN.md +73 -13
- package/adapters/claude/.claude-plugin/marketplace.json +1 -1
- package/adapters/claude/.claude-plugin/plugin.json +1 -1
- package/adapters/claude/bin/release-skill.bundle.mjs +1718 -600
- package/adapters/claude/schemas/release-plan.schema.json +44 -2
- package/adapters/claude/schemas/release-project.schema.json +46 -4
- package/adapters/claude/schemas/release-run.schema.json +1 -0
- package/adapters/codex/.codex-plugin/plugin.json +2 -2
- package/adapters/codex/bin/release-skill.bundle.mjs +1718 -600
- package/adapters/codex/schemas/release-plan.schema.json +44 -2
- package/adapters/codex/schemas/release-project.schema.json +46 -4
- package/adapters/codex/schemas/release-run.schema.json +1 -0
- package/adapters/kimi/.kimi-plugin/plugin.json +1 -1
- package/adapters/kimi/bin/release-skill.bundle.mjs +1718 -600
- package/adapters/kimi/schemas/release-plan.schema.json +44 -2
- package/adapters/kimi/schemas/release-project.schema.json +46 -4
- package/adapters/kimi/schemas/release-run.schema.json +1 -0
- package/adapters/workbuddy/.codebuddy-plugin/plugin.json +12 -0
- package/adapters/workbuddy/bin/release-skill.bundle.mjs +86481 -0
- package/adapters/workbuddy/bin/release-skill.mjs +54 -0
- package/adapters/workbuddy/native/safe-write/binding.gyp +41 -0
- package/adapters/workbuddy/native/safe-write/prebuilds/darwin-arm64/safe_write.node +0 -0
- package/adapters/workbuddy/native/safe-write/prebuilds.json +24 -0
- package/adapters/workbuddy/native/safe-write/src/safe_write.cc +2032 -0
- package/adapters/workbuddy/schemas/.render-manifest.json +37 -0
- package/adapters/workbuddy/schemas/approval-record.schema.json +115 -0
- package/adapters/workbuddy/schemas/artifact-lock.schema.json +111 -0
- package/adapters/workbuddy/schemas/artifact-plan.schema.json +52 -0
- package/adapters/workbuddy/schemas/artifact-policy.schema.json +76 -0
- package/adapters/workbuddy/schemas/evidence-event.schema.json +89 -0
- package/adapters/workbuddy/schemas/release-plan.schema.json +924 -0
- package/adapters/workbuddy/schemas/release-project.schema.json +951 -0
- package/adapters/workbuddy/schemas/release-run.schema.json +344 -0
- package/adapters/workbuddy/skills/release-assess/SKILL.md +51 -0
- package/adapters/workbuddy/skills/release-help/SKILL.md +77 -0
- package/adapters/workbuddy/skills/release-prepare/SKILL.md +92 -0
- package/adapters/workbuddy/skills/release-publish/SKILL.md +57 -0
- package/adapters/workbuddy/skills/release-reconcile/SKILL.md +73 -0
- package/adapters/workbuddy/skills/release-setup/SKILL.md +95 -0
- package/adapters/workbuddy/skills/release-verify/SKILL.md +70 -0
- package/bin/release-skill-cli.mjs +46 -4
- package/bin/release-skill.bundle.mjs +1718 -600
- package/package.json +2 -1
- package/references/02-project-config.md +7 -0
- package/references/06-adapter-contract.md +21 -2
- package/schemas/release-plan.schema.json +44 -2
- package/schemas/release-project.schema.json +46 -4
- package/schemas/release-run.schema.json +1 -0
- package/scripts/sync-public-files.mjs +27 -4
- package/src/adapters/contract.mjs +1 -0
- package/src/adapters/plugin-marketplace.mjs +536 -23
- package/src/commands/assess.mjs +50 -1
- package/src/commands/prepare.mjs +273 -9
- package/src/commands/publish.mjs +1 -0
- package/src/commands/reconcile.mjs +1 -0
- package/src/commands/setup.mjs +7 -3
- package/src/commands/verify.mjs +2 -0
- package/src/core/checkpoints.mjs +7 -2
- package/src/core/plan.mjs +97 -4
- package/src/core/verification-gates.mjs +1 -1
- package/src/platforms/codebuddy.mjs +618 -0
- package/src/platforms/registry.mjs +100 -5
- package/src/producers/build-adapters.mjs +48 -6
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Platform registry — the single source of truth for consumer-platform
|
|
3
|
-
* knowledge (claude / codex / kimi).
|
|
3
|
+
* knowledge (claude / codex / kimi / codebuddy).
|
|
4
4
|
*
|
|
5
5
|
* T2.2 converges platform facts that were scattered across plugin-marketplace.mjs,
|
|
6
6
|
* build-adapters.mjs, prepare.mjs, plan.mjs and project.yaml into this module.
|
|
@@ -23,6 +23,8 @@
|
|
|
23
23
|
* file; kimi's side-effecting manual-requirement and manifest-reading
|
|
24
24
|
* strategies live in ./kimi.mjs (§4.2's per-platform-module option — the only
|
|
25
25
|
* non-trivial strategies) and are referenced from the kimi descriptor below.
|
|
26
|
+
* codebuddy's analogous human-attestation strategies live in ./codebuddy.mjs
|
|
27
|
+
* and are referenced from the codebuddy descriptor below.
|
|
26
28
|
* plugin-marketplace.mjs consumes every platform difference through this
|
|
27
29
|
* registry; see the t2-2 deviation record for the step-2 wiring details.
|
|
28
30
|
*
|
|
@@ -36,6 +38,10 @@ import {
|
|
|
36
38
|
readKimiManifest,
|
|
37
39
|
KIMI_MANIFEST_CANDIDATES,
|
|
38
40
|
} from './kimi.mjs';
|
|
41
|
+
import {
|
|
42
|
+
executeCodeBuddyManualRequirement,
|
|
43
|
+
readCodeBuddyManifest,
|
|
44
|
+
} from './codebuddy.mjs';
|
|
39
45
|
|
|
40
46
|
// --- claude strategy -------------------------------------------------------
|
|
41
47
|
|
|
@@ -155,6 +161,10 @@ const CLAUDE = Object.freeze({
|
|
|
155
161
|
// Claude carries the authoritative version in the marketplace entry: the
|
|
156
162
|
// preflight binds entry.version to the action version.
|
|
157
163
|
marketplaceEntryCarriesVersion: true,
|
|
164
|
+
// External marketplace form: `claude plugin marketplace add repo@<ref>` can
|
|
165
|
+
// only pin a branch/tag NAME (a bare commit sha fails to clone and the
|
|
166
|
+
// resolved sha is not recorded locally) — name-form weak freeze.
|
|
167
|
+
marketplaceRefForm: 'name',
|
|
158
168
|
knownHostArtifacts: Object.freeze(['.in_use']),
|
|
159
169
|
schemaRequiredFields: Object.freeze(['plugin', 'marketplace', 'entrySkill']),
|
|
160
170
|
skillRendering: Object.freeze({ mode: 'verbatim', preamble: null, placeholder: '${CLAUDE_PLUGIN_ROOT}' }),
|
|
@@ -204,6 +214,9 @@ const CODEX = Object.freeze({
|
|
|
204
214
|
// Codex keeps the authoritative version in .codex-plugin/plugin.json; the
|
|
205
215
|
// marketplace entry version is not bound to the action version.
|
|
206
216
|
marketplaceEntryCarriesVersion: false,
|
|
217
|
+
// External marketplace form: `codex plugin marketplace add repo --ref <ref>`
|
|
218
|
+
// accepts a bare commit sha — sha-form strong freeze.
|
|
219
|
+
marketplaceRefForm: 'sha',
|
|
207
220
|
knownHostArtifacts: Object.freeze(['.git', '.codex-plugin/migrated-command-skills']),
|
|
208
221
|
schemaRequiredFields: Object.freeze(['plugin', 'marketplace', 'entrySkill']),
|
|
209
222
|
skillRendering: Object.freeze({ mode: 'substitute', preamble: 'codex', placeholder: '${CLAUDE_PLUGIN_ROOT}' }),
|
|
@@ -251,6 +264,9 @@ const KIMI = Object.freeze({
|
|
|
251
264
|
// apply (null = N/A, never consulted: kimi preflight reads its manifest via
|
|
252
265
|
// strategy.readManifest).
|
|
253
266
|
marketplaceEntryCarriesVersion: null,
|
|
267
|
+
// kimi has no marketplace add at all, so the marketplace ref form does not
|
|
268
|
+
// apply (null = N/A, never consulted).
|
|
269
|
+
marketplaceRefForm: null,
|
|
254
270
|
knownHostArtifacts: Object.freeze(['.git']),
|
|
255
271
|
schemaRequiredFields: Object.freeze(['plugin', 'entrySkill']),
|
|
256
272
|
skillRendering: Object.freeze({ mode: 'substitute', preamble: 'kimi', placeholder: '${CLAUDE_PLUGIN_ROOT}' }),
|
|
@@ -272,12 +288,88 @@ const KIMI = Object.freeze({
|
|
|
272
288
|
}),
|
|
273
289
|
});
|
|
274
290
|
|
|
275
|
-
|
|
276
|
-
|
|
291
|
+
// CodeBuddy (desktop product WorkBuddy) is a NON-automatable human-attestation
|
|
292
|
+
// platform like kimi: the codebuddy CLI's marketplace add/install cannot pin a
|
|
293
|
+
// frozen ref (no ref option; the install tracks the default branch / latest),
|
|
294
|
+
// so an automated install checkpoint cannot guarantee frozen-artifact identity.
|
|
295
|
+
// Install state has a stable on-disk layout, so the closed loop is proven by a
|
|
296
|
+
// human attestation + read-only verification (./codebuddy.mjs), fail-closed at
|
|
297
|
+
// the same severity as kimi.
|
|
298
|
+
//
|
|
299
|
+
// NAMING MAPPING: the platform id is `codebuddy`, but its BUILD adapter keeps
|
|
300
|
+
// the historical directory name `workbuddy` (`adapters/workbuddy/`, manifest
|
|
301
|
+
// `.codebuddy-plugin/plugin.json`). `buildAdapter.name = 'workbuddy'` drives
|
|
302
|
+
// the build-adapters producer + public-file collection; the pipeline identity
|
|
303
|
+
// (distributionType/actionType/consumer) stays `codebuddy`.
|
|
304
|
+
const CODEBUDDY = Object.freeze({
|
|
305
|
+
id: 'codebuddy',
|
|
306
|
+
distributionType: 'codebuddy-plugin',
|
|
307
|
+
actionType: 'codebuddy-marketplace-install',
|
|
308
|
+
adapter: 'plugin-marketplace',
|
|
309
|
+
automatable: false,
|
|
310
|
+
cli: null,
|
|
311
|
+
jsonProtocol: Object.freeze({
|
|
312
|
+
listOutput: null,
|
|
313
|
+
installPathSource: null,
|
|
314
|
+
marketplaceAddOutput: null,
|
|
315
|
+
pluginInstallOutput: null,
|
|
316
|
+
}),
|
|
317
|
+
// The closed loop never execs the codebuddy CLI; HOME is the only isolation
|
|
318
|
+
// input and exists solely so the attestation's isolated cli-channel home has
|
|
319
|
+
// a base. No unverified host env vars are fabricated.
|
|
320
|
+
isolationEnv: (home) => ({ HOME: home }),
|
|
321
|
+
// codebuddy never execs a CLI; its isolated cli home is created by the
|
|
322
|
+
// manual-requirement strategy under the attestation authority.
|
|
323
|
+
isolationSubdirs: Object.freeze([]),
|
|
324
|
+
manifestPaths: Object.freeze({
|
|
325
|
+
// Single authoritative manifest (no precedence chain, unlike kimi).
|
|
326
|
+
plugin: '.codebuddy-plugin/plugin.json',
|
|
327
|
+
marketplace: null,
|
|
328
|
+
}),
|
|
329
|
+
marketplaceSourceForm: null,
|
|
330
|
+
// codebuddy installs from a unified marketplace but carries no marketplace
|
|
331
|
+
// identity in the action (the marketplace is a fixed constant in
|
|
332
|
+
// ./codebuddy.mjs); the entry-version binding does not apply (null = N/A).
|
|
333
|
+
marketplaceEntryCarriesVersion: null,
|
|
334
|
+
// codebuddy has no marketplace add that can pin a frozen ref (attestation
|
|
335
|
+
// loop instead), so the marketplace ref form does not apply (null = N/A).
|
|
336
|
+
marketplaceRefForm: null,
|
|
337
|
+
knownHostArtifacts: Object.freeze(['.git']),
|
|
338
|
+
schemaRequiredFields: Object.freeze(['plugin', 'entrySkill']),
|
|
339
|
+
// Declarative rendering intent (the build-adapters producer keys on
|
|
340
|
+
// buildAdapter.name = 'workbuddy'): pure ${CLAUDE_PLUGIN_ROOT} ->
|
|
341
|
+
// ${CODEBUDDY_PLUGIN_ROOT} substitution, no entry-resolution preamble
|
|
342
|
+
// (CodeBuddy expands the variable inline in skill content).
|
|
343
|
+
skillRendering: Object.freeze({ mode: 'substitute', preamble: null, placeholder: '${CODEBUDDY_PLUGIN_ROOT}' }),
|
|
344
|
+
buildAdapter: Object.freeze({
|
|
345
|
+
// Build adapter keeps the historical `workbuddy` directory name; the fields
|
|
346
|
+
// are byte-for-byte the legacy BUILD_ONLY workbuddy entry so the generated
|
|
347
|
+
// adapters/workbuddy/ tree is unchanged.
|
|
348
|
+
name: 'workbuddy',
|
|
349
|
+
pluginDirName: '.codebuddy-plugin',
|
|
350
|
+
templateFileName: 'plugin.json',
|
|
351
|
+
marketplaceFileName: null,
|
|
352
|
+
hasMarketplace: false,
|
|
353
|
+
}),
|
|
354
|
+
strategy: Object.freeze({
|
|
355
|
+
parseListOutput: null,
|
|
356
|
+
extractInstallPath: null,
|
|
357
|
+
extractListIdentity: null,
|
|
358
|
+
crossValidateListEntry: null,
|
|
359
|
+
// codebuddy's side-effecting manual-requirement builder and manifest reader
|
|
360
|
+
// live in ./codebuddy.mjs (per-platform-module option, mirroring kimi).
|
|
361
|
+
buildManualRequirement: executeCodeBuddyManualRequirement,
|
|
362
|
+
readManifest: readCodeBuddyManifest,
|
|
363
|
+
}),
|
|
364
|
+
});
|
|
277
365
|
|
|
278
|
-
|
|
279
|
-
const
|
|
366
|
+
/** Ordered platform registry. Order is significant (claude, codex, kimi, codebuddy). */
|
|
367
|
+
export const PLATFORMS = Object.freeze([CLAUDE, CODEX, KIMI, CODEBUDDY]);
|
|
368
|
+
|
|
369
|
+
const VALID_DISTRIBUTION_TYPES = new Set(['claude-plugin', 'codex-plugin', 'kimi-plugin', 'codebuddy-plugin']);
|
|
370
|
+
const VALID_ACTION_TYPES = new Set(['claude-marketplace-install', 'codex-marketplace-install', 'kimi-marketplace-install', 'codebuddy-marketplace-install']);
|
|
280
371
|
const VALID_SOURCE_FORMS = new Set(['string', 'local-path-object', null]);
|
|
372
|
+
const VALID_MARKETPLACE_REF_FORMS = new Set(['sha', 'name', null]);
|
|
281
373
|
const VALID_LIST_OUTPUTS = new Set(['array', 'installed-object', null]);
|
|
282
374
|
const VALID_CLI_OUTPUTS = new Set(['json', null]);
|
|
283
375
|
const VALID_ENTRY_VERSION_BINDING = new Set([true, false, null]);
|
|
@@ -333,6 +425,9 @@ export function assertRegistry(registry = PLATFORMS) {
|
|
|
333
425
|
if (!VALID_SOURCE_FORMS.has(platform.marketplaceSourceForm)) {
|
|
334
426
|
throw new Error(`platform registry: ${label} has illegal marketplaceSourceForm "${platform.marketplaceSourceForm}"`);
|
|
335
427
|
}
|
|
428
|
+
if (!VALID_MARKETPLACE_REF_FORMS.has(platform.marketplaceRefForm)) {
|
|
429
|
+
throw new Error(`platform registry: ${label} has illegal marketplaceRefForm "${platform.marketplaceRefForm}"`);
|
|
430
|
+
}
|
|
336
431
|
if (!Array.isArray(platform.knownHostArtifacts)) {
|
|
337
432
|
throw new Error(`platform registry: ${label} knownHostArtifacts must be an array`);
|
|
338
433
|
}
|
|
@@ -2,10 +2,12 @@
|
|
|
2
2
|
* Pure producer: build adapters from skills and plugin templates.
|
|
3
3
|
*
|
|
4
4
|
* Reads skill metadata from skills-src/ and plugin.json templates,
|
|
5
|
-
* generates self-contained adapter directories for each platform
|
|
5
|
+
* generates self-contained adapter directories for each platform
|
|
6
|
+
* (claude, codex, kimi, and the build-only workbuddy adapter).
|
|
6
7
|
*
|
|
7
8
|
* Each adapter root contains:
|
|
8
|
-
* - Plugin manifest (.claude-plugin/, .codex-plugin/,
|
|
9
|
+
* - Plugin manifest (.claude-plugin/, .codex-plugin/, .kimi-plugin/, or
|
|
10
|
+
* .codebuddy-plugin/)
|
|
9
11
|
* - Skills with host-specific root resolution
|
|
10
12
|
* - bin/release-skill.mjs (wrapper) + bin/release-skill.bundle.mjs (self-contained bundle)
|
|
11
13
|
* - schemas/ (JSON Schema files)
|
|
@@ -195,8 +197,15 @@ export function computeBuildAdaptersDigest(sourceBytes) {
|
|
|
195
197
|
// of platform knowledge). The build shape mirrors the legacy inline table
|
|
196
198
|
// byte-for-byte: marketplaceFileName is present only when the platform
|
|
197
199
|
// co-locates a marketplace manifest in its plugin dir (claude).
|
|
198
|
-
|
|
199
|
-
|
|
200
|
+
//
|
|
201
|
+
// The build adapter NAME defaults to the platform id, but a platform may keep a
|
|
202
|
+
// historical directory name distinct from its pipeline id via
|
|
203
|
+
// `buildAdapter.name`: codebuddy (pipeline id) builds the `workbuddy` adapter
|
|
204
|
+
// tree (adapters/workbuddy/, manifest .codebuddy-plugin/plugin.json). This is
|
|
205
|
+
// what lets codebuddy join the publish pipeline WITHOUT changing a single byte
|
|
206
|
+
// of the generated workbuddy adapter (the former BUILD_ONLY workbuddy entry).
|
|
207
|
+
const REGISTRY_PLATFORMS = PLATFORM_REGISTRY.map((platform) => ({
|
|
208
|
+
name: platform.buildAdapter?.name ?? platform.id,
|
|
200
209
|
pluginDirName: platform.buildAdapter.pluginDirName,
|
|
201
210
|
templateFileName: platform.buildAdapter.templateFileName,
|
|
202
211
|
...(platform.buildAdapter.hasMarketplace
|
|
@@ -205,6 +214,28 @@ export const PLATFORMS = PLATFORM_REGISTRY.map((platform) => ({
|
|
|
205
214
|
hasMarketplace: platform.buildAdapter.hasMarketplace,
|
|
206
215
|
}));
|
|
207
216
|
|
|
217
|
+
/**
|
|
218
|
+
* Build-only distribution adapters: generated, self-contained plugin trees
|
|
219
|
+
* that are NOT wired into the automated publish/reconcile/verify pipeline —
|
|
220
|
+
* no registry PLATFORMS membership, no distributionType/actionType in the
|
|
221
|
+
* plan schemas, no automated install checkpoint. A host joins the pipeline
|
|
222
|
+
* only with a full registry descriptor (strategy, CLI protocol, schema enum);
|
|
223
|
+
* until then a build-only entry lets the build emit an installable adapter
|
|
224
|
+
* tree without fabricating an unverified install protocol.
|
|
225
|
+
*
|
|
226
|
+
* Currently EMPTY: every platform the build emits now has a full registry
|
|
227
|
+
* descriptor. workbuddy (the CodeBuddy/WorkBuddy plugin, manifest
|
|
228
|
+
* `.codebuddy-plugin/plugin.json`, `${CODEBUDDY_PLUGIN_ROOT}` expanded inline
|
|
229
|
+
* in skill content) moved into the registry as the `codebuddy` platform with
|
|
230
|
+
* `buildAdapter.name = 'workbuddy'`, so its adapter tree is still produced —
|
|
231
|
+
* byte-for-byte unchanged — via REGISTRY_PLATFORMS. This constant is retained
|
|
232
|
+
* (still exported and consumed below) for future build-only hosts that have an
|
|
233
|
+
* installable adapter tree but no verified install protocol yet.
|
|
234
|
+
*/
|
|
235
|
+
export const BUILD_ONLY_ADAPTERS = Object.freeze([]);
|
|
236
|
+
|
|
237
|
+
export const PLATFORMS = Object.freeze([...REGISTRY_PLATFORMS, ...BUILD_ONLY_ADAPTERS]);
|
|
238
|
+
|
|
208
239
|
const REQUIRED_SCHEMA_FILES = Object.freeze([
|
|
209
240
|
'approval-record.schema.json',
|
|
210
241
|
'artifact-policy.schema.json',
|
|
@@ -316,14 +347,22 @@ const KIMI_PREAMBLE = `\
|
|
|
316
347
|
* - Codex: replaces the Claude-only path with $RELEASE_SKILL_ENTRY,
|
|
317
348
|
* and prepends the path resolution protocol preamble.
|
|
318
349
|
* - Kimi: same substitution as Codex, with the Kimi Code preamble.
|
|
350
|
+
* - WorkBuddy: pure variable substitution (${CLAUDE_PLUGIN_ROOT} ->
|
|
351
|
+
* ${CODEBUDDY_PLUGIN_ROOT}); CodeBuddy expands the variable inline in
|
|
352
|
+
* skill content (official plugin reference), the same mechanism Claude
|
|
353
|
+
* uses, so no entry-resolution preamble is needed.
|
|
319
354
|
*
|
|
320
355
|
* @param {string} content - Canonical SKILL.md content.
|
|
321
|
-
* @param {string} platformName - 'claude', 'codex', or '
|
|
356
|
+
* @param {string} platformName - 'claude', 'codex', 'kimi', or 'workbuddy'.
|
|
322
357
|
* @returns {string}
|
|
323
358
|
*/
|
|
324
359
|
function renderSkillForPlatform(content, platformName) {
|
|
325
360
|
if (platformName === 'claude') return content;
|
|
326
361
|
|
|
362
|
+
if (platformName === 'workbuddy') {
|
|
363
|
+
return content.replaceAll('${CLAUDE_PLUGIN_ROOT}', '${CODEBUDDY_PLUGIN_ROOT}');
|
|
364
|
+
}
|
|
365
|
+
|
|
327
366
|
if (platformName === 'codex' || platformName === 'kimi') {
|
|
328
367
|
const hostLabel = platformName === 'codex' ? 'Codex' : 'Kimi';
|
|
329
368
|
const preamble = platformName === 'codex' ? CODEX_PREAMBLE : KIMI_PREAMBLE;
|
|
@@ -393,8 +432,11 @@ async function generateAdapterFiles(platform, skills, templateJson, root, market
|
|
|
393
432
|
const adapted = JSON.parse(JSON.stringify(templateJson));
|
|
394
433
|
|
|
395
434
|
// Preserve platform-supported directory auto-discovery in generated adapters.
|
|
435
|
+
// The CodeBuddy server-side validator (`codebuddy plugin validate`) requires
|
|
436
|
+
// `skills` to be an array of component paths, so the workbuddy adapter emits
|
|
437
|
+
// ["./skills/"]; claude/codex/kimi hosts keep the directory-string form.
|
|
396
438
|
if (typeof adapted.skills === 'string') {
|
|
397
|
-
adapted.skills = './skills/';
|
|
439
|
+
adapted.skills = platform.name === 'workbuddy' ? ['./skills/'] : './skills/';
|
|
398
440
|
} else if (Array.isArray(adapted.skills)) {
|
|
399
441
|
for (const skill of adapted.skills) {
|
|
400
442
|
skill.source = `../skills/${skill.name}/SKILL.md`;
|