claudekit-cli 4.0.0-dev.3 → 4.0.0-dev.4

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/cli-manifest.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
- "version": "4.0.0-dev.3",
3
- "generatedAt": "2026-05-09T03:16:37.030Z",
2
+ "version": "4.0.0-dev.4",
3
+ "generatedAt": "2026-05-09T14:28:30.285Z",
4
4
  "commands": {
5
5
  "agents": {
6
6
  "name": "agents",
package/dist/index.js CHANGED
@@ -12552,6 +12552,100 @@ async function migrateRegistryV2ToV3(v2Registry) {
12552
12552
  appliedManifestVersion: undefined
12553
12553
  };
12554
12554
  }
12555
+ function getStringField(item, field) {
12556
+ const record = item;
12557
+ if (!(field in record) || record[field] === undefined) {
12558
+ return;
12559
+ }
12560
+ const value = record[field];
12561
+ if (typeof value !== "string") {
12562
+ throw new Error("portable-registry.json has unsupported schema/version");
12563
+ }
12564
+ return value;
12565
+ }
12566
+ function getOwnedSections(item) {
12567
+ const record = item;
12568
+ if (!("ownedSections" in record) || record.ownedSections === undefined) {
12569
+ return;
12570
+ }
12571
+ const value = record.ownedSections;
12572
+ if (!Array.isArray(value) || !value.every((section) => typeof section === "string")) {
12573
+ throw new Error("portable-registry.json has unsupported schema/version");
12574
+ }
12575
+ return value;
12576
+ }
12577
+ function getInstallSource(item) {
12578
+ const installSource = getStringField(item, "installSource");
12579
+ if (installSource === undefined) {
12580
+ return "kit";
12581
+ }
12582
+ if (installSource !== "kit" && installSource !== "manual") {
12583
+ throw new Error("portable-registry.json has unsupported schema/version");
12584
+ }
12585
+ return installSource;
12586
+ }
12587
+ async function repairStaleRegistryV3(registry) {
12588
+ const installations = [];
12589
+ for (const item of registry.installations) {
12590
+ let targetChecksum = normalizeChecksum(getStringField(item, "targetChecksum")) || UNKNOWN_CHECKSUM;
12591
+ if (targetChecksum === UNKNOWN_CHECKSUM && existsSync2(item.path)) {
12592
+ try {
12593
+ targetChecksum = await computeFileChecksum(item.path);
12594
+ } catch {
12595
+ targetChecksum = UNKNOWN_CHECKSUM;
12596
+ }
12597
+ }
12598
+ installations.push({
12599
+ ...item,
12600
+ sourceChecksum: normalizeChecksum(getStringField(item, "sourceChecksum")) || UNKNOWN_CHECKSUM,
12601
+ targetChecksum,
12602
+ installSource: getInstallSource(item),
12603
+ ownedSections: getOwnedSections(item)
12604
+ });
12605
+ }
12606
+ return normalizePortableRegistryChecksums({
12607
+ ...registry,
12608
+ version: "3.0",
12609
+ installations,
12610
+ lastReconciled: registry.lastReconciled,
12611
+ appliedManifestVersion: registry.appliedManifestVersion
12612
+ });
12613
+ }
12614
+ async function persistCurrentStaleRegistryV3Repair(preparedRepair) {
12615
+ return withRegistryLock(async () => {
12616
+ let content;
12617
+ try {
12618
+ content = await readFile2(REGISTRY_PATH, "utf-8");
12619
+ } catch (error) {
12620
+ if (isErrnoCode(error, "ENOENT")) {
12621
+ return readPortableRegistryInternal({ persistStaleV3Repair: false });
12622
+ }
12623
+ throw error;
12624
+ }
12625
+ let data;
12626
+ try {
12627
+ data = JSON.parse(content);
12628
+ } catch (error) {
12629
+ throw new Error(`portable-registry.json is not valid JSON: ${error instanceof Error ? error.message : "Unknown parse error"}`);
12630
+ }
12631
+ const v3Result = PortableRegistrySchemaV3.safeParse(data);
12632
+ if (v3Result.success) {
12633
+ return normalizePortableRegistryChecksums(v3Result.data);
12634
+ }
12635
+ const repairableV3Result = RepairablePortableRegistrySchemaV3.safeParse(data);
12636
+ if (!repairableV3Result.success) {
12637
+ return readPortableRegistryInternal({ persistStaleV3Repair: false });
12638
+ }
12639
+ const repairedRegistry = preparedRepair && preparedRepair.sourceContent === content ? preparedRepair.repairedRegistry : await repairStaleRegistryV3(repairableV3Result.data);
12640
+ if (await isMigrationLocked()) {
12641
+ logger.verbose("Migration in progress by another process, using repaired v3 view");
12642
+ return repairedRegistry;
12643
+ }
12644
+ logger.verbose("Repairing stale portable registry v3.0 fields");
12645
+ await writePortableRegistry(repairedRegistry);
12646
+ return repairedRegistry;
12647
+ });
12648
+ }
12555
12649
  async function isMigrationLocked() {
12556
12650
  try {
12557
12651
  const lockContent = await readFile2(MIGRATION_LOCK_PATH, "utf-8");
@@ -12589,6 +12683,9 @@ async function removeMigrationLock() {
12589
12683
  } catch {}
12590
12684
  }
12591
12685
  async function readPortableRegistry() {
12686
+ return readPortableRegistryInternal({ persistStaleV3Repair: true });
12687
+ }
12688
+ async function readPortableRegistryInternal(options2) {
12592
12689
  try {
12593
12690
  const content = await readFile2(REGISTRY_PATH, "utf-8");
12594
12691
  let data;
@@ -12601,6 +12698,21 @@ async function readPortableRegistry() {
12601
12698
  if (v3Result.success) {
12602
12699
  return normalizePortableRegistryChecksums(v3Result.data);
12603
12700
  }
12701
+ const repairableV3Result = RepairablePortableRegistrySchemaV3.safeParse(data);
12702
+ if (repairableV3Result.success) {
12703
+ const repairedRegistry = await repairStaleRegistryV3(repairableV3Result.data);
12704
+ if (!options2.persistStaleV3Repair) {
12705
+ return repairedRegistry;
12706
+ }
12707
+ if (await isMigrationLocked()) {
12708
+ logger.verbose("Migration in progress by another process, using repaired v3 view");
12709
+ return repairedRegistry;
12710
+ }
12711
+ return persistCurrentStaleRegistryV3Repair({
12712
+ sourceContent: content,
12713
+ repairedRegistry
12714
+ });
12715
+ }
12604
12716
  const v2Result = PortableRegistrySchema.safeParse(data);
12605
12717
  if (!v2Result.success) {
12606
12718
  throw new Error("portable-registry.json has unsupported schema/version");
@@ -12640,6 +12752,9 @@ async function readPortableRegistry() {
12640
12752
  }
12641
12753
  return { version: "3.0", installations: [] };
12642
12754
  }
12755
+ async function readPortableRegistryWithinRegistryLock() {
12756
+ return readPortableRegistryInternal({ persistStaleV3Repair: false });
12757
+ }
12643
12758
  async function writePortableRegistry(registry) {
12644
12759
  const dir = dirname(REGISTRY_PATH);
12645
12760
  if (!existsSync2(dir)) {
@@ -12682,7 +12797,7 @@ async function withRegistryLock(operation) {
12682
12797
  }
12683
12798
  async function addPortableInstallation(item, type, provider, global2, path, sourcePath, options2) {
12684
12799
  await withRegistryLock(async () => {
12685
- const registry = await readPortableRegistry();
12800
+ const registry = await readPortableRegistryWithinRegistryLock();
12686
12801
  registry.installations = registry.installations.filter((i) => !(i.item === item && i.type === type && i.provider === provider && i.global === global2));
12687
12802
  registry.installations.push({
12688
12803
  item,
@@ -12703,7 +12818,7 @@ async function addPortableInstallation(item, type, provider, global2, path, sour
12703
12818
  }
12704
12819
  async function removePortableInstallation(item, type, provider, global2) {
12705
12820
  return withRegistryLock(async () => {
12706
- const registry = await readPortableRegistry();
12821
+ const registry = await readPortableRegistryWithinRegistryLock();
12707
12822
  const index = registry.installations.findIndex((i) => i.item === item && i.type === type && i.provider === provider && i.global === global2);
12708
12823
  if (index === -1)
12709
12824
  return null;
@@ -12727,14 +12842,14 @@ function findPortableInstallations(registry, item, type, provider, global2) {
12727
12842
  }
12728
12843
  async function updateAppliedManifestVersion(version) {
12729
12844
  await withRegistryLock(async () => {
12730
- const registry = await readPortableRegistry();
12845
+ const registry = await readPortableRegistryWithinRegistryLock();
12731
12846
  registry.appliedManifestVersion = version;
12732
12847
  await writePortableRegistry(registry);
12733
12848
  });
12734
12849
  }
12735
12850
  async function removeInstallationsByFilter(predicate) {
12736
12851
  return withRegistryLock(async () => {
12737
- const registry = await readPortableRegistry();
12852
+ const registry = await readPortableRegistryWithinRegistryLock();
12738
12853
  const removed = [];
12739
12854
  registry.installations = registry.installations.filter((entry) => {
12740
12855
  if (predicate(entry)) {
@@ -12751,7 +12866,7 @@ async function removeInstallationsByFilter(predicate) {
12751
12866
  }
12752
12867
  async function syncPortableRegistry() {
12753
12868
  return withRegistryLock(async () => {
12754
- const registry = await readPortableRegistry();
12869
+ const registry = await readPortableRegistryWithinRegistryLock();
12755
12870
  const removed = [];
12756
12871
  registry.installations = registry.installations.filter((i) => {
12757
12872
  if (!existsSync2(i.path)) {
@@ -12766,7 +12881,7 @@ async function syncPortableRegistry() {
12766
12881
  return { removed };
12767
12882
  });
12768
12883
  }
12769
- var import_proper_lockfile, home2, REGISTRY_PATH, REGISTRY_LOCK_PATH, LEGACY_REGISTRY_PATH, MIGRATION_LOCK_PATH, PortableInstallationSchema, PortableRegistrySchema, PortableInstallationSchemaV3, PortableRegistrySchemaV3, LegacyInstallationSchema, LegacyRegistrySchema;
12884
+ var import_proper_lockfile, home2, REGISTRY_PATH, REGISTRY_LOCK_PATH, LEGACY_REGISTRY_PATH, MIGRATION_LOCK_PATH, PortableInstallationSchema, PortableRegistrySchema, PortableInstallationSchemaV3, PortableRegistrySchemaV3, RepairablePortableRegistrySchemaV3, LegacyInstallationSchema, LegacyRegistrySchema;
12770
12885
  var init_portable_registry = __esm(() => {
12771
12886
  init_zod();
12772
12887
  init_logger();
@@ -12811,6 +12926,12 @@ var init_portable_registry = __esm(() => {
12811
12926
  lastReconciled: exports_external.string().optional(),
12812
12927
  appliedManifestVersion: exports_external.string().optional()
12813
12928
  });
12929
+ RepairablePortableRegistrySchemaV3 = exports_external.object({
12930
+ version: exports_external.literal("3.0"),
12931
+ installations: exports_external.array(PortableInstallationSchema),
12932
+ lastReconciled: exports_external.string().optional(),
12933
+ appliedManifestVersion: exports_external.string().optional()
12934
+ }).passthrough();
12814
12935
  LegacyInstallationSchema = exports_external.object({
12815
12936
  skill: exports_external.string(),
12816
12937
  agent: exports_external.string(),
@@ -62359,7 +62480,7 @@ var package_default;
62359
62480
  var init_package = __esm(() => {
62360
62481
  package_default = {
62361
62482
  name: "claudekit-cli",
62362
- version: "4.0.0-dev.3",
62483
+ version: "4.0.0-dev.4",
62363
62484
  description: "CLI tool for bootstrapping and updating ClaudeKit projects",
62364
62485
  type: "module",
62365
62486
  repository: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claudekit-cli",
3
- "version": "4.0.0-dev.3",
3
+ "version": "4.0.0-dev.4",
4
4
  "description": "CLI tool for bootstrapping and updating ClaudeKit projects",
5
5
  "type": "module",
6
6
  "repository": {