@drunkcoding/agents-and-skills 0.0.34 → 0.0.35
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 +12 -7
- package/plugins/multica-tool/scripts/multica-import.mjs +41 -4
- package/plugins/multica-tool/skills/import/SKILL.md +10 -11
- package/plugins/multica-tool/skills/sync/SKILL.md +11 -8
- 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.35",
|
|
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.35",
|
|
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.35",
|
|
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.35",
|
|
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.35",
|
|
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.35",
|
|
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"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as nodeFs from "node:fs";
|
|
2
2
|
import { dirname } from "node:path";
|
|
3
|
-
import { slugify, getSkill, getAgent, getSquad, getSquadMembers, makeCli, realExec, requireAuth, resolveWorkspaceId } from "./lib.mjs";
|
|
3
|
+
import { slugify, getSkill, getAgent, getSquad, getSquadMembers, listRuntimes, makeCli, realExec, requireAuth, resolveWorkspaceId } from "./lib.mjs";
|
|
4
4
|
|
|
5
5
|
const nonEmpty = (v) => v && typeof v === "object" && Object.keys(v).length > 0;
|
|
6
6
|
|
|
@@ -24,7 +24,7 @@ export function buildManifest({ scope, sourceWorkspaceId, skills, agents, squad
|
|
|
24
24
|
scope,
|
|
25
25
|
sourceWorkspaceId,
|
|
26
26
|
skills: [...seenSkills.values()].map((s) => ({ name: s.name, dir: `skills/${slugify(s.name)}`, sourceId: s.sourceId })),
|
|
27
|
-
agents: [...seenAgents.values()].map((a) => ({ name: a.name, file: `agents/${slugify(a.name)}.json`, sourceRuntimeId: a.sourceRuntimeId, skillNames: a.skillNames, hadSecrets: !!a.hadSecrets })),
|
|
27
|
+
agents: [...seenAgents.values()].map((a) => ({ name: a.name, file: `agents/${slugify(a.name)}.json`, sourceRuntimeId: a.sourceRuntimeId, sourceRuntimeProvider: a.sourceRuntimeProvider ?? null, skillNames: a.skillNames, hadSecrets: !!a.hadSecrets })),
|
|
28
28
|
squads: squad ? [{ name: squad.name, file: `squads/${slugify(squad.name)}.json`, description: squad.description ?? "", instructions: squad.instructions ?? "", leaderName: squad.leaderName, members: squad.members }] : [],
|
|
29
29
|
};
|
|
30
30
|
}
|
|
@@ -37,9 +37,10 @@ function collectSkill(cli, id, skills) {
|
|
|
37
37
|
|
|
38
38
|
// Keyed by agent id (so squad leaderId/memberId resolve to names). Stores the
|
|
39
39
|
// normalized agent, its redaction result, and its skill names.
|
|
40
|
-
function collectAgent(cli, id, agentsById, skills) {
|
|
40
|
+
function collectAgent(cli, id, agentsById, skills, providerById) {
|
|
41
41
|
if (agentsById.has(id)) return agentsById.get(id);
|
|
42
42
|
const a = getAgent(cli, id);
|
|
43
|
+
a.sourceRuntimeProvider = providerById.get(a.runtimeId) ?? null;
|
|
43
44
|
const skillNames = a.skills.map((sk) => collectSkill(cli, sk.id, skills));
|
|
44
45
|
const red = redactAgent(a);
|
|
45
46
|
const entry = { raw: a, red, skillNames };
|
|
@@ -51,14 +52,18 @@ export function exportResource({ cli, scope, ids, outDir, sourceWorkspaceId, fs
|
|
|
51
52
|
const skills = new Map(); // name -> normalized skill
|
|
52
53
|
const agentsById = new Map(); // id -> { raw, red, skillNames }
|
|
53
54
|
let squad = null;
|
|
55
|
+
// Lazy + memoized: only fetched when an agent is actually collected (skips
|
|
56
|
+
// the extra CLI call on skill-only exports).
|
|
57
|
+
let providerById = null;
|
|
58
|
+
const getProviderById = () => providerById ??= new Map(listRuntimes(cli).map((r) => [r.id, r.provider]));
|
|
54
59
|
|
|
55
60
|
if (scope === "skill") collectSkill(cli, ids.skillId, skills);
|
|
56
|
-
if (scope === "agent") collectAgent(cli, ids.agentId, agentsById, skills);
|
|
61
|
+
if (scope === "agent") collectAgent(cli, ids.agentId, agentsById, skills, getProviderById());
|
|
57
62
|
if (scope === "squad") {
|
|
58
63
|
const sq = getSquad(cli, ids.squadId);
|
|
59
64
|
const members = getSquadMembers(cli, ids.squadId).filter((m) => m.memberType === "agent");
|
|
60
|
-
for (const m of members) collectAgent(cli, m.memberId, agentsById, skills);
|
|
61
|
-
if (!agentsById.has(sq.leaderId)) collectAgent(cli, sq.leaderId, agentsById, skills);
|
|
65
|
+
for (const m of members) collectAgent(cli, m.memberId, agentsById, skills, getProviderById());
|
|
66
|
+
if (!agentsById.has(sq.leaderId)) collectAgent(cli, sq.leaderId, agentsById, skills, getProviderById());
|
|
62
67
|
const nameOf = (id) => agentsById.get(id)?.raw.name;
|
|
63
68
|
squad = {
|
|
64
69
|
name: sq.name,
|
|
@@ -72,7 +77,7 @@ export function exportResource({ cli, scope, ids, outDir, sourceWorkspaceId, fs
|
|
|
72
77
|
const manifest = buildManifest({
|
|
73
78
|
scope, sourceWorkspaceId,
|
|
74
79
|
skills: [...skills.values()].map((s) => ({ name: s.name, sourceId: s.id })),
|
|
75
|
-
agents: [...agentsById.values()].map((a) => ({ name: a.raw.name, sourceRuntimeId: a.raw.runtimeId, skillNames: a.skillNames, hadSecrets: a.red.hadSecrets })),
|
|
80
|
+
agents: [...agentsById.values()].map((a) => ({ name: a.raw.name, sourceRuntimeId: a.raw.runtimeId, sourceRuntimeProvider: a.raw.sourceRuntimeProvider, skillNames: a.skillNames, hadSecrets: a.red.hadSecrets })),
|
|
76
81
|
squad,
|
|
77
82
|
});
|
|
78
83
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as nodeFs from "node:fs";
|
|
2
|
-
import { listSkills, listAgents, listSquads, getSquadMembers, findByName, makeCli, realExec, requireAuth, resolveWorkspaceId } from "./lib.mjs";
|
|
2
|
+
import { listSkills, listAgents, listSquads, listRuntimes, getSquadMembers, findByName, makeCli, realExec, requireAuth, resolveWorkspaceId } from "./lib.mjs";
|
|
3
3
|
|
|
4
4
|
// Relative paths of every file under root (recursing into subdirs like scripts/).
|
|
5
5
|
function walkSkillFiles(fs, root, rel = "") {
|
|
@@ -118,13 +118,50 @@ export function collectSourceRuntimes(manifest) {
|
|
|
118
118
|
return [...new Set((manifest.agents ?? []).map((a) => a.sourceRuntimeId).filter(Boolean))];
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
+
// sourceRuntimeId -> provider (e.g. "claude", "opencode"), from whichever agent recorded it.
|
|
122
|
+
function collectRuntimeProviders(manifest) {
|
|
123
|
+
const map = new Map();
|
|
124
|
+
for (const a of manifest.agents ?? []) {
|
|
125
|
+
if (a.sourceRuntimeId && a.sourceRuntimeProvider && !map.has(a.sourceRuntimeId)) {
|
|
126
|
+
map.set(a.sourceRuntimeId, a.sourceRuntimeProvider);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return map;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Starts from the explicit --runtime-map (always wins), then auto-resolves any
|
|
133
|
+
// remaining source runtime by provider — only when exactly one destination
|
|
134
|
+
// runtime shares that provider. Ambiguous (0 or 2+ matches) stays unresolved.
|
|
135
|
+
export function resolveRuntimeMap({ cli, manifest, runtimeMap }) {
|
|
136
|
+
const effective = new Map(runtimeMap);
|
|
137
|
+
const missing = collectSourceRuntimes(manifest).filter((r) => !effective.has(r));
|
|
138
|
+
if (!missing.length) return { effective, unresolved: [] };
|
|
139
|
+
|
|
140
|
+
const providers = collectRuntimeProviders(manifest);
|
|
141
|
+
const resolvable = missing.filter((r) => providers.has(r));
|
|
142
|
+
const destRuntimes = resolvable.length ? listRuntimes(cli) : [];
|
|
143
|
+
const unresolved = [];
|
|
144
|
+
for (const srcId of missing) {
|
|
145
|
+
const provider = providers.get(srcId);
|
|
146
|
+
const matches = provider ? destRuntimes.filter((r) => r.provider === provider) : [];
|
|
147
|
+
if (matches.length === 1) effective.set(srcId, matches[0].id);
|
|
148
|
+
else unresolved.push({ srcId, provider, matchCount: matches.length });
|
|
149
|
+
}
|
|
150
|
+
return { effective, unresolved };
|
|
151
|
+
}
|
|
152
|
+
|
|
121
153
|
export function importBundle({ cli, dir, runtimeMap, fs = nodeFs }) {
|
|
122
154
|
const manifest = JSON.parse(fs.readFileSync(`${dir}/manifest.json`, "utf8"));
|
|
123
|
-
const
|
|
124
|
-
if (
|
|
155
|
+
const { effective, unresolved } = resolveRuntimeMap({ cli, manifest, runtimeMap });
|
|
156
|
+
if (unresolved.length) {
|
|
157
|
+
const detail = unresolved.map(({ srcId, provider, matchCount }) => provider
|
|
158
|
+
? `${srcId} (provider "${provider}": ${matchCount} matching runtimes in destination, expected exactly 1)`
|
|
159
|
+
: `${srcId} (no provider recorded)`).join(", ");
|
|
160
|
+
throw new Error(`Unmapped runtimes: ${detail} — pass --runtime-map, aborting before any write`);
|
|
161
|
+
}
|
|
125
162
|
|
|
126
163
|
const skillRes = importSkills({ cli, manifest, dir, fs });
|
|
127
|
-
const agentRes = importAgents({ cli, manifest, dir, skillIdMap: skillRes.idMap, runtimeMap, fs });
|
|
164
|
+
const agentRes = importAgents({ cli, manifest, dir, skillIdMap: skillRes.idMap, runtimeMap: effective, fs });
|
|
128
165
|
let squadRes = { newId: null, created: 0, updated: 0 };
|
|
129
166
|
if (manifest.squads?.length) squadRes = importSquad({ cli, squad: manifest.squads[0], agentIdMap: agentRes.idMap });
|
|
130
167
|
|
|
@@ -12,25 +12,24 @@ Import a local Multica bundle (produced by the export skill) into a target works
|
|
|
12
12
|
|
|
13
13
|
Ask the user to confirm the name of the target workspace if not already stated. You will need the exact workspace name as registered in Multica.
|
|
14
14
|
|
|
15
|
-
## Step 2 —
|
|
15
|
+
## Step 2 — Run the import (auto-mapping first)
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
Each exported agent record carries its source runtime's `provider` (e.g. `claude`, `opencode`) alongside its ID. The import script auto-maps a source runtime to the target workspace's runtime when there is **exactly one** runtime of that provider there — no manual mapping needed in the common case. Try the import without `--runtime-map` first:
|
|
18
18
|
|
|
19
19
|
```bash
|
|
20
|
-
|
|
20
|
+
node "${CLAUDE_PLUGIN_ROOT}/scripts/multica-import.mjs" \
|
|
21
|
+
--dir <folder> \
|
|
22
|
+
--workspace <workspace-name>
|
|
21
23
|
```
|
|
22
24
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
List runtimes available in the target workspace:
|
|
25
|
+
If it aborts with `Unmapped runtimes: ...` (0 or 2+ runtimes share that provider in the target workspace, or the bundle predates provider capture), resolve manually:
|
|
26
26
|
|
|
27
27
|
```bash
|
|
28
|
-
|
|
28
|
+
cat <folder>/manifest.json # note each distinct sourceRuntimeId
|
|
29
|
+
multica runtime list --output json # list target workspace runtimes
|
|
29
30
|
```
|
|
30
31
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
## Step 3 — Run the import
|
|
32
|
+
Ask the user to pick a matching target runtime by name or ID for each unmapped `sourceRuntimeId`, then re-run with an explicit map (explicit entries always take precedence over auto-mapping):
|
|
34
33
|
|
|
35
34
|
```bash
|
|
36
35
|
node "${CLAUDE_PLUGIN_ROOT}/scripts/multica-import.mjs" \
|
|
@@ -39,7 +38,7 @@ node "${CLAUDE_PLUGIN_ROOT}/scripts/multica-import.mjs" \
|
|
|
39
38
|
--runtime-map <srcId1=dstId1,srcId2=dstId2,...>
|
|
40
39
|
```
|
|
41
40
|
|
|
42
|
-
## Step
|
|
41
|
+
## Step 3 — Report results
|
|
43
42
|
|
|
44
43
|
Parse the JSON output and report:
|
|
45
44
|
|
|
@@ -18,29 +18,32 @@ sync <type> <name> from <src-ws> to <dest-ws>
|
|
|
18
18
|
|
|
19
19
|
Where `<type>` is `skill`, `agent`, or `squad`; `<name>` is the resource name; `<src-ws>` and `<dest-ws>` are workspace names registered in Multica.
|
|
20
20
|
|
|
21
|
-
## Step 2 —
|
|
21
|
+
## Step 2 — Run the sync (auto-mapping first)
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
For agents and squads, each exported agent record carries its source runtime's `provider` (e.g. `claude`, `opencode`) alongside its ID. The sync script auto-maps a source runtime to the destination workspace's runtime when there is **exactly one** runtime of that provider there — no manual mapping needed in the common case. For skills (which have no runtime dependency), an empty runtime map is always acceptable. Try the sync without `--runtime-map` first:
|
|
24
24
|
|
|
25
25
|
```bash
|
|
26
|
-
multica
|
|
26
|
+
node "${CLAUDE_PLUGIN_ROOT}/scripts/multica-sync.mjs" \
|
|
27
|
+
<type> <name> from <src-ws> <dest-ws>
|
|
27
28
|
```
|
|
28
29
|
|
|
29
|
-
|
|
30
|
+
If it aborts with `Unmapped runtimes: ...` (0 or 2+ runtimes share that provider in the destination workspace), resolve manually:
|
|
30
31
|
|
|
31
|
-
|
|
32
|
+
```bash
|
|
33
|
+
multica runtime list --workspace-id <dest-ws-id> --output json # list destination workspace runtimes
|
|
34
|
+
```
|
|
32
35
|
|
|
33
|
-
|
|
36
|
+
Ask the user to select a matching target runtime by name or ID for each unmapped `sourceRuntimeId`, then re-run with an explicit map (explicit entries always take precedence over auto-mapping):
|
|
34
37
|
|
|
35
38
|
```bash
|
|
36
39
|
node "${CLAUDE_PLUGIN_ROOT}/scripts/multica-sync.mjs" \
|
|
37
40
|
<type> <name> from <src-ws> <dest-ws> \
|
|
38
|
-
|
|
41
|
+
--runtime-map <srcId1=dstId1,srcId2=dstId2,...>
|
|
39
42
|
```
|
|
40
43
|
|
|
41
44
|
The script exports to a temporary directory, imports into the destination workspace, then cleans up the temporary files automatically.
|
|
42
45
|
|
|
43
|
-
## Step
|
|
46
|
+
## Step 3 — Report results
|
|
44
47
|
|
|
45
48
|
Parse the JSON output and report:
|
|
46
49
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "plugin-validator",
|
|
3
3
|
"displayName": "Plugin Validator",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.35",
|
|
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.35",
|
|
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"
|