agentpacks 0.5.0 → 0.6.0
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/README.md +8 -1
- package/dist/api.js +98 -19
- package/dist/cli/export-cmd.js +76 -19
- package/dist/cli/generate.js +29 -0
- package/dist/cli/install.js +7 -0
- package/dist/cli/models-explain.js +7 -0
- package/dist/cli/pack/list.js +7 -0
- package/dist/cli/pack/validate.js +7 -0
- package/dist/cli/publish.js +7 -0
- package/dist/core/config.d.ts +7 -0
- package/dist/core/config.js +7 -0
- package/dist/core/index.js +7 -0
- package/dist/core/metarepo.js +7 -0
- package/dist/core/pack-loader.js +7 -0
- package/dist/exporters/cursor-plugin.d.ts +18 -18
- package/dist/exporters/cursor-plugin.js +117 -29
- package/dist/exporters/index.js +117 -29
- package/dist/index.js +98 -19
- package/dist/node/api.js +98 -19
- package/dist/node/cli/export-cmd.js +76 -19
- package/dist/node/cli/generate.js +29 -0
- package/dist/node/cli/install.js +7 -0
- package/dist/node/cli/models-explain.js +7 -0
- package/dist/node/cli/pack/list.js +7 -0
- package/dist/node/cli/pack/validate.js +7 -0
- package/dist/node/cli/publish.js +7 -0
- package/dist/node/core/config.js +7 -0
- package/dist/node/core/index.js +7 -0
- package/dist/node/core/metarepo.js +7 -0
- package/dist/node/core/pack-loader.js +7 -0
- package/dist/node/exporters/cursor-plugin.js +117 -29
- package/dist/node/exporters/index.js +117 -29
- package/dist/node/index.js +98 -19
- package/dist/node/targets/cursor.js +67 -7
- package/dist/node/targets/index.js +22 -0
- package/dist/node/targets/registry.js +22 -0
- package/dist/targets/cursor.d.ts +1 -1
- package/dist/targets/cursor.js +67 -7
- package/dist/targets/index.js +22 -0
- package/dist/targets/registry.js +22 -0
- package/package.json +2 -2
|
@@ -251,6 +251,44 @@ function skillMatchesTarget(skill, targetId) {
|
|
|
251
251
|
return Array.isArray(targets) && targets.includes(targetId);
|
|
252
252
|
}
|
|
253
253
|
|
|
254
|
+
// src/features/hooks.ts
|
|
255
|
+
import { join as join3 } from "path";
|
|
256
|
+
var TARGET_OVERRIDE_KEYS = ["cursor", "claudecode", "opencode"];
|
|
257
|
+
function parseHooks(packDir, packName) {
|
|
258
|
+
const hooksPath = join3(packDir, "hooks", "hooks.json");
|
|
259
|
+
const raw = readJsonOrNull(hooksPath);
|
|
260
|
+
if (!raw)
|
|
261
|
+
return null;
|
|
262
|
+
const shared = raw.hooks ?? {};
|
|
263
|
+
const targetOverrides = {};
|
|
264
|
+
for (const key of TARGET_OVERRIDE_KEYS) {
|
|
265
|
+
const override = raw[key];
|
|
266
|
+
if (override && typeof override === "object" && "hooks" in override && override.hooks) {
|
|
267
|
+
targetOverrides[key] = override.hooks;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
return {
|
|
271
|
+
packName,
|
|
272
|
+
sourcePath: hooksPath,
|
|
273
|
+
version: raw.version,
|
|
274
|
+
shared,
|
|
275
|
+
targetOverrides
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
function resolveHooksForTarget(hooks, targetId) {
|
|
279
|
+
const merged = {};
|
|
280
|
+
for (const [event, entries] of Object.entries(hooks.shared)) {
|
|
281
|
+
merged[event] = [...entries];
|
|
282
|
+
}
|
|
283
|
+
const overrides = hooks.targetOverrides[targetId];
|
|
284
|
+
if (overrides) {
|
|
285
|
+
for (const [event, entries] of Object.entries(overrides)) {
|
|
286
|
+
merged[event] = [...merged[event] ?? [], ...entries];
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
return merged;
|
|
290
|
+
}
|
|
291
|
+
|
|
254
292
|
// src/core/profile-resolver.ts
|
|
255
293
|
function resolveModels(merged, modelProfile, targetId) {
|
|
256
294
|
let defaultModel = merged.default;
|
|
@@ -374,7 +412,7 @@ class BaseTarget {
|
|
|
374
412
|
}
|
|
375
413
|
|
|
376
414
|
// src/targets/cursor.ts
|
|
377
|
-
import { resolve, join as
|
|
415
|
+
import { resolve, join as join4 } from "path";
|
|
378
416
|
var TARGET_ID = "cursor";
|
|
379
417
|
|
|
380
418
|
class CursorTarget extends BaseTarget {
|
|
@@ -416,7 +454,7 @@ class CursorTarget extends BaseTarget {
|
|
|
416
454
|
if (globs) {
|
|
417
455
|
frontmatter.globs = globs;
|
|
418
456
|
}
|
|
419
|
-
const filepath =
|
|
457
|
+
const filepath = join4(rulesDir, `${rule.name}.mdc`);
|
|
420
458
|
const content = serializeFrontmatter(frontmatter, rule.content);
|
|
421
459
|
writeGeneratedFile(filepath, content);
|
|
422
460
|
filesWritten.push(filepath);
|
|
@@ -442,7 +480,7 @@ class CursorTarget extends BaseTarget {
|
|
|
442
480
|
if (model) {
|
|
443
481
|
frontmatter.model = model;
|
|
444
482
|
}
|
|
445
|
-
const filepath =
|
|
483
|
+
const filepath = join4(agentsDir, `${agent.name}.md`);
|
|
446
484
|
const content = serializeFrontmatter(frontmatter, agent.content);
|
|
447
485
|
writeGeneratedFile(filepath, content);
|
|
448
486
|
filesWritten.push(filepath);
|
|
@@ -457,13 +495,13 @@ class CursorTarget extends BaseTarget {
|
|
|
457
495
|
ensureDir(skillsDir);
|
|
458
496
|
const skills = features.skills.filter((s) => skillMatchesTarget(s, TARGET_ID));
|
|
459
497
|
for (const skill of skills) {
|
|
460
|
-
const skillSubDir =
|
|
498
|
+
const skillSubDir = join4(skillsDir, skill.name);
|
|
461
499
|
ensureDir(skillSubDir);
|
|
462
500
|
const frontmatter = {
|
|
463
501
|
name: skill.name,
|
|
464
502
|
description: skill.meta.description ?? ""
|
|
465
503
|
};
|
|
466
|
-
const filepath =
|
|
504
|
+
const filepath = join4(skillSubDir, "SKILL.md");
|
|
467
505
|
const content = serializeFrontmatter(frontmatter, skill.content);
|
|
468
506
|
writeGeneratedFile(filepath, content);
|
|
469
507
|
filesWritten.push(filepath);
|
|
@@ -478,11 +516,33 @@ class CursorTarget extends BaseTarget {
|
|
|
478
516
|
ensureDir(commandsDir);
|
|
479
517
|
const commands = features.commands.filter((c) => commandMatchesTarget(c, TARGET_ID));
|
|
480
518
|
for (const cmd of commands) {
|
|
481
|
-
const filepath =
|
|
519
|
+
const filepath = join4(commandsDir, `${cmd.name}.md`);
|
|
482
520
|
writeGeneratedFile(filepath, cmd.content);
|
|
483
521
|
filesWritten.push(filepath);
|
|
484
522
|
}
|
|
485
523
|
}
|
|
524
|
+
if (effective.includes("hooks")) {
|
|
525
|
+
const hooksFilepath = resolve(cursorDir, "hooks.json");
|
|
526
|
+
if (deleteExisting) {
|
|
527
|
+
removeIfExists(hooksFilepath);
|
|
528
|
+
filesDeleted.push(hooksFilepath);
|
|
529
|
+
}
|
|
530
|
+
const mergedHooks = {};
|
|
531
|
+
for (const hookSet of features.hooks) {
|
|
532
|
+
const events = resolveHooksForTarget(hookSet, TARGET_ID);
|
|
533
|
+
for (const [event, entries] of Object.entries(events)) {
|
|
534
|
+
if (!mergedHooks[event]) {
|
|
535
|
+
mergedHooks[event] = [];
|
|
536
|
+
}
|
|
537
|
+
mergedHooks[event].push(...entries);
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
if (Object.keys(mergedHooks).length > 0) {
|
|
541
|
+
const hooksVersion = features.hooks.find((h) => h.version !== undefined)?.version ?? 1;
|
|
542
|
+
writeGeneratedJson(hooksFilepath, { version: hooksVersion, hooks: mergedHooks }, { header: false });
|
|
543
|
+
filesWritten.push(hooksFilepath);
|
|
544
|
+
}
|
|
545
|
+
}
|
|
486
546
|
if (effective.includes("mcp")) {
|
|
487
547
|
const mcpEntries = Object.entries(features.mcpServers);
|
|
488
548
|
if (mcpEntries.length > 0) {
|
|
@@ -508,7 +568,7 @@ class CursorTarget extends BaseTarget {
|
|
|
508
568
|
if (guidanceContent) {
|
|
509
569
|
const rulesDir = resolve(cursorDir, "rules");
|
|
510
570
|
ensureDir(rulesDir);
|
|
511
|
-
const filepath =
|
|
571
|
+
const filepath = join4(rulesDir, "model-config.mdc");
|
|
512
572
|
writeGeneratedFile(filepath, guidanceContent, { header: false });
|
|
513
573
|
filesWritten.push(filepath);
|
|
514
574
|
}
|
|
@@ -782,6 +782,28 @@ class CursorTarget extends BaseTarget {
|
|
|
782
782
|
filesWritten.push(filepath);
|
|
783
783
|
}
|
|
784
784
|
}
|
|
785
|
+
if (effective.includes("hooks")) {
|
|
786
|
+
const hooksFilepath = resolve2(cursorDir, "hooks.json");
|
|
787
|
+
if (deleteExisting) {
|
|
788
|
+
removeIfExists(hooksFilepath);
|
|
789
|
+
filesDeleted.push(hooksFilepath);
|
|
790
|
+
}
|
|
791
|
+
const mergedHooks = {};
|
|
792
|
+
for (const hookSet of features.hooks) {
|
|
793
|
+
const events = resolveHooksForTarget(hookSet, TARGET_ID2);
|
|
794
|
+
for (const [event, entries] of Object.entries(events)) {
|
|
795
|
+
if (!mergedHooks[event]) {
|
|
796
|
+
mergedHooks[event] = [];
|
|
797
|
+
}
|
|
798
|
+
mergedHooks[event].push(...entries);
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
if (Object.keys(mergedHooks).length > 0) {
|
|
802
|
+
const hooksVersion = features.hooks.find((h) => h.version !== undefined)?.version ?? 1;
|
|
803
|
+
writeGeneratedJson(hooksFilepath, { version: hooksVersion, hooks: mergedHooks }, { header: false });
|
|
804
|
+
filesWritten.push(hooksFilepath);
|
|
805
|
+
}
|
|
806
|
+
}
|
|
785
807
|
if (effective.includes("mcp")) {
|
|
786
808
|
const mcpEntries = Object.entries(features.mcpServers);
|
|
787
809
|
if (mcpEntries.length > 0) {
|
|
@@ -782,6 +782,28 @@ class CursorTarget extends BaseTarget {
|
|
|
782
782
|
filesWritten.push(filepath);
|
|
783
783
|
}
|
|
784
784
|
}
|
|
785
|
+
if (effective.includes("hooks")) {
|
|
786
|
+
const hooksFilepath = resolve2(cursorDir, "hooks.json");
|
|
787
|
+
if (deleteExisting) {
|
|
788
|
+
removeIfExists(hooksFilepath);
|
|
789
|
+
filesDeleted.push(hooksFilepath);
|
|
790
|
+
}
|
|
791
|
+
const mergedHooks = {};
|
|
792
|
+
for (const hookSet of features.hooks) {
|
|
793
|
+
const events = resolveHooksForTarget(hookSet, TARGET_ID2);
|
|
794
|
+
for (const [event, entries] of Object.entries(events)) {
|
|
795
|
+
if (!mergedHooks[event]) {
|
|
796
|
+
mergedHooks[event] = [];
|
|
797
|
+
}
|
|
798
|
+
mergedHooks[event].push(...entries);
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
if (Object.keys(mergedHooks).length > 0) {
|
|
802
|
+
const hooksVersion = features.hooks.find((h) => h.version !== undefined)?.version ?? 1;
|
|
803
|
+
writeGeneratedJson(hooksFilepath, { version: hooksVersion, hooks: mergedHooks }, { header: false });
|
|
804
|
+
filesWritten.push(hooksFilepath);
|
|
805
|
+
}
|
|
806
|
+
}
|
|
785
807
|
if (effective.includes("mcp")) {
|
|
786
808
|
const mcpEntries = Object.entries(features.mcpServers);
|
|
787
809
|
if (mcpEntries.length > 0) {
|
package/dist/targets/cursor.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { BaseTarget, type GenerateOptions, type GenerateResult } from './base-ta
|
|
|
3
3
|
/**
|
|
4
4
|
* Cursor target generator.
|
|
5
5
|
* Generates: .cursor/rules/, .cursor/skills/, .cursor/agents/, .cursor/commands/,
|
|
6
|
-
* .cursor/mcp.json, .cursorignore
|
|
6
|
+
* .cursor/hooks.json, .cursor/mcp.json, .cursorignore
|
|
7
7
|
*/
|
|
8
8
|
export declare class CursorTarget extends BaseTarget {
|
|
9
9
|
readonly id = "cursor";
|
package/dist/targets/cursor.js
CHANGED
|
@@ -251,6 +251,44 @@ function skillMatchesTarget(skill, targetId) {
|
|
|
251
251
|
return Array.isArray(targets) && targets.includes(targetId);
|
|
252
252
|
}
|
|
253
253
|
|
|
254
|
+
// src/features/hooks.ts
|
|
255
|
+
import { join as join3 } from "path";
|
|
256
|
+
var TARGET_OVERRIDE_KEYS = ["cursor", "claudecode", "opencode"];
|
|
257
|
+
function parseHooks(packDir, packName) {
|
|
258
|
+
const hooksPath = join3(packDir, "hooks", "hooks.json");
|
|
259
|
+
const raw = readJsonOrNull(hooksPath);
|
|
260
|
+
if (!raw)
|
|
261
|
+
return null;
|
|
262
|
+
const shared = raw.hooks ?? {};
|
|
263
|
+
const targetOverrides = {};
|
|
264
|
+
for (const key of TARGET_OVERRIDE_KEYS) {
|
|
265
|
+
const override = raw[key];
|
|
266
|
+
if (override && typeof override === "object" && "hooks" in override && override.hooks) {
|
|
267
|
+
targetOverrides[key] = override.hooks;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
return {
|
|
271
|
+
packName,
|
|
272
|
+
sourcePath: hooksPath,
|
|
273
|
+
version: raw.version,
|
|
274
|
+
shared,
|
|
275
|
+
targetOverrides
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
function resolveHooksForTarget(hooks, targetId) {
|
|
279
|
+
const merged = {};
|
|
280
|
+
for (const [event, entries] of Object.entries(hooks.shared)) {
|
|
281
|
+
merged[event] = [...entries];
|
|
282
|
+
}
|
|
283
|
+
const overrides = hooks.targetOverrides[targetId];
|
|
284
|
+
if (overrides) {
|
|
285
|
+
for (const [event, entries] of Object.entries(overrides)) {
|
|
286
|
+
merged[event] = [...merged[event] ?? [], ...entries];
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
return merged;
|
|
290
|
+
}
|
|
291
|
+
|
|
254
292
|
// src/core/profile-resolver.ts
|
|
255
293
|
function resolveModels(merged, modelProfile, targetId) {
|
|
256
294
|
let defaultModel = merged.default;
|
|
@@ -374,7 +412,7 @@ class BaseTarget {
|
|
|
374
412
|
}
|
|
375
413
|
|
|
376
414
|
// src/targets/cursor.ts
|
|
377
|
-
import { resolve, join as
|
|
415
|
+
import { resolve, join as join4 } from "path";
|
|
378
416
|
var TARGET_ID = "cursor";
|
|
379
417
|
|
|
380
418
|
class CursorTarget extends BaseTarget {
|
|
@@ -416,7 +454,7 @@ class CursorTarget extends BaseTarget {
|
|
|
416
454
|
if (globs) {
|
|
417
455
|
frontmatter.globs = globs;
|
|
418
456
|
}
|
|
419
|
-
const filepath =
|
|
457
|
+
const filepath = join4(rulesDir, `${rule.name}.mdc`);
|
|
420
458
|
const content = serializeFrontmatter(frontmatter, rule.content);
|
|
421
459
|
writeGeneratedFile(filepath, content);
|
|
422
460
|
filesWritten.push(filepath);
|
|
@@ -442,7 +480,7 @@ class CursorTarget extends BaseTarget {
|
|
|
442
480
|
if (model) {
|
|
443
481
|
frontmatter.model = model;
|
|
444
482
|
}
|
|
445
|
-
const filepath =
|
|
483
|
+
const filepath = join4(agentsDir, `${agent.name}.md`);
|
|
446
484
|
const content = serializeFrontmatter(frontmatter, agent.content);
|
|
447
485
|
writeGeneratedFile(filepath, content);
|
|
448
486
|
filesWritten.push(filepath);
|
|
@@ -457,13 +495,13 @@ class CursorTarget extends BaseTarget {
|
|
|
457
495
|
ensureDir(skillsDir);
|
|
458
496
|
const skills = features.skills.filter((s) => skillMatchesTarget(s, TARGET_ID));
|
|
459
497
|
for (const skill of skills) {
|
|
460
|
-
const skillSubDir =
|
|
498
|
+
const skillSubDir = join4(skillsDir, skill.name);
|
|
461
499
|
ensureDir(skillSubDir);
|
|
462
500
|
const frontmatter = {
|
|
463
501
|
name: skill.name,
|
|
464
502
|
description: skill.meta.description ?? ""
|
|
465
503
|
};
|
|
466
|
-
const filepath =
|
|
504
|
+
const filepath = join4(skillSubDir, "SKILL.md");
|
|
467
505
|
const content = serializeFrontmatter(frontmatter, skill.content);
|
|
468
506
|
writeGeneratedFile(filepath, content);
|
|
469
507
|
filesWritten.push(filepath);
|
|
@@ -478,11 +516,33 @@ class CursorTarget extends BaseTarget {
|
|
|
478
516
|
ensureDir(commandsDir);
|
|
479
517
|
const commands = features.commands.filter((c) => commandMatchesTarget(c, TARGET_ID));
|
|
480
518
|
for (const cmd of commands) {
|
|
481
|
-
const filepath =
|
|
519
|
+
const filepath = join4(commandsDir, `${cmd.name}.md`);
|
|
482
520
|
writeGeneratedFile(filepath, cmd.content);
|
|
483
521
|
filesWritten.push(filepath);
|
|
484
522
|
}
|
|
485
523
|
}
|
|
524
|
+
if (effective.includes("hooks")) {
|
|
525
|
+
const hooksFilepath = resolve(cursorDir, "hooks.json");
|
|
526
|
+
if (deleteExisting) {
|
|
527
|
+
removeIfExists(hooksFilepath);
|
|
528
|
+
filesDeleted.push(hooksFilepath);
|
|
529
|
+
}
|
|
530
|
+
const mergedHooks = {};
|
|
531
|
+
for (const hookSet of features.hooks) {
|
|
532
|
+
const events = resolveHooksForTarget(hookSet, TARGET_ID);
|
|
533
|
+
for (const [event, entries] of Object.entries(events)) {
|
|
534
|
+
if (!mergedHooks[event]) {
|
|
535
|
+
mergedHooks[event] = [];
|
|
536
|
+
}
|
|
537
|
+
mergedHooks[event].push(...entries);
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
if (Object.keys(mergedHooks).length > 0) {
|
|
541
|
+
const hooksVersion = features.hooks.find((h) => h.version !== undefined)?.version ?? 1;
|
|
542
|
+
writeGeneratedJson(hooksFilepath, { version: hooksVersion, hooks: mergedHooks }, { header: false });
|
|
543
|
+
filesWritten.push(hooksFilepath);
|
|
544
|
+
}
|
|
545
|
+
}
|
|
486
546
|
if (effective.includes("mcp")) {
|
|
487
547
|
const mcpEntries = Object.entries(features.mcpServers);
|
|
488
548
|
if (mcpEntries.length > 0) {
|
|
@@ -508,7 +568,7 @@ class CursorTarget extends BaseTarget {
|
|
|
508
568
|
if (guidanceContent) {
|
|
509
569
|
const rulesDir = resolve(cursorDir, "rules");
|
|
510
570
|
ensureDir(rulesDir);
|
|
511
|
-
const filepath =
|
|
571
|
+
const filepath = join4(rulesDir, "model-config.mdc");
|
|
512
572
|
writeGeneratedFile(filepath, guidanceContent, { header: false });
|
|
513
573
|
filesWritten.push(filepath);
|
|
514
574
|
}
|
package/dist/targets/index.js
CHANGED
|
@@ -782,6 +782,28 @@ class CursorTarget extends BaseTarget {
|
|
|
782
782
|
filesWritten.push(filepath);
|
|
783
783
|
}
|
|
784
784
|
}
|
|
785
|
+
if (effective.includes("hooks")) {
|
|
786
|
+
const hooksFilepath = resolve2(cursorDir, "hooks.json");
|
|
787
|
+
if (deleteExisting) {
|
|
788
|
+
removeIfExists(hooksFilepath);
|
|
789
|
+
filesDeleted.push(hooksFilepath);
|
|
790
|
+
}
|
|
791
|
+
const mergedHooks = {};
|
|
792
|
+
for (const hookSet of features.hooks) {
|
|
793
|
+
const events = resolveHooksForTarget(hookSet, TARGET_ID2);
|
|
794
|
+
for (const [event, entries] of Object.entries(events)) {
|
|
795
|
+
if (!mergedHooks[event]) {
|
|
796
|
+
mergedHooks[event] = [];
|
|
797
|
+
}
|
|
798
|
+
mergedHooks[event].push(...entries);
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
if (Object.keys(mergedHooks).length > 0) {
|
|
802
|
+
const hooksVersion = features.hooks.find((h) => h.version !== undefined)?.version ?? 1;
|
|
803
|
+
writeGeneratedJson(hooksFilepath, { version: hooksVersion, hooks: mergedHooks }, { header: false });
|
|
804
|
+
filesWritten.push(hooksFilepath);
|
|
805
|
+
}
|
|
806
|
+
}
|
|
785
807
|
if (effective.includes("mcp")) {
|
|
786
808
|
const mcpEntries = Object.entries(features.mcpServers);
|
|
787
809
|
if (mcpEntries.length > 0) {
|
package/dist/targets/registry.js
CHANGED
|
@@ -782,6 +782,28 @@ class CursorTarget extends BaseTarget {
|
|
|
782
782
|
filesWritten.push(filepath);
|
|
783
783
|
}
|
|
784
784
|
}
|
|
785
|
+
if (effective.includes("hooks")) {
|
|
786
|
+
const hooksFilepath = resolve2(cursorDir, "hooks.json");
|
|
787
|
+
if (deleteExisting) {
|
|
788
|
+
removeIfExists(hooksFilepath);
|
|
789
|
+
filesDeleted.push(hooksFilepath);
|
|
790
|
+
}
|
|
791
|
+
const mergedHooks = {};
|
|
792
|
+
for (const hookSet of features.hooks) {
|
|
793
|
+
const events = resolveHooksForTarget(hookSet, TARGET_ID2);
|
|
794
|
+
for (const [event, entries] of Object.entries(events)) {
|
|
795
|
+
if (!mergedHooks[event]) {
|
|
796
|
+
mergedHooks[event] = [];
|
|
797
|
+
}
|
|
798
|
+
mergedHooks[event].push(...entries);
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
if (Object.keys(mergedHooks).length > 0) {
|
|
802
|
+
const hooksVersion = features.hooks.find((h) => h.version !== undefined)?.version ?? 1;
|
|
803
|
+
writeGeneratedJson(hooksFilepath, { version: hooksVersion, hooks: mergedHooks }, { header: false });
|
|
804
|
+
filesWritten.push(hooksFilepath);
|
|
805
|
+
}
|
|
806
|
+
}
|
|
785
807
|
if (effective.includes("mcp")) {
|
|
786
808
|
const mcpEntries = Object.entries(features.mcpServers);
|
|
787
809
|
if (mcpEntries.length > 0) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agentpacks",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Composable AI agent configuration manager. Pack-based rules, commands, skills, hooks, and MCP sync across OpenCode, Cursor, Claude Code, Codex, Gemini, Copilot, and more.",
|
|
6
6
|
"keywords": [
|
|
@@ -500,7 +500,7 @@
|
|
|
500
500
|
"gray-matter": "^4.0.3",
|
|
501
501
|
"zod": "^4.3.5",
|
|
502
502
|
"jsonc-parser": "^3.3.1",
|
|
503
|
-
"glob": "^13.0.
|
|
503
|
+
"glob": "^13.0.6"
|
|
504
504
|
},
|
|
505
505
|
"devDependencies": {
|
|
506
506
|
"@contractspec/tool.typescript": "2.6.0",
|