@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.
@@ -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.37",
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.37",
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.37",
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.37",
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.37",
76
+ "version": "0.0.38",
77
77
  "category": "workflow",
78
78
  "keywords": [
79
79
  "multica",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drunkcoding/agents-and-skills",
3
- "version": "0.0.37",
3
+ "version": "0.0.38",
4
4
  "description": "Personal collection of Claude Code skills and agents, installable via `npx skills`.",
5
5
  "keywords": [
6
6
  "claude-code",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "html-effectiveness",
3
3
  "displayName": "HTML Effectiveness Reports",
4
- "version": "0.0.37",
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"
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "multica-tool",
3
- "version": "0.0.37",
3
+ "version": "0.0.38",
4
4
  "description": "Export, import, and sync Multica skills, agents, and squads between workspaces via the multica CLI."
5
5
  }
@@ -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. They
59
- // return a stable camelCase shape so downstream code never sees snake_case.
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
- maxConcurrentTasks: a.max_concurrent_tasks,
75
- runtimeConfig: a.runtime_config,
76
- customArgs: a.custom_args,
77
- thinkingLevel: a.thinking_level,
78
- runtimeId: a.runtime_id,
79
- hasCustomEnv: a.has_custom_env,
80
- mcpConfig: a.mcp_config,
81
- mcpConfigRedacted: !!a.mcp_config_redacted,
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, leaderId: s.leader_id };
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
- memberId: m.member_id, memberType: m.member_type, role: m.role || "member",
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 (camelCase) agent from getAgent, with `customEnv`/
9
- // `customEnvFetchFailed` attached by the caller (collectAgent) — getAgent
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, hasCustomEnv, mcpConfigRedacted, customEnvFetchFailed, mcpConfig, customEnv, skills, runtimeId, ...rest } = a;
12
- const mcpUsable = !mcpConfigRedacted && nonEmpty(mcpConfig);
13
- const envUsable = !customEnvFetchFailed && nonEmpty(customEnv);
14
- // mcpConfigRedacted / customEnvFetchFailed alone still flag hadSecrets even
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 || !!mcpConfigRedacted || !!customEnvFetchFailed;
17
+ const hadSecrets = mcpUsable || envUsable || !!mcp_config_redacted || !!custom_env_fetch_failed;
18
18
  return {
19
- // sourceId lets import-time mention rewriting map stale `mention://agent/<id>`
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
- sourceId: id,
24
- sourceRuntimeId: runtimeId,
25
- skillNames: [],
26
- mcpConfig: mcpUsable ? mcpConfig : null,
27
- customEnv: envUsable ? customEnv : null,
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)}`, sourceId: s.sourceId })),
44
- agents: [...seenAgents.values()].map((a) => ({ name: a.name, file: `agents/${slugify(a.name)}.json`, sourceId: a.sourceId, sourceRuntimeId: a.sourceRuntimeId, sourceRuntimeProvider: a.sourceRuntimeProvider ?? null, skillNames: a.skillNames, hadSecrets: !!a.hadSecrets })),
45
- squads: squad ? [{ name: squad.name, file: `squads/${slugify(squad.name)}.json`, description: squad.description ?? "", instructions: squad.instructions ?? "", leaderName: squad.leaderName, members: squad.members }] : [],
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 leaderId/memberId resolve to names). Stores the
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.sourceRuntimeProvider = providerById.get(a.runtimeId) ?? null;
61
- a.customEnv = {};
62
- a.customEnvFetchFailed = false;
63
- if (a.hasCustomEnv) {
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.customEnv = getAgentCustomEnv(cli, id);
65
+ a.custom_env = getAgentCustomEnv(cli, id);
66
66
  } catch {
67
- a.customEnvFetchFailed = true; // e.g. insufficient permission — non-fatal, warned via hadSecrets
67
+ a.custom_env_fetch_failed = true; // e.g. insufficient permission — non-fatal, warned via hadSecrets
68
68
  }
69
69
  }
70
- const skillNames = a.skills.map((sk) => collectSkill(cli, sk.id, skills));
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, skillNames };
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, skillNames }
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.memberType === "agent");
91
- for (const m of members) collectAgent(cli, m.memberId, agentsById, skills, getProviderById());
92
- if (!agentsById.has(sq.leaderId)) collectAgent(cli, sq.leaderId, agentsById, skills, getProviderById());
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
- leaderName: nameOf(sq.leaderId),
99
- members: members.map((m) => ({ agentName: nameOf(m.memberId), role: m.role })),
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, sourceId: s.id })),
106
- agents: [...agentsById.values()].map((a) => ({ name: a.raw.name, sourceId: a.raw.id, sourceRuntimeId: a.raw.runtimeId, sourceRuntimeProvider: a.raw.sourceRuntimeProvider, skillNames: a.skillNames, hadSecrets: a.red.hadSecrets })),
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, skillNames } = agentByName.get(entry.name);
129
- const record = { ...red.record, skillNames };
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.sourceRuntimeId);
68
- if (!targetRuntime) throw new Error(`Unmapped runtime "${rec.sourceRuntimeId}" for agent "${rec.name}"`);
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.maxConcurrentTasks ?? 6),
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.thinkingLevel) common.push("--thinking-level", rec.thinkingLevel);
78
- if (rec.runtimeConfig && Object.keys(rec.runtimeConfig).length) common.push("--runtime-config", JSON.stringify(rec.runtimeConfig));
79
- if (Array.isArray(rec.customArgs) && rec.customArgs.length) common.push("--custom-args", JSON.stringify(rec.customArgs));
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.sourceId) sourceIdMap.set(rec.sourceId, id);
91
- const skillIds = (rec.skillNames ?? []).map((n) => skillIdMap.get(n)).filter(Boolean);
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.mcpConfig && Object.keys(rec.mcpConfig).length > 0;
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.mcpConfig) });
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.customEnv && Object.keys(rec.customEnv).length > 0;
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.customEnv) });
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.leaderName);
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.memberId));
169
+ const present = new Set(getSquadMembers(cli, id).map((m) => m.member_id));
170
170
  for (const m of squad.members) {
171
- if (m.agentName === squad.leaderName) continue;
172
- const memberId = agentIdMap.get(m.agentName);
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.sourceRuntimeId).filter(Boolean))];
180
+ return [...new Set((manifest.agents ?? []).map((a) => a.source_runtime_id).filter(Boolean))];
181
181
  }
182
182
 
183
- // sourceRuntimeId -> provider (e.g. "claude", "opencode"), from whichever agent recorded it.
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.sourceRuntimeId && a.sourceRuntimeProvider && !map.has(a.sourceRuntimeId)) {
188
- map.set(a.sourceRuntimeId, a.sourceRuntimeProvider);
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.hadSecrets).map((a) => a.name),
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 sourceRuntimeId
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 `sourceRuntimeId`, then re-run with an explicit map (explicit entries always take precedence over auto-mapping):
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 `sourceRuntimeId`, then re-run with an explicit map (explicit entries always take precedence over auto-mapping):
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.37",
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.37",
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"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tech-graph",
3
- "version": "0.0.37",
3
+ "version": "0.0.38",
4
4
  "description": "Step-by-step wizard for generating technical diagrams as SVG+PNG.",
5
5
  "author": {
6
6
  "name": "steven"