agent-conf 2.0.4 → 2.1.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/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
+ CanonicalRepoConfigSchema,
3
4
  addManagedMetadata,
4
5
  buildAgentsMd,
5
6
  checkAllManagedFiles,
@@ -12,7 +13,7 @@ import {
12
13
  parseGlobalBlockMetadata,
13
14
  stripMetadataComments,
14
15
  validateSkillFrontmatter
15
- } from "./chunk-EN5LTDER.js";
16
+ } from "./chunk-MZ2GBXCB.js";
16
17
 
17
18
  // src/cli.ts
18
19
  import { Command } from "commander";
@@ -49,7 +50,9 @@ var ContentSchema = z.object({
49
50
  merged: z.boolean()
50
51
  }),
51
52
  skills: z.array(z.string()),
52
- targets: z.array(z.string()).optional()
53
+ targets: z.array(z.string()).optional(),
54
+ /** Marker prefix used for managed content (default: "agent-conf") */
55
+ marker_prefix: z.string().optional()
53
56
  });
54
57
  var LockfileSchema = z.object({
55
58
  version: z.literal("1"),
@@ -66,7 +69,7 @@ var CONFIG_DIR = ".agent-conf";
66
69
  var LOCKFILE_NAME = "lockfile.json";
67
70
  var CLI_VERSION = "0.1.0";
68
71
  function getBuildCommit() {
69
- return true ? "ceff9aa02d2b0d813fff15615e9a0b530148a6ac" : "unknown";
72
+ return true ? "495cb19c3410dc3d585d83d93279944ff665eb9e" : "unknown";
70
73
  }
71
74
  function getLockfilePath(targetDir) {
72
75
  return path.join(targetDir, CONFIG_DIR, LOCKFILE_NAME);
@@ -97,7 +100,8 @@ async function writeLockfile(targetDir, options) {
97
100
  merged: true
98
101
  },
99
102
  skills: options.skills,
100
- targets: options.targets ?? ["claude"]
103
+ targets: options.targets ?? ["claude"],
104
+ marker_prefix: options.markerPrefix
101
105
  },
102
106
  cli_version: CLI_VERSION
103
107
  };
@@ -153,14 +157,17 @@ async function checkCommand(options = {}) {
153
157
  return;
154
158
  }
155
159
  const targets = lockfile.content.targets ?? ["claude"];
160
+ const markerPrefix = lockfile.content.marker_prefix;
156
161
  const modifiedFiles = [];
157
- const allFiles = await checkAllManagedFiles(targetDir, targets);
162
+ const checkOptions = markerPrefix ? { markerPrefix, metadataPrefix: markerPrefix } : {};
163
+ const allFiles = await checkAllManagedFiles(targetDir, targets, checkOptions);
164
+ const keyPrefix = markerPrefix ? `${markerPrefix.replace(/-/g, "_")}_` : "agent_conf_";
158
165
  for (const file of allFiles) {
159
166
  if (!file.hasChanges) continue;
160
167
  if (file.type === "agents") {
161
168
  const agentsMdPath = path2.join(targetDir, "AGENTS.md");
162
169
  const content = await fs2.readFile(agentsMdPath, "utf-8");
163
- const parsed = parseAgentsMd(content);
170
+ const parsed = parseAgentsMd(content, markerPrefix ? { prefix: markerPrefix } : void 0);
164
171
  if (parsed.globalBlock) {
165
172
  const metadata = parseGlobalBlockMetadata(parsed.globalBlock);
166
173
  const contentWithoutMeta = stripMetadataComments(parsed.globalBlock);
@@ -177,8 +184,11 @@ async function checkCommand(options = {}) {
177
184
  const content = await fs2.readFile(skillPath, "utf-8");
178
185
  const { frontmatter } = parseFrontmatter(content);
179
186
  const metadata = frontmatter.metadata;
180
- const storedHash = metadata?.agent_conf_content_hash ?? "unknown";
181
- const currentHash = computeContentHash(content);
187
+ const storedHash = metadata?.[`${keyPrefix}content_hash`] ?? "unknown";
188
+ const currentHash = computeContentHash(
189
+ content,
190
+ markerPrefix ? { metadataPrefix: markerPrefix } : void 0
191
+ );
182
192
  modifiedFiles.push({
183
193
  path: file.path,
184
194
  type: "skill",
@@ -187,6 +197,23 @@ async function checkCommand(options = {}) {
187
197
  });
188
198
  }
189
199
  }
200
+ if (allFiles.length === 0) {
201
+ if (options.quiet) {
202
+ process.exit(1);
203
+ }
204
+ console.log();
205
+ console.log(pc.bold("agent-conf check"));
206
+ console.log();
207
+ console.log(`${pc.red("\u2717")} No managed files found`);
208
+ console.log();
209
+ console.log(pc.dim("This repository appears to be synced but no managed files were detected."));
210
+ if (markerPrefix) {
211
+ console.log(pc.dim(`Expected marker prefix: ${markerPrefix}`));
212
+ }
213
+ console.log(pc.dim("Run 'agent-conf sync' to restore the managed files."));
214
+ console.log();
215
+ process.exit(1);
216
+ }
190
217
  if (options.quiet) {
191
218
  if (modifiedFiles.length > 0) {
192
219
  process.exit(1);
@@ -568,9 +595,10 @@ function stripAgentsReference(content) {
568
595
  }
569
596
  async function mergeAgentsMd(targetDir, globalContent, _source, options = { override: false }) {
570
597
  const existing = await gatherExistingContent(targetDir);
598
+ const markerOptions = options.markerPrefix ? { prefix: options.markerPrefix } : void 0;
571
599
  const contentToMerge = [];
572
600
  if (existing.agentsMd !== null && !options.override) {
573
- const parsed = parseAgentsMd(existing.agentsMd);
601
+ const parsed = parseAgentsMd(existing.agentsMd, markerOptions);
574
602
  if (parsed.hasMarkers) {
575
603
  const repoContent2 = extractRepoBlockContent(parsed);
576
604
  if (repoContent2) {
@@ -589,7 +617,7 @@ async function mergeAgentsMd(targetDir, globalContent, _source, options = { over
589
617
  }
590
618
  }
591
619
  const repoContent = contentToMerge.length > 0 ? contentToMerge.join("\n\n") : null;
592
- const content = buildAgentsMd(globalContent, repoContent, {});
620
+ const content = buildAgentsMd(globalContent, repoContent, {}, markerOptions);
593
621
  const merged = !options.override && (existing.agentsMd !== null || existing.claudeMd !== null);
594
622
  const preservedRepoContent = contentToMerge.length > 0;
595
623
  return {
@@ -676,9 +704,11 @@ function getTargetConfig(target) {
676
704
 
677
705
  // src/core/sync.ts
678
706
  async function sync(targetDir, resolvedSource, options = { override: false, targets: ["claude"] }) {
707
+ const markerPrefix = resolvedSource.markerPrefix;
679
708
  const globalContent = await fs5.readFile(resolvedSource.agentsMdPath, "utf-8");
680
709
  const mergeResult = await mergeAgentsMd(targetDir, globalContent, resolvedSource.source, {
681
- override: options.override
710
+ override: options.override,
711
+ markerPrefix
682
712
  });
683
713
  await writeAgentsMd(targetDir, mergeResult.content);
684
714
  const skillDirs = await fg("*/", {
@@ -707,7 +737,8 @@ async function sync(targetDir, resolvedSource, options = { override: false, targ
707
737
  targetDir,
708
738
  resolvedSource.skillsPath,
709
739
  skillNames,
710
- config
740
+ config,
741
+ markerPrefix
711
742
  );
712
743
  totalCopied += skillsCopied;
713
744
  let instructionsResult;
@@ -735,7 +766,8 @@ async function sync(targetDir, resolvedSource, options = { override: false, targ
735
766
  source: resolvedSource.source,
736
767
  globalBlockContent: globalContent,
737
768
  skills: skillNames,
738
- targets: options.targets
769
+ targets: options.targets,
770
+ markerPrefix
739
771
  };
740
772
  if (options.pinnedVersion) {
741
773
  lockfileOptions.pinnedVersion = options.pinnedVersion;
@@ -755,18 +787,18 @@ async function sync(targetDir, resolvedSource, options = { override: false, targ
755
787
  }
756
788
  };
757
789
  }
758
- async function syncSkillsToTarget(targetDir, sourceSkillsPath, skillNames, config) {
790
+ async function syncSkillsToTarget(targetDir, sourceSkillsPath, skillNames, config, metadataPrefix) {
759
791
  const targetSkillsPath = path5.join(targetDir, config.dir, "skills");
760
792
  let copied = 0;
761
793
  for (const skillName of skillNames) {
762
794
  const sourceDir = path5.join(sourceSkillsPath, skillName);
763
795
  const targetSkillDir = path5.join(targetSkillsPath, skillName);
764
- const filesCopied = await copySkillDirectory(sourceDir, targetSkillDir);
796
+ const filesCopied = await copySkillDirectory(sourceDir, targetSkillDir, metadataPrefix);
765
797
  copied += filesCopied;
766
798
  }
767
799
  return copied;
768
800
  }
769
- async function copySkillDirectory(sourceDir, targetDir) {
801
+ async function copySkillDirectory(sourceDir, targetDir, metadataPrefix) {
770
802
  await fs5.mkdir(targetDir, { recursive: true });
771
803
  const entries = await fs5.readdir(sourceDir, { withFileTypes: true });
772
804
  let copied = 0;
@@ -774,10 +806,10 @@ async function copySkillDirectory(sourceDir, targetDir) {
774
806
  const sourcePath = path5.join(sourceDir, entry.name);
775
807
  const targetPath = path5.join(targetDir, entry.name);
776
808
  if (entry.isDirectory()) {
777
- copied += await copySkillDirectory(sourcePath, targetPath);
809
+ copied += await copySkillDirectory(sourcePath, targetPath, metadataPrefix);
778
810
  } else if (entry.name === "SKILL.md") {
779
811
  const content = await fs5.readFile(sourcePath, "utf-8");
780
- const contentWithMetadata = addManagedMetadata(content);
812
+ const contentWithMetadata = addManagedMetadata(content, { metadataPrefix });
781
813
  await fs5.writeFile(targetPath, contentWithMetadata, "utf-8");
782
814
  copied++;
783
815
  } else {
@@ -817,9 +849,10 @@ async function getSyncStatus(targetDir) {
817
849
  function findOrphanedSkills(previousSkills, currentSkills) {
818
850
  return previousSkills.filter((skill) => !currentSkills.includes(skill));
819
851
  }
820
- async function deleteOrphanedSkills(targetDir, orphanedSkills, targets, previouslyTrackedSkills) {
852
+ async function deleteOrphanedSkills(targetDir, orphanedSkills, targets, previouslyTrackedSkills, options = {}) {
821
853
  const deleted = [];
822
854
  const skipped = [];
855
+ const metadataOptions = options.metadataPrefix ? { metadataPrefix: options.metadataPrefix } : void 0;
823
856
  for (const skillName of orphanedSkills) {
824
857
  let wasDeleted = false;
825
858
  for (const target of targets) {
@@ -832,15 +865,15 @@ async function deleteOrphanedSkills(targetDir, orphanedSkills, targets, previous
832
865
  const skillMdPath = path5.join(skillDir, "SKILL.md");
833
866
  try {
834
867
  const content = await fs5.readFile(skillMdPath, "utf-8");
835
- const { isManaged, hasManualChanges } = await import("./skill-metadata-XANK6RZP.js");
836
- if (!isManaged(content)) {
868
+ const { isManaged, hasManualChanges } = await import("./skill-metadata-DK2WBJJ3.js");
869
+ if (!isManaged(content, metadataOptions)) {
837
870
  if (!skipped.includes(skillName)) {
838
871
  skipped.push(skillName);
839
872
  }
840
873
  continue;
841
874
  }
842
875
  const wasInPreviousLockfile = previouslyTrackedSkills.includes(skillName);
843
- const isUnmodified = !hasManualChanges(content);
876
+ const isUnmodified = !hasManualChanges(content, metadataOptions);
844
877
  if (!wasInPreviousLockfile && !isUnmodified) {
845
878
  if (!skipped.includes(skillName)) {
846
879
  skipped.push(skillName);
@@ -864,7 +897,7 @@ async function deleteOrphanedSkills(targetDir, orphanedSkills, targets, previous
864
897
  }
865
898
 
866
899
  // src/commands/shared.ts
867
- import * as path11 from "path";
900
+ import * as path12 from "path";
868
901
  import * as prompts3 from "@clack/prompts";
869
902
  import pc5 from "picocolors";
870
903
 
@@ -982,16 +1015,40 @@ async function installPreCommitHook(targetDir, config) {
982
1015
 
983
1016
  // src/core/source.ts
984
1017
  import { exec } from "child_process";
985
- import * as fs7 from "fs/promises";
986
- import * as path7 from "path";
1018
+ import * as fs8 from "fs/promises";
1019
+ import * as path8 from "path";
987
1020
  import { promisify } from "util";
988
1021
  import { simpleGit } from "simple-git";
1022
+
1023
+ // src/config/loader.ts
1024
+ import * as fs7 from "fs/promises";
1025
+ import * as path7 from "path";
1026
+ import { parse as parseYaml } from "yaml";
1027
+ var CANONICAL_REPO_CONFIG = "agent-conf.yaml";
1028
+ async function loadCanonicalRepoConfig(basePath) {
1029
+ const configPath = path7.join(basePath, CANONICAL_REPO_CONFIG);
1030
+ try {
1031
+ const content = await fs7.readFile(configPath, "utf-8");
1032
+ const parsed = parseYaml(content);
1033
+ return CanonicalRepoConfigSchema.parse(parsed);
1034
+ } catch (error) {
1035
+ if (isNodeError(error) && error.code === "ENOENT") {
1036
+ return void 0;
1037
+ }
1038
+ throw new Error(`Failed to load ${CANONICAL_REPO_CONFIG}: ${error}`);
1039
+ }
1040
+ }
1041
+ function isNodeError(error) {
1042
+ return error instanceof Error && "code" in error;
1043
+ }
1044
+
1045
+ // src/core/source.ts
989
1046
  var execAsync = promisify(exec);
990
1047
  var DEFAULT_REF = "master";
991
1048
  async function resolveLocalSource(options = {}) {
992
1049
  let basePath;
993
1050
  if (options.path) {
994
- basePath = path7.resolve(options.path);
1051
+ basePath = path8.resolve(options.path);
995
1052
  } else {
996
1053
  basePath = await findCanonicalRepo(process.cwd());
997
1054
  }
@@ -1003,6 +1060,8 @@ async function resolveLocalSource(options = {}) {
1003
1060
  commitSha = log2.latest?.hash;
1004
1061
  } catch {
1005
1062
  }
1063
+ const canonicalConfig = await loadCanonicalRepoConfig(basePath);
1064
+ const markerPrefix = canonicalConfig?.markers.prefix ?? "agent-conf";
1006
1065
  const source = {
1007
1066
  type: "local",
1008
1067
  path: basePath,
@@ -1011,8 +1070,9 @@ async function resolveLocalSource(options = {}) {
1011
1070
  return {
1012
1071
  source,
1013
1072
  basePath,
1014
- agentsMdPath: path7.join(basePath, "instructions", "AGENTS.md"),
1015
- skillsPath: path7.join(basePath, "skills")
1073
+ agentsMdPath: path8.join(basePath, "instructions", "AGENTS.md"),
1074
+ skillsPath: path8.join(basePath, "skills"),
1075
+ markerPrefix
1016
1076
  };
1017
1077
  }
1018
1078
  async function resolveGithubSource(options, tempDir) {
@@ -1021,6 +1081,8 @@ async function resolveGithubSource(options, tempDir) {
1021
1081
  const clonedGit = simpleGit(tempDir);
1022
1082
  const log2 = await clonedGit.log({ maxCount: 1 });
1023
1083
  const commitSha = log2.latest?.hash ?? "";
1084
+ const canonicalConfig = await loadCanonicalRepoConfig(tempDir);
1085
+ const markerPrefix = canonicalConfig?.markers.prefix ?? "agent-conf";
1024
1086
  const source = {
1025
1087
  type: "github",
1026
1088
  repository,
@@ -1030,8 +1092,9 @@ async function resolveGithubSource(options, tempDir) {
1030
1092
  return {
1031
1093
  source,
1032
1094
  basePath: tempDir,
1033
- agentsMdPath: path7.join(tempDir, "instructions", "AGENTS.md"),
1034
- skillsPath: path7.join(tempDir, "skills")
1095
+ agentsMdPath: path8.join(tempDir, "instructions", "AGENTS.md"),
1096
+ skillsPath: path8.join(tempDir, "skills"),
1097
+ markerPrefix
1035
1098
  };
1036
1099
  }
1037
1100
  async function cloneRepository(repository, ref, tempDir) {
@@ -1056,19 +1119,19 @@ async function isGhAvailable() {
1056
1119
  }
1057
1120
  }
1058
1121
  async function findCanonicalRepo(startDir) {
1059
- let currentDir = path7.resolve(startDir);
1060
- const root = path7.parse(currentDir).root;
1122
+ let currentDir = path8.resolve(startDir);
1123
+ const root = path8.parse(currentDir).root;
1061
1124
  let checkDir = currentDir;
1062
1125
  while (checkDir !== root) {
1063
1126
  if (await isCanonicalRepo(checkDir)) {
1064
1127
  return checkDir;
1065
1128
  }
1066
- checkDir = path7.dirname(checkDir);
1129
+ checkDir = path8.dirname(checkDir);
1067
1130
  }
1068
- currentDir = path7.resolve(startDir);
1131
+ currentDir = path8.resolve(startDir);
1069
1132
  while (currentDir !== root) {
1070
- const parentDir = path7.dirname(currentDir);
1071
- const siblingCanonicalRepo = path7.join(parentDir, "agent-conf");
1133
+ const parentDir = path8.dirname(currentDir);
1134
+ const siblingCanonicalRepo = path8.join(parentDir, "agent-conf");
1072
1135
  if (await isCanonicalRepo(siblingCanonicalRepo)) {
1073
1136
  return siblingCanonicalRepo;
1074
1137
  }
@@ -1080,15 +1143,15 @@ async function findCanonicalRepo(startDir) {
1080
1143
  }
1081
1144
  async function isCanonicalRepo(dir) {
1082
1145
  try {
1083
- const stat4 = await fs7.stat(dir).catch(() => null);
1146
+ const stat4 = await fs8.stat(dir).catch(() => null);
1084
1147
  if (!stat4?.isDirectory()) {
1085
1148
  return false;
1086
1149
  }
1087
- const instructionsPath = path7.join(dir, "instructions", "AGENTS.md");
1088
- const skillsPath = path7.join(dir, "skills");
1150
+ const instructionsPath = path8.join(dir, "instructions", "AGENTS.md");
1151
+ const skillsPath = path8.join(dir, "skills");
1089
1152
  const [instructionsExists, skillsExists] = await Promise.all([
1090
- fs7.access(instructionsPath).then(() => true).catch(() => false),
1091
- fs7.access(skillsPath).then(() => true).catch(() => false)
1153
+ fs8.access(instructionsPath).then(() => true).catch(() => false),
1154
+ fs8.access(skillsPath).then(() => true).catch(() => false)
1092
1155
  ]);
1093
1156
  if (!instructionsExists || !skillsExists) {
1094
1157
  return false;
@@ -1110,11 +1173,11 @@ async function isCanonicalRepo(dir) {
1110
1173
  }
1111
1174
  }
1112
1175
  async function validateCanonicalRepo(basePath) {
1113
- const agentsMdPath = path7.join(basePath, "instructions", "AGENTS.md");
1114
- const skillsPath = path7.join(basePath, "skills");
1176
+ const agentsMdPath = path8.join(basePath, "instructions", "AGENTS.md");
1177
+ const skillsPath = path8.join(basePath, "skills");
1115
1178
  const [agentsMdExists, skillsExists] = await Promise.all([
1116
- fs7.access(agentsMdPath).then(() => true).catch(() => false),
1117
- fs7.access(skillsPath).then(() => true).catch(() => false)
1179
+ fs8.access(agentsMdPath).then(() => true).catch(() => false),
1180
+ fs8.access(skillsPath).then(() => true).catch(() => false)
1118
1181
  ]);
1119
1182
  if (!agentsMdExists) {
1120
1183
  throw new Error(`Invalid canonical repository: missing instructions/AGENTS.md at ${basePath}`);
@@ -1233,8 +1296,8 @@ function compareVersions(a, b) {
1233
1296
  }
1234
1297
 
1235
1298
  // src/core/workflows.ts
1236
- import * as fs8 from "fs/promises";
1237
- import * as path8 from "path";
1299
+ import * as fs9 from "fs/promises";
1300
+ import * as path9 from "path";
1238
1301
  var DEFAULT_CLI_NAME2 = "agent-conf";
1239
1302
  var WORKFLOWS_DIR = ".github/workflows";
1240
1303
  function getWorkflowConfig(sourceRepo, config) {
@@ -1263,10 +1326,10 @@ function getWorkflowFiles(config) {
1263
1326
  ];
1264
1327
  }
1265
1328
  function getWorkflowsDir(repoRoot) {
1266
- return path8.join(repoRoot, WORKFLOWS_DIR);
1329
+ return path9.join(repoRoot, WORKFLOWS_DIR);
1267
1330
  }
1268
1331
  function getWorkflowPath(repoRoot, filename) {
1269
- return path8.join(repoRoot, WORKFLOWS_DIR, filename);
1332
+ return path9.join(repoRoot, WORKFLOWS_DIR, filename);
1270
1333
  }
1271
1334
  function generateSyncWorkflow(versionRef, config) {
1272
1335
  const { sourceRepo, cliName, secretName } = config;
@@ -1356,13 +1419,13 @@ function generateWorkflow(workflow, versionRef, config) {
1356
1419
  }
1357
1420
  async function ensureWorkflowsDir(repoRoot) {
1358
1421
  const dir = getWorkflowsDir(repoRoot);
1359
- await fs8.mkdir(dir, { recursive: true });
1422
+ await fs9.mkdir(dir, { recursive: true });
1360
1423
  }
1361
1424
  async function writeWorkflow(repoRoot, workflow, versionRef, config) {
1362
1425
  await ensureWorkflowsDir(repoRoot);
1363
1426
  const filePath = getWorkflowPath(repoRoot, workflow.filename);
1364
1427
  const content = generateWorkflow(workflow, versionRef, config);
1365
- await fs8.writeFile(filePath, content, "utf-8");
1428
+ await fs9.writeFile(filePath, content, "utf-8");
1366
1429
  }
1367
1430
  async function syncWorkflows(repoRoot, versionRef, sourceRepo, resolvedConfig) {
1368
1431
  const config = getWorkflowConfig(sourceRepo, resolvedConfig);
@@ -1377,7 +1440,7 @@ async function syncWorkflows(repoRoot, versionRef, sourceRepo, resolvedConfig) {
1377
1440
  const expectedContent = generateWorkflow(workflow, versionRef, config);
1378
1441
  let existingContent = null;
1379
1442
  try {
1380
- existingContent = await fs8.readFile(filePath, "utf-8");
1443
+ existingContent = await fs9.readFile(filePath, "utf-8");
1381
1444
  } catch {
1382
1445
  }
1383
1446
  if (existingContent === null) {
@@ -1394,15 +1457,15 @@ async function syncWorkflows(repoRoot, versionRef, sourceRepo, resolvedConfig) {
1394
1457
  }
1395
1458
 
1396
1459
  // src/utils/fs.ts
1397
- import * as fs9 from "fs/promises";
1460
+ import * as fs10 from "fs/promises";
1398
1461
  import * as os2 from "os";
1399
- import * as path9 from "path";
1462
+ import * as path10 from "path";
1400
1463
  async function ensureDir(dirPath) {
1401
- await fs9.mkdir(dirPath, { recursive: true });
1464
+ await fs10.mkdir(dirPath, { recursive: true });
1402
1465
  }
1403
1466
  async function fileExists(filePath) {
1404
1467
  try {
1405
- await fs9.access(filePath);
1468
+ await fs10.access(filePath);
1406
1469
  return true;
1407
1470
  } catch {
1408
1471
  return false;
@@ -1410,7 +1473,7 @@ async function fileExists(filePath) {
1410
1473
  }
1411
1474
  async function directoryExists(dirPath) {
1412
1475
  try {
1413
- const stat4 = await fs9.stat(dirPath);
1476
+ const stat4 = await fs10.stat(dirPath);
1414
1477
  return stat4.isDirectory();
1415
1478
  } catch {
1416
1479
  return false;
@@ -1418,28 +1481,28 @@ async function directoryExists(dirPath) {
1418
1481
  }
1419
1482
  async function createTempDir(prefix = "agent-conf-") {
1420
1483
  const tmpDir = os2.tmpdir();
1421
- return fs9.mkdtemp(path9.join(tmpDir, prefix));
1484
+ return fs10.mkdtemp(path10.join(tmpDir, prefix));
1422
1485
  }
1423
1486
  async function removeTempDir(dirPath) {
1424
1487
  try {
1425
- await fs9.rm(dirPath, { recursive: true, force: true });
1488
+ await fs10.rm(dirPath, { recursive: true, force: true });
1426
1489
  } catch {
1427
1490
  }
1428
1491
  }
1429
1492
  function resolvePath(inputPath) {
1430
1493
  if (inputPath.startsWith("~")) {
1431
- return path9.join(os2.homedir(), inputPath.slice(1));
1494
+ return path10.join(os2.homedir(), inputPath.slice(1));
1432
1495
  }
1433
- return path9.resolve(inputPath);
1496
+ return path10.resolve(inputPath);
1434
1497
  }
1435
1498
 
1436
1499
  // src/utils/git.ts
1437
- import * as fs10 from "fs/promises";
1438
- import * as path10 from "path";
1500
+ import * as fs11 from "fs/promises";
1501
+ import * as path11 from "path";
1439
1502
  import { simpleGit as simpleGit2 } from "simple-git";
1440
1503
  async function directoryExistsForGit(dir) {
1441
1504
  try {
1442
- const stat4 = await fs10.stat(dir);
1505
+ const stat4 = await fs11.stat(dir);
1443
1506
  return stat4.isDirectory();
1444
1507
  } catch {
1445
1508
  return false;
@@ -1466,7 +1529,7 @@ async function getGitProjectName(dir) {
1466
1529
  if (!gitRoot) {
1467
1530
  return null;
1468
1531
  }
1469
- return path10.basename(gitRoot);
1532
+ return path11.basename(gitRoot);
1470
1533
  }
1471
1534
  async function isGitRoot(dir) {
1472
1535
  if (!await directoryExistsForGit(dir)) {
@@ -1477,11 +1540,11 @@ async function isGitRoot(dir) {
1477
1540
  return false;
1478
1541
  }
1479
1542
  try {
1480
- const realDir = await fs10.realpath(dir);
1481
- const realGitRoot = await fs10.realpath(gitRoot);
1543
+ const realDir = await fs11.realpath(dir);
1544
+ const realGitRoot = await fs11.realpath(gitRoot);
1482
1545
  return realDir === realGitRoot;
1483
1546
  } catch {
1484
- return path10.resolve(dir) === path10.resolve(gitRoot);
1547
+ return path11.resolve(dir) === path11.resolve(gitRoot);
1485
1548
  }
1486
1549
  }
1487
1550
  async function getGitOrganization(dir) {
@@ -1790,7 +1853,7 @@ async function performSync(options) {
1790
1853
  console.log();
1791
1854
  console.log(pc5.bold("Sync complete:"));
1792
1855
  console.log();
1793
- const agentsMdPath = formatPath(path11.join(targetDir, "AGENTS.md"));
1856
+ const agentsMdPath = formatPath(path12.join(targetDir, "AGENTS.md"));
1794
1857
  if (result.agentsMd.merged) {
1795
1858
  const label = context.commandName === "sync" ? "(updated)" : "(merged)";
1796
1859
  console.log(` ${pc5.green("+")} ${agentsMdPath} ${pc5.dim(label)}`);
@@ -1800,7 +1863,7 @@ async function performSync(options) {
1800
1863
  for (const targetResult of result.targets) {
1801
1864
  const config = getTargetConfig(targetResult.target);
1802
1865
  if (config.instructionsFile) {
1803
- const instructionsPath = targetResult.instructionsMd.location === "root" ? formatPath(path11.join(targetDir, config.instructionsFile)) : formatPath(path11.join(targetDir, config.dir, config.instructionsFile));
1866
+ const instructionsPath = targetResult.instructionsMd.location === "root" ? formatPath(path12.join(targetDir, config.instructionsFile)) : formatPath(path12.join(targetDir, config.dir, config.instructionsFile));
1804
1867
  if (targetResult.instructionsMd.created) {
1805
1868
  console.log(` ${pc5.green("+")} ${instructionsPath} ${pc5.dim("(created)")}`);
1806
1869
  } else if (targetResult.instructionsMd.updated) {
@@ -1810,13 +1873,13 @@ async function performSync(options) {
1810
1873
  console.log(` ${pc5.dim("-")} ${instructionsPath} ${pc5.dim("(unchanged)")}`);
1811
1874
  }
1812
1875
  }
1813
- const skillsPath = formatPath(path11.join(targetDir, config.dir, "skills"));
1876
+ const skillsPath = formatPath(path12.join(targetDir, config.dir, "skills"));
1814
1877
  console.log(
1815
1878
  ` ${pc5.green("+")} ${skillsPath}/ ${pc5.dim(`(${result.skills.synced.length} skills, ${targetResult.skills.copied} files)`)}`
1816
1879
  );
1817
1880
  if (orphanResult.deleted.length > 0) {
1818
1881
  for (const skill of orphanResult.deleted) {
1819
- const orphanPath = formatPath(path11.join(targetDir, config.dir, "skills", skill));
1882
+ const orphanPath = formatPath(path12.join(targetDir, config.dir, "skills", skill));
1820
1883
  console.log(
1821
1884
  ` ${pc5.red("-")} ${orphanPath}/ ${pc5.dim("(removed - no longer in source)")}`
1822
1885
  );
@@ -1824,28 +1887,28 @@ async function performSync(options) {
1824
1887
  }
1825
1888
  if (orphanResult.skipped.length > 0) {
1826
1889
  for (const skill of orphanResult.skipped) {
1827
- const orphanPath = formatPath(path11.join(targetDir, config.dir, "skills", skill));
1890
+ const orphanPath = formatPath(path12.join(targetDir, config.dir, "skills", skill));
1828
1891
  console.log(` ${pc5.yellow("!")} ${orphanPath}/ ${pc5.dim("(orphaned but skipped)")}`);
1829
1892
  }
1830
1893
  }
1831
1894
  }
1832
1895
  if (workflowResult) {
1833
1896
  for (const filename of workflowResult.created) {
1834
- const workflowPath = formatPath(path11.join(targetDir, ".github/workflows", filename));
1897
+ const workflowPath = formatPath(path12.join(targetDir, ".github/workflows", filename));
1835
1898
  console.log(` ${pc5.green("+")} ${workflowPath} ${pc5.dim("(created)")}`);
1836
1899
  }
1837
1900
  for (const filename of workflowResult.updated) {
1838
- const workflowPath = formatPath(path11.join(targetDir, ".github/workflows", filename));
1901
+ const workflowPath = formatPath(path12.join(targetDir, ".github/workflows", filename));
1839
1902
  console.log(` ${pc5.yellow("~")} ${workflowPath} ${pc5.dim("(updated)")}`);
1840
1903
  }
1841
1904
  for (const filename of workflowResult.unchanged) {
1842
- const workflowPath = formatPath(path11.join(targetDir, ".github/workflows", filename));
1905
+ const workflowPath = formatPath(path12.join(targetDir, ".github/workflows", filename));
1843
1906
  console.log(` ${pc5.dim("-")} ${workflowPath} ${pc5.dim("(unchanged)")}`);
1844
1907
  }
1845
1908
  }
1846
- const lockfilePath = formatPath(path11.join(targetDir, ".agent-conf", "agent-conf.lock"));
1909
+ const lockfilePath = formatPath(path12.join(targetDir, ".agent-conf", "agent-conf.lock"));
1847
1910
  console.log(` ${pc5.green("+")} ${lockfilePath}`);
1848
- const hookPath = formatPath(path11.join(targetDir, ".git/hooks/pre-commit"));
1911
+ const hookPath = formatPath(path12.join(targetDir, ".git/hooks/pre-commit"));
1849
1912
  if (hookResult.installed) {
1850
1913
  if (hookResult.alreadyExisted && !hookResult.wasUpdated) {
1851
1914
  console.log(` ${pc5.dim("-")} ${hookPath} ${pc5.dim("(unchanged)")}`);
@@ -1915,8 +1978,8 @@ async function initCommand(options) {
1915
1978
  }
1916
1979
 
1917
1980
  // src/commands/init-canonical-repo.ts
1918
- import * as fs11 from "fs/promises";
1919
- import * as path12 from "path";
1981
+ import * as fs12 from "fs/promises";
1982
+ import * as path13 from "path";
1920
1983
  import * as prompts5 from "@clack/prompts";
1921
1984
  import pc7 from "picocolors";
1922
1985
  import { stringify as stringifyYaml } from "yaml";
@@ -2217,8 +2280,8 @@ async function initCanonicalRepoCommand(options) {
2217
2280
  const logger = createLogger();
2218
2281
  console.log();
2219
2282
  prompts5.intro(pc7.bold("agent-conf init-canonical-repo"));
2220
- const targetDir = options.dir ? path12.resolve(options.dir) : process.cwd();
2221
- const dirName = path12.basename(targetDir);
2283
+ const targetDir = options.dir ? path13.resolve(options.dir) : process.cwd();
2284
+ const dirName = path13.basename(targetDir);
2222
2285
  const cwd = process.cwd();
2223
2286
  let isAtGitRoot = await isGitRoot(targetDir);
2224
2287
  let gitProjectName = await getGitProjectName(targetDir);
@@ -2227,7 +2290,7 @@ async function initCanonicalRepoCommand(options) {
2227
2290
  const cwdIsGitRoot = await isGitRoot(cwd);
2228
2291
  const cwdGitProjectName = await getGitProjectName(cwd);
2229
2292
  const cwdGitOrganization = await getGitOrganization(cwd);
2230
- if (cwdIsGitRoot && path12.resolve(targetDir) === path12.resolve(cwd)) {
2293
+ if (cwdIsGitRoot && path13.resolve(targetDir) === path13.resolve(cwd)) {
2231
2294
  isAtGitRoot = true;
2232
2295
  gitProjectName = cwdGitProjectName;
2233
2296
  gitOrganization = cwdGitOrganization;
@@ -2246,7 +2309,7 @@ async function initCanonicalRepoCommand(options) {
2246
2309
  }
2247
2310
  const dirExists = await directoryExists(targetDir);
2248
2311
  if (dirExists) {
2249
- const configExists = await fileExists(path12.join(targetDir, "agent-conf.yaml"));
2312
+ const configExists = await fileExists(path13.join(targetDir, "agent-conf.yaml"));
2250
2313
  if (configExists && !options.yes) {
2251
2314
  const shouldContinue = await prompts5.confirm({
2252
2315
  message: "This directory already has an agent-conf.yaml. Overwrite?",
@@ -2328,34 +2391,34 @@ async function initCanonicalRepoCommand(options) {
2328
2391
  spinner.start();
2329
2392
  try {
2330
2393
  await ensureDir(resolvedOptions.targetDir);
2331
- const instructionsDir = path12.join(resolvedOptions.targetDir, "instructions");
2332
- const skillsDir = path12.join(resolvedOptions.targetDir, "skills");
2333
- const workflowsDir = path12.join(resolvedOptions.targetDir, ".github", "workflows");
2394
+ const instructionsDir = path13.join(resolvedOptions.targetDir, "instructions");
2395
+ const skillsDir = path13.join(resolvedOptions.targetDir, "skills");
2396
+ const workflowsDir = path13.join(resolvedOptions.targetDir, ".github", "workflows");
2334
2397
  await ensureDir(instructionsDir);
2335
2398
  await ensureDir(skillsDir);
2336
2399
  await ensureDir(workflowsDir);
2337
- const configPath = path12.join(resolvedOptions.targetDir, "agent-conf.yaml");
2338
- await fs11.writeFile(configPath, generateConfigYaml(resolvedOptions), "utf-8");
2339
- const agentsMdPath = path12.join(instructionsDir, "AGENTS.md");
2340
- await fs11.writeFile(agentsMdPath, generateAgentsMd(resolvedOptions), "utf-8");
2400
+ const configPath = path13.join(resolvedOptions.targetDir, "agent-conf.yaml");
2401
+ await fs12.writeFile(configPath, generateConfigYaml(resolvedOptions), "utf-8");
2402
+ const agentsMdPath = path13.join(instructionsDir, "AGENTS.md");
2403
+ await fs12.writeFile(agentsMdPath, generateAgentsMd(resolvedOptions), "utf-8");
2341
2404
  if (resolvedOptions.includeExamples) {
2342
- const exampleSkillDir = path12.join(skillsDir, "example-skill");
2343
- const referencesDir = path12.join(exampleSkillDir, "references");
2405
+ const exampleSkillDir = path13.join(skillsDir, "example-skill");
2406
+ const referencesDir = path13.join(exampleSkillDir, "references");
2344
2407
  await ensureDir(referencesDir);
2345
- const skillMdPath = path12.join(exampleSkillDir, "SKILL.md");
2346
- await fs11.writeFile(skillMdPath, generateExampleSkillMd(), "utf-8");
2347
- const gitkeepPath = path12.join(referencesDir, ".gitkeep");
2348
- await fs11.writeFile(gitkeepPath, "", "utf-8");
2408
+ const skillMdPath = path13.join(exampleSkillDir, "SKILL.md");
2409
+ await fs12.writeFile(skillMdPath, generateExampleSkillMd(), "utf-8");
2410
+ const gitkeepPath = path13.join(referencesDir, ".gitkeep");
2411
+ await fs12.writeFile(gitkeepPath, "", "utf-8");
2349
2412
  }
2350
- const syncWorkflowPath = path12.join(workflowsDir, "sync-reusable.yml");
2351
- const checkWorkflowPath = path12.join(workflowsDir, "check-reusable.yml");
2413
+ const syncWorkflowPath = path13.join(workflowsDir, "sync-reusable.yml");
2414
+ const checkWorkflowPath = path13.join(workflowsDir, "check-reusable.yml");
2352
2415
  const repoFullName = resolvedOptions.organization ? `${resolvedOptions.organization}/${resolvedOptions.name}` : resolvedOptions.name;
2353
- await fs11.writeFile(
2416
+ await fs12.writeFile(
2354
2417
  syncWorkflowPath,
2355
2418
  generateSyncWorkflow2(repoFullName, resolvedOptions.markerPrefix),
2356
2419
  "utf-8"
2357
2420
  );
2358
- await fs11.writeFile(
2421
+ await fs12.writeFile(
2359
2422
  checkWorkflowPath,
2360
2423
  generateCheckWorkflow2(repoFullName, resolvedOptions.markerPrefix),
2361
2424
  "utf-8"
@@ -2367,7 +2430,7 @@ async function initCanonicalRepoCommand(options) {
2367
2430
  console.log(` ${pc7.green("+")} ${formatPath(agentsMdPath)}`);
2368
2431
  if (resolvedOptions.includeExamples) {
2369
2432
  console.log(
2370
- ` ${pc7.green("+")} ${formatPath(path12.join(skillsDir, "example-skill/SKILL.md"))}`
2433
+ ` ${pc7.green("+")} ${formatPath(path13.join(skillsDir, "example-skill/SKILL.md"))}`
2371
2434
  );
2372
2435
  }
2373
2436
  console.log(` ${pc7.green("+")} ${formatPath(syncWorkflowPath)}`);
@@ -2398,7 +2461,7 @@ async function initCanonicalRepoCommand(options) {
2398
2461
  }
2399
2462
 
2400
2463
  // src/commands/status.ts
2401
- import * as path13 from "path";
2464
+ import * as path14 from "path";
2402
2465
  import pc8 from "picocolors";
2403
2466
  async function statusCommand(options = {}) {
2404
2467
  const targetDir = process.cwd();
@@ -2451,7 +2514,7 @@ async function statusCommand(options = {}) {
2451
2514
  }
2452
2515
  console.log();
2453
2516
  }
2454
- const lockfilePath = formatPath(path13.join(targetDir, ".agent-conf", "agent-conf.lock"));
2517
+ const lockfilePath = formatPath(path14.join(targetDir, ".agent-conf", "agent-conf.lock"));
2455
2518
  console.log(pc8.dim(`Lock file: ${lockfilePath}`));
2456
2519
  console.log(pc8.dim(`CLI version: ${lockfile.cli_version}`));
2457
2520
  console.log();