opendevbrowser 0.0.21 → 0.0.23

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.
Files changed (54) hide show
  1. package/README.md +13 -3
  2. package/dist/{chunk-4KVXCXV3.js → chunk-2MG7BRPF.js} +521 -84
  3. package/dist/{chunk-4KVXCXV3.js.map → chunk-2MG7BRPF.js.map} +1 -1
  4. package/dist/chunk-3ILXPKSJ.js +86 -0
  5. package/dist/chunk-3ILXPKSJ.js.map +1 -0
  6. package/dist/{chunk-ZE2E7ZGH.js → chunk-K2TEHJCV.js} +240 -33
  7. package/dist/chunk-K2TEHJCV.js.map +1 -0
  8. package/dist/chunk-QVWOPIZJ.js +612 -0
  9. package/dist/chunk-QVWOPIZJ.js.map +1 -0
  10. package/dist/{chunk-3VA6XR25.js → chunk-STGGGVYT.js} +23 -100
  11. package/dist/chunk-STGGGVYT.js.map +1 -0
  12. package/dist/cli/commands/macro-resolve.d.ts.map +1 -1
  13. package/dist/cli/commands/uninstall.d.ts +1 -0
  14. package/dist/cli/commands/uninstall.d.ts.map +1 -1
  15. package/dist/cli/daemon-commands.d.ts.map +1 -1
  16. package/dist/cli/help.d.ts.map +1 -1
  17. package/dist/cli/index.js +298 -618
  18. package/dist/cli/index.js.map +1 -1
  19. package/dist/cli/installers/postinstall-skill-sync.d.ts +15 -0
  20. package/dist/cli/installers/postinstall-skill-sync.d.ts.map +1 -0
  21. package/dist/cli/installers/postinstall-skill-sync.js +48 -0
  22. package/dist/cli/installers/postinstall-skill-sync.js.map +1 -0
  23. package/dist/cli/installers/skills.d.ts +9 -14
  24. package/dist/cli/installers/skills.d.ts.map +1 -1
  25. package/dist/cli/skill-lifecycle.d.ts +26 -0
  26. package/dist/cli/skill-lifecycle.d.ts.map +1 -0
  27. package/dist/cli/update-skill-modes.d.ts +3 -0
  28. package/dist/cli/update-skill-modes.d.ts.map +1 -0
  29. package/dist/cli/utils/workflow-message.d.ts +1 -0
  30. package/dist/cli/utils/workflow-message.d.ts.map +1 -1
  31. package/dist/index.js +25 -9
  32. package/dist/index.js.map +1 -1
  33. package/dist/opendevbrowser.js +25 -9
  34. package/dist/opendevbrowser.js.map +1 -1
  35. package/dist/providers/social/platform.d.ts.map +1 -1
  36. package/dist/providers/social/search-quality.d.ts.map +1 -1
  37. package/dist/providers/social/youtube.d.ts.map +1 -1
  38. package/dist/providers/workflow-handoff.d.ts +27 -3
  39. package/dist/providers/workflow-handoff.d.ts.map +1 -1
  40. package/dist/providers/workflows.d.ts +1 -0
  41. package/dist/providers/workflows.d.ts.map +1 -1
  42. package/dist/{providers-ZIVHHH4F.js → providers-6YVHKTOJ.js} +2 -2
  43. package/dist/public-surface/generated-manifest.d.ts +162 -4
  44. package/dist/public-surface/generated-manifest.d.ts.map +1 -1
  45. package/dist/public-surface/source.d.ts +12 -6
  46. package/dist/public-surface/source.d.ts.map +1 -1
  47. package/dist/skills/skill-loader.js +2 -1
  48. package/dist/tools/macro_resolve.d.ts.map +1 -1
  49. package/extension/manifest.json +1 -1
  50. package/package.json +6 -4
  51. package/scripts/postinstall-sync-skills.mjs +33 -0
  52. package/dist/chunk-3VA6XR25.js.map +0 -1
  53. package/dist/chunk-ZE2E7ZGH.js.map +0 -1
  54. /package/dist/{providers-ZIVHHH4F.js.map → providers-6YVHKTOJ.js.map} +0 -0
@@ -0,0 +1,612 @@
1
+ import {
2
+ getBundledSkillsDir,
3
+ listBundledSkillDirectories
4
+ } from "./chunk-3ILXPKSJ.js";
5
+
6
+ // src/cli/installers/skills.ts
7
+ import * as crypto from "crypto";
8
+ import * as fs2 from "fs";
9
+ import * as path3 from "path";
10
+
11
+ // src/cli/utils/config.ts
12
+ import * as fs from "fs";
13
+ import * as path from "path";
14
+ import * as os from "os";
15
+ import { parse as parseJsonc, modify, applyEdits } from "jsonc-parser";
16
+ var PLUGIN_NAME = "opendevbrowser";
17
+ var SCHEMA_URL = "https://opencode.ai/config.json";
18
+ function getGlobalConfigPath() {
19
+ const configDir = process.env.OPENCODE_CONFIG_DIR || path.join(os.homedir(), ".config", "opencode");
20
+ return path.join(configDir, "opencode.json");
21
+ }
22
+ function getLocalConfigPath() {
23
+ return path.join(process.cwd(), "opencode.json");
24
+ }
25
+ function ensureDir(dirPath) {
26
+ if (!fs.existsSync(dirPath)) {
27
+ fs.mkdirSync(dirPath, { recursive: true });
28
+ }
29
+ }
30
+ function readConfig(configPath) {
31
+ if (!fs.existsSync(configPath)) {
32
+ return { content: "", config: {} };
33
+ }
34
+ const content = fs.readFileSync(configPath, "utf-8");
35
+ const errors = [];
36
+ const parsed = parseJsonc(content, errors, { allowTrailingComma: true });
37
+ if (errors.length > 0) {
38
+ const firstError = errors[0];
39
+ throw new Error(`Invalid JSONC at ${configPath}: parse error at offset ${firstError?.offset ?? 0}`);
40
+ }
41
+ return { content, config: parsed ?? {} };
42
+ }
43
+ function hasPlugin(config, pluginName = PLUGIN_NAME) {
44
+ return config.plugin?.includes(pluginName) ?? false;
45
+ }
46
+ function createConfigWithPlugin(pluginName = PLUGIN_NAME) {
47
+ return {
48
+ $schema: SCHEMA_URL,
49
+ plugin: [pluginName]
50
+ };
51
+ }
52
+ function updateConfigContent(content, pluginName = PLUGIN_NAME) {
53
+ if (!content.trim()) {
54
+ return JSON.stringify(createConfigWithPlugin(pluginName), null, 2) + "\n";
55
+ }
56
+ const parsed = parseJsonc(content, [], { allowTrailingComma: true }) ?? {};
57
+ if (parsed.plugin?.includes(pluginName)) {
58
+ return content;
59
+ }
60
+ let result = content;
61
+ if (!parsed.$schema) {
62
+ const edits2 = modify(result, ["$schema"], SCHEMA_URL, { formattingOptions: { tabSize: 2, insertSpaces: true } });
63
+ result = applyEdits(result, edits2);
64
+ }
65
+ const newPlugins = parsed.plugin ? [...parsed.plugin, pluginName] : [pluginName];
66
+ const edits = modify(result, ["plugin"], newPlugins, { formattingOptions: { tabSize: 2, insertSpaces: true } });
67
+ result = applyEdits(result, edits);
68
+ return result;
69
+ }
70
+ function removePluginFromContent(content, pluginName = PLUGIN_NAME) {
71
+ if (!content.trim()) {
72
+ return content;
73
+ }
74
+ const parsed = parseJsonc(content, [], { allowTrailingComma: true }) ?? {};
75
+ if (!parsed.plugin?.includes(pluginName)) {
76
+ return content;
77
+ }
78
+ const newPlugins = parsed.plugin.filter((p) => p !== pluginName);
79
+ const edits = modify(content, ["plugin"], newPlugins.length > 0 ? newPlugins : void 0, {
80
+ formattingOptions: { tabSize: 2, insertSpaces: true }
81
+ });
82
+ return applyEdits(content, edits);
83
+ }
84
+
85
+ // src/cli/utils/skills.ts
86
+ import * as path2 from "path";
87
+ import * as os2 from "os";
88
+ var SKILL_DIR_NAME = "skill";
89
+ var SKILLS_DIR_NAME = "skills";
90
+ function getGlobalSkillDir() {
91
+ const configDir = process.env.OPENCODE_CONFIG_DIR || path2.join(os2.homedir(), ".config", "opencode");
92
+ return path2.join(configDir, SKILL_DIR_NAME);
93
+ }
94
+ function getLocalSkillDir() {
95
+ return path2.join(process.cwd(), ".opencode", SKILL_DIR_NAME);
96
+ }
97
+ function getCodexHomeDir() {
98
+ return process.env.CODEX_HOME || path2.join(os2.homedir(), ".codex");
99
+ }
100
+ function getClaudeCodeHomeDir() {
101
+ return process.env.CLAUDECODE_HOME || path2.join(os2.homedir(), ".claude");
102
+ }
103
+ function getAmpHomeDir() {
104
+ return process.env.AMP_CLI_HOME || path2.join(os2.homedir(), ".amp");
105
+ }
106
+ function dedupeTargets(targets) {
107
+ const deduped = /* @__PURE__ */ new Map();
108
+ for (const target of targets) {
109
+ const key = path2.resolve(target.dir);
110
+ const existing = deduped.get(key);
111
+ if (existing) {
112
+ if (!existing.agents.includes(target.agent)) {
113
+ existing.agents.push(target.agent);
114
+ }
115
+ continue;
116
+ }
117
+ deduped.set(key, { agents: [target.agent], dir: target.dir });
118
+ }
119
+ return Array.from(deduped.values());
120
+ }
121
+ function getGlobalSkillTargets() {
122
+ const claudeSkillsDir = path2.join(getClaudeCodeHomeDir(), SKILLS_DIR_NAME);
123
+ const ampSkillsDir = path2.join(getAmpHomeDir(), SKILLS_DIR_NAME);
124
+ return dedupeTargets([
125
+ { agent: "opencode", dir: getGlobalSkillDir() },
126
+ { agent: "codex", dir: path2.join(getCodexHomeDir(), SKILLS_DIR_NAME) },
127
+ { agent: "claudecode", dir: claudeSkillsDir },
128
+ { agent: "ampcli", dir: ampSkillsDir }
129
+ ]);
130
+ }
131
+ function getLocalSkillTargets() {
132
+ const localClaudeSkillsDir = path2.join(process.cwd(), ".claude", SKILLS_DIR_NAME);
133
+ const localAmpSkillsDir = path2.join(process.cwd(), ".amp", SKILLS_DIR_NAME);
134
+ return dedupeTargets([
135
+ { agent: "opencode", dir: getLocalSkillDir() },
136
+ { agent: "codex", dir: path2.join(process.cwd(), ".codex", SKILLS_DIR_NAME) },
137
+ { agent: "claudecode", dir: localClaudeSkillsDir },
138
+ { agent: "ampcli", dir: localAmpSkillsDir }
139
+ ]);
140
+ }
141
+
142
+ // src/cli/installers/skills.ts
143
+ var MANAGED_SKILLS_MARKER = ".opendevbrowser-managed-skills.json";
144
+ var MANAGED_SKILL_SENTINEL = ".opendevbrowser-managed-skill.json";
145
+ var MANAGED_SKILL_OWNER = "opendevbrowser";
146
+ var MANAGED_PACK_PREFIX = "opendevbrowser-";
147
+ function getTargets(mode) {
148
+ return mode === "global" ? getGlobalSkillTargets() : getLocalSkillTargets();
149
+ }
150
+ function getCanonicalBundledSkillNames() {
151
+ return listBundledSkillDirectories().map((entry) => entry.name);
152
+ }
153
+ function getManagedSkillsMarkerPath(targetDir) {
154
+ return path3.join(targetDir, MANAGED_SKILLS_MARKER);
155
+ }
156
+ function getManagedSkillSentinelPath(targetPath) {
157
+ return path3.join(targetPath, MANAGED_SKILL_SENTINEL);
158
+ }
159
+ function snapshotManagedSkillsMarker(targetDir) {
160
+ const markerPath = getManagedSkillsMarkerPath(targetDir);
161
+ return fs2.existsSync(markerPath) ? fs2.readFileSync(markerPath, "utf8") : null;
162
+ }
163
+ function restoreManagedSkillsMarker(targetDir, previousMarker) {
164
+ if (previousMarker === null) {
165
+ removeManagedSkillsMarker(targetDir);
166
+ return;
167
+ }
168
+ fs2.writeFileSync(getManagedSkillsMarkerPath(targetDir), previousMarker, "utf8");
169
+ }
170
+ function hasManagedSkillsMarker(targetDir) {
171
+ return fs2.existsSync(getManagedSkillsMarkerPath(targetDir));
172
+ }
173
+ function isSafePathSegment(value) {
174
+ return value.length > 0 && value !== "." && value !== ".." && !value.includes("/") && !value.includes("\\") && path3.basename(value) === value;
175
+ }
176
+ function isManagedPackName(value) {
177
+ return isSafePathSegment(value) && value.startsWith(MANAGED_PACK_PREFIX);
178
+ }
179
+ function readManagedSkillsMarker(targetDir) {
180
+ if (!hasManagedSkillsMarker(targetDir)) {
181
+ return null;
182
+ }
183
+ try {
184
+ const raw = fs2.readFileSync(getManagedSkillsMarkerPath(targetDir), "utf8");
185
+ const parsed = JSON.parse(raw);
186
+ return Array.isArray(parsed.managedPacks) ? {
187
+ managedPacks: parsed.managedPacks.filter(
188
+ (value) => typeof value === "string" && isManagedPackName(value)
189
+ ),
190
+ managesAllCanonicalPacks: parsed.managesAllCanonicalPacks !== false
191
+ } : null;
192
+ } catch {
193
+ return null;
194
+ }
195
+ }
196
+ function writeManagedSkillsMarker(targetDir, packNames, managesAllCanonicalPacks) {
197
+ const marker = {
198
+ managedPacks: Array.from(new Set(packNames)),
199
+ managesAllCanonicalPacks
200
+ };
201
+ fs2.writeFileSync(
202
+ getManagedSkillsMarkerPath(targetDir),
203
+ `${JSON.stringify(marker, null, 2)}
204
+ `,
205
+ "utf8"
206
+ );
207
+ }
208
+ function removeManagedSkillsMarker(targetDir) {
209
+ fs2.rmSync(getManagedSkillsMarkerPath(targetDir), { force: true });
210
+ }
211
+ function writeManagedSkillSentinel(targetPath, packName, fingerprint) {
212
+ const sentinel = {
213
+ managedBy: MANAGED_SKILL_OWNER,
214
+ packName,
215
+ fingerprint
216
+ };
217
+ fs2.writeFileSync(
218
+ getManagedSkillSentinelPath(targetPath),
219
+ `${JSON.stringify(sentinel, null, 2)}
220
+ `,
221
+ "utf8"
222
+ );
223
+ }
224
+ function readManagedSkillFingerprint(targetPath) {
225
+ const sentinelPath = getManagedSkillSentinelPath(targetPath);
226
+ if (!fs2.existsSync(sentinelPath)) {
227
+ return null;
228
+ }
229
+ try {
230
+ const raw = fs2.readFileSync(sentinelPath, "utf8");
231
+ const parsed = JSON.parse(raw);
232
+ return parsed.managedBy === MANAGED_SKILL_OWNER && parsed.packName === path3.basename(targetPath) && typeof parsed.fingerprint === "string" ? parsed.fingerprint : null;
233
+ } catch {
234
+ return null;
235
+ }
236
+ }
237
+ function getSentinelManagedPackNames(targetDir, packNames) {
238
+ const canonicalPackNames = new Set(packNames);
239
+ const candidatePackNames = new Set(packNames);
240
+ if (fs2.existsSync(targetDir) && isDirectoryPath(targetDir)) {
241
+ for (const entry of fs2.readdirSync(targetDir, { withFileTypes: true })) {
242
+ if (entry.isDirectory() && isManagedPackName(entry.name)) {
243
+ candidatePackNames.add(entry.name);
244
+ }
245
+ }
246
+ }
247
+ return Array.from(candidatePackNames).filter((packName) => {
248
+ const targetPath = path3.join(targetDir, packName);
249
+ if (!fs2.existsSync(targetPath) || readManagedSkillFingerprint(targetPath) === null) {
250
+ return false;
251
+ }
252
+ return canonicalPackNames.has(packName) || shouldRemoveRetiredManagedPack(targetPath);
253
+ });
254
+ }
255
+ function hasManagedCanonicalBundledSkillInTarget(targetDir, packNames) {
256
+ return getSentinelManagedPackNames(targetDir, packNames).length > 0;
257
+ }
258
+ function removeManagedPackArtifacts(targetDir, packNames) {
259
+ const removed = [];
260
+ const missing = [];
261
+ for (const packName of packNames) {
262
+ const targetPath = path3.join(targetDir, packName);
263
+ if (fs2.existsSync(targetPath)) {
264
+ fs2.rmSync(targetPath, { recursive: true, force: true });
265
+ removed.push(packName);
266
+ continue;
267
+ }
268
+ missing.push(packName);
269
+ }
270
+ return { removed, missing };
271
+ }
272
+ function formatSummary(parts, totalTargets, failures) {
273
+ const summary = parts.length > 0 ? parts.join(", ") : "no lifecycle changes";
274
+ const failureSummary = failures > 0 ? `, ${failures} failed` : "";
275
+ return `${summary} across ${totalTargets} targets${failureSummary}`;
276
+ }
277
+ function hashDirectoryTree(dirPath) {
278
+ const hash = crypto.createHash("sha256");
279
+ const visit = (currentPath, relativePath) => {
280
+ const entries = fs2.readdirSync(currentPath, { withFileTypes: true }).sort((left, right) => left.name.localeCompare(right.name));
281
+ for (const entry of entries) {
282
+ const absolutePath = path3.join(currentPath, entry.name);
283
+ const entryRelativePath = relativePath ? path3.posix.join(relativePath, entry.name) : entry.name;
284
+ if (entry.isFile() && entry.name === MANAGED_SKILL_SENTINEL) {
285
+ continue;
286
+ }
287
+ if (entry.isDirectory()) {
288
+ hash.update(`D:${entryRelativePath}\0`);
289
+ visit(absolutePath, entryRelativePath);
290
+ continue;
291
+ }
292
+ if (entry.isFile()) {
293
+ hash.update(`F:${entryRelativePath}\0`);
294
+ hash.update(fs2.readFileSync(absolutePath));
295
+ hash.update("\0");
296
+ continue;
297
+ }
298
+ if (entry.isSymbolicLink()) {
299
+ hash.update(`L:${entryRelativePath}\0${fs2.readlinkSync(absolutePath)}\0`);
300
+ }
301
+ }
302
+ };
303
+ visit(dirPath, "");
304
+ return hash.digest("hex");
305
+ }
306
+ function isDirectoryPath(targetPath) {
307
+ return fs2.lstatSync(targetPath).isDirectory();
308
+ }
309
+ function shouldRemoveRetiredManagedPack(targetPath) {
310
+ if (!fs2.existsSync(targetPath) || !isDirectoryPath(targetPath)) {
311
+ return false;
312
+ }
313
+ const fingerprint = readManagedSkillFingerprint(targetPath);
314
+ return fingerprint !== null && hashDirectoryTree(targetPath) === fingerprint;
315
+ }
316
+ function syncSkillDirectory(sourcePath, targetPath, sourceFingerprint) {
317
+ if (!fs2.existsSync(targetPath)) {
318
+ fs2.cpSync(sourcePath, targetPath, { recursive: true });
319
+ return "installed";
320
+ }
321
+ if (isDirectoryPath(targetPath)) {
322
+ const targetFingerprint = hashDirectoryTree(targetPath);
323
+ if (targetFingerprint === sourceFingerprint) {
324
+ return "unchanged";
325
+ }
326
+ }
327
+ const parentDir = path3.dirname(targetPath);
328
+ const targetName = path3.basename(targetPath);
329
+ const stagingRoot = fs2.mkdtempSync(path3.join(parentDir, `.${targetName}-sync-`));
330
+ const stagedPath = path3.join(stagingRoot, targetName);
331
+ const backupPath = path3.join(stagingRoot, `${targetName}-backup`);
332
+ try {
333
+ fs2.cpSync(sourcePath, stagedPath, { recursive: true });
334
+ fs2.renameSync(targetPath, backupPath);
335
+ try {
336
+ fs2.renameSync(stagedPath, targetPath);
337
+ } catch (error) {
338
+ if (fs2.existsSync(backupPath) && !fs2.existsSync(targetPath)) {
339
+ fs2.renameSync(backupPath, targetPath);
340
+ }
341
+ throw error;
342
+ }
343
+ fs2.rmSync(backupPath, { recursive: true, force: true });
344
+ return "refreshed";
345
+ } finally {
346
+ if (fs2.existsSync(stagedPath)) {
347
+ fs2.rmSync(stagedPath, { recursive: true, force: true });
348
+ }
349
+ if (fs2.existsSync(backupPath)) {
350
+ fs2.rmSync(backupPath, { recursive: true, force: true });
351
+ }
352
+ fs2.rmSync(stagingRoot, { recursive: true, force: true });
353
+ }
354
+ }
355
+ function buildSyncMessage(mode, result) {
356
+ return `Skills ${mode} sync: ${formatSummary(
357
+ [
358
+ result.installed.length > 0 ? `${result.installed.length} installed` : "",
359
+ result.refreshed.length > 0 ? `${result.refreshed.length} refreshed` : "",
360
+ result.unchanged.length > 0 ? `${result.unchanged.length} unchanged` : ""
361
+ ].filter(Boolean),
362
+ result.targets.length,
363
+ result.targets.filter((entry) => !entry.success).length
364
+ )}`;
365
+ }
366
+ function buildRemovalMessage(mode, result) {
367
+ return `Skills ${mode} removal: ${formatSummary(
368
+ [
369
+ result.removed.length > 0 ? `${result.removed.length} removed` : "",
370
+ result.missing.length > 0 ? `${result.missing.length} already absent` : ""
371
+ ].filter(Boolean),
372
+ result.targets.length,
373
+ result.targets.filter((entry) => !entry.success).length
374
+ )}`;
375
+ }
376
+ function resolveManagedPackScope(target, marker, packNames) {
377
+ const requestedAllCanonicalPacks = target.managedPackNames === void 0;
378
+ const managesAllCanonicalPacks = requestedAllCanonicalPacks || marker?.managesAllCanonicalPacks === true;
379
+ const managedPackNames = managesAllCanonicalPacks ? Array.from(/* @__PURE__ */ new Set([...marker?.managedPacks ?? [], ...packNames])) : Array.from(new Set(target.managedPackNames ?? marker?.managedPacks ?? []));
380
+ const activePackNames = managesAllCanonicalPacks ? [...packNames] : managedPackNames.filter((packName) => packNames.includes(packName));
381
+ return {
382
+ managedPackNames,
383
+ activePackNames,
384
+ managesAllCanonicalPacks
385
+ };
386
+ }
387
+ function createNoOpSkillRemovalResult(mode) {
388
+ const result = {
389
+ success: true,
390
+ message: "",
391
+ mode,
392
+ targets: [],
393
+ removed: [],
394
+ missing: []
395
+ };
396
+ result.message = buildRemovalMessage(mode, result);
397
+ return result;
398
+ }
399
+ function getBundledSkillLifecycleTargets(mode, options) {
400
+ const packNames = getCanonicalBundledSkillNames();
401
+ return getTargets(mode).flatMap((target) => {
402
+ const marker = readManagedSkillsMarker(target.dir);
403
+ if (marker) {
404
+ if (marker.managesAllCanonicalPacks || !options.includeLegacyArtifacts) {
405
+ return marker.managesAllCanonicalPacks ? [target] : [{ ...target, managedPackNames: marker.managedPacks }];
406
+ }
407
+ const managedPackNames2 = Array.from(/* @__PURE__ */ new Set([
408
+ ...marker.managedPacks,
409
+ ...getSentinelManagedPackNames(target.dir, packNames)
410
+ ]));
411
+ return managedPackNames2.length > 0 ? [{ ...target, managedPackNames: managedPackNames2 }] : [];
412
+ }
413
+ if (!options.includeLegacyArtifacts) {
414
+ return [];
415
+ }
416
+ const managedPackNames = getSentinelManagedPackNames(target.dir, packNames);
417
+ return managedPackNames.length > 0 ? [{ ...target, managedPackNames }] : [];
418
+ });
419
+ }
420
+ function getBundledSkillTargets(mode) {
421
+ return getTargets(mode);
422
+ }
423
+ function syncBundledSkillsForTargets(mode, targets) {
424
+ const targetResults = [];
425
+ try {
426
+ const sourceDir = getBundledSkillsDir();
427
+ const packNames = getCanonicalBundledSkillNames();
428
+ const bundledFingerprints = /* @__PURE__ */ new Map();
429
+ for (const packName of packNames) {
430
+ const sourcePath = path3.join(sourceDir, packName);
431
+ if (!fs2.existsSync(sourcePath)) {
432
+ throw new Error(`Bundled skill directory missing: ${packName}`);
433
+ }
434
+ bundledFingerprints.set(packName, hashDirectoryTree(sourcePath));
435
+ }
436
+ for (const target of targets) {
437
+ const installed = [];
438
+ const refreshed = [];
439
+ const unchanged = [];
440
+ const previousMarker = snapshotManagedSkillsMarker(target.dir);
441
+ try {
442
+ ensureDir(target.dir);
443
+ const managedTarget = target;
444
+ const marker = readManagedSkillsMarker(target.dir);
445
+ const { managedPackNames, activePackNames, managesAllCanonicalPacks } = resolveManagedPackScope(
446
+ managedTarget,
447
+ marker,
448
+ packNames
449
+ );
450
+ const activePackNameSet = new Set(activePackNames);
451
+ writeManagedSkillsMarker(target.dir, managedPackNames, managesAllCanonicalPacks);
452
+ for (const packName of activePackNames) {
453
+ const sourcePath = path3.join(sourceDir, packName);
454
+ const targetPath = path3.join(target.dir, packName);
455
+ const sourceFingerprint = bundledFingerprints.get(packName);
456
+ if (!sourceFingerprint) {
457
+ throw new Error(`Bundled fingerprint missing: ${packName}`);
458
+ }
459
+ const outcome = syncSkillDirectory(sourcePath, targetPath, sourceFingerprint);
460
+ writeManagedSkillSentinel(targetPath, packName, sourceFingerprint);
461
+ if (outcome === "installed") {
462
+ installed.push(packName);
463
+ } else if (outcome === "refreshed") {
464
+ refreshed.push(packName);
465
+ } else {
466
+ unchanged.push(packName);
467
+ }
468
+ }
469
+ const retiredPackNames = managedPackNames.filter((packName) => {
470
+ return !activePackNameSet.has(packName) && shouldRemoveRetiredManagedPack(path3.join(target.dir, packName));
471
+ });
472
+ removeManagedPackArtifacts(target.dir, retiredPackNames);
473
+ if (activePackNames.length > 0 || managesAllCanonicalPacks) {
474
+ writeManagedSkillsMarker(target.dir, activePackNames, managesAllCanonicalPacks);
475
+ } else {
476
+ removeManagedSkillsMarker(target.dir);
477
+ }
478
+ targetResults.push({
479
+ agents: target.agents,
480
+ targetDir: target.dir,
481
+ installed,
482
+ refreshed,
483
+ unchanged,
484
+ success: true
485
+ });
486
+ } catch (error) {
487
+ restoreManagedSkillsMarker(target.dir, previousMarker);
488
+ const message = error instanceof Error ? error.message : String(error);
489
+ targetResults.push({
490
+ agents: target.agents,
491
+ targetDir: target.dir,
492
+ installed,
493
+ refreshed,
494
+ unchanged,
495
+ success: false,
496
+ error: message
497
+ });
498
+ }
499
+ }
500
+ const result = {
501
+ success: targetResults.every((entry) => entry.success),
502
+ message: "",
503
+ mode,
504
+ targets: targetResults,
505
+ installed: targetResults.flatMap((entry) => entry.installed),
506
+ refreshed: targetResults.flatMap((entry) => entry.refreshed),
507
+ unchanged: targetResults.flatMap((entry) => entry.unchanged)
508
+ };
509
+ result.message = buildSyncMessage(mode, result);
510
+ return result;
511
+ } catch (error) {
512
+ const message = error instanceof Error ? error.message : String(error);
513
+ const result = {
514
+ success: false,
515
+ message: "",
516
+ mode,
517
+ targets: targetResults,
518
+ installed: targetResults.flatMap((entry) => entry.installed),
519
+ refreshed: targetResults.flatMap((entry) => entry.refreshed),
520
+ unchanged: targetResults.flatMap((entry) => entry.unchanged)
521
+ };
522
+ result.message = `Failed to sync skills (${mode}): ${message}`;
523
+ return result;
524
+ }
525
+ }
526
+ function syncBundledSkills(mode) {
527
+ return syncBundledSkillsForTargets(mode, getTargets(mode));
528
+ }
529
+ function removeBundledSkillsForTargets(mode, targets) {
530
+ const packNames = getCanonicalBundledSkillNames();
531
+ const targetResults = [];
532
+ for (const target of targets) {
533
+ const removed = [];
534
+ const missing = [];
535
+ try {
536
+ const managedTarget = target;
537
+ const marker = readManagedSkillsMarker(target.dir);
538
+ const { managedPackNames, activePackNames } = resolveManagedPackScope(
539
+ managedTarget,
540
+ marker,
541
+ packNames
542
+ );
543
+ const currentRemoval = removeManagedPackArtifacts(
544
+ target.dir,
545
+ activePackNames
546
+ );
547
+ removed.push(...currentRemoval.removed);
548
+ missing.push(...currentRemoval.missing);
549
+ const retiredPackNames = managedPackNames.filter((packName) => {
550
+ return !packNames.includes(packName) && shouldRemoveRetiredManagedPack(path3.join(target.dir, packName));
551
+ });
552
+ const retiredRemoval = removeManagedPackArtifacts(target.dir, retiredPackNames);
553
+ removed.push(...retiredRemoval.removed);
554
+ missing.push(...retiredRemoval.missing);
555
+ removeManagedSkillsMarker(target.dir);
556
+ targetResults.push({
557
+ agents: target.agents,
558
+ targetDir: target.dir,
559
+ removed,
560
+ missing,
561
+ success: true
562
+ });
563
+ } catch (error) {
564
+ const message = error instanceof Error ? error.message : String(error);
565
+ targetResults.push({
566
+ agents: target.agents,
567
+ targetDir: target.dir,
568
+ removed,
569
+ missing,
570
+ success: false,
571
+ error: message
572
+ });
573
+ }
574
+ }
575
+ const result = {
576
+ success: targetResults.every((entry) => entry.success),
577
+ message: "",
578
+ mode,
579
+ targets: targetResults,
580
+ removed: targetResults.flatMap((entry) => entry.removed),
581
+ missing: targetResults.flatMap((entry) => entry.missing)
582
+ };
583
+ result.message = buildRemovalMessage(mode, result);
584
+ return result;
585
+ }
586
+ function hasBundledSkillArtifacts(mode) {
587
+ const packNames = getCanonicalBundledSkillNames();
588
+ const targets = getTargets(mode);
589
+ return targets.some((target) => hasManagedCanonicalBundledSkillInTarget(target.dir, packNames));
590
+ }
591
+ function hasManagedBundledSkillInstall(mode) {
592
+ return getTargets(mode).some((target) => readManagedSkillsMarker(target.dir) !== null);
593
+ }
594
+
595
+ export {
596
+ getGlobalConfigPath,
597
+ getLocalConfigPath,
598
+ ensureDir,
599
+ readConfig,
600
+ hasPlugin,
601
+ updateConfigContent,
602
+ removePluginFromContent,
603
+ createNoOpSkillRemovalResult,
604
+ getBundledSkillLifecycleTargets,
605
+ getBundledSkillTargets,
606
+ syncBundledSkillsForTargets,
607
+ syncBundledSkills,
608
+ removeBundledSkillsForTargets,
609
+ hasBundledSkillArtifacts,
610
+ hasManagedBundledSkillInstall
611
+ };
612
+ //# sourceMappingURL=chunk-QVWOPIZJ.js.map