@drunkcoding/agents-and-skills 0.0.43 → 0.0.44
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 +5 -0
- package/plugins/multica-tool/scripts/multica-export.mjs +76 -33
- package/plugins/multica-tool/scripts/multica-import.mjs +28 -6
- 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.44",
|
|
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.44",
|
|
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.44",
|
|
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.44",
|
|
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.44",
|
|
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.44",
|
|
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"
|
|
@@ -53,6 +53,9 @@ export function resolveWorkspaceId(cli, name) {
|
|
|
53
53
|
export const listRuntimes = (cli) => cli.json(["runtime", "list"]);
|
|
54
54
|
export const listSkills = (cli) => cli.json(["skill", "list"]);
|
|
55
55
|
export const listAgents = (cli) => cli.json(["agent", "list"]);
|
|
56
|
+
// Includes archived agents (archived_at set) — used wherever a name match or an
|
|
57
|
+
// id lookup must also see agents excluded from the default listing above.
|
|
58
|
+
export const listAgentsIncludingArchived = (cli) => cli.json(["agent", "list", "--include-archived"]);
|
|
56
59
|
export const listSquads = (cli) => cli.json(["squad", "list"]);
|
|
57
60
|
export const listWorkspaceMembers = (cli) => cli.json(["workspace", "member", "list"]);
|
|
58
61
|
|
|
@@ -72,6 +75,8 @@ export function getAgent(cli, id) {
|
|
|
72
75
|
const a = cli.json(["agent", "get", id]);
|
|
73
76
|
return {
|
|
74
77
|
id: a.id, name: a.name, description: a.description, instructions: a.instructions,
|
|
78
|
+
// Export-time signal only (never written to a bundle record — see redactAgent).
|
|
79
|
+
archived_at: a.archived_at ?? null,
|
|
75
80
|
model: a.model, visibility: a.visibility, avatar_url: a.avatar_url ?? null,
|
|
76
81
|
service_tier: a.service_tier ?? "",
|
|
77
82
|
permission_mode: a.permission_mode ?? null,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as nodeFs from "node:fs";
|
|
2
2
|
import { spawnSync } from "node:child_process";
|
|
3
3
|
import { dirname } from "node:path";
|
|
4
|
-
import { slugify, getSkill, getAgent, getAgentCustomEnv, getSquad, getSquadMembers, listRuntimes, listSkills, listAgents, listSquads, listProjects, getProject, getProjectResources, listWorkspaceMembers, getAutopilot, makeCli, realExec, requireAuth, resolveWorkspaceId } from "./lib.mjs";
|
|
4
|
+
import { slugify, getSkill, getAgent, getAgentCustomEnv, getSquad, getSquadMembers, listRuntimes, listSkills, listAgents, listAgentsIncludingArchived, listSquads, listProjects, getProject, getProjectResources, listWorkspaceMembers, getAutopilot, makeCli, realExec, requireAuth, resolveWorkspaceId } from "./lib.mjs";
|
|
5
5
|
|
|
6
6
|
const nonEmpty = (v) => v && typeof v === "object" && Object.keys(v).length > 0;
|
|
7
7
|
|
|
@@ -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, instructions, ...rest } = a;
|
|
34
|
+
const { id, has_custom_env, mcp_config_redacted, custom_env_fetch_failed, mcp_config, custom_env, skills, runtime_id, instructions, archived_at, ...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
|
|
@@ -96,10 +96,15 @@ function collectSkill(cli, id, skills) {
|
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
// Keyed by agent id (so squad leader_id/member_id resolve to names). Stores the
|
|
99
|
-
// normalized agent, its redaction result, and its skill names.
|
|
99
|
+
// normalized agent, its redaction result, and its skill names. Returns
|
|
100
|
+
// `{ archived: true, name }` instead of collecting when the agent is archived —
|
|
101
|
+
// callers reached via a squad/project/explicit id lookup must decide how to
|
|
102
|
+
// handle that (the workspace-listing loop never hits this: listAgents() already
|
|
103
|
+
// excludes archived agents server-side).
|
|
100
104
|
function collectAgent(cli, id, agentsById, skills, providerById) {
|
|
101
105
|
if (agentsById.has(id)) return agentsById.get(id);
|
|
102
106
|
const a = getAgent(cli, id);
|
|
107
|
+
if (a.archived_at) return { archived: true, name: a.name };
|
|
103
108
|
a.source_runtime_provider = providerById.get(a.runtime_id) ?? null;
|
|
104
109
|
a.custom_env = {};
|
|
105
110
|
a.custom_env_fetch_failed = false;
|
|
@@ -117,22 +122,6 @@ function collectAgent(cli, id, agentsById, skills, providerById) {
|
|
|
117
122
|
return entry;
|
|
118
123
|
}
|
|
119
124
|
|
|
120
|
-
// Collect a project's portable metadata + its lead agent (bundled, like a squad
|
|
121
|
-
// leader) and github_repo/other resources. Returns the project bundle record.
|
|
122
|
-
function collectProject(cli, id, agentsById, skills, providerById) {
|
|
123
|
-
const p = getProject(cli, id);
|
|
124
|
-
let lead_name = null;
|
|
125
|
-
if (p.lead_type === "agent" && p.lead_id) {
|
|
126
|
-
lead_name = collectAgent(cli, p.lead_id, agentsById, skills, providerById).raw.name;
|
|
127
|
-
}
|
|
128
|
-
return {
|
|
129
|
-
title: p.title, description: p.description, icon: p.icon,
|
|
130
|
-
priority: p.priority, status: p.status, due_date: p.due_date, start_date: p.start_date,
|
|
131
|
-
source_id: id, lead_type: p.lead_type, lead_name, lead_source_id: p.lead_id,
|
|
132
|
-
resources: getProjectResources(cli, id),
|
|
133
|
-
};
|
|
134
|
-
}
|
|
135
|
-
|
|
136
125
|
export function exportResource({ cli, scope, ids, outDir, sourceWorkspaceId, fs = nodeFs, download = fetchBinary }) {
|
|
137
126
|
const skills = new Map(); // name -> normalized skill
|
|
138
127
|
const agentsById = new Map(); // id -> { raw, red, skill_names }
|
|
@@ -144,12 +133,34 @@ export function exportResource({ cli, scope, ids, outDir, sourceWorkspaceId, fs
|
|
|
144
133
|
let providerById = null;
|
|
145
134
|
const getProviderById = () => providerById ??= new Map(listRuntimes(cli).map((r) => [r.id, r.provider]));
|
|
146
135
|
|
|
147
|
-
//
|
|
136
|
+
// Archived agents skipped anywhere below, deduped by (name, path, detail) —
|
|
137
|
+
// the operator-facing "why isn't X in my bundle" report.
|
|
138
|
+
const archivedAgentsSkipped = [];
|
|
139
|
+
const seenArchivedSkip = new Set();
|
|
140
|
+
function recordArchivedSkip(name, path, detail) {
|
|
141
|
+
const key = [name, path, detail ?? ""].join("|");
|
|
142
|
+
if (seenArchivedSkip.has(key)) return;
|
|
143
|
+
seenArchivedSkip.add(key);
|
|
144
|
+
archivedAgentsSkipped.push(detail ? { name, path, detail } : { name, path });
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Collect a squad's agents (leader + members) and return the squad bundle
|
|
148
|
+
// object — or null when the leader is archived, since a squad can't import
|
|
149
|
+
// without one (the whole squad is excluded from the bundle, not emitted leaderless).
|
|
148
150
|
function collectOneSquad(squadId) {
|
|
149
151
|
const sq = getSquad(cli, squadId);
|
|
150
|
-
const
|
|
151
|
-
|
|
152
|
-
|
|
152
|
+
const leaderEntry = collectAgent(cli, sq.leader_id, agentsById, skills, getProviderById());
|
|
153
|
+
if (leaderEntry.archived) {
|
|
154
|
+
recordArchivedSkip(leaderEntry.name, "squad leader", sq.name);
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
const allMembers = getSquadMembers(cli, squadId).filter((m) => m.member_type === "agent");
|
|
158
|
+
const members = [];
|
|
159
|
+
for (const m of allMembers) {
|
|
160
|
+
const entry = collectAgent(cli, m.member_id, agentsById, skills, getProviderById());
|
|
161
|
+
if (entry.archived) { recordArchivedSkip(entry.name, "squad member", sq.name); continue; }
|
|
162
|
+
members.push(m);
|
|
163
|
+
}
|
|
153
164
|
const nameOf = (id) => agentsById.get(id)?.raw.name;
|
|
154
165
|
return {
|
|
155
166
|
name: sq.name, description: sq.description, instructions: sq.instructions, avatar_url: sq.avatar_url,
|
|
@@ -158,6 +169,30 @@ export function exportResource({ cli, scope, ids, outDir, sourceWorkspaceId, fs
|
|
|
158
169
|
};
|
|
159
170
|
}
|
|
160
171
|
|
|
172
|
+
// Collect a project's portable metadata + its lead agent (bundled, like a
|
|
173
|
+
// squad leader) and github_repo/other resources. An archived lead is dropped
|
|
174
|
+
// (project still exports, just with no lead set) — unlike a squad, a project
|
|
175
|
+
// has no hard requirement for one.
|
|
176
|
+
function collectProject(id) {
|
|
177
|
+
const p = getProject(cli, id);
|
|
178
|
+
let lead_name = null, lead_type = p.lead_type, lead_source_id = p.lead_id;
|
|
179
|
+
if (p.lead_type === "agent" && p.lead_id) {
|
|
180
|
+
const entry = collectAgent(cli, p.lead_id, agentsById, skills, getProviderById());
|
|
181
|
+
if (entry.archived) {
|
|
182
|
+
recordArchivedSkip(entry.name, "project lead", p.title);
|
|
183
|
+
lead_type = null; lead_source_id = null;
|
|
184
|
+
} else {
|
|
185
|
+
lead_name = entry.raw.name;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return {
|
|
189
|
+
title: p.title, description: p.description, icon: p.icon,
|
|
190
|
+
priority: p.priority, status: p.status, due_date: p.due_date, start_date: p.start_date,
|
|
191
|
+
source_id: id, lead_type, lead_name, lead_source_id,
|
|
192
|
+
resources: getProjectResources(cli, id),
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
|
|
161
196
|
// Collect a single autopilot: its assignee (agent, or squad + members + skills)
|
|
162
197
|
// and, when present, the destination-portable project title / subscriber names.
|
|
163
198
|
// Webhook trigger secrets (url/token) are never read into the bundle — only
|
|
@@ -166,11 +201,11 @@ export function exportResource({ cli, scope, ids, outDir, sourceWorkspaceId, fs
|
|
|
166
201
|
const ap = getAutopilot(cli, autopilotId);
|
|
167
202
|
let assignee_name = null;
|
|
168
203
|
if (ap.assignee_type === "agent") {
|
|
169
|
-
|
|
204
|
+
const entry = collectAgent(cli, ap.assignee_id, agentsById, skills, getProviderById());
|
|
205
|
+
assignee_name = entry.archived ? null : entry.raw.name;
|
|
170
206
|
} else if (ap.assignee_type === "squad") {
|
|
171
207
|
const sq = collectOneSquad(ap.assignee_id);
|
|
172
|
-
squads.push(sq);
|
|
173
|
-
assignee_name = sq.name;
|
|
208
|
+
if (sq) { squads.push(sq); assignee_name = sq.name; }
|
|
174
209
|
}
|
|
175
210
|
let project_title = null;
|
|
176
211
|
if (ap.project_id) {
|
|
@@ -193,16 +228,24 @@ export function exportResource({ cli, scope, ids, outDir, sourceWorkspaceId, fs
|
|
|
193
228
|
}
|
|
194
229
|
|
|
195
230
|
if (scope === "skill") collectSkill(cli, ids.skillId, skills);
|
|
196
|
-
else if (scope === "agent")
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
231
|
+
else if (scope === "agent") {
|
|
232
|
+
const entry = collectAgent(cli, ids.agentId, agentsById, skills, getProviderById());
|
|
233
|
+
if (entry.archived) throw new Error(`Cannot export agent "${entry.name}": it is archived`);
|
|
234
|
+
}
|
|
235
|
+
else if (scope === "squad") { const sq = collectOneSquad(ids.squadId); if (sq) squads.push(sq); }
|
|
236
|
+
else if (scope === "project") projects.push(collectProject(ids.projectId));
|
|
237
|
+
else if (scope === "projects") for (const p of listProjects(cli)) projects.push(collectProject(p.id));
|
|
200
238
|
else if (scope === "autopilot") autopilots.push(collectOneAutopilot(ids.autopilotId));
|
|
201
239
|
else if (scope === "all") {
|
|
202
240
|
for (const s of listSkills(cli)) collectSkill(cli, s.id, skills);
|
|
203
241
|
for (const a of listAgents(cli)) collectAgent(cli, a.id, agentsById, skills, getProviderById());
|
|
204
|
-
for (const sq of listSquads(cli))
|
|
205
|
-
for (const p of listProjects(cli)) projects.push(collectProject(
|
|
242
|
+
for (const sq of listSquads(cli)) { const built = collectOneSquad(sq.id); if (built) squads.push(built); }
|
|
243
|
+
for (const p of listProjects(cli)) projects.push(collectProject(p.id));
|
|
244
|
+
// listAgents() above already excludes archived agents server-side — surface
|
|
245
|
+
// that exclusion in the report too, not just the squad/project paths.
|
|
246
|
+
for (const a of listAgentsIncludingArchived(cli)) {
|
|
247
|
+
if (a.archived_at) recordArchivedSkip(a.name, "workspace listing");
|
|
248
|
+
}
|
|
206
249
|
}
|
|
207
250
|
|
|
208
251
|
// Orphan-skill cleanup: drop skills that no exported agent references via its
|
|
@@ -290,7 +333,7 @@ export function exportResource({ cli, scope, ids, outDir, sourceWorkspaceId, fs
|
|
|
290
333
|
}
|
|
291
334
|
fs.writeFileSync(`${outDir}/manifest.json`, JSON.stringify(manifest, null, 2));
|
|
292
335
|
return {
|
|
293
|
-
manifest, warnings, pruned_skills,
|
|
336
|
+
manifest, warnings, pruned_skills, archivedAgentsSkipped,
|
|
294
337
|
autopilotWebhookTriggers: autopilots.filter((a) => a.had_webhook_trigger).map((a) => a.title),
|
|
295
338
|
};
|
|
296
339
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as nodeFs from "node:fs";
|
|
2
|
-
import { listSkills, listAgents, listSquads, listRuntimes, listWorkspaceMembers, getSquadMembers, findByName, makeCli, realExec, requireAuth, resolveWorkspaceId, listProjects, getProjectResources, findByTitle, listAutopilots, getAutopilot } from "./lib.mjs";
|
|
2
|
+
import { listSkills, listAgents, listAgentsIncludingArchived, listSquads, listRuntimes, listWorkspaceMembers, getSquadMembers, findByName, makeCli, realExec, requireAuth, resolveWorkspaceId, listProjects, getProjectResources, findByTitle, listAutopilots, getAutopilot } from "./lib.mjs";
|
|
3
3
|
|
|
4
4
|
// User-facing selectable types are agents/squads/projects/autopilots; skills follow agents.
|
|
5
5
|
export function parseInclude(raw) {
|
|
@@ -86,8 +86,10 @@ export function importAgents({ cli, manifest, dir, skillIdMap, runtimeMap, fs =
|
|
|
86
86
|
// Lazy + memoized: destination member user_ids, only listed when an agent needs them.
|
|
87
87
|
let destMemberIds = null;
|
|
88
88
|
const getDestMemberIds = () => destMemberIds ??= new Set(listWorkspaceMembers(cli).map((m) => m.user_id));
|
|
89
|
-
let created = 0, updated = 0;
|
|
90
|
-
|
|
89
|
+
let created = 0, updated = 0, reused = 0;
|
|
90
|
+
// Includes archived agents so a bundle name matching a retired agent restores
|
|
91
|
+
// and reuses it instead of failing to create under the held name.
|
|
92
|
+
const existing = listAgentsIncludingArchived(cli);
|
|
91
93
|
|
|
92
94
|
for (const a of manifest.agents) {
|
|
93
95
|
const rec = JSON.parse(fs.readFileSync(`${dir}/${a.file}`, "utf8"));
|
|
@@ -108,7 +110,14 @@ export function importAgents({ cli, manifest, dir, skillIdMap, runtimeMap, fs =
|
|
|
108
110
|
if (rec.service_tier) common.push("--service-tier", rec.service_tier);
|
|
109
111
|
const match = findByName(existing, rec.name);
|
|
110
112
|
let id;
|
|
111
|
-
if (match) {
|
|
113
|
+
if (match && match.archived_at) {
|
|
114
|
+
// Restored agent then updated exactly like an active-name match — the
|
|
115
|
+
// matched id is now active, so a re-import of this bundle will find it
|
|
116
|
+
// via the plain `match` branch below and never restore twice.
|
|
117
|
+
cli.run(["agent", "restore", match.id]);
|
|
118
|
+
cli.run(["agent", "update", match.id, "--runtime-id", targetRuntime, ...common]);
|
|
119
|
+
id = match.id; reused++;
|
|
120
|
+
} else if (match) {
|
|
112
121
|
cli.run(["agent", "update", match.id, "--runtime-id", targetRuntime, ...common]);
|
|
113
122
|
id = match.id; updated++;
|
|
114
123
|
} else {
|
|
@@ -178,7 +187,7 @@ export function importAgents({ cli, manifest, dir, skillIdMap, runtimeMap, fs =
|
|
|
178
187
|
}
|
|
179
188
|
}
|
|
180
189
|
}
|
|
181
|
-
return { idMap, sourceIdMap, created, updated, secretsApplyFailures, avatarApplyFailures, avatarUnsupported, permissionApplyFailures, permissionUnsupported };
|
|
190
|
+
return { idMap, sourceIdMap, created, updated, reused, secretsApplyFailures, avatarApplyFailures, avatarUnsupported, permissionApplyFailures, permissionUnsupported };
|
|
182
191
|
}
|
|
183
192
|
|
|
184
193
|
// Rewrites `mention://agent/<id>` links (e.g. `[@dev-backend](mention://agent/<id>)`)
|
|
@@ -448,7 +457,7 @@ export function importBundle({ cli, dir, runtimeMap, include, fs = nodeFs }) {
|
|
|
448
457
|
: { idMap: new Map(), created: 0, updated: 0 };
|
|
449
458
|
const agentRes = inc.has("agents")
|
|
450
459
|
? importAgents({ cli, manifest, dir, skillIdMap: skillRes.idMap, runtimeMap: effective, fs })
|
|
451
|
-
: { idMap: new Map(), sourceIdMap: new Map(), created: 0, updated: 0, secretsApplyFailures: [], avatarApplyFailures: [], avatarUnsupported: [], permissionApplyFailures: [], permissionUnsupported: [] };
|
|
460
|
+
: { idMap: new Map(), sourceIdMap: new Map(), created: 0, updated: 0, reused: 0, secretsApplyFailures: [], avatarApplyFailures: [], avatarUnsupported: [], permissionApplyFailures: [], permissionUnsupported: [] };
|
|
452
461
|
// Runs after every agent exists so forward-referencing mentions resolve.
|
|
453
462
|
const mentionRes = inc.has("agents")
|
|
454
463
|
? rewriteAgentMentions({ cli, manifest, dir, agentIdMap: agentRes.idMap, sourceIdMap: agentRes.sourceIdMap, fs })
|
|
@@ -482,6 +491,9 @@ export function importBundle({ cli, dir, runtimeMap, include, fs = nodeFs }) {
|
|
|
482
491
|
include: [...inc],
|
|
483
492
|
created: { skills: skillRes.created, agents: agentRes.created, squads: squadsCreated, projects: projectRes.created, autopilots: autopilotRes.created },
|
|
484
493
|
updated: { skills: skillRes.updated, agents: agentRes.updated, squads: squadsUpdated, projects: projectRes.updated, autopilots: autopilotRes.updated },
|
|
494
|
+
// Agents restored from archived + updated to the bundle's definition — distinct
|
|
495
|
+
// from a plain update (an active-name match). Only agents can be reused today.
|
|
496
|
+
reused: { agents: agentRes.reused },
|
|
485
497
|
mentionsRewritten: mentionRes.updated,
|
|
486
498
|
skillIdMap: Object.fromEntries(skillRes.idMap),
|
|
487
499
|
agentIdMap: Object.fromEntries(agentRes.idMap),
|
|
@@ -531,6 +543,16 @@ export function preflight({ cli, dir, runtimeMap, include, fs = nodeFs }) {
|
|
|
531
543
|
? `${u.srcId} (provider "${u.provider}": ${u.matchCount} matches, expected 1)`
|
|
532
544
|
: `${u.srcId} (no provider recorded)` });
|
|
533
545
|
}
|
|
546
|
+
|
|
547
|
+
// Read-only check, mirrors importAgents' restore-and-reuse match — never
|
|
548
|
+
// calls restore itself, just reports what a real import would do.
|
|
549
|
+
const existingAgents = listAgentsIncludingArchived(cli);
|
|
550
|
+
for (const a of manifest.agents ?? []) {
|
|
551
|
+
const match = findByName(existingAgents, a.name);
|
|
552
|
+
if (match && match.archived_at) {
|
|
553
|
+
incompatibilities.push({ type: "agent-archived-will-restore", detail: `${a.name} (archived in destination — import would restore and reuse it)` });
|
|
554
|
+
}
|
|
555
|
+
}
|
|
534
556
|
}
|
|
535
557
|
|
|
536
558
|
if (inc.has("projects")) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "plugin-validator",
|
|
3
3
|
"displayName": "Plugin Validator",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.44",
|
|
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.44",
|
|
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"
|