agent-conf 2.0.4 → 2.1.1

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