@drunkcoding/agents-and-skills 0.0.39 → 0.0.40
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 +5 -5
- package/package.json +1 -1
- package/plugins/html-effectiveness/.claude-plugin/plugin.json +1 -1
- package/plugins/multica-tool/.claude-plugin/plugin.json +1 -1
- package/plugins/multica-tool/scripts/multica-export.mjs +24 -4
- package/plugins/multica-tool/scripts/multica-import.mjs +17 -4
- package/plugins/multica-tool/skills/export/SKILL.md +1 -1
- package/plugins/multica-tool/skills/import/SKILL.md +2 -0
- package/plugins/plugin-validator/.claude-plugin/plugin.json +1 -1
- package/plugins/team-share/.claude-plugin/plugin.json +1 -1
- package/plugins/tech-graph/.claude-plugin/plugin.json +1 -1
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"name": "tech-graph",
|
|
13
13
|
"source": "./plugins/tech-graph",
|
|
14
14
|
"description": "6-step wizard for technical diagrams (SVG/PNG) via fireworks-tech-graph",
|
|
15
|
-
"version": "0.0.
|
|
15
|
+
"version": "0.0.40",
|
|
16
16
|
"category": "diagram",
|
|
17
17
|
"keywords": [
|
|
18
18
|
"diagram",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"name": "html-effectiveness",
|
|
27
27
|
"source": "./plugins/html-effectiveness",
|
|
28
28
|
"description": "Generate self-contained interactive HTML reports from 20 upstream templates via a conversational agent.",
|
|
29
|
-
"version": "0.0.
|
|
29
|
+
"version": "0.0.40",
|
|
30
30
|
"category": "reports",
|
|
31
31
|
"keywords": [
|
|
32
32
|
"html",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"name": "plugin-validator",
|
|
42
42
|
"source": "./plugins/plugin-validator",
|
|
43
43
|
"description": "Orchestrated validator for Claude Code plugins — validates skills, agents, commands, and hooks across every plugin under plugins/**.",
|
|
44
|
-
"version": "0.0.
|
|
44
|
+
"version": "0.0.40",
|
|
45
45
|
"category": "tooling",
|
|
46
46
|
"keywords": [
|
|
47
47
|
"validation",
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
"name": "team-share",
|
|
58
58
|
"source": "./plugins/team-share",
|
|
59
59
|
"description": "Onboard your team with an interactive setup menu: install CodeGraph, build the Understand-Anything knowledge graph, and share Claude Code settings — run any combination, all idempotent.",
|
|
60
|
-
"version": "0.0.
|
|
60
|
+
"version": "0.0.40",
|
|
61
61
|
"category": "tooling",
|
|
62
62
|
"keywords": [
|
|
63
63
|
"onboarding",
|
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
"name": "multica-tool",
|
|
74
74
|
"source": "./plugins/multica-tool",
|
|
75
75
|
"description": "Export, import, and sync Multica skills, agents, and squads between workspaces.",
|
|
76
|
-
"version": "0.0.
|
|
76
|
+
"version": "0.0.40",
|
|
77
77
|
"category": "workflow",
|
|
78
78
|
"keywords": [
|
|
79
79
|
"multica",
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "html-effectiveness",
|
|
3
3
|
"displayName": "HTML Effectiveness Reports",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.40",
|
|
5
5
|
"description": "Generate self-contained interactive HTML reports from 20 upstream templates via a conversational agent.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Steven Hoang"
|
|
@@ -31,7 +31,7 @@ export function redactAgent(a) {
|
|
|
31
31
|
// a is a normalized agent from getAgent, with `custom_env`/
|
|
32
32
|
// `custom_env_fetch_failed` attached by the caller (collectAgent) — getAgent
|
|
33
33
|
// itself never fetches custom_env, since it requires a separate audited call.
|
|
34
|
-
const { id, has_custom_env, mcp_config_redacted, custom_env_fetch_failed, mcp_config, custom_env, skills, runtime_id, ...rest } = a;
|
|
34
|
+
const { id, has_custom_env, mcp_config_redacted, custom_env_fetch_failed, mcp_config, custom_env, skills, runtime_id, instructions, ...rest } = a;
|
|
35
35
|
const mcpUsable = !mcp_config_redacted && nonEmpty(mcp_config);
|
|
36
36
|
const envUsable = !custom_env_fetch_failed && nonEmpty(custom_env);
|
|
37
37
|
// mcp_config_redacted / custom_env_fetch_failed alone still flag hadSecrets even
|
|
@@ -39,10 +39,10 @@ export function redactAgent(a) {
|
|
|
39
39
|
// but couldn't be captured, not just silently see an empty bundle.
|
|
40
40
|
const hadSecrets = mcpUsable || envUsable || !!mcp_config_redacted || !!custom_env_fetch_failed;
|
|
41
41
|
return {
|
|
42
|
-
// source_id lets import-time mention rewriting map stale `mention://agent/<id>`
|
|
43
|
-
// links (in this or another agent's/squad's instructions) to the new id.
|
|
44
42
|
record: {
|
|
45
43
|
...rest,
|
|
44
|
+
// source_id lets import-time mention rewriting map stale `mention://agent/<id>`
|
|
45
|
+
// links (in this or another agent's/squad's instructions) to the new id.
|
|
46
46
|
source_id: id,
|
|
47
47
|
source_runtime_id: runtime_id,
|
|
48
48
|
skill_names: [],
|
|
@@ -51,6 +51,9 @@ export function redactAgent(a) {
|
|
|
51
51
|
had_secrets: hadSecrets,
|
|
52
52
|
},
|
|
53
53
|
hadSecrets,
|
|
54
|
+
// instructions are written to a sibling .md by the caller (see avatar_file),
|
|
55
|
+
// never embedded in the JSON record.
|
|
56
|
+
instructions: instructions ?? "",
|
|
54
57
|
};
|
|
55
58
|
}
|
|
56
59
|
|
|
@@ -65,7 +68,13 @@ export function buildManifest({ scope, sourceWorkspaceId, skills, agents, squads
|
|
|
65
68
|
source_workspace_id: sourceWorkspaceId,
|
|
66
69
|
skills: [...seenSkills.values()].map((s) => ({ name: s.name, dir: `skills/${slugify(s.name)}`, source_id: s.source_id })),
|
|
67
70
|
agents: [...seenAgents.values()].map((a) => ({ name: a.name, file: `agents/${slugify(a.name)}.json`, source_id: a.source_id, source_runtime_id: a.source_runtime_id, source_runtime_provider: a.source_runtime_provider ?? null, skill_names: a.skill_names, had_secrets: !!a.had_secrets })),
|
|
68
|
-
squads: (squads ?? []).map((squad) =>
|
|
71
|
+
squads: (squads ?? []).map((squad) => {
|
|
72
|
+
const file = `squads/${slugify(squad.name)}.json`;
|
|
73
|
+
const entry = { name: squad.name, file, description: squad.description ?? "", avatar_url: squad.avatar_url ?? null, leader_name: squad.leader_name, members: squad.members };
|
|
74
|
+
// Instructions go to a sibling .md (see squad write loop); only referenced when non-empty.
|
|
75
|
+
if (squad.instructions) entry.instructions_file = file.replace(/\.json$/, ".md");
|
|
76
|
+
return entry;
|
|
77
|
+
}),
|
|
69
78
|
};
|
|
70
79
|
}
|
|
71
80
|
|
|
@@ -170,10 +179,21 @@ export function exportResource({ cli, scope, ids, outDir, sourceWorkspaceId, fs
|
|
|
170
179
|
record.avatar_file = rel;
|
|
171
180
|
}
|
|
172
181
|
}
|
|
182
|
+
// Instructions live in a sibling .md for reviewability (same sibling-file
|
|
183
|
+
// pattern as avatar_file); only written when non-empty.
|
|
184
|
+
if (red.instructions) {
|
|
185
|
+
const rel = entry.file.replace(/\.json$/, ".md");
|
|
186
|
+
fs.writeFileSync(`${outDir}/${rel}`, red.instructions);
|
|
187
|
+
record.instructions_file = rel;
|
|
188
|
+
}
|
|
173
189
|
fs.writeFileSync(`${outDir}/${entry.file}`, JSON.stringify(record, null, 2));
|
|
174
190
|
}
|
|
191
|
+
const squadInstrByName = new Map(squads.map((s) => [s.name, s.instructions ?? ""]));
|
|
175
192
|
for (const entry of manifest.squads) {
|
|
176
193
|
fs.mkdirSync(`${outDir}/squads`, { recursive: true });
|
|
194
|
+
if (entry.instructions_file) {
|
|
195
|
+
fs.writeFileSync(`${outDir}/${entry.instructions_file}`, squadInstrByName.get(entry.name) ?? "");
|
|
196
|
+
}
|
|
177
197
|
fs.writeFileSync(`${outDir}/${entry.file}`, JSON.stringify(entry, null, 2));
|
|
178
198
|
}
|
|
179
199
|
fs.writeFileSync(`${outDir}/manifest.json`, JSON.stringify(manifest, null, 2));
|
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
import * as nodeFs from "node:fs";
|
|
2
2
|
import { listSkills, listAgents, listSquads, listRuntimes, listWorkspaceMembers, getSquadMembers, findByName, makeCli, realExec, requireAuth, resolveWorkspaceId } from "./lib.mjs";
|
|
3
3
|
|
|
4
|
+
// Instructions live in a sibling .md referenced by `instructions_file` (mirrors
|
|
5
|
+
// avatar_file). Legacy bundles carry no instructions_file and keep instructions
|
|
6
|
+
// inline in the JSON — fall back to that so older exports still import.
|
|
7
|
+
function readInstructions(fs, dir, rec) {
|
|
8
|
+
if (rec.instructions_file && fs.existsSync(`${dir}/${rec.instructions_file}`)) {
|
|
9
|
+
return fs.readFileSync(`${dir}/${rec.instructions_file}`, "utf8");
|
|
10
|
+
}
|
|
11
|
+
return rec.instructions ?? "";
|
|
12
|
+
}
|
|
13
|
+
|
|
4
14
|
// Relative paths of every file under root (recursing into subdirs like scripts/).
|
|
5
15
|
function walkSkillFiles(fs, root, rel = "") {
|
|
6
16
|
const out = [];
|
|
@@ -82,7 +92,8 @@ export function importAgents({ cli, manifest, dir, skillIdMap, runtimeMap, fs =
|
|
|
82
92
|
"--max-concurrent-tasks", String(rec.max_concurrent_tasks ?? 6),
|
|
83
93
|
];
|
|
84
94
|
if (rec.description) common.push("--description", rec.description);
|
|
85
|
-
|
|
95
|
+
const instructions = readInstructions(fs, dir, rec);
|
|
96
|
+
if (instructions) common.push("--instructions", instructions);
|
|
86
97
|
if (rec.model) common.push("--model", rec.model);
|
|
87
98
|
if (rec.thinking_level) common.push("--thinking-level", rec.thinking_level);
|
|
88
99
|
if (rec.runtime_config && Object.keys(rec.runtime_config).length) common.push("--runtime-config", JSON.stringify(rec.runtime_config));
|
|
@@ -184,9 +195,10 @@ export function rewriteAgentMentions({ cli, manifest, dir, agentIdMap, sourceIdM
|
|
|
184
195
|
let updated = 0;
|
|
185
196
|
for (const a of manifest.agents) {
|
|
186
197
|
const rec = JSON.parse(fs.readFileSync(`${dir}/${a.file}`, "utf8"));
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
198
|
+
const instructions = readInstructions(fs, dir, rec);
|
|
199
|
+
if (!instructions) continue;
|
|
200
|
+
const rewritten = rewriteMentions(instructions, sourceIdMap);
|
|
201
|
+
if (rewritten === instructions) continue;
|
|
190
202
|
cli.run(["agent", "update", agentIdMap.get(rec.name), "--instructions", rewritten]);
|
|
191
203
|
updated++;
|
|
192
204
|
}
|
|
@@ -280,6 +292,7 @@ export function importBundle({ cli, dir, runtimeMap, fs = nodeFs }) {
|
|
|
280
292
|
const squadIdMap = new Map();
|
|
281
293
|
let squadsCreated = 0, squadsUpdated = 0;
|
|
282
294
|
for (const squad of manifest.squads ?? []) {
|
|
295
|
+
squad.instructions = readInstructions(fs, dir, squad);
|
|
283
296
|
const r = importSquad({ cli, squad, agentIdMap: agentRes.idMap, sourceIdMap: agentRes.sourceIdMap });
|
|
284
297
|
squadIdMap.set(squad.name, r.newId);
|
|
285
298
|
squadsCreated += r.created;
|
|
@@ -52,7 +52,7 @@ node "${CLAUDE_PLUGIN_ROOT}/scripts/multica-export.mjs" \
|
|
|
52
52
|
|
|
53
53
|
Pass `--scope all` (with no `--id`) to export the **entire workspace** — every skill, agent, and squad — into one flat, deduped bundle. A skill or agent shared across many agents/squads is written exactly once and referenced by name.
|
|
54
54
|
|
|
55
|
-
The script writes `manifest.json`, skill SKILL.md files, agent JSON files, and squad JSON files into `<dir>`.
|
|
55
|
+
The script writes `manifest.json`, skill `SKILL.md` files, agent JSON files, and squad JSON files into `<dir>`. Each agent's and squad's **instructions** (system prompt / charter) are written to a sibling Markdown file — `agents/<slug>.md`, `squads/<slug>.md` — referenced by an `instructions_file` key in the JSON, so the prose is easy to read, diff, and edit. Agents/squads with no instructions get no `.md`.
|
|
56
56
|
|
|
57
57
|
Avatars are captured automatically: an agent's uploaded-image avatar is downloaded into the bundle (`agents/<slug>.avatar.<ext>`) and referenced by `avatar_file`; emoji avatars (agents and squads) and a squad's avatar are recorded as the `avatar_url` string.
|
|
58
58
|
|
|
@@ -40,6 +40,8 @@ node "${CLAUDE_PLUGIN_ROOT}/scripts/multica-import.mjs" \
|
|
|
40
40
|
|
|
41
41
|
The import also rewrites any `mention://agent/<id>` link inside squad and agent instructions (e.g. `[@dev-backend](mention://agent/<id>)`) from the source agent's id to its new id in the target workspace — the CLI does this automatically for every agent captured in the bundle; no extra flag needed. Mentions pointing to an agent outside the bundle are left untouched.
|
|
42
42
|
|
|
43
|
+
Instructions are read back from each resource's sibling `.md` (`agents/<slug>.md`, `squads/<slug>.md`) when present — editing that Markdown is the supported way to review and enhance an agent's or squad's instructions before import. Older bundles that predate the split (instructions inline in the JSON, no `instructions_file`) still import unchanged.
|
|
44
|
+
|
|
43
45
|
Avatars are restored automatically, but **only when the target resource has none** — an existing agent or squad that already carries an avatar is never overwritten. New agents get their bundled image re-uploaded; new squads get their `avatar_url` (emoji or URL) set. An agent whose source avatar was an emoji can't be restored (the CLI has no emoji setter for agents) and is reported as unsupported.
|
|
44
46
|
|
|
45
47
|
## Step 3 — Report results
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "plugin-validator",
|
|
3
3
|
"displayName": "Plugin Validator",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.40",
|
|
5
5
|
"description": "Orchestrated validator for Claude Code plugins — validates skills, agents, commands, and hooks across every plugin under plugins/**.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Steven Hoang"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "team-share",
|
|
3
3
|
"displayName": "Team Share",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.40",
|
|
5
5
|
"description": "Onboard your team with an interactive setup menu: install CodeGraph, build the Understand-Anything knowledge graph, and share Claude Code settings — run any combination, all idempotent.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Steven Hoang"
|