cyber-agentkit 0.0.0-stage → 0.7.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/dist/index.js ADDED
@@ -0,0 +1,652 @@
1
+ import { A as skillFoldersVerified, B as isRecord, C as userReferencesDir, D as adminSkillFolders, F as packageDir, H as stripJsonComments, I as detectHarness, L as installedPlugins, M as pluginManifestName, N as pluginManifestPaths, O as harnessSkillFolders, P as declaredDependencies, R as enabledPlugins, T as skillsIn, U as managedPolicyLocations, V as readText, b as projectReferencesDir, d as parseReferenceName, j as skillsDirectories, k as pluginSkillFolders, l as referenceNames, n as referenceImplementations, o as listReferences, r as checkReferences, s as searchReferences, t as whereReference, u as resolveReference, w as skillName, x as referenceLayers, y as defaultLayer, z as pluginStorage } from "./reference-where-BhymfNgA.js";
2
+ import { join } from "node:path";
3
+ import { homedir } from "node:os";
4
+ //#region src/plugins/plugin-dependencies.ts
5
+ /**
6
+ * Whether a harness lets a plugin declare other plugins it depends on. Only Claude Code does, via
7
+ * `dependencies` in `plugin.json` (E-CC-X1). The other harnesses' manifests have no such field
8
+ * (E-CUR-X1, E-CODEX-X1, E-COPILOT-X1, E-OC-X1, E-KILO-X1, E-GEM-P4, E-QWEN-P3, E-VSC-X1,
9
+ * E-CLINE-X1, E-CRUSH-X1, E-OH-X1, E-AUG-X1).
10
+ */
11
+ function supportsPluginDependencies(harness) {
12
+ return harness === "claude-code";
13
+ }
14
+ //#endregion
15
+ //#region src/dependencies/plugin-dependencies.ts
16
+ /**
17
+ * Read the `dependencies` array of a Claude Code `plugin.json`: `"name"`, `"name@marketplace"`, or
18
+ * `{ name, marketplace, version }` entries (E-DEP-1, E-CC-X1). Entries of any other shape are skipped.
19
+ */
20
+ function declaredPluginDependencies(manifest) {
21
+ const entries = isRecord(manifest) ? manifest.dependencies : void 0;
22
+ if (!Array.isArray(entries)) return [];
23
+ const dependencies = [];
24
+ for (const entry of entries) {
25
+ const raw = typeof entry === "string" ? entry : isRecord(entry) ? entry.name : void 0;
26
+ if (typeof raw !== "string" || raw === "") continue;
27
+ const [name, inline] = raw.split("@");
28
+ if (name === "") continue;
29
+ const object = isRecord(entry) ? entry : {};
30
+ const marketplace = nonEmpty(object.marketplace) ?? nonEmpty(inline);
31
+ const version = nonEmpty(object.version);
32
+ dependencies.push({
33
+ name,
34
+ ...marketplace && { marketplace },
35
+ ...version && { version }
36
+ });
37
+ }
38
+ return dependencies;
39
+ }
40
+ const nonEmpty = (value) => typeof value === "string" && value !== "" ? value : void 0;
41
+ /** The extension namespaces a root `plugin.json` may author its dependency list under, newest first (E-DEP-6, E-DEP-7). */
42
+ const extensionNamespaces = ["org.spikyuni.plugin-manager", "org.cyberuni.universal-plugin"];
43
+ /**
44
+ * Read what the plugin at `pluginRoot` declares: `dependencies` under `extensions["org.spikyuni.plugin-manager"]`,
45
+ * else under `extensions["org.cyberuni.universal-plugin"]` in the root `plugin.json`, else `dependencies` in
46
+ * `.claude-plugin/plugin.json` (E-DEP-1, E-DEP-6, E-DEP-7).
47
+ */
48
+ async function readPluginDependencies(pluginRoot) {
49
+ const root = join(pluginRoot, "plugin.json");
50
+ const sources = [...extensionNamespaces.map((namespace) => ({
51
+ path: root,
52
+ pick: (manifest) => {
53
+ const extensions = isRecord(manifest) ? manifest.extensions : void 0;
54
+ return isRecord(extensions) ? extensions[namespace] : void 0;
55
+ }
56
+ })), {
57
+ path: join(pluginRoot, ".claude-plugin", "plugin.json"),
58
+ pick: (manifest) => manifest
59
+ }];
60
+ let error;
61
+ for (const { path, pick } of sources) try {
62
+ const text = await readText(path);
63
+ if (text === void 0) continue;
64
+ const dependencies = declaredPluginDependencies(pick(JSON.parse(stripJsonComments(text))));
65
+ if (dependencies.length > 0) return {
66
+ dependencies,
67
+ path
68
+ };
69
+ } catch (cause) {
70
+ error ??= `${path}: ${String(cause)}`;
71
+ }
72
+ return {
73
+ dependencies: [],
74
+ path: sources.at(-1)?.path ?? pluginRoot,
75
+ ...error && { error }
76
+ };
77
+ }
78
+ const rank = {
79
+ enabled: 3,
80
+ installed: 2,
81
+ disabled: 1,
82
+ missing: 0,
83
+ unknown: 0
84
+ };
85
+ /**
86
+ * Check which declared dependencies the harness has installed and enabled, and return the steps
87
+ * that settle the rest. Nothing is installed.
88
+ */
89
+ async function checkPluginDependencies(harness, options = {}) {
90
+ const read = options.dependencies ? {
91
+ dependencies: options.dependencies,
92
+ error: void 0
93
+ } : options.pluginRoot ? await readPluginDependencies(options.pluginRoot) : {
94
+ dependencies: [],
95
+ error: void 0
96
+ };
97
+ const [installed, enabled] = await Promise.all([installedPlugins(harness, options), enabledPlugins(harness, options)]);
98
+ const enablement = new Map(enabled.plugins.map((plugin) => [plugin.id, plugin.enabled]));
99
+ const dependencies = read.dependencies.map((dependency) => {
100
+ if (!installed.supported) return {
101
+ ...dependency,
102
+ state: "unknown"
103
+ };
104
+ const ids = installed.plugins.map((plugin) => plugin.id).filter((id) => dependency.marketplace ? id === `${dependency.name}@${dependency.marketplace}` : id.split("@")[0] === dependency.name);
105
+ let best = {
106
+ ...dependency,
107
+ state: "missing"
108
+ };
109
+ for (const id of new Set(ids)) {
110
+ const flag = enablement.get(id);
111
+ const state = flag === true ? "enabled" : flag === false ? "disabled" : "installed";
112
+ if (rank[state] > rank[best.state]) best = {
113
+ ...dependency,
114
+ state,
115
+ id
116
+ };
117
+ }
118
+ return best;
119
+ });
120
+ const supported = supportsPluginDependencies(harness);
121
+ return {
122
+ harness,
123
+ supported,
124
+ autoResolved: supported,
125
+ dependencies,
126
+ steps: supported ? claudeCodeSteps(dependencies) : manualSteps(harness, read.dependencies),
127
+ ...read.error && { error: read.error },
128
+ research: [
129
+ "E-DEP-1",
130
+ "E-DEP-2",
131
+ "E-DEP-3",
132
+ "E-DEP-4",
133
+ "E-DEP-5",
134
+ "E-DEP-6",
135
+ "E-DEP-7",
136
+ "E-CC-X1"
137
+ ]
138
+ };
139
+ }
140
+ const label = (dependency) => dependency.marketplace ? `${dependency.name}@${dependency.marketplace}` : dependency.name;
141
+ /** E-DEP-2: `plugin install` installs missing dependencies; E-DEP-3: cross-marketplace needs a root allow-list. */
142
+ function claudeCodeSteps(dependencies) {
143
+ const steps = [];
144
+ for (const dependency of dependencies) if (dependency.state === "missing" || dependency.state === "unknown") {
145
+ steps.push(`Install ${label(dependency)}: claude plugin install ${label(dependency)}`);
146
+ if (dependency.marketplace) steps.push(`If ${label(dependency)} is not in the declaring plugin's marketplace, that marketplace's root must list ${dependency.marketplace} in allowCrossMarketplaceDependenciesOn, or you must already have it enabled.`);
147
+ } else if (dependency.state === "disabled") steps.push(`Enable ${dependency.id ?? label(dependency)}: set it to true in enabledPlugins.`);
148
+ if (steps.length > 0) steps.push("Run /reload-plugins.");
149
+ return steps;
150
+ }
151
+ /** E-DEP-4, E-DEP-5, E-CC-X1: no other harness's manifest declares dependencies. */
152
+ function manualSteps(harness, dependencies) {
153
+ if (dependencies.length === 0) return [];
154
+ return [`${harness} has no plugin dependency field, so nothing is resolved for you. Install and enable each plugin yourself.`, ...dependencies.map((dependency) => `Install ${dependency.name}${dependency.marketplace ? ` from ${dependency.marketplace}` : ""} through ${harness}'s plugin install flow, then enable it.`)];
155
+ }
156
+ //#endregion
157
+ //#region src/harness/harness-id.ts
158
+ const harnessIds = [
159
+ "claude-code",
160
+ "cursor",
161
+ "codex",
162
+ "copilot-cli",
163
+ "opencode",
164
+ "kilo",
165
+ "gemini-cli",
166
+ "qwen-code",
167
+ "vscode-copilot",
168
+ "cline",
169
+ "crush",
170
+ "openhands",
171
+ "augment"
172
+ ];
173
+ //#endregion
174
+ //#region src/headless/headless-invocation.ts
175
+ const claudeUsage = {
176
+ event: "result",
177
+ tokens: "usage",
178
+ costUsd: "total_cost_usd",
179
+ accumulate: "last"
180
+ };
181
+ const qwenUsage = {
182
+ event: "result",
183
+ tokens: "usage",
184
+ accumulate: "last"
185
+ };
186
+ const unverified = "has a documented one-shot mode, but its flags were not read directly from a vendor page, so they are not encoded";
187
+ /**
188
+ * How to run a harness non-interactively on one prompt: the command, how to choose the model and
189
+ * permission mode, the output formats and where usage appears in them, the transcript location,
190
+ * and the exit codes.
191
+ *
192
+ * Returns `supported: false` for Copilot in VS Code, which documents no headless mode (E-VSC-H1).
193
+ * Returns `supported: 'unknown'` for OpenCode, Kilo Code, Cline, Crush, OpenHands, and the Auggie
194
+ * CLI: each has a one-shot mode, but the research read it only through a summarizing fetch or from
195
+ * source (E-OC-H1, E-KILO-H1, E-CLINE-H1, E-CRUSH-H1, E-OH-H1, E-AUG-H1).
196
+ */
197
+ function headlessInvocation(harness) {
198
+ switch (harness) {
199
+ case "claude-code": return {
200
+ harness,
201
+ supported: true,
202
+ executable: "claude",
203
+ oneShot: ["-p"],
204
+ modelFlag: "--model",
205
+ permission: {
206
+ flag: "--permission-mode",
207
+ values: [
208
+ "acceptEdits",
209
+ "auto",
210
+ "bypassPermissions",
211
+ "manual",
212
+ "dontAsk",
213
+ "plan"
214
+ ],
215
+ unattended: ["--permission-mode", "bypassPermissions"]
216
+ },
217
+ outputFormats: [
218
+ {
219
+ name: "text",
220
+ args: []
221
+ },
222
+ {
223
+ name: "json",
224
+ args: ["--output-format", "json"],
225
+ usage: claudeUsage
226
+ },
227
+ {
228
+ name: "stream-json",
229
+ args: [
230
+ "--output-format",
231
+ "stream-json",
232
+ "--verbose"
233
+ ],
234
+ usage: claudeUsage
235
+ }
236
+ ],
237
+ transcript: {
238
+ path: "~/.claude/projects/<project>/<session-id>.jsonl",
239
+ baseDirEnv: "CLAUDE_CONFIG_DIR",
240
+ disable: ["--no-session-persistence"]
241
+ },
242
+ exitCodes: [{
243
+ code: 0,
244
+ meaning: "success"
245
+ }, {
246
+ code: 143,
247
+ meaning: "terminated by SIGTERM"
248
+ }],
249
+ research: [
250
+ "E-CC-H1",
251
+ "E-CC-H2",
252
+ "E-CC-H3",
253
+ "E-CC-H4",
254
+ "E-CC-H5",
255
+ "E-CC-H6"
256
+ ]
257
+ };
258
+ case "codex": return {
259
+ harness,
260
+ supported: true,
261
+ executable: "codex",
262
+ oneShot: ["exec"],
263
+ modelFlag: "--model",
264
+ permission: {
265
+ flag: "--sandbox",
266
+ values: [
267
+ "read-only",
268
+ "workspace-write",
269
+ "danger-full-access"
270
+ ],
271
+ unattended: ["--dangerously-bypass-approvals-and-sandbox"]
272
+ },
273
+ outputFormats: [{
274
+ name: "text",
275
+ args: []
276
+ }, {
277
+ name: "jsonl",
278
+ args: ["--json"],
279
+ usage: {
280
+ event: "turn.completed",
281
+ tokens: "usage",
282
+ accumulate: "sum"
283
+ }
284
+ }],
285
+ transcript: {
286
+ path: "~/.codex/sessions/<yyyy>/<mm>/<dd>/rollout-<timestamp>-<thread-id>.jsonl",
287
+ baseDirEnv: "CODEX_HOME",
288
+ disable: ["--ephemeral"]
289
+ },
290
+ exitCodes: [{
291
+ code: 0,
292
+ meaning: "success"
293
+ }, {
294
+ code: 1,
295
+ meaning: "the run reported a fatal error, or the prompt or options were invalid"
296
+ }],
297
+ research: [
298
+ "E-CODEX-H1",
299
+ "E-CODEX-H2",
300
+ "E-CODEX-H3",
301
+ "E-CODEX-H4",
302
+ "E-CODEX-H5"
303
+ ]
304
+ };
305
+ case "copilot-cli": return {
306
+ harness,
307
+ supported: true,
308
+ executable: "copilot",
309
+ oneShot: [],
310
+ promptFlag: "-p",
311
+ modelFlag: "--model",
312
+ permission: {
313
+ values: [],
314
+ unattended: ["--allow-all"]
315
+ },
316
+ outputFormats: [{
317
+ name: "text",
318
+ args: []
319
+ }, {
320
+ name: "json",
321
+ args: ["--output-format", "json"]
322
+ }],
323
+ transcript: {
324
+ path: "~/.copilot/session-state/<session-id>/events.jsonl",
325
+ baseDirEnv: "COPILOT_HOME"
326
+ },
327
+ exitCodes: [],
328
+ research: [
329
+ "E-COPILOT-H1",
330
+ "E-COPILOT-H2",
331
+ "E-COPILOT-H3"
332
+ ]
333
+ };
334
+ case "cursor": return {
335
+ harness,
336
+ supported: true,
337
+ executable: "cursor-agent",
338
+ oneShot: ["-p"],
339
+ modelFlag: "--model",
340
+ permission: {
341
+ values: [],
342
+ unattended: ["--force"]
343
+ },
344
+ outputFormats: [
345
+ {
346
+ name: "text",
347
+ args: []
348
+ },
349
+ {
350
+ name: "json",
351
+ args: ["--output-format", "json"]
352
+ },
353
+ {
354
+ name: "stream-json",
355
+ args: ["--output-format", "stream-json"]
356
+ }
357
+ ],
358
+ exitCodes: [{
359
+ code: 0,
360
+ meaning: "success"
361
+ }, {
362
+ code: 1,
363
+ meaning: "failure"
364
+ }],
365
+ research: [
366
+ "E-CUR-H1",
367
+ "E-CUR-H2",
368
+ "E-CUR-H3"
369
+ ]
370
+ };
371
+ case "gemini-cli": return {
372
+ harness,
373
+ supported: true,
374
+ executable: "gemini",
375
+ oneShot: [],
376
+ promptFlag: "-p",
377
+ modelFlag: "--model",
378
+ permission: {
379
+ flag: "--approval-mode",
380
+ values: [
381
+ "default",
382
+ "auto_edit",
383
+ "yolo",
384
+ "plan"
385
+ ],
386
+ unattended: ["--approval-mode", "yolo"]
387
+ },
388
+ outputFormats: [
389
+ {
390
+ name: "text",
391
+ args: []
392
+ },
393
+ {
394
+ name: "json",
395
+ args: ["--output-format", "json"],
396
+ usage: {
397
+ tokens: "stats",
398
+ accumulate: "last"
399
+ }
400
+ },
401
+ {
402
+ name: "stream-json",
403
+ args: ["--output-format", "stream-json"],
404
+ usage: {
405
+ event: "result",
406
+ tokens: "stats",
407
+ accumulate: "last"
408
+ }
409
+ }
410
+ ],
411
+ transcript: { path: "~/.gemini/tmp/<project_hash>/chats/" },
412
+ exitCodes: [
413
+ {
414
+ code: 0,
415
+ meaning: "success"
416
+ },
417
+ {
418
+ code: 1,
419
+ meaning: "general error or API failure"
420
+ },
421
+ {
422
+ code: 42,
423
+ meaning: "input error: an invalid prompt or arguments"
424
+ },
425
+ {
426
+ code: 53,
427
+ meaning: "turn limit exceeded"
428
+ }
429
+ ],
430
+ research: [
431
+ "E-GEM-H1",
432
+ "E-GEM-H2",
433
+ "E-GEM-H3"
434
+ ]
435
+ };
436
+ case "qwen-code": return {
437
+ harness,
438
+ supported: true,
439
+ executable: "qwen",
440
+ oneShot: [],
441
+ promptFlag: "-p",
442
+ modelFlag: "--model",
443
+ permission: {
444
+ flag: "--approval-mode",
445
+ values: [
446
+ "plan",
447
+ "default",
448
+ "auto-edit",
449
+ "auto",
450
+ "yolo"
451
+ ],
452
+ unattended: ["--approval-mode", "yolo"]
453
+ },
454
+ outputFormats: [
455
+ {
456
+ name: "text",
457
+ args: []
458
+ },
459
+ {
460
+ name: "json",
461
+ args: ["--output-format", "json"],
462
+ usage: qwenUsage
463
+ },
464
+ {
465
+ name: "stream-json",
466
+ args: ["--output-format", "stream-json"],
467
+ usage: qwenUsage
468
+ }
469
+ ],
470
+ transcript: { path: "~/.qwen/projects/<sanitized-cwd>/chats/" },
471
+ exitCodes: [
472
+ {
473
+ code: 53,
474
+ meaning: "turn limit exceeded"
475
+ },
476
+ {
477
+ code: 55,
478
+ meaning: "tool-call or wall-time budget exceeded"
479
+ },
480
+ {
481
+ code: 130,
482
+ meaning: "interrupted by SIGINT"
483
+ }
484
+ ],
485
+ research: ["E-QWEN-H1", "E-QWEN-H2"]
486
+ };
487
+ case "vscode-copilot": return {
488
+ harness,
489
+ supported: false,
490
+ reason: "agent mode runs inside the editor; the docs point terminal use to the Copilot CLI",
491
+ research: ["E-VSC-H1"]
492
+ };
493
+ case "opencode": return {
494
+ harness,
495
+ supported: "unknown",
496
+ reason: `\`opencode run\` ${unverified}`,
497
+ research: ["E-OC-H1"]
498
+ };
499
+ case "kilo": return {
500
+ harness,
501
+ supported: "unknown",
502
+ reason: `\`kilo run\` ${unverified}`,
503
+ research: ["E-KILO-H1"]
504
+ };
505
+ case "cline": return {
506
+ harness,
507
+ supported: "unknown",
508
+ reason: `the Cline CLI ${unverified}`,
509
+ research: ["E-CLINE-H1"]
510
+ };
511
+ case "crush": return {
512
+ harness,
513
+ supported: "unknown",
514
+ reason: `\`crush run\` ${unverified}`,
515
+ research: ["E-CRUSH-H1"]
516
+ };
517
+ case "openhands": return {
518
+ harness,
519
+ supported: "unknown",
520
+ reason: `\`openhands --headless\` ${unverified}`,
521
+ research: ["E-OH-H1"]
522
+ };
523
+ case "augment": return {
524
+ harness,
525
+ supported: "unknown",
526
+ reason: `\`auggie --print\` ${unverified}`,
527
+ research: ["E-AUG-H1"]
528
+ };
529
+ }
530
+ }
531
+ /**
532
+ * The command line for one headless run, built from `headlessInvocation()`. It does not run it.
533
+ *
534
+ * Returns `undefined` when the harness's headless mode is not supported or not verified. Throws
535
+ * when `outputFormat` names a format the harness lacks, or `permission` names a mode the harness
536
+ * has no flag for.
537
+ */
538
+ function headlessCommand(harness, options) {
539
+ const mode = headlessInvocation(harness);
540
+ if (mode.supported !== true) return void 0;
541
+ const args = [...mode.oneShot];
542
+ if (options.model !== void 0) args.push(mode.modelFlag, options.model);
543
+ if (options.permission === "unattended") args.push(...mode.permission.unattended);
544
+ else if (options.permission !== void 0) {
545
+ const { flag, values } = mode.permission;
546
+ if (flag === void 0 || !values.includes(options.permission)) throw new Error(`${harness} has no permission mode "${options.permission}"`);
547
+ args.push(flag, options.permission);
548
+ }
549
+ if (options.outputFormat !== void 0) {
550
+ const format = mode.outputFormats.find((f) => f.name === options.outputFormat);
551
+ if (format === void 0) throw new Error(`${harness} has no output format "${options.outputFormat}"`);
552
+ args.push(...format.args);
553
+ }
554
+ if (mode.promptFlag === void 0) args.push(options.prompt);
555
+ else args.push(mode.promptFlag, options.prompt);
556
+ return {
557
+ executable: mode.executable,
558
+ args
559
+ };
560
+ }
561
+ //#endregion
562
+ //#region src/references/load-reference.ts
563
+ /**
564
+ * Resolves one reference for `root` the way `reference show` does, returning the full record: every
565
+ * field `show` prints with `--metadata` and `--trace`. A name that is not a reference name comes back
566
+ * `invalid`, and one no contribution answers `missing`; neither throws.
567
+ */
568
+ async function loadReference(name, options) {
569
+ const layers = await referenceLayers({
570
+ ...options,
571
+ home: options.home ?? homedir(),
572
+ platform: options.platform ?? process.platform
573
+ });
574
+ return resolveReference(name, layers);
575
+ }
576
+ //#endregion
577
+ //#region src/skills/skill-invocation.ts
578
+ /**
579
+ * How a user invokes a plugin's skill in a harness.
580
+ *
581
+ * Claude Code, Codex, and Copilot in VS Code namespace by plugin; elsewhere two plugins' skills with
582
+ * the same name collide. Codex names a plugin skill `<plugin>:<skill>`, and its `$` mention takes the
583
+ * whole name (E-SR-CODEX-5, E-SR-CODEX-18). Copilot CLI lists `<plugin>:<skill>` only while two
584
+ * enabled plugins share the name (E-SR-COPILOT-8); whether that form can be typed is not verified,
585
+ * so it returns the bare `/<skill>`.
586
+ *
587
+ * Kilo Code returns `/<skill>` in both the CLI and the VS Code extension; when a custom command or
588
+ * MCP prompt has the same name, the skill is typed `/<skill>:skill` instead (E-KILO-S3).
589
+ *
590
+ * OpenCode returns `/<skill>` too, but when a built-in (`init`, `review`), config command, or MCP
591
+ * prompt has the same name, that one wins and the skill has no command (E-OC-S3).
592
+ *
593
+ * Returns `undefined` for Gemini CLI, Qwen Code, and Crush, which document no typed form: the model
594
+ * loads a skill through a tool call when its description matches the task (E-GEM-S2, E-QWEN-S1,
595
+ * E-CRUSH-S1). Crush can also list a skill in its command
596
+ * palette, which is picked, not typed (E-CRUSH-S2). OpenHands triggers skills from the model too;
597
+ * only a plugin's commands take a `/<plugin>:<command>` form (E-OH-S2, E-OH-S3).
598
+ *
599
+ * Also returns `undefined` for the Auggie CLI: a plugin skill's internal name is `<plugin>:<skill>`,
600
+ * but what the user types for it is not confirmed (E-AUG-S3).
601
+ */
602
+ function skillInvocation(harness, { plugin, skill }) {
603
+ switch (harness) {
604
+ case "claude-code": return {
605
+ text: `/${plugin}:${skill}`,
606
+ namespaced: true,
607
+ research: "E-CC-S1"
608
+ };
609
+ case "cursor": return {
610
+ text: `/${skill}`,
611
+ namespaced: false,
612
+ research: "E-CUR-S1"
613
+ };
614
+ case "codex": return {
615
+ text: `$${plugin}:${skill}`,
616
+ namespaced: true,
617
+ research: "E-SR-CODEX-18"
618
+ };
619
+ case "copilot-cli": return {
620
+ text: `/${skill}`,
621
+ namespaced: false,
622
+ research: "E-COPILOT-S6"
623
+ };
624
+ case "vscode-copilot": return {
625
+ text: `/${plugin}:${skill}`,
626
+ namespaced: true,
627
+ research: "E-VSC-S1"
628
+ };
629
+ case "cline": return {
630
+ text: `/${skill}`,
631
+ namespaced: false,
632
+ research: "E-CLINE-S2"
633
+ };
634
+ case "kilo": return {
635
+ text: `/${skill}`,
636
+ namespaced: false,
637
+ research: "E-KILO-S3"
638
+ };
639
+ case "opencode": return {
640
+ text: `/${skill}`,
641
+ namespaced: false,
642
+ research: "E-OC-S3"
643
+ };
644
+ case "gemini-cli":
645
+ case "qwen-code":
646
+ case "crush":
647
+ case "openhands":
648
+ case "augment": return;
649
+ }
650
+ }
651
+ //#endregion
652
+ export { adminSkillFolders, checkPluginDependencies, checkReferences, declaredDependencies, declaredPluginDependencies, defaultLayer, detectHarness, enabledPlugins, harnessIds, harnessSkillFolders, headlessCommand, headlessInvocation, installedPlugins, listReferences, loadReference, managedPolicyLocations, packageDir, parseReferenceName, pluginManifestName, pluginManifestPaths, pluginSkillFolders, pluginStorage, projectReferencesDir, readPluginDependencies, referenceImplementations, referenceLayers, referenceNames, resolveReference, searchReferences, skillFoldersVerified, skillInvocation, skillName, skillsDirectories, skillsIn, supportsPluginDependencies, userReferencesDir, whereReference };