@drunkcoding/agents-and-skills 0.0.37 → 0.0.38
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/lib.mjs +13 -12
- package/plugins/multica-tool/scripts/multica-export.mjs +37 -37
- package/plugins/multica-tool/scripts/multica-import.mjs +21 -21
- package/plugins/multica-tool/skills/import/SKILL.md +2 -2
- package/plugins/multica-tool/skills/sync/SKILL.md +1 -1
- 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.38",
|
|
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.38",
|
|
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.38",
|
|
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.38",
|
|
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.38",
|
|
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.38",
|
|
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"
|
|
@@ -55,8 +55,9 @@ export const listSkills = (cli) => cli.json(["skill", "list"]);
|
|
|
55
55
|
export const listAgents = (cli) => cli.json(["agent", "list"]);
|
|
56
56
|
export const listSquads = (cli) => cli.json(["squad", "list"]);
|
|
57
57
|
|
|
58
|
-
// Get-wrappers: the ONLY place that knows the raw CLI field names
|
|
59
|
-
//
|
|
58
|
+
// Get-wrappers: the ONLY place that knows the raw CLI field names — an
|
|
59
|
+
// explicit allow-list, so unexpected/internal CLI fields never leak into a
|
|
60
|
+
// bundle. Field names mirror the CLI's own snake_case; nothing is renamed.
|
|
60
61
|
export function getSkill(cli, id) {
|
|
61
62
|
const s = cli.json(["skill", "get", id]);
|
|
62
63
|
return {
|
|
@@ -71,14 +72,14 @@ export function getAgent(cli, id) {
|
|
|
71
72
|
return {
|
|
72
73
|
id: a.id, name: a.name, description: a.description, instructions: a.instructions,
|
|
73
74
|
model: a.model, visibility: a.visibility,
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
75
|
+
max_concurrent_tasks: a.max_concurrent_tasks,
|
|
76
|
+
runtime_config: a.runtime_config,
|
|
77
|
+
custom_args: a.custom_args,
|
|
78
|
+
thinking_level: a.thinking_level,
|
|
79
|
+
runtime_id: a.runtime_id,
|
|
80
|
+
has_custom_env: a.has_custom_env,
|
|
81
|
+
mcp_config: a.mcp_config,
|
|
82
|
+
mcp_config_redacted: !!a.mcp_config_redacted,
|
|
82
83
|
skills: (a.skills ?? []).map((sk) => ({ id: sk.id, name: sk.name })),
|
|
83
84
|
};
|
|
84
85
|
}
|
|
@@ -92,10 +93,10 @@ export function getAgentCustomEnv(cli, id) {
|
|
|
92
93
|
|
|
93
94
|
export function getSquad(cli, id) {
|
|
94
95
|
const s = cli.json(["squad", "get", id]);
|
|
95
|
-
return { id: s.id, name: s.name, description: s.description, instructions: s.instructions,
|
|
96
|
+
return { id: s.id, name: s.name, description: s.description, instructions: s.instructions, leader_id: s.leader_id };
|
|
96
97
|
}
|
|
97
98
|
|
|
98
99
|
export const getSquadMembers = (cli, id) =>
|
|
99
100
|
(cli.json(["squad", "member", "list", id]) ?? []).map((m) => ({
|
|
100
|
-
|
|
101
|
+
member_id: m.member_id, member_type: m.member_type, role: m.role || "member",
|
|
101
102
|
}));
|
|
@@ -5,27 +5,27 @@ import { slugify, getSkill, getAgent, getAgentCustomEnv, getSquad, getSquadMembe
|
|
|
5
5
|
const nonEmpty = (v) => v && typeof v === "object" && Object.keys(v).length > 0;
|
|
6
6
|
|
|
7
7
|
export function redactAgent(a) {
|
|
8
|
-
// a is a normalized
|
|
9
|
-
// `
|
|
8
|
+
// a is a normalized agent from getAgent, with `custom_env`/
|
|
9
|
+
// `custom_env_fetch_failed` attached by the caller (collectAgent) — getAgent
|
|
10
10
|
// itself never fetches custom_env, since it requires a separate audited call.
|
|
11
|
-
const { id,
|
|
12
|
-
const mcpUsable = !
|
|
13
|
-
const envUsable = !
|
|
14
|
-
//
|
|
11
|
+
const { id, has_custom_env, mcp_config_redacted, custom_env_fetch_failed, mcp_config, custom_env, skills, runtime_id, ...rest } = a;
|
|
12
|
+
const mcpUsable = !mcp_config_redacted && nonEmpty(mcp_config);
|
|
13
|
+
const envUsable = !custom_env_fetch_failed && nonEmpty(custom_env);
|
|
14
|
+
// mcp_config_redacted / custom_env_fetch_failed alone still flag hadSecrets even
|
|
15
15
|
// when unusable — the user should know something was present at the source
|
|
16
16
|
// but couldn't be captured, not just silently see an empty bundle.
|
|
17
|
-
const hadSecrets = mcpUsable || envUsable || !!
|
|
17
|
+
const hadSecrets = mcpUsable || envUsable || !!mcp_config_redacted || !!custom_env_fetch_failed;
|
|
18
18
|
return {
|
|
19
|
-
//
|
|
19
|
+
// source_id lets import-time mention rewriting map stale `mention://agent/<id>`
|
|
20
20
|
// links (in this or another agent's/squad's instructions) to the new id.
|
|
21
21
|
record: {
|
|
22
22
|
...rest,
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
hadSecrets,
|
|
23
|
+
source_id: id,
|
|
24
|
+
source_runtime_id: runtime_id,
|
|
25
|
+
skill_names: [],
|
|
26
|
+
mcp_config: mcpUsable ? mcp_config : null,
|
|
27
|
+
custom_env: envUsable ? custom_env : null,
|
|
28
|
+
had_secrets: hadSecrets,
|
|
29
29
|
},
|
|
30
30
|
hadSecrets,
|
|
31
31
|
};
|
|
@@ -39,10 +39,10 @@ export function buildManifest({ scope, sourceWorkspaceId, skills, agents, squad
|
|
|
39
39
|
return {
|
|
40
40
|
version: "1",
|
|
41
41
|
scope,
|
|
42
|
-
sourceWorkspaceId,
|
|
43
|
-
skills: [...seenSkills.values()].map((s) => ({ name: s.name, dir: `skills/${slugify(s.name)}`,
|
|
44
|
-
agents: [...seenAgents.values()].map((a) => ({ name: a.name, file: `agents/${slugify(a.name)}.json`,
|
|
45
|
-
squads: squad ? [{ name: squad.name, file: `squads/${slugify(squad.name)}.json`, description: squad.description ?? "", instructions: squad.instructions ?? "",
|
|
42
|
+
source_workspace_id: sourceWorkspaceId,
|
|
43
|
+
skills: [...seenSkills.values()].map((s) => ({ name: s.name, dir: `skills/${slugify(s.name)}`, source_id: s.source_id })),
|
|
44
|
+
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 })),
|
|
45
|
+
squads: squad ? [{ name: squad.name, file: `squads/${slugify(squad.name)}.json`, description: squad.description ?? "", instructions: squad.instructions ?? "", leader_name: squad.leader_name, members: squad.members }] : [],
|
|
46
46
|
};
|
|
47
47
|
}
|
|
48
48
|
|
|
@@ -52,31 +52,31 @@ function collectSkill(cli, id, skills) {
|
|
|
52
52
|
return s.name;
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
// Keyed by agent id (so squad
|
|
55
|
+
// Keyed by agent id (so squad leader_id/member_id resolve to names). Stores the
|
|
56
56
|
// normalized agent, its redaction result, and its skill names.
|
|
57
57
|
function collectAgent(cli, id, agentsById, skills, providerById) {
|
|
58
58
|
if (agentsById.has(id)) return agentsById.get(id);
|
|
59
59
|
const a = getAgent(cli, id);
|
|
60
|
-
a.
|
|
61
|
-
a.
|
|
62
|
-
a.
|
|
63
|
-
if (a.
|
|
60
|
+
a.source_runtime_provider = providerById.get(a.runtime_id) ?? null;
|
|
61
|
+
a.custom_env = {};
|
|
62
|
+
a.custom_env_fetch_failed = false;
|
|
63
|
+
if (a.has_custom_env) {
|
|
64
64
|
try {
|
|
65
|
-
a.
|
|
65
|
+
a.custom_env = getAgentCustomEnv(cli, id);
|
|
66
66
|
} catch {
|
|
67
|
-
a.
|
|
67
|
+
a.custom_env_fetch_failed = true; // e.g. insufficient permission — non-fatal, warned via hadSecrets
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
|
-
const
|
|
70
|
+
const skill_names = a.skills.map((sk) => collectSkill(cli, sk.id, skills));
|
|
71
71
|
const red = redactAgent(a);
|
|
72
|
-
const entry = { raw: a, red,
|
|
72
|
+
const entry = { raw: a, red, skill_names };
|
|
73
73
|
agentsById.set(id, entry);
|
|
74
74
|
return entry;
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
export function exportResource({ cli, scope, ids, outDir, sourceWorkspaceId, fs = nodeFs }) {
|
|
78
78
|
const skills = new Map(); // name -> normalized skill
|
|
79
|
-
const agentsById = new Map(); // id -> { raw, red,
|
|
79
|
+
const agentsById = new Map(); // id -> { raw, red, skill_names }
|
|
80
80
|
let squad = null;
|
|
81
81
|
// Lazy + memoized: only fetched when an agent is actually collected (skips
|
|
82
82
|
// the extra CLI call on skill-only exports).
|
|
@@ -87,23 +87,23 @@ export function exportResource({ cli, scope, ids, outDir, sourceWorkspaceId, fs
|
|
|
87
87
|
if (scope === "agent") collectAgent(cli, ids.agentId, agentsById, skills, getProviderById());
|
|
88
88
|
if (scope === "squad") {
|
|
89
89
|
const sq = getSquad(cli, ids.squadId);
|
|
90
|
-
const members = getSquadMembers(cli, ids.squadId).filter((m) => m.
|
|
91
|
-
for (const m of members) collectAgent(cli, m.
|
|
92
|
-
if (!agentsById.has(sq.
|
|
90
|
+
const members = getSquadMembers(cli, ids.squadId).filter((m) => m.member_type === "agent");
|
|
91
|
+
for (const m of members) collectAgent(cli, m.member_id, agentsById, skills, getProviderById());
|
|
92
|
+
if (!agentsById.has(sq.leader_id)) collectAgent(cli, sq.leader_id, agentsById, skills, getProviderById());
|
|
93
93
|
const nameOf = (id) => agentsById.get(id)?.raw.name;
|
|
94
94
|
squad = {
|
|
95
95
|
name: sq.name,
|
|
96
96
|
description: sq.description,
|
|
97
97
|
instructions: sq.instructions,
|
|
98
|
-
|
|
99
|
-
members: members.map((m) => ({
|
|
98
|
+
leader_name: nameOf(sq.leader_id),
|
|
99
|
+
members: members.map((m) => ({ agent_name: nameOf(m.member_id), role: m.role })),
|
|
100
100
|
};
|
|
101
101
|
}
|
|
102
102
|
|
|
103
103
|
const manifest = buildManifest({
|
|
104
104
|
scope, sourceWorkspaceId,
|
|
105
|
-
skills: [...skills.values()].map((s) => ({ name: s.name,
|
|
106
|
-
agents: [...agentsById.values()].map((a) => ({ name: a.raw.name,
|
|
105
|
+
skills: [...skills.values()].map((s) => ({ name: s.name, source_id: s.id })),
|
|
106
|
+
agents: [...agentsById.values()].map((a) => ({ name: a.raw.name, source_id: a.raw.id, source_runtime_id: a.raw.runtime_id, source_runtime_provider: a.raw.source_runtime_provider, skill_names: a.skill_names, had_secrets: a.red.hadSecrets })),
|
|
107
107
|
squad,
|
|
108
108
|
});
|
|
109
109
|
|
|
@@ -125,8 +125,8 @@ export function exportResource({ cli, scope, ids, outDir, sourceWorkspaceId, fs
|
|
|
125
125
|
// Index agent entries by name for the manifest writing loop.
|
|
126
126
|
const agentByName = new Map([...agentsById.values()].map((a) => [a.raw.name, a]));
|
|
127
127
|
for (const entry of manifest.agents) {
|
|
128
|
-
const { raw, red,
|
|
129
|
-
const record = { ...red.record,
|
|
128
|
+
const { raw, red, skill_names } = agentByName.get(entry.name);
|
|
129
|
+
const record = { ...red.record, skill_names };
|
|
130
130
|
if (red.hadSecrets) warnings.push(raw.name);
|
|
131
131
|
fs.mkdirSync(`${outDir}/agents`, { recursive: true });
|
|
132
132
|
fs.writeFileSync(`${outDir}/${entry.file}`, JSON.stringify(record, null, 2));
|
|
@@ -64,19 +64,19 @@ export function importAgents({ cli, manifest, dir, skillIdMap, runtimeMap, fs =
|
|
|
64
64
|
|
|
65
65
|
for (const a of manifest.agents) {
|
|
66
66
|
const rec = JSON.parse(fs.readFileSync(`${dir}/${a.file}`, "utf8"));
|
|
67
|
-
const targetRuntime = runtimeMap.get(rec.
|
|
68
|
-
if (!targetRuntime) throw new Error(`Unmapped runtime "${rec.
|
|
67
|
+
const targetRuntime = runtimeMap.get(rec.source_runtime_id);
|
|
68
|
+
if (!targetRuntime) throw new Error(`Unmapped runtime "${rec.source_runtime_id}" for agent "${rec.name}"`);
|
|
69
69
|
// Only pass optional flags when present — `--model ""` would CLEAR the model.
|
|
70
70
|
const common = [
|
|
71
71
|
"--visibility", rec.visibility ?? "private",
|
|
72
|
-
"--max-concurrent-tasks", String(rec.
|
|
72
|
+
"--max-concurrent-tasks", String(rec.max_concurrent_tasks ?? 6),
|
|
73
73
|
];
|
|
74
74
|
if (rec.description) common.push("--description", rec.description);
|
|
75
75
|
if (rec.instructions) common.push("--instructions", rec.instructions);
|
|
76
76
|
if (rec.model) common.push("--model", rec.model);
|
|
77
|
-
if (rec.
|
|
78
|
-
if (rec.
|
|
79
|
-
if (Array.isArray(rec.
|
|
77
|
+
if (rec.thinking_level) common.push("--thinking-level", rec.thinking_level);
|
|
78
|
+
if (rec.runtime_config && Object.keys(rec.runtime_config).length) common.push("--runtime-config", JSON.stringify(rec.runtime_config));
|
|
79
|
+
if (Array.isArray(rec.custom_args) && rec.custom_args.length) common.push("--custom-args", JSON.stringify(rec.custom_args));
|
|
80
80
|
const match = findByName(existing, rec.name);
|
|
81
81
|
let id;
|
|
82
82
|
if (match) {
|
|
@@ -87,8 +87,8 @@ export function importAgents({ cli, manifest, dir, skillIdMap, runtimeMap, fs =
|
|
|
87
87
|
id = JSON.parse(out).id; created++;
|
|
88
88
|
}
|
|
89
89
|
idMap.set(rec.name, id);
|
|
90
|
-
if (rec.
|
|
91
|
-
const skillIds = (rec.
|
|
90
|
+
if (rec.source_id) sourceIdMap.set(rec.source_id, id);
|
|
91
|
+
const skillIds = (rec.skill_names ?? []).map((n) => skillIdMap.get(n)).filter(Boolean);
|
|
92
92
|
cli.run(["agent", "skills", "set", id, "--skill-ids", skillIds.join(",")]);
|
|
93
93
|
|
|
94
94
|
// mcp_config/custom_env carry real secrets. Each is applied via its OWN
|
|
@@ -97,20 +97,20 @@ export function importAgents({ cli, manifest, dir, skillIdMap, runtimeMap, fs =
|
|
|
97
97
|
// sidesteps the fact that only one stdin payload can be read per process
|
|
98
98
|
// anyway. `agent update --mcp-config-stdin` works on a freshly-created id
|
|
99
99
|
// too, so no create/update branching is needed here.
|
|
100
|
-
const hasMcpConfig = rec.
|
|
100
|
+
const hasMcpConfig = rec.mcp_config && Object.keys(rec.mcp_config).length > 0;
|
|
101
101
|
if (hasMcpConfig) {
|
|
102
102
|
try {
|
|
103
|
-
cli.run(["agent", "update", id, "--mcp-config-stdin"], { input: JSON.stringify(rec.
|
|
103
|
+
cli.run(["agent", "update", id, "--mcp-config-stdin"], { input: JSON.stringify(rec.mcp_config) });
|
|
104
104
|
} catch {
|
|
105
105
|
secretsApplyFailures.push(rec.name);
|
|
106
106
|
}
|
|
107
107
|
}
|
|
108
108
|
// custom_env has no flag on `agent update` at all — `agent env set` is the
|
|
109
109
|
// only way to set it on an existing agent, so it's always a follow-up call.
|
|
110
|
-
const hasCustomEnv = rec.
|
|
110
|
+
const hasCustomEnv = rec.custom_env && Object.keys(rec.custom_env).length > 0;
|
|
111
111
|
if (hasCustomEnv) {
|
|
112
112
|
try {
|
|
113
|
-
cli.run(["agent", "env", "set", id, "--custom-env-stdin"], { input: JSON.stringify(rec.
|
|
113
|
+
cli.run(["agent", "env", "set", id, "--custom-env-stdin"], { input: JSON.stringify(rec.custom_env) });
|
|
114
114
|
} catch {
|
|
115
115
|
secretsApplyFailures.push(rec.name);
|
|
116
116
|
}
|
|
@@ -151,7 +151,7 @@ export function rewriteAgentMentions({ cli, manifest, dir, agentIdMap, sourceIdM
|
|
|
151
151
|
|
|
152
152
|
export function importSquad({ cli, squad, agentIdMap, sourceIdMap }) {
|
|
153
153
|
const existing = listSquads(cli);
|
|
154
|
-
const leaderId = agentIdMap.get(squad.
|
|
154
|
+
const leaderId = agentIdMap.get(squad.leader_name);
|
|
155
155
|
const match = findByName(existing, squad.name);
|
|
156
156
|
let id, created = 0, updated = 0;
|
|
157
157
|
// Squad instructions commonly list @mentions of teammate agents by their
|
|
@@ -166,10 +166,10 @@ export function importSquad({ cli, squad, agentIdMap, sourceIdMap }) {
|
|
|
166
166
|
id = JSON.parse(out).id; created++;
|
|
167
167
|
}
|
|
168
168
|
// Add non-leader members, skipping any already present so re-runs are idempotent.
|
|
169
|
-
const present = new Set(getSquadMembers(cli, id).map((m) => m.
|
|
169
|
+
const present = new Set(getSquadMembers(cli, id).map((m) => m.member_id));
|
|
170
170
|
for (const m of squad.members) {
|
|
171
|
-
if (m.
|
|
172
|
-
const memberId = agentIdMap.get(m.
|
|
171
|
+
if (m.agent_name === squad.leader_name) continue;
|
|
172
|
+
const memberId = agentIdMap.get(m.agent_name);
|
|
173
173
|
if (present.has(memberId)) continue;
|
|
174
174
|
cli.run(["squad", "member", "add", id, "--member-id", memberId, "--role", m.role, "--type", "agent"]);
|
|
175
175
|
}
|
|
@@ -177,15 +177,15 @@ export function importSquad({ cli, squad, agentIdMap, sourceIdMap }) {
|
|
|
177
177
|
}
|
|
178
178
|
|
|
179
179
|
export function collectSourceRuntimes(manifest) {
|
|
180
|
-
return [...new Set((manifest.agents ?? []).map((a) => a.
|
|
180
|
+
return [...new Set((manifest.agents ?? []).map((a) => a.source_runtime_id).filter(Boolean))];
|
|
181
181
|
}
|
|
182
182
|
|
|
183
|
-
//
|
|
183
|
+
// source_runtime_id -> provider (e.g. "claude", "opencode"), from whichever agent recorded it.
|
|
184
184
|
function collectRuntimeProviders(manifest) {
|
|
185
185
|
const map = new Map();
|
|
186
186
|
for (const a of manifest.agents ?? []) {
|
|
187
|
-
if (a.
|
|
188
|
-
map.set(a.
|
|
187
|
+
if (a.source_runtime_id && a.source_runtime_provider && !map.has(a.source_runtime_id)) {
|
|
188
|
+
map.set(a.source_runtime_id, a.source_runtime_provider);
|
|
189
189
|
}
|
|
190
190
|
}
|
|
191
191
|
return map;
|
|
@@ -236,7 +236,7 @@ export function importBundle({ cli, dir, runtimeMap, fs = nodeFs }) {
|
|
|
236
236
|
skillIdMap: Object.fromEntries(skillRes.idMap),
|
|
237
237
|
agentIdMap: Object.fromEntries(agentRes.idMap),
|
|
238
238
|
squadId: squadRes.newId,
|
|
239
|
-
secretsReminder: (manifest.agents ?? []).filter((a) => a.
|
|
239
|
+
secretsReminder: (manifest.agents ?? []).filter((a) => a.had_secrets).map((a) => a.name),
|
|
240
240
|
secretsApplyFailures: agentRes.secretsApplyFailures,
|
|
241
241
|
};
|
|
242
242
|
}
|
|
@@ -25,11 +25,11 @@ node "${CLAUDE_PLUGIN_ROOT}/scripts/multica-import.mjs" \
|
|
|
25
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
|
-
cat <folder>/manifest.json # note each distinct
|
|
28
|
+
cat <folder>/manifest.json # note each distinct source_runtime_id
|
|
29
29
|
multica runtime list --output json # list target workspace runtimes
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
-
Ask the user to pick a matching target runtime by name or ID for each unmapped `
|
|
32
|
+
Ask the user to pick a matching target runtime by name or ID for each unmapped `source_runtime_id`, then re-run with an explicit map (explicit entries always take precedence over auto-mapping):
|
|
33
33
|
|
|
34
34
|
```bash
|
|
35
35
|
node "${CLAUDE_PLUGIN_ROOT}/scripts/multica-import.mjs" \
|
|
@@ -33,7 +33,7 @@ If it aborts with `Unmapped runtimes: ...` (0 or 2+ runtimes share that provider
|
|
|
33
33
|
multica runtime list --workspace-id <dest-ws-id> --output json # list destination workspace runtimes
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
-
Ask the user to select a matching target runtime by name or ID for each unmapped `
|
|
36
|
+
Ask the user to select a matching target runtime by name or ID for each unmapped `source_runtime_id`, then re-run with an explicit map (explicit entries always take precedence over auto-mapping):
|
|
37
37
|
|
|
38
38
|
```bash
|
|
39
39
|
node "${CLAUDE_PLUGIN_ROOT}/scripts/multica-sync.mjs" \
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "plugin-validator",
|
|
3
3
|
"displayName": "Plugin Validator",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.38",
|
|
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.38",
|
|
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"
|