opencode-swarm-plugin 0.61.0 → 0.62.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/bin/swarm.ts +303 -2339
- package/claude-plugin/dist/index.js +830 -635
- package/claude-plugin/dist/schemas/cell.d.ts +1 -0
- package/claude-plugin/dist/schemas/cell.d.ts.map +1 -1
- package/claude-plugin/hooks/hooks.json +9 -0
- package/dist/bin/swarm.js +78737 -81712
- package/dist/examples/plugin-wrapper-template.ts +8 -3
- package/dist/hive.d.ts.map +1 -1
- package/dist/hive.js +3 -1
- package/dist/index.d.ts +45 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +186 -2
- package/dist/marketplace/index.js +830 -635
- package/dist/plugin.js +186 -2
- package/dist/schemas/cell.d.ts +1 -0
- package/dist/schemas/cell.d.ts.map +1 -1
- package/dist/skills.d.ts +16 -0
- package/dist/skills.d.ts.map +1 -1
- package/dist/swarm-orchestrate.d.ts +110 -0
- package/dist/swarm-orchestrate.d.ts.map +1 -1
- package/dist/swarm-prompts.js +184 -2
- package/dist/swarm.d.ts +40 -0
- package/dist/swarm.d.ts.map +1 -1
- package/examples/plugin-wrapper-template.ts +8 -3
- package/global-skills/skill-generator/SKILL.md +155 -0
- package/global-skills/skill-generator/references/conventions.md +361 -0
- package/global-skills/skill-generator/scripts/generate-skill.sh +193 -0
- package/package.json +1 -1
package/dist/swarm-prompts.js
CHANGED
|
@@ -17256,6 +17256,7 @@ __export(exports_skills, {
|
|
|
17256
17256
|
validateCSOCompliance: () => validateCSOCompliance,
|
|
17257
17257
|
skills_use: () => skills_use,
|
|
17258
17258
|
skills_update: () => skills_update,
|
|
17259
|
+
skills_reload: () => skills_reload,
|
|
17259
17260
|
skills_read: () => skills_read,
|
|
17260
17261
|
skills_list: () => skills_list,
|
|
17261
17262
|
skills_init: () => skills_init,
|
|
@@ -17740,7 +17741,7 @@ var import_gray_matter, ALWAYS_ON_GUIDANCE_HEADER = "## Always-On Guidance Skill
|
|
|
17740
17741
|
- Read before Edit; no speculative changes or output`, OPUS_4_5_GUIDANCE = `#### Opus 4.5 (Concise)
|
|
17741
17742
|
- Be concise and deliberate while obeying mandates
|
|
17742
17743
|
- Follow tool priorities without shortcuts
|
|
17743
|
-
- Prefer direct answers over speculation`, skillsProjectDirectory, skillsCache = null, PROJECT_SKILL_DIRECTORIES, skills_list, skills_use, skills_execute, skills_read, DEFAULT_SKILLS_DIR = ".opencode/skill", skills_create, skills_update, skills_delete, skills_add_script, skills_init, skillsTools;
|
|
17744
|
+
- Prefer direct answers over speculation`, skillsProjectDirectory, skillsCache = null, PROJECT_SKILL_DIRECTORIES, skills_list, skills_use, skills_execute, skills_read, DEFAULT_SKILLS_DIR = ".opencode/skill", skills_create, skills_update, skills_delete, skills_add_script, skills_reload, skills_init, skillsTools;
|
|
17744
17745
|
var init_skills = __esm(() => {
|
|
17745
17746
|
init_dist();
|
|
17746
17747
|
import_gray_matter = __toESM(require_gray_matter(), 1);
|
|
@@ -18170,6 +18171,38 @@ executed with skills_execute. Use for:
|
|
|
18170
18171
|
}
|
|
18171
18172
|
}
|
|
18172
18173
|
});
|
|
18174
|
+
skills_reload = tool({
|
|
18175
|
+
description: `Hot-reload skills by clearing cache and re-scanning skill directories.
|
|
18176
|
+
|
|
18177
|
+
Use this to:
|
|
18178
|
+
- Test a newly created skill immediately without restarting
|
|
18179
|
+
- Verify skill modifications took effect
|
|
18180
|
+
- Refresh skills after external changes
|
|
18181
|
+
|
|
18182
|
+
The tool clears the cached skills, re-scans all skill directories,
|
|
18183
|
+
and returns a list of loaded skills.`,
|
|
18184
|
+
args: {},
|
|
18185
|
+
async execute() {
|
|
18186
|
+
invalidateSkillsCache();
|
|
18187
|
+
const skills = await discoverSkills();
|
|
18188
|
+
const refs = Array.from(skills.values()).map((skill) => ({
|
|
18189
|
+
name: skill.metadata.name,
|
|
18190
|
+
description: skill.metadata.description,
|
|
18191
|
+
path: skill.path,
|
|
18192
|
+
hasScripts: skill.hasScripts
|
|
18193
|
+
}));
|
|
18194
|
+
return JSON.stringify({
|
|
18195
|
+
success: true,
|
|
18196
|
+
reloaded: refs.length,
|
|
18197
|
+
skills: refs.map((r) => ({
|
|
18198
|
+
name: r.name,
|
|
18199
|
+
description: r.description,
|
|
18200
|
+
hasScripts: r.hasScripts
|
|
18201
|
+
})),
|
|
18202
|
+
message: `Reloaded ${refs.length} skill(s). All skills are now up-to-date.`
|
|
18203
|
+
}, null, 2);
|
|
18204
|
+
}
|
|
18205
|
+
});
|
|
18173
18206
|
skills_init = tool({
|
|
18174
18207
|
description: `Initialize a new skill with full directory structure and templates.
|
|
18175
18208
|
|
|
@@ -18282,6 +18315,7 @@ echo "Project directory: $1"
|
|
|
18282
18315
|
skills_update,
|
|
18283
18316
|
skills_delete,
|
|
18284
18317
|
skills_add_script,
|
|
18318
|
+
skills_reload,
|
|
18285
18319
|
skills_init
|
|
18286
18320
|
};
|
|
18287
18321
|
});
|
|
@@ -39524,6 +39558,7 @@ var EpicCreateArgsSchema = exports_external.object({
|
|
|
39524
39558
|
epic_id: exports_external.string().optional(),
|
|
39525
39559
|
subtasks: exports_external.array(exports_external.object({
|
|
39526
39560
|
title: exports_external.string().min(1),
|
|
39561
|
+
description: exports_external.string().optional(),
|
|
39527
39562
|
priority: exports_external.number().int().min(0).max(3).default(2),
|
|
39528
39563
|
files: exports_external.array(exports_external.string()).optional().default([]),
|
|
39529
39564
|
id_suffix: exports_external.string().optional()
|
|
@@ -40553,7 +40588,8 @@ var hive_create_epic = tool({
|
|
|
40553
40588
|
title: subtask.title,
|
|
40554
40589
|
type: "task",
|
|
40555
40590
|
priority: subtask.priority ?? 2,
|
|
40556
|
-
parent_id: epic.id
|
|
40591
|
+
parent_id: epic.id,
|
|
40592
|
+
description: subtask.description
|
|
40557
40593
|
});
|
|
40558
40594
|
await adapter.markDirty(projectKey, subtaskCell.id);
|
|
40559
40595
|
created.push(subtaskCell);
|
|
@@ -43806,6 +43842,152 @@ var swarm_recover = tool({
|
|
|
43806
43842
|
}
|
|
43807
43843
|
}
|
|
43808
43844
|
});
|
|
43845
|
+
var swarm_branch = tool({
|
|
43846
|
+
description: "Create a session branch for exploration. Saves current context with a label for later return.",
|
|
43847
|
+
args: {
|
|
43848
|
+
project_key: tool.schema.string().describe("Project path"),
|
|
43849
|
+
agent_name: tool.schema.string().describe("Agent name"),
|
|
43850
|
+
bead_id: tool.schema.string().describe("Current subtask bead ID"),
|
|
43851
|
+
epic_id: tool.schema.string().describe("Epic bead ID"),
|
|
43852
|
+
branch_label: tool.schema.string().describe("Label for this branch (e.g., 'debug-cache-issue')"),
|
|
43853
|
+
branch_purpose: tool.schema.string().describe("Why branching? (e.g., 'investigate API timeout')"),
|
|
43854
|
+
files_modified: tool.schema.array(tool.schema.string()).describe("Files modified before branching"),
|
|
43855
|
+
progress_percent: tool.schema.number().min(0).max(100).optional().describe("Current progress percentage")
|
|
43856
|
+
},
|
|
43857
|
+
async execute(args) {
|
|
43858
|
+
try {
|
|
43859
|
+
const branchId = `branch-${Date.now()}-${args.branch_label.replace(/[^a-z0-9-]/gi, "-")}`;
|
|
43860
|
+
const checkpoint = {
|
|
43861
|
+
epic_id: args.epic_id,
|
|
43862
|
+
bead_id: args.bead_id,
|
|
43863
|
+
strategy: "file-based",
|
|
43864
|
+
files: args.files_modified,
|
|
43865
|
+
dependencies: [],
|
|
43866
|
+
directives: {
|
|
43867
|
+
branch_label: args.branch_label,
|
|
43868
|
+
branch_purpose: args.branch_purpose,
|
|
43869
|
+
branch_id: branchId
|
|
43870
|
+
},
|
|
43871
|
+
recovery: {
|
|
43872
|
+
last_checkpoint: Date.now(),
|
|
43873
|
+
files_modified: args.files_modified,
|
|
43874
|
+
progress_percent: args.progress_percent || 0,
|
|
43875
|
+
last_message: `Branched for: ${args.branch_purpose}`
|
|
43876
|
+
}
|
|
43877
|
+
};
|
|
43878
|
+
const { createEvent: createEvent5, appendEvent: appendEvent4 } = await import("swarm-mail");
|
|
43879
|
+
const checkpointData = JSON.stringify(checkpoint);
|
|
43880
|
+
const event = createEvent5("swarm_checkpointed", {
|
|
43881
|
+
project_key: args.project_key,
|
|
43882
|
+
epic_id: args.epic_id,
|
|
43883
|
+
bead_id: args.bead_id,
|
|
43884
|
+
strategy: checkpoint.strategy,
|
|
43885
|
+
files: checkpoint.files,
|
|
43886
|
+
dependencies: checkpoint.dependencies,
|
|
43887
|
+
directives: checkpoint.directives,
|
|
43888
|
+
recovery: checkpoint.recovery,
|
|
43889
|
+
checkpoint_size_bytes: Buffer.byteLength(checkpointData, "utf8"),
|
|
43890
|
+
trigger: "manual"
|
|
43891
|
+
});
|
|
43892
|
+
await appendEvent4(event, args.project_key);
|
|
43893
|
+
return JSON.stringify({
|
|
43894
|
+
success: true,
|
|
43895
|
+
branch_id: branchId,
|
|
43896
|
+
branch_label: args.branch_label,
|
|
43897
|
+
branch_purpose: args.branch_purpose,
|
|
43898
|
+
checkpoint_timestamp: Date.now(),
|
|
43899
|
+
message: `Session branched: ${args.branch_label}. Use swarm_return to restore main context.`,
|
|
43900
|
+
files_snapshot: args.files_modified
|
|
43901
|
+
}, null, 2);
|
|
43902
|
+
} catch (error45) {
|
|
43903
|
+
console.warn(`[swarm_branch] Failed to create branch ${args.branch_label}:`, error45);
|
|
43904
|
+
return JSON.stringify({
|
|
43905
|
+
success: false,
|
|
43906
|
+
error: error45 instanceof Error ? error45.message : String(error45),
|
|
43907
|
+
message: `Failed to branch session: ${args.branch_label}`
|
|
43908
|
+
}, null, 2);
|
|
43909
|
+
}
|
|
43910
|
+
}
|
|
43911
|
+
});
|
|
43912
|
+
var swarm_return = tool({
|
|
43913
|
+
description: "Return from session branch. Restores main context, optionally carrying back learnings.",
|
|
43914
|
+
args: {
|
|
43915
|
+
project_key: tool.schema.string().describe("Project path"),
|
|
43916
|
+
epic_id: tool.schema.string().describe("Epic bead ID"),
|
|
43917
|
+
branch_label: tool.schema.string().optional().describe("Label of branch to return from (defaults to latest)"),
|
|
43918
|
+
carry_back_learnings: tool.schema.string().optional().describe("Learnings or insights to carry back to main context"),
|
|
43919
|
+
carry_back_files: tool.schema.array(tool.schema.string()).optional().describe("Files to preserve from branch (others discarded)")
|
|
43920
|
+
},
|
|
43921
|
+
async execute(args) {
|
|
43922
|
+
try {
|
|
43923
|
+
const { getSwarmMailLibSQL: getSwarmMailLibSQL5 } = await import("swarm-mail");
|
|
43924
|
+
const swarmMail = await getSwarmMailLibSQL5(args.project_key);
|
|
43925
|
+
const db = await swarmMail.getDatabase();
|
|
43926
|
+
const result = await db.query(args.branch_label ? `SELECT * FROM swarm_contexts
|
|
43927
|
+
WHERE epic_id = $1 AND json_extract(directives, '$.branch_label') = $2
|
|
43928
|
+
ORDER BY updated_at DESC
|
|
43929
|
+
LIMIT 1` : `SELECT * FROM swarm_contexts
|
|
43930
|
+
WHERE epic_id = $1 AND json_extract(directives, '$.branch_id') IS NOT NULL
|
|
43931
|
+
ORDER BY updated_at DESC
|
|
43932
|
+
LIMIT 1`, args.branch_label ? [args.epic_id, args.branch_label] : [args.epic_id]);
|
|
43933
|
+
if (!result.rows || result.rows.length === 0) {
|
|
43934
|
+
return JSON.stringify({
|
|
43935
|
+
success: false,
|
|
43936
|
+
found: false,
|
|
43937
|
+
message: args.branch_label ? `No branch found with label: ${args.branch_label}` : "No branch checkpoints found for this epic",
|
|
43938
|
+
epic_id: args.epic_id
|
|
43939
|
+
}, null, 2);
|
|
43940
|
+
}
|
|
43941
|
+
const row = result.rows[0];
|
|
43942
|
+
const parseIfString = (val) => typeof val === "string" ? JSON.parse(val) : val;
|
|
43943
|
+
const context = {
|
|
43944
|
+
id: row.id,
|
|
43945
|
+
epic_id: row.epic_id,
|
|
43946
|
+
bead_id: row.bead_id,
|
|
43947
|
+
strategy: row.strategy,
|
|
43948
|
+
files: parseIfString(row.files),
|
|
43949
|
+
dependencies: parseIfString(row.dependencies),
|
|
43950
|
+
directives: parseIfString(row.directives),
|
|
43951
|
+
recovery: parseIfString(row.recovery),
|
|
43952
|
+
created_at: row.created_at,
|
|
43953
|
+
updated_at: row.updated_at
|
|
43954
|
+
};
|
|
43955
|
+
const { createEvent: createEvent5, appendEvent: appendEvent4 } = await import("swarm-mail");
|
|
43956
|
+
const event = createEvent5("swarm_recovered", {
|
|
43957
|
+
project_key: args.project_key,
|
|
43958
|
+
epic_id: args.epic_id,
|
|
43959
|
+
bead_id: context.bead_id,
|
|
43960
|
+
recovered_from_checkpoint: context.recovery.last_checkpoint
|
|
43961
|
+
});
|
|
43962
|
+
await appendEvent4(event, args.project_key);
|
|
43963
|
+
const branchLabel = context.directives.branch_label || "unnamed-branch";
|
|
43964
|
+
return JSON.stringify({
|
|
43965
|
+
success: true,
|
|
43966
|
+
found: true,
|
|
43967
|
+
branch_label: branchLabel,
|
|
43968
|
+
branch_purpose: context.directives.branch_purpose,
|
|
43969
|
+
context_restored: {
|
|
43970
|
+
bead_id: context.bead_id,
|
|
43971
|
+
files: context.files,
|
|
43972
|
+
progress_percent: context.recovery.progress_percent
|
|
43973
|
+
},
|
|
43974
|
+
learnings_carried_back: args.carry_back_learnings || null,
|
|
43975
|
+
files_carried_back: args.carry_back_files || [],
|
|
43976
|
+
message: `Returned from branch: ${branchLabel}`,
|
|
43977
|
+
age_seconds: Math.round((Date.now() - context.updated_at) / 1000)
|
|
43978
|
+
}, null, 2);
|
|
43979
|
+
} catch (error45) {
|
|
43980
|
+
console.warn(`[swarm_return] Failed to return from branch:`, error45);
|
|
43981
|
+
return JSON.stringify({
|
|
43982
|
+
success: false,
|
|
43983
|
+
found: false,
|
|
43984
|
+
error: error45 instanceof Error ? error45.message : String(error45),
|
|
43985
|
+
message: "Failed to return from branch",
|
|
43986
|
+
epic_id: args.epic_id
|
|
43987
|
+
}, null, 2);
|
|
43988
|
+
}
|
|
43989
|
+
}
|
|
43990
|
+
});
|
|
43809
43991
|
var swarm_learn = tool({
|
|
43810
43992
|
description: `Analyze completed work and optionally create a skill from learned patterns.
|
|
43811
43993
|
|
package/dist/swarm.d.ts
CHANGED
|
@@ -340,6 +340,46 @@ export declare const swarmTools: {
|
|
|
340
340
|
epic_id: string;
|
|
341
341
|
}, context: import("@opencode-ai/plugin").ToolContext): Promise<string>;
|
|
342
342
|
};
|
|
343
|
+
swarm_branch: {
|
|
344
|
+
description: string;
|
|
345
|
+
args: {
|
|
346
|
+
project_key: import("zod").ZodString;
|
|
347
|
+
agent_name: import("zod").ZodString;
|
|
348
|
+
bead_id: import("zod").ZodString;
|
|
349
|
+
epic_id: import("zod").ZodString;
|
|
350
|
+
branch_label: import("zod").ZodString;
|
|
351
|
+
branch_purpose: import("zod").ZodString;
|
|
352
|
+
files_modified: import("zod").ZodArray<import("zod").ZodString>;
|
|
353
|
+
progress_percent: import("zod").ZodOptional<import("zod").ZodNumber>;
|
|
354
|
+
};
|
|
355
|
+
execute(args: {
|
|
356
|
+
project_key: string;
|
|
357
|
+
agent_name: string;
|
|
358
|
+
bead_id: string;
|
|
359
|
+
epic_id: string;
|
|
360
|
+
branch_label: string;
|
|
361
|
+
branch_purpose: string;
|
|
362
|
+
files_modified: string[];
|
|
363
|
+
progress_percent?: number | undefined;
|
|
364
|
+
}, context: import("@opencode-ai/plugin").ToolContext): Promise<string>;
|
|
365
|
+
};
|
|
366
|
+
swarm_return: {
|
|
367
|
+
description: string;
|
|
368
|
+
args: {
|
|
369
|
+
project_key: import("zod").ZodString;
|
|
370
|
+
epic_id: import("zod").ZodString;
|
|
371
|
+
branch_label: import("zod").ZodOptional<import("zod").ZodString>;
|
|
372
|
+
carry_back_learnings: import("zod").ZodOptional<import("zod").ZodString>;
|
|
373
|
+
carry_back_files: import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodString>>;
|
|
374
|
+
};
|
|
375
|
+
execute(args: {
|
|
376
|
+
project_key: string;
|
|
377
|
+
epic_id: string;
|
|
378
|
+
branch_label?: string | undefined;
|
|
379
|
+
carry_back_learnings?: string | undefined;
|
|
380
|
+
carry_back_files?: string[] | undefined;
|
|
381
|
+
}, context: import("@opencode-ai/plugin").ToolContext): Promise<string>;
|
|
382
|
+
};
|
|
343
383
|
swarm_learn: {
|
|
344
384
|
description: string;
|
|
345
385
|
args: {
|
package/dist/swarm.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"swarm.d.ts","sourceRoot":"","sources":["../src/swarm.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,gBAAgB,CAAC;AAW/B;;;GAGG;AACH,eAAO,MAAM,UAAU
|
|
1
|
+
{"version":3,"file":"swarm.d.ts","sourceRoot":"","sources":["../src/swarm.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,gBAAgB,CAAC;AAW/B;;;GAGG;AACH,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAQtB,CAAC"}
|
|
@@ -40,7 +40,10 @@ import { tool } from "@opencode-ai/plugin";
|
|
|
40
40
|
import { spawn } from "child_process";
|
|
41
41
|
import { appendFileSync, mkdirSync, existsSync } from "node:fs";
|
|
42
42
|
import { join } from "node:path";
|
|
43
|
-
import { homedir } from "node:os";
|
|
43
|
+
import { homedir, platform } from "node:os";
|
|
44
|
+
|
|
45
|
+
// Platform detection for Windows compatibility
|
|
46
|
+
const isWindows = platform() === "win32";
|
|
44
47
|
|
|
45
48
|
// =============================================================================
|
|
46
49
|
// Swarm Signature Detection (INLINED - do not import from opencode-swarm-plugin)
|
|
@@ -304,7 +307,9 @@ function getSwarmSummary(projection: SwarmProjection): string {
|
|
|
304
307
|
// Constants
|
|
305
308
|
// =============================================================================
|
|
306
309
|
|
|
307
|
-
|
|
310
|
+
// On Windows, use .cmd extension to avoid shell escaping issues with JSON args
|
|
311
|
+
const SWARM_CLI = isWindows ? "swarm.cmd" : "swarm";
|
|
312
|
+
const OPENCODE_CLI = isWindows ? "opencode.cmd" : "opencode";
|
|
308
313
|
|
|
309
314
|
// =============================================================================
|
|
310
315
|
// File-based Logging (writes to ~/.config/swarm-tools/logs/)
|
|
@@ -2058,7 +2063,7 @@ Keep the prompt concise but actionable. Use actual data from the snapshot, not p
|
|
|
2058
2063
|
const llmStart = Date.now();
|
|
2059
2064
|
const result = await new Promise<{ exitCode: number; stdout: string; stderr: string }>(
|
|
2060
2065
|
(resolve, reject) => {
|
|
2061
|
-
const proc = spawn(
|
|
2066
|
+
const proc = spawn(OPENCODE_CLI, ["run", "-m", liteModel, "--", promptText], {
|
|
2062
2067
|
cwd: projectDirectory,
|
|
2063
2068
|
stdio: ["ignore", "pipe", "pipe"],
|
|
2064
2069
|
timeout: 30000, // 30 second timeout
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: skill-generator
|
|
3
|
+
description: Meta-skill for generating new skills with proper format and structure. Use when creating new skills for the swarm system or when agents need to generate skill scaffolds. Ensures skills follow conventions (frontmatter format, directory structure, bundled resources).
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Skill Generator
|
|
7
|
+
|
|
8
|
+
Generate new skills with proper format, structure, and conventions. This meta-skill helps agents create skills without hallucinating the format.
|
|
9
|
+
|
|
10
|
+
## Quick Start
|
|
11
|
+
|
|
12
|
+
To generate a new skill:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
bash scripts/generate-skill.sh <skill-name> [target-directory]
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
This creates a complete skill scaffold with:
|
|
19
|
+
- SKILL.md with proper frontmatter
|
|
20
|
+
- scripts/ directory for executable helpers
|
|
21
|
+
- references/ directory for documentation
|
|
22
|
+
- Placeholder content following conventions
|
|
23
|
+
|
|
24
|
+
## Skill Format Conventions
|
|
25
|
+
|
|
26
|
+
Every skill MUST include:
|
|
27
|
+
|
|
28
|
+
1. **SKILL.md** (required) - Main skill file with:
|
|
29
|
+
- YAML frontmatter (name, description)
|
|
30
|
+
- Markdown body with instructions
|
|
31
|
+
|
|
32
|
+
2. **Bundled Resources** (optional):
|
|
33
|
+
- `scripts/` - Executable code (bash/python/etc)
|
|
34
|
+
- `references/` - Documentation loaded on-demand
|
|
35
|
+
- `assets/` - Files used in output (templates, etc)
|
|
36
|
+
|
|
37
|
+
### Frontmatter Requirements
|
|
38
|
+
|
|
39
|
+
```yaml
|
|
40
|
+
---
|
|
41
|
+
name: skill-name
|
|
42
|
+
description: What the skill does AND when to use it. Include triggering scenarios.
|
|
43
|
+
---
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
The description field is critical for skill discovery and triggering. Include:
|
|
47
|
+
- What the skill does
|
|
48
|
+
- When to use it (specific triggers)
|
|
49
|
+
- What contexts activate it
|
|
50
|
+
|
|
51
|
+
### Directory Structure
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
skill-name/
|
|
55
|
+
├── SKILL.md (required)
|
|
56
|
+
├── scripts/ (optional)
|
|
57
|
+
│ └── example-script.sh
|
|
58
|
+
├── references/ (optional)
|
|
59
|
+
│ └── conventions.md
|
|
60
|
+
└── assets/ (optional)
|
|
61
|
+
└── template-file
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Writing Effective Skills
|
|
65
|
+
|
|
66
|
+
### Keep SKILL.md Lean
|
|
67
|
+
|
|
68
|
+
Target <500 lines in SKILL.md. Move detailed content to references/:
|
|
69
|
+
|
|
70
|
+
- Core workflow → SKILL.md
|
|
71
|
+
- Detailed examples → references/
|
|
72
|
+
- API docs → references/
|
|
73
|
+
- Long explanations → references/
|
|
74
|
+
|
|
75
|
+
### Use Imperative Form
|
|
76
|
+
|
|
77
|
+
Write instructions as commands:
|
|
78
|
+
- "Read the file first" ✓
|
|
79
|
+
- "You should read the file" ✗
|
|
80
|
+
- "Check for patterns" ✓
|
|
81
|
+
- "Consider checking patterns" ✗
|
|
82
|
+
|
|
83
|
+
### Progressive Disclosure
|
|
84
|
+
|
|
85
|
+
Skills use three-level loading:
|
|
86
|
+
|
|
87
|
+
1. **Metadata** (~100 words) - Always in context
|
|
88
|
+
2. **SKILL.md body** (<5k words) - When skill triggers
|
|
89
|
+
3. **Bundled resources** (unlimited) - Loaded as needed
|
|
90
|
+
|
|
91
|
+
## Bundled Resources
|
|
92
|
+
|
|
93
|
+
### scripts/
|
|
94
|
+
|
|
95
|
+
Executable code for deterministic tasks:
|
|
96
|
+
- When the same code is rewritten repeatedly
|
|
97
|
+
- When reliability is critical
|
|
98
|
+
- Run via bash/python without loading to context
|
|
99
|
+
|
|
100
|
+
Make scripts executable:
|
|
101
|
+
```bash
|
|
102
|
+
chmod +x scripts/my-script.sh
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### references/
|
|
106
|
+
|
|
107
|
+
Documentation loaded on-demand:
|
|
108
|
+
- Database schemas
|
|
109
|
+
- API documentation
|
|
110
|
+
- Detailed workflow guides
|
|
111
|
+
- Domain knowledge
|
|
112
|
+
|
|
113
|
+
Keep reference files focused. For files >100 lines, include a table of contents.
|
|
114
|
+
|
|
115
|
+
Reference from SKILL.md with clear guidance on when to read:
|
|
116
|
+
```markdown
|
|
117
|
+
See references/api-docs.md for complete API reference.
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### assets/
|
|
121
|
+
|
|
122
|
+
Files used in output (not loaded to context):
|
|
123
|
+
- Templates
|
|
124
|
+
- Images/icons
|
|
125
|
+
- Boilerplate code
|
|
126
|
+
- Fonts/typography
|
|
127
|
+
|
|
128
|
+
## What NOT to Include
|
|
129
|
+
|
|
130
|
+
Do NOT create these files:
|
|
131
|
+
- README.md
|
|
132
|
+
- INSTALLATION_GUIDE.md
|
|
133
|
+
- QUICK_REFERENCE.md
|
|
134
|
+
- CHANGELOG.md
|
|
135
|
+
|
|
136
|
+
Skills should contain only what an AI agent needs to execute the task. No auxiliary documentation.
|
|
137
|
+
|
|
138
|
+
## Validation
|
|
139
|
+
|
|
140
|
+
Before finalizing, validate the skill:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
bun scripts/validate-skill.ts path/to/skill
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Checks:
|
|
147
|
+
- YAML frontmatter format
|
|
148
|
+
- Required fields present
|
|
149
|
+
- No TODO placeholders
|
|
150
|
+
- No extraneous files
|
|
151
|
+
- Naming conventions
|
|
152
|
+
|
|
153
|
+
## Reference
|
|
154
|
+
|
|
155
|
+
See references/conventions.md for complete skill format specification.
|