canopycms 0.0.60 → 0.0.61-int.75

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (218) hide show
  1. package/dist/api/__test__/mock-client.d.ts +29 -0
  2. package/dist/api/__test__/mock-client.d.ts.map +1 -1
  3. package/dist/api/__test__/mock-client.js +51 -0
  4. package/dist/api/__test__/mock-client.js.map +1 -1
  5. package/dist/api/admin-branch-health.d.ts +65 -0
  6. package/dist/api/admin-branch-health.d.ts.map +1 -0
  7. package/dist/api/admin-branch-health.js +448 -0
  8. package/dist/api/admin-branch-health.js.map +1 -0
  9. package/dist/api/admin.d.ts +136 -0
  10. package/dist/api/admin.d.ts.map +1 -0
  11. package/dist/api/admin.js +338 -0
  12. package/dist/api/admin.js.map +1 -0
  13. package/dist/api/assets.d.ts.map +1 -1
  14. package/dist/api/assets.js +4 -0
  15. package/dist/api/assets.js.map +1 -1
  16. package/dist/api/branch-merge.d.ts +6 -0
  17. package/dist/api/branch-merge.d.ts.map +1 -1
  18. package/dist/api/branch-merge.js +13 -3
  19. package/dist/api/branch-merge.js.map +1 -1
  20. package/dist/api/branch-status.d.ts.map +1 -1
  21. package/dist/api/branch-status.js +15 -5
  22. package/dist/api/branch-status.js.map +1 -1
  23. package/dist/api/branch-withdraw.d.ts +6 -0
  24. package/dist/api/branch-withdraw.d.ts.map +1 -1
  25. package/dist/api/branch-withdraw.js +15 -3
  26. package/dist/api/branch-withdraw.js.map +1 -1
  27. package/dist/api/branch.d.ts +11 -1
  28. package/dist/api/branch.d.ts.map +1 -1
  29. package/dist/api/branch.js +70 -4
  30. package/dist/api/branch.js.map +1 -1
  31. package/dist/api/client.d.ts +34 -0
  32. package/dist/api/client.d.ts.map +1 -1
  33. package/dist/api/client.js +47 -0
  34. package/dist/api/client.js.map +1 -1
  35. package/dist/api/comments.d.ts.map +1 -1
  36. package/dist/api/comments.js +4 -0
  37. package/dist/api/comments.js.map +1 -1
  38. package/dist/api/content.d.ts.map +1 -1
  39. package/dist/api/content.js +4 -4
  40. package/dist/api/content.js.map +1 -1
  41. package/dist/api/entries.js +1 -1
  42. package/dist/api/entries.js.map +1 -1
  43. package/dist/api/github-sync.d.ts.map +1 -1
  44. package/dist/api/github-sync.js +14 -3
  45. package/dist/api/github-sync.js.map +1 -1
  46. package/dist/api/guards.d.ts +7 -1
  47. package/dist/api/guards.d.ts.map +1 -1
  48. package/dist/api/guards.js +54 -0
  49. package/dist/api/guards.js.map +1 -1
  50. package/dist/api/index.d.ts +1 -0
  51. package/dist/api/index.d.ts.map +1 -1
  52. package/dist/api/index.js +0 -1
  53. package/dist/api/index.js.map +1 -1
  54. package/dist/api/schema.js +7 -7
  55. package/dist/api/schema.js.map +1 -1
  56. package/dist/authorization/branch.d.ts +14 -1
  57. package/dist/authorization/branch.d.ts.map +1 -1
  58. package/dist/authorization/branch.js +5 -3
  59. package/dist/authorization/branch.js.map +1 -1
  60. package/dist/authorization/index.d.ts +1 -0
  61. package/dist/authorization/index.d.ts.map +1 -1
  62. package/dist/authorization/index.js +2 -0
  63. package/dist/authorization/index.js.map +1 -1
  64. package/dist/authorization/protected-branch.d.ts +39 -0
  65. package/dist/authorization/protected-branch.d.ts.map +1 -0
  66. package/dist/authorization/protected-branch.js +43 -0
  67. package/dist/authorization/protected-branch.js.map +1 -0
  68. package/dist/branch-health.d.ts +78 -0
  69. package/dist/branch-health.d.ts.map +1 -0
  70. package/dist/branch-health.js +151 -0
  71. package/dist/branch-health.js.map +1 -0
  72. package/dist/branch-metadata.d.ts +20 -0
  73. package/dist/branch-metadata.d.ts.map +1 -1
  74. package/dist/branch-metadata.js +21 -1
  75. package/dist/branch-metadata.js.map +1 -1
  76. package/dist/branch-registry.d.ts.map +1 -1
  77. package/dist/branch-registry.js +13 -1
  78. package/dist/branch-registry.js.map +1 -1
  79. package/dist/cli/cli.js +154 -13
  80. package/dist/cli/generate-ai-content.js +54 -10
  81. package/dist/cli/init.js +72 -0
  82. package/dist/cli/sync.d.ts.map +1 -1
  83. package/dist/cli/sync.js +4 -1
  84. package/dist/cli/sync.js.map +1 -1
  85. package/dist/content-store.d.ts +16 -0
  86. package/dist/content-store.d.ts.map +1 -1
  87. package/dist/content-store.js +22 -6
  88. package/dist/content-store.js.map +1 -1
  89. package/dist/editor/BranchManager.d.ts +9 -1
  90. package/dist/editor/BranchManager.d.ts.map +1 -1
  91. package/dist/editor/BranchManager.js +20 -9
  92. package/dist/editor/BranchManager.js.map +1 -1
  93. package/dist/editor/CommentsPanel.d.ts.map +1 -1
  94. package/dist/editor/CommentsPanel.js +4 -12
  95. package/dist/editor/CommentsPanel.js.map +1 -1
  96. package/dist/editor/Editor.d.ts.map +1 -1
  97. package/dist/editor/Editor.js +46 -10
  98. package/dist/editor/Editor.js.map +1 -1
  99. package/dist/editor/EntryNavigator.d.ts +7 -0
  100. package/dist/editor/EntryNavigator.d.ts.map +1 -1
  101. package/dist/editor/EntryNavigator.js +17 -5
  102. package/dist/editor/EntryNavigator.js.map +1 -1
  103. package/dist/editor/FormRenderer.d.ts.map +1 -1
  104. package/dist/editor/FormRenderer.js +4 -0
  105. package/dist/editor/FormRenderer.js.map +1 -1
  106. package/dist/editor/admin/SystemHealthPanel.d.ts +6 -0
  107. package/dist/editor/admin/SystemHealthPanel.d.ts.map +1 -0
  108. package/dist/editor/admin/SystemHealthPanel.js +234 -0
  109. package/dist/editor/admin/SystemHealthPanel.js.map +1 -0
  110. package/dist/editor/admin/useSystemHealth.d.ts +40 -0
  111. package/dist/editor/admin/useSystemHealth.d.ts.map +1 -0
  112. package/dist/editor/admin/useSystemHealth.js +205 -0
  113. package/dist/editor/admin/useSystemHealth.js.map +1 -0
  114. package/dist/editor/comments/FieldWrapper.d.ts.map +1 -1
  115. package/dist/editor/comments/FieldWrapper.js +1 -1
  116. package/dist/editor/comments/FieldWrapper.js.map +1 -1
  117. package/dist/editor/comments/InlineCommentThread.d.ts.map +1 -1
  118. package/dist/editor/comments/InlineCommentThread.js +2 -21
  119. package/dist/editor/comments/InlineCommentThread.js.map +1 -1
  120. package/dist/editor/comments/ThreadCarousel.d.ts +2 -0
  121. package/dist/editor/comments/ThreadCarousel.d.ts.map +1 -1
  122. package/dist/editor/comments/ThreadCarousel.js +5 -2
  123. package/dist/editor/comments/ThreadCarousel.js.map +1 -1
  124. package/dist/editor/components/EditorHeader.d.ts +11 -0
  125. package/dist/editor/components/EditorHeader.d.ts.map +1 -1
  126. package/dist/editor/components/EditorHeader.js +75 -41
  127. package/dist/editor/components/EditorHeader.js.map +1 -1
  128. package/dist/editor/components/EditorSidebar.d.ts +7 -1
  129. package/dist/editor/components/EditorSidebar.d.ts.map +1 -1
  130. package/dist/editor/components/EditorSidebar.js +3 -3
  131. package/dist/editor/components/EditorSidebar.js.map +1 -1
  132. package/dist/editor/fields/ImageField.d.ts.map +1 -1
  133. package/dist/editor/fields/ImageField.js +4 -1
  134. package/dist/editor/fields/ImageField.js.map +1 -1
  135. package/dist/editor/fields/StringListField.d.ts +20 -0
  136. package/dist/editor/fields/StringListField.d.ts.map +1 -0
  137. package/dist/editor/fields/StringListField.js +25 -0
  138. package/dist/editor/fields/StringListField.js.map +1 -0
  139. package/dist/editor/hooks/useBranchActions.d.ts.map +1 -1
  140. package/dist/editor/hooks/useBranchActions.js +8 -2
  141. package/dist/editor/hooks/useBranchActions.js.map +1 -1
  142. package/dist/editor/hooks/useBranchManager.d.ts +12 -3
  143. package/dist/editor/hooks/useBranchManager.d.ts.map +1 -1
  144. package/dist/editor/hooks/useBranchManager.js +16 -1
  145. package/dist/editor/hooks/useBranchManager.js.map +1 -1
  146. package/dist/editor/hooks/useDraftManager.d.ts +7 -0
  147. package/dist/editor/hooks/useDraftManager.d.ts.map +1 -1
  148. package/dist/editor/hooks/useDraftManager.js +57 -3
  149. package/dist/editor/hooks/useDraftManager.js.map +1 -1
  150. package/dist/editor/hooks/useEntryManager.d.ts.map +1 -1
  151. package/dist/editor/hooks/useEntryManager.js +25 -7
  152. package/dist/editor/hooks/useEntryManager.js.map +1 -1
  153. package/dist/editor/media/AssetCard.d.ts.map +1 -1
  154. package/dist/editor/media/AssetCard.js +23 -2
  155. package/dist/editor/media/AssetCard.js.map +1 -1
  156. package/dist/editor/relative-time.d.ts +8 -0
  157. package/dist/editor/relative-time.d.ts.map +1 -0
  158. package/dist/editor/relative-time.js +26 -0
  159. package/dist/editor/relative-time.js.map +1 -0
  160. package/dist/git-manager.d.ts.map +1 -1
  161. package/dist/git-manager.js +10 -2
  162. package/dist/git-manager.js.map +1 -1
  163. package/dist/http/handler.d.ts.map +1 -1
  164. package/dist/http/handler.js +20 -9
  165. package/dist/http/handler.js.map +1 -1
  166. package/dist/http/router.d.ts.map +1 -1
  167. package/dist/http/router.js +2 -0
  168. package/dist/http/router.js.map +1 -1
  169. package/dist/paths/branch-name.d.ts +20 -0
  170. package/dist/paths/branch-name.d.ts.map +1 -0
  171. package/dist/paths/branch-name.js +24 -0
  172. package/dist/paths/branch-name.js.map +1 -0
  173. package/dist/paths/branch.d.ts +2 -8
  174. package/dist/paths/branch.d.ts.map +1 -1
  175. package/dist/paths/branch.js +6 -12
  176. package/dist/paths/branch.js.map +1 -1
  177. package/dist/paths/index.d.ts +2 -1
  178. package/dist/paths/index.d.ts.map +1 -1
  179. package/dist/paths/index.js +4 -1
  180. package/dist/paths/index.js.map +1 -1
  181. package/dist/services.js +9 -1
  182. package/dist/services.js.map +1 -1
  183. package/dist/task-queue/index.d.ts +2 -2
  184. package/dist/task-queue/index.d.ts.map +1 -1
  185. package/dist/task-queue/index.js +1 -1
  186. package/dist/task-queue/index.js.map +1 -1
  187. package/dist/task-queue/task-queue.d.ts +37 -1
  188. package/dist/task-queue/task-queue.d.ts.map +1 -1
  189. package/dist/task-queue/task-queue.js +104 -0
  190. package/dist/task-queue/task-queue.js.map +1 -1
  191. package/dist/task-queue/types.d.ts +11 -0
  192. package/dist/task-queue/types.d.ts.map +1 -1
  193. package/dist/types.d.ts +41 -0
  194. package/dist/types.d.ts.map +1 -1
  195. package/dist/utils/occ-json-write.d.ts.map +1 -1
  196. package/dist/utils/occ-json-write.js +7 -0
  197. package/dist/utils/occ-json-write.js.map +1 -1
  198. package/dist/utils/provisioning-lock.d.ts +19 -0
  199. package/dist/utils/provisioning-lock.d.ts.map +1 -1
  200. package/dist/utils/provisioning-lock.js +26 -0
  201. package/dist/utils/provisioning-lock.js.map +1 -1
  202. package/dist/validation/reference-validator.d.ts +17 -1
  203. package/dist/validation/reference-validator.d.ts.map +1 -1
  204. package/dist/validation/reference-validator.js +33 -10
  205. package/dist/validation/reference-validator.js.map +1 -1
  206. package/dist/worker/cms-worker.d.ts +38 -0
  207. package/dist/worker/cms-worker.d.ts.map +1 -1
  208. package/dist/worker/cms-worker.js +328 -25
  209. package/dist/worker/cms-worker.js.map +1 -1
  210. package/dist/worker/task-queue.d.ts +3 -3
  211. package/dist/worker/task-queue.d.ts.map +1 -1
  212. package/dist/worker/task-queue.js +2 -2
  213. package/dist/worker/task-queue.js.map +1 -1
  214. package/dist/worker/worker-status.d.ts +48 -0
  215. package/dist/worker/worker-status.d.ts.map +1 -0
  216. package/dist/worker/worker-status.js +53 -0
  217. package/dist/worker/worker-status.js.map +1 -0
  218. package/package.json +1 -1
package/dist/cli/cli.js CHANGED
@@ -362,6 +362,36 @@ async function retryTask(taskDir, taskId, error, logger = nullLogger) {
362
362
  });
363
363
  logger.debug("Retrying task", { id: taskId, retryCount, backoffMs });
364
364
  }
365
+ async function requeueFailedTask(taskDir, taskId, logger = nullLogger) {
366
+ const failedPath = path5.join(taskDir, "failed", `${taskId}.json`);
367
+ let content;
368
+ try {
369
+ content = await fs4.readFile(failedPath, "utf-8");
370
+ } catch (err) {
371
+ if (isNotFoundError2(err))
372
+ return { error: "not-found" };
373
+ throw err;
374
+ }
375
+ const original = parseTaskJson(content);
376
+ if (!original)
377
+ return { error: "unparseable" };
378
+ const newTaskId = crypto.randomUUID();
379
+ const newTask = {
380
+ id: newTaskId,
381
+ action: original.action,
382
+ payload: { ...original.payload, requeuedFrom: taskId },
383
+ status: "pending",
384
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
385
+ retryCount: 0,
386
+ maxRetries: original.maxRetries
387
+ };
388
+ const pendingPath = path5.join(taskDir, "pending", `${newTaskId}.json`);
389
+ await atomicWriteFile(pendingPath, JSON.stringify(newTask, null, 2));
390
+ await fs4.unlink(failedPath).catch(() => {
391
+ });
392
+ logger.debug("Requeued failed task", { originalId: taskId, newTaskId });
393
+ return { newTaskId };
394
+ }
365
395
  async function recoverOrphanedTasks(taskDir, maxAgeMs = 5 * 6e4, logger = nullLogger) {
366
396
  const processingDir = path5.join(taskDir, "processing");
367
397
  const pendingDir = path5.join(taskDir, "pending");
@@ -491,6 +521,46 @@ async function getQueueStats(taskDir) {
491
521
  }
492
522
  return stats;
493
523
  }
524
+ async function listCorruptTaskFiles(taskDir, limit = 50, logger = nullLogger) {
525
+ const corruptDir = path5.join(taskDir, "corrupt");
526
+ let files;
527
+ try {
528
+ files = await fs4.readdir(corruptDir);
529
+ } catch (err) {
530
+ if (isNotFoundError2(err))
531
+ return [];
532
+ throw err;
533
+ }
534
+ const entries = [];
535
+ for (const fileName of files.filter((f) => f.endsWith(".json"))) {
536
+ const filePath = path5.join(corruptDir, fileName);
537
+ try {
538
+ const stat = await fs4.stat(filePath);
539
+ entries.push({
540
+ fileName,
541
+ size: stat.size,
542
+ mtime: stat.mtime.toISOString(),
543
+ rawSnippet: await readSnippet(filePath, 500)
544
+ });
545
+ } catch (err) {
546
+ if (isNotFoundError2(err))
547
+ continue;
548
+ logger.debug("Failed to read corrupt task file", { fileName });
549
+ }
550
+ }
551
+ entries.sort((a, b) => new Date(b.mtime).getTime() - new Date(a.mtime).getTime());
552
+ return entries.slice(0, limit);
553
+ }
554
+ async function readSnippet(filePath, maxBytes) {
555
+ const handle = await fs4.open(filePath, "r");
556
+ try {
557
+ const buffer = Buffer.alloc(maxBytes);
558
+ const { bytesRead } = await handle.read(buffer, 0, maxBytes, 0);
559
+ return buffer.subarray(0, bytesRead).toString("utf-8");
560
+ } finally {
561
+ await handle.close();
562
+ }
563
+ }
494
564
  function parseTaskJson(content) {
495
565
  try {
496
566
  const parsed = JSON.parse(content);
@@ -1271,8 +1341,10 @@ var init_init = __esm({
1271
1341
  getQueueStats: () => getQueueStats,
1272
1342
  getTask: () => getTask,
1273
1343
  getTaskResult: () => getTask,
1344
+ listCorruptTaskFiles: () => listCorruptTaskFiles,
1274
1345
  listTasks: () => listTasks,
1275
1346
  recoverOrphanedTasks: () => recoverOrphanedTasks,
1347
+ requeueFailedTask: () => requeueFailedTask,
1276
1348
  retryTask: () => retryTask
1277
1349
  });
1278
1350
  init_task_queue3 = __esm2({
@@ -3056,6 +3128,8 @@ async function withOccFileLock(filePath, fn) {
3056
3128
  return await fn();
3057
3129
  } finally {
3058
3130
  await release().catch((err) => {
3131
+ if (isNodeError3(err) && err.code === "ENOENT")
3132
+ return;
3059
3133
  log4.warn("lock", `Failed to release lock for ${filePath}`, { error: getErrorMessage3(err) });
3060
3134
  });
3061
3135
  }
@@ -3570,7 +3644,7 @@ async function generateAIContentCLI(options) {
3570
3644
  console.log(` Output: ${result.outputDir}
3571
3645
  `);
3572
3646
  }
3573
- var __defProp3, __getOwnPropNames3, __esm3, __export3, init_normalize2, ROOT_COLLECTION_ID, init_types3, normalizePathValue, flattenSchema, init_flatten2, ProdClientSafeStrategy2, DevClientSafeStrategy2, clientStrategyCache, init_client_safe_strategy, primitiveFieldTypes2, fieldTypes2, init_types22, fieldBaseSchema2, selectOptionSchema2, referenceOptionSchema2, primitiveFieldSchema2, ASPECT_RATIO_RE2, imageFieldSchema2, selectFieldSchema2, referenceFieldSchema2, fieldHolder2, blockSchema2, blockFieldSchema2, objectFieldSchema2, inlineGroupFieldSchema2, customFieldSchema2, knownFieldSchema2, fieldSchema2, init_field2, relativePathSchema2, entryTypeSchema2, collectionSchema2, init_collection2, mediaSchema2, init_media2, defaultBranchAccessSchema2, defaultPathAccessLevelSchema2, defaultPathAccessLevelsSchema2, defaultPathAccessSchema2, defaultBaseBranchSchema2, defaultRemoteNameSchema2, defaultRemoteUrlSchema2, gitBotAuthorNameSchema2, gitBotAuthorEmailSchema2, githubTokenEnvVarSchema2, operatingModeSchema2, deployedAsSchema2, contentRootSchema2, sourceRootSchema2, deploymentNameSchema2, devContentSyncSchema2, devConfigSchema2, editorConfigSchema2, CanopyConfigSchema2, DEFAULT_PROD_WORKSPACE2, init_config3, permissionTargetSchema2, pathPermissionSchema2, init_permissions2, init_validation2, init_helpers2, init_config22, ProdStrategy2, DevStrategy2, strategyCache2, init_client_unsafe_strategy, operating_mode_exports, init_operating_mode, locks, BASE58_PATTERN, CONTENT_ID_PATTERN, PHYSICAL_SEGMENT_PATTERN, isValidId, EMPTY_LOGICAL_PATH, ContentIdIndex, registry, finalization, LOG_LEVELS2, DebugLogger2, testLogger2, log2, META_DIR, entryTypeMetaSchema, collectionMetaSchema, rootCollectionMetaSchema, isDeployedStatic, isBuildMode, STATIC_DEPLOY_USER, SCHEMA_CACHE_VERSION, MTIME_CHECK_DEBOUNCE_MS, SCHEMA_GENERATION_RESOURCE, BranchSchemaCache, RESOURCE, getFormatExtension, isDataOnlyFormat, asRecord, BranchPathError, resolveContentBranchesRoot, ContentStoreError, ContentConflictError, DEFAULT_INDEX_FRESHNESS_INTERVAL_MS, FORCED_REFRESH_MIN_INTERVAL_MS, STALE_LOOKUP, ContentStore, ATTR_CONTENT, BLOCK_PREFIX, BLOCK_SUFFIX, BLOCK_RESTORE_RE, INLINE_PREFIX, INLINE_SUFFIX, INLINE_RESTORE_RE, FLAT_CELL_TYPES, log22, BASE58_CHAR, ENTRY_LINK_PATTERN, log3, REGISTRY_FILE, REGISTRY_STALE_FILE, REGISTRY_TEMP_FILE, REGISTRY_VERSION, RESOURCE2, GET_MISS_REFRESH_MIN_INTERVAL_MS, BranchRegistry, log4, OccWriteConflictError, BRANCH_META_DIR, BRANCH_META_FILE, CURRENT_SCHEMA_VERSION, BranchMetadataConflictError, BranchMetadataFileManager, getBranchMetadataFileManager, loadBranchContext, NETWORK_SCHEME_PATTERN, TRANSPORT_HELPER_PATTERN, LEADING_OPTION_PATTERN, WINDOWS_DRIVE_PATTERN, COLON_BEFORE_SLASH_PATTERN, log5, GIT_ENV_PASSTHROUGH, remoteInitLocks, GitConflictError, GitManager, log6, workspaceInitLocks, BranchWorkspaceManager, log7, normalizePath, readEntryData, parseTypedFilename, listCollectionEntries, MAX_INPUT_PIXELS, KNOWN_FIELD_TYPES, STRING_FIELD_TYPES, selectOptionValues, jiti;
3647
+ var __defProp3, __getOwnPropNames3, __esm3, __export3, init_normalize2, ROOT_COLLECTION_ID, init_types3, normalizePathValue, flattenSchema, init_flatten2, ProdClientSafeStrategy2, DevClientSafeStrategy2, clientStrategyCache, init_client_safe_strategy, primitiveFieldTypes2, fieldTypes2, init_types22, fieldBaseSchema2, selectOptionSchema2, referenceOptionSchema2, primitiveFieldSchema2, ASPECT_RATIO_RE2, imageFieldSchema2, selectFieldSchema2, referenceFieldSchema2, fieldHolder2, blockSchema2, blockFieldSchema2, objectFieldSchema2, inlineGroupFieldSchema2, customFieldSchema2, knownFieldSchema2, fieldSchema2, init_field2, relativePathSchema2, entryTypeSchema2, collectionSchema2, init_collection2, mediaSchema2, init_media2, defaultBranchAccessSchema2, defaultPathAccessLevelSchema2, defaultPathAccessLevelsSchema2, defaultPathAccessSchema2, defaultBaseBranchSchema2, defaultRemoteNameSchema2, defaultRemoteUrlSchema2, gitBotAuthorNameSchema2, gitBotAuthorEmailSchema2, githubTokenEnvVarSchema2, operatingModeSchema2, deployedAsSchema2, contentRootSchema2, sourceRootSchema2, deploymentNameSchema2, devContentSyncSchema2, devConfigSchema2, editorConfigSchema2, CanopyConfigSchema2, DEFAULT_PROD_WORKSPACE2, init_config3, permissionTargetSchema2, pathPermissionSchema2, init_permissions2, init_validation2, init_helpers2, init_config22, ProdStrategy2, DevStrategy2, strategyCache2, init_client_unsafe_strategy, operating_mode_exports, init_operating_mode, locks, BASE58_PATTERN, CONTENT_ID_PATTERN, PHYSICAL_SEGMENT_PATTERN, isValidId, EMPTY_LOGICAL_PATH, ContentIdIndex, registry, finalization, LOG_LEVELS2, DebugLogger2, testLogger2, log2, META_DIR, entryTypeMetaSchema, collectionMetaSchema, rootCollectionMetaSchema, isDeployedStatic, isBuildMode, STATIC_DEPLOY_USER, SCHEMA_CACHE_VERSION, MTIME_CHECK_DEBOUNCE_MS, SCHEMA_GENERATION_RESOURCE, BranchSchemaCache, RESOURCE, getFormatExtension, isDataOnlyFormat, asRecord, BranchPathError, resolveContentBranchesRoot, ContentStoreError, ContentConflictError, DEFAULT_INDEX_FRESHNESS_INTERVAL_MS, FORCED_REFRESH_MIN_INTERVAL_MS, STALE_LOOKUP, ContentStore, ATTR_CONTENT, BLOCK_PREFIX, BLOCK_SUFFIX, BLOCK_RESTORE_RE, INLINE_PREFIX, INLINE_SUFFIX, INLINE_RESTORE_RE, FLAT_CELL_TYPES, log22, BASE58_CHAR, ENTRY_LINK_PATTERN, log3, REGISTRY_FILE, REGISTRY_STALE_FILE, REGISTRY_TEMP_FILE, REGISTRY_VERSION, RESOURCE2, GET_MISS_REFRESH_MIN_INTERVAL_MS, BranchRegistry, log4, OccWriteConflictError, BRANCH_META_DIR, BRANCH_META_FILE, CURRENT_SCHEMA_VERSION, BranchMetadataConflictError, BranchMetadataCorruptError, BranchMetadataFileManager, getBranchMetadataFileManager, loadBranchContext, NETWORK_SCHEME_PATTERN, TRANSPORT_HELPER_PATTERN, LEADING_OPTION_PATTERN, WINDOWS_DRIVE_PATTERN, COLON_BEFORE_SLASH_PATTERN, log5, GIT_ENV_PASSTHROUGH, remoteInitLocks, GitConflictError, GitManager, log6, workspaceInitLocks, BranchWorkspaceManager, log7, normalizePath, readEntryData, parseTypedFilename, listCollectionEntries, MAX_INPUT_PIXELS, KNOWN_FIELD_TYPES, STRING_FIELD_TYPES, selectOptionValues, jiti;
3574
3648
  var init_generate_ai_content = __esm({
3575
3649
  "dist/cli/generate-ai-content.js"() {
3576
3650
  "use strict";
@@ -5541,8 +5615,22 @@ var init_generate_ai_content = __esm({
5541
5615
  * Returns array of entry metadata (relativePath, collection, slug).
5542
5616
  * Returns empty array if the collection doesn't exist.
5543
5617
  */
5544
- async getCollectionEntryPaths(collectionPath) {
5545
- const idIndex = await this.idIndex();
5618
+ /**
5619
+ * Resolve a schema collection referenced by name or logical path.
5620
+ *
5621
+ * Accepts either a full logical path ("content/authors") or a bare
5622
+ * collection name ("authors") — the contract reference fields use for
5623
+ * `collections: [...]` (see README). This is the single normalization
5624
+ * point shared by reference-option loading and reference validation so
5625
+ * the dropdown and the write boundary can never disagree.
5626
+ *
5627
+ * CAVEAT: the bare-name fallback matches on the LAST path segment and
5628
+ * returns the first hit in schema order — with two collections sharing a
5629
+ * leaf name (e.g. content/blog/posts and content/news/posts), a bare
5630
+ * 'posts' is ambiguous. Use the full logical path in schemas that nest
5631
+ * same-named collections.
5632
+ */
5633
+ resolveCollectionItem(collectionPath) {
5546
5634
  const normalized = normalizeFilesystemPath(collectionPath);
5547
5635
  let item = this.schemaIndex.get(normalized);
5548
5636
  if (!item) {
@@ -5556,10 +5644,14 @@ var init_generate_ai_content = __esm({
5556
5644
  }
5557
5645
  }
5558
5646
  }
5559
- if (!item || item.type !== "collection") {
5647
+ return item && item.type === "collection" ? item : void 0;
5648
+ }
5649
+ async getCollectionEntryPaths(collectionPath) {
5650
+ const idIndex = await this.idIndex();
5651
+ const collection = this.resolveCollectionItem(collectionPath);
5652
+ if (!collection) {
5560
5653
  return [];
5561
5654
  }
5562
- const collection = item;
5563
5655
  const treeEntries = idIndex.getEntriesInCollectionTree(collection.logicalPath);
5564
5656
  const entries = [];
5565
5657
  for (const location of treeEntries) {
@@ -5837,7 +5929,13 @@ var init_generate_ai_content = __esm({
5837
5929
  continue;
5838
5930
  }
5839
5931
  const branchRoot = path10.join(this.root, entry.name);
5840
- const meta = await BranchMetadataFileManager.loadOnly(branchRoot);
5932
+ let meta;
5933
+ try {
5934
+ meta = await BranchMetadataFileManager.loadOnly(branchRoot);
5935
+ } catch (err) {
5936
+ console.warn(`CanopyCMS: Skipping branch directory '${entry.name}' during registry scan: ${getErrorMessage3(err)}`);
5937
+ continue;
5938
+ }
5841
5939
  if (meta) {
5842
5940
  branches.push({
5843
5941
  branch: meta.branch,
@@ -5871,6 +5969,14 @@ var init_generate_ai_content = __esm({
5871
5969
  this.name = "BranchMetadataConflictError";
5872
5970
  }
5873
5971
  };
5972
+ BranchMetadataCorruptError = class extends Error {
5973
+ constructor(branchRoot, cause) {
5974
+ super(`Corrupt branch metadata in '${branchRoot}': ${cause}`);
5975
+ this.name = "BranchMetadataCorruptError";
5976
+ this.branchRoot = branchRoot;
5977
+ this.parseCause = cause;
5978
+ }
5979
+ };
5874
5980
  BranchMetadataFileManager = class _BranchMetadataFileManager {
5875
5981
  constructor(branchRoot, baseRoot, options) {
5876
5982
  this.branchRoot = path12.resolve(branchRoot);
@@ -5883,7 +5989,8 @@ var init_generate_ai_content = __esm({
5883
5989
  * Use this for read-only access (e.g., in registry scanning or loadBranchContext).
5884
5990
  */
5885
5991
  static async loadOnly(branchRoot) {
5886
- const filePath = path12.join(path12.resolve(branchRoot), BRANCH_META_DIR, BRANCH_META_FILE);
5992
+ const resolvedRoot = path12.resolve(branchRoot);
5993
+ const filePath = path12.join(resolvedRoot, BRANCH_META_DIR, BRANCH_META_FILE);
5887
5994
  try {
5888
5995
  const raw = await fs12.readFile(filePath, "utf8");
5889
5996
  return JSON.parse(raw);
@@ -5891,6 +5998,9 @@ var init_generate_ai_content = __esm({
5891
5998
  if (isNotFoundError4(err)) {
5892
5999
  return null;
5893
6000
  }
6001
+ if (err instanceof SyntaxError) {
6002
+ throw new BranchMetadataCorruptError(resolvedRoot, err.message);
6003
+ }
5894
6004
  throw err;
5895
6005
  }
5896
6006
  }
@@ -6556,8 +6666,9 @@ var init_generate_ai_content = __esm({
6556
6666
  }
6557
6667
  async pullBaseInner() {
6558
6668
  await this.git.fetch(this.remote, this.baseBranch);
6669
+ const fetchedTip = (await this.git.revparse(["FETCH_HEAD"])).trim();
6559
6670
  try {
6560
- await this.git.merge([`${this.remote}/${this.baseBranch}`]);
6671
+ await this.git.merge([fetchedTip]);
6561
6672
  } catch (err) {
6562
6673
  try {
6563
6674
  const status = await this.git.status();
@@ -6612,8 +6723,9 @@ var init_generate_ai_content = __esm({
6612
6723
  }
6613
6724
  async rebaseOntoBaseInner() {
6614
6725
  await this.git.fetch(this.remote, this.baseBranch);
6726
+ const fetchedTip = (await this.git.revparse(["FETCH_HEAD"])).trim();
6615
6727
  try {
6616
- await this.git.rebase([`${this.remote}/${this.baseBranch}`]);
6728
+ await this.git.rebase([fetchedTip]);
6617
6729
  } catch (err) {
6618
6730
  try {
6619
6731
  const status = await this.git.status();
@@ -8210,7 +8322,7 @@ async function selectBranch(options, branchesDir) {
8210
8322
  let branches = [];
8211
8323
  if (await filePathExists(branchesDir)) {
8212
8324
  const entries = await fs23.readdir(branchesDir, { withFileTypes: true });
8213
- branches = entries.filter((e) => e.isDirectory()).map((e) => e.name);
8325
+ branches = entries.filter((e) => e.isDirectory() && !e.name.startsWith(".")).map((e) => e.name);
8214
8326
  }
8215
8327
  let branchName = options.branch;
8216
8328
  if (!branchName) {
@@ -8589,11 +8701,19 @@ var init_resolve = __esm({
8589
8701
  }
8590
8702
  });
8591
8703
 
8704
+ // dist/paths/branch-name.js
8705
+ var init_branch_name = __esm({
8706
+ "dist/paths/branch-name.js"() {
8707
+ "use strict";
8708
+ }
8709
+ });
8710
+
8592
8711
  // dist/paths/branch.js
8593
8712
  var init_branch = __esm({
8594
8713
  "dist/paths/branch.js"() {
8595
8714
  "use strict";
8596
8715
  init_operating_mode2();
8716
+ init_branch_name();
8597
8717
  }
8598
8718
  });
8599
8719
 
@@ -8606,6 +8726,7 @@ var init_paths = __esm({
8606
8726
  init_validation3();
8607
8727
  init_resolve();
8608
8728
  init_branch();
8729
+ init_branch_name();
8609
8730
  }
8610
8731
  });
8611
8732
 
@@ -8756,6 +8877,8 @@ async function withOccFileLock2(filePath, fn) {
8756
8877
  return await fn();
8757
8878
  } finally {
8758
8879
  await release().catch((err) => {
8880
+ if (isNodeError(err) && err.code === "ENOENT")
8881
+ return;
8759
8882
  log11.warn("lock", `Failed to release lock for ${filePath}`, { error: getErrorMessage(err) });
8760
8883
  });
8761
8884
  }
@@ -8935,7 +9058,13 @@ var init_branch_registry = __esm({
8935
9058
  continue;
8936
9059
  }
8937
9060
  const branchRoot = path28.join(this.root, entry.name);
8938
- const meta = await BranchMetadataFileManager2.loadOnly(branchRoot);
9061
+ let meta;
9062
+ try {
9063
+ meta = await BranchMetadataFileManager2.loadOnly(branchRoot);
9064
+ } catch (err) {
9065
+ console.warn(`CanopyCMS: Skipping branch directory '${entry.name}' during registry scan: ${getErrorMessage(err)}`);
9066
+ continue;
9067
+ }
8939
9068
  if (meta) {
8940
9069
  branches.push({
8941
9070
  branch: meta.branch,
@@ -8959,7 +9088,7 @@ var init_branch_registry = __esm({
8959
9088
  // dist/branch-metadata.js
8960
9089
  import fs26 from "node:fs/promises";
8961
9090
  import path29 from "node:path";
8962
- var BRANCH_META_DIR2, BRANCH_META_FILE2, CURRENT_SCHEMA_VERSION2, BranchMetadataConflictError2, BranchMetadataFileManager2;
9091
+ var BRANCH_META_DIR2, BRANCH_META_FILE2, CURRENT_SCHEMA_VERSION2, BranchMetadataConflictError2, BranchMetadataCorruptError2, BranchMetadataFileManager2;
8963
9092
  var init_branch_metadata = __esm({
8964
9093
  "dist/branch-metadata.js"() {
8965
9094
  "use strict";
@@ -8977,6 +9106,14 @@ var init_branch_metadata = __esm({
8977
9106
  this.name = "BranchMetadataConflictError";
8978
9107
  }
8979
9108
  };
9109
+ BranchMetadataCorruptError2 = class extends Error {
9110
+ constructor(branchRoot, cause) {
9111
+ super(`Corrupt branch metadata in '${branchRoot}': ${cause}`);
9112
+ this.name = "BranchMetadataCorruptError";
9113
+ this.branchRoot = branchRoot;
9114
+ this.parseCause = cause;
9115
+ }
9116
+ };
8980
9117
  BranchMetadataFileManager2 = class _BranchMetadataFileManager2 {
8981
9118
  constructor(branchRoot, baseRoot, options) {
8982
9119
  this.branchRoot = path29.resolve(branchRoot);
@@ -8989,7 +9126,8 @@ var init_branch_metadata = __esm({
8989
9126
  * Use this for read-only access (e.g., in registry scanning or loadBranchContext).
8990
9127
  */
8991
9128
  static async loadOnly(branchRoot) {
8992
- const filePath = path29.join(path29.resolve(branchRoot), BRANCH_META_DIR2, BRANCH_META_FILE2);
9129
+ const resolvedRoot = path29.resolve(branchRoot);
9130
+ const filePath = path29.join(resolvedRoot, BRANCH_META_DIR2, BRANCH_META_FILE2);
8993
9131
  try {
8994
9132
  const raw = await fs26.readFile(filePath, "utf8");
8995
9133
  return JSON.parse(raw);
@@ -8997,6 +9135,9 @@ var init_branch_metadata = __esm({
8997
9135
  if (isNotFoundError(err)) {
8998
9136
  return null;
8999
9137
  }
9138
+ if (err instanceof SyntaxError) {
9139
+ throw new BranchMetadataCorruptError2(resolvedRoot, err.message);
9140
+ }
9000
9141
  throw err;
9001
9142
  }
9002
9143
  }
@@ -1805,14 +1805,18 @@ function validateAndNormalizePath(root, target) {
1805
1805
  init_operating_mode();
1806
1806
  import fs7 from "node:fs/promises";
1807
1807
  import path7 from "node:path";
1808
- var BranchPathError = class extends Error {
1809
- };
1808
+
1809
+ // dist/paths/branch-name.js
1810
1810
  function sanitizeBranchName(branchName) {
1811
1811
  const replaced = branchName.replace(/[^a-zA-Z0-9._-]/g, "-");
1812
1812
  const squashed = replaced.replace(/-+/g, "-");
1813
1813
  const trimmedDots = squashed.replace(/^\.+/, "").replace(/(?<!\.)\.+$/, "");
1814
1814
  return trimmedDots || "branch";
1815
1815
  }
1816
+
1817
+ // dist/paths/branch.js
1818
+ var BranchPathError = class extends Error {
1819
+ };
1816
1820
  var resolveContentBranchesRoot = (mode, override) => {
1817
1821
  return operatingStrategy(mode).getContentBranchesRoot(override);
1818
1822
  };
@@ -2644,8 +2648,22 @@ var ContentStore = class {
2644
2648
  * Returns array of entry metadata (relativePath, collection, slug).
2645
2649
  * Returns empty array if the collection doesn't exist.
2646
2650
  */
2647
- async getCollectionEntryPaths(collectionPath) {
2648
- const idIndex = await this.idIndex();
2651
+ /**
2652
+ * Resolve a schema collection referenced by name or logical path.
2653
+ *
2654
+ * Accepts either a full logical path ("content/authors") or a bare
2655
+ * collection name ("authors") — the contract reference fields use for
2656
+ * `collections: [...]` (see README). This is the single normalization
2657
+ * point shared by reference-option loading and reference validation so
2658
+ * the dropdown and the write boundary can never disagree.
2659
+ *
2660
+ * CAVEAT: the bare-name fallback matches on the LAST path segment and
2661
+ * returns the first hit in schema order — with two collections sharing a
2662
+ * leaf name (e.g. content/blog/posts and content/news/posts), a bare
2663
+ * 'posts' is ambiguous. Use the full logical path in schemas that nest
2664
+ * same-named collections.
2665
+ */
2666
+ resolveCollectionItem(collectionPath) {
2649
2667
  const normalized = normalizeFilesystemPath(collectionPath);
2650
2668
  let item = this.schemaIndex.get(normalized);
2651
2669
  if (!item) {
@@ -2659,10 +2677,14 @@ var ContentStore = class {
2659
2677
  }
2660
2678
  }
2661
2679
  }
2662
- if (!item || item.type !== "collection") {
2680
+ return item && item.type === "collection" ? item : void 0;
2681
+ }
2682
+ async getCollectionEntryPaths(collectionPath) {
2683
+ const idIndex = await this.idIndex();
2684
+ const collection = this.resolveCollectionItem(collectionPath);
2685
+ if (!collection) {
2663
2686
  return [];
2664
2687
  }
2665
- const collection = item;
2666
2688
  const treeEntries = idIndex.getEntriesInCollectionTree(collection.logicalPath);
2667
2689
  const entries = [];
2668
2690
  for (const location of treeEntries) {
@@ -3844,7 +3866,13 @@ var BranchRegistry = class {
3844
3866
  continue;
3845
3867
  }
3846
3868
  const branchRoot = path10.join(this.root, entry.name);
3847
- const meta = await BranchMetadataFileManager.loadOnly(branchRoot);
3869
+ let meta;
3870
+ try {
3871
+ meta = await BranchMetadataFileManager.loadOnly(branchRoot);
3872
+ } catch (err) {
3873
+ console.warn(`CanopyCMS: Skipping branch directory '${entry.name}' during registry scan: ${getErrorMessage(err)}`);
3874
+ continue;
3875
+ }
3848
3876
  if (meta) {
3849
3877
  branches.push({
3850
3878
  branch: meta.branch,
@@ -3983,6 +4011,8 @@ async function withOccFileLock(filePath, fn) {
3983
4011
  return await fn();
3984
4012
  } finally {
3985
4013
  await release().catch((err) => {
4014
+ if (isNodeError(err) && err.code === "ENOENT")
4015
+ return;
3986
4016
  log4.warn("lock", `Failed to release lock for ${filePath}`, { error: getErrorMessage(err) });
3987
4017
  });
3988
4018
  }
@@ -3998,6 +4028,14 @@ var BranchMetadataConflictError = class extends Error {
3998
4028
  this.name = "BranchMetadataConflictError";
3999
4029
  }
4000
4030
  };
4031
+ var BranchMetadataCorruptError = class extends Error {
4032
+ constructor(branchRoot, cause) {
4033
+ super(`Corrupt branch metadata in '${branchRoot}': ${cause}`);
4034
+ this.name = "BranchMetadataCorruptError";
4035
+ this.branchRoot = branchRoot;
4036
+ this.parseCause = cause;
4037
+ }
4038
+ };
4001
4039
  var BranchMetadataFileManager = class _BranchMetadataFileManager {
4002
4040
  constructor(branchRoot, baseRoot, options) {
4003
4041
  this.branchRoot = path12.resolve(branchRoot);
@@ -4010,7 +4048,8 @@ var BranchMetadataFileManager = class _BranchMetadataFileManager {
4010
4048
  * Use this for read-only access (e.g., in registry scanning or loadBranchContext).
4011
4049
  */
4012
4050
  static async loadOnly(branchRoot) {
4013
- const filePath = path12.join(path12.resolve(branchRoot), BRANCH_META_DIR, BRANCH_META_FILE);
4051
+ const resolvedRoot = path12.resolve(branchRoot);
4052
+ const filePath = path12.join(resolvedRoot, BRANCH_META_DIR, BRANCH_META_FILE);
4014
4053
  try {
4015
4054
  const raw = await fs12.readFile(filePath, "utf8");
4016
4055
  return JSON.parse(raw);
@@ -4018,6 +4057,9 @@ var BranchMetadataFileManager = class _BranchMetadataFileManager {
4018
4057
  if (isNotFoundError(err)) {
4019
4058
  return null;
4020
4059
  }
4060
+ if (err instanceof SyntaxError) {
4061
+ throw new BranchMetadataCorruptError(resolvedRoot, err.message);
4062
+ }
4021
4063
  throw err;
4022
4064
  }
4023
4065
  }
@@ -4766,8 +4808,9 @@ var GitManager = class _GitManager {
4766
4808
  }
4767
4809
  async pullBaseInner() {
4768
4810
  await this.git.fetch(this.remote, this.baseBranch);
4811
+ const fetchedTip = (await this.git.revparse(["FETCH_HEAD"])).trim();
4769
4812
  try {
4770
- await this.git.merge([`${this.remote}/${this.baseBranch}`]);
4813
+ await this.git.merge([fetchedTip]);
4771
4814
  } catch (err) {
4772
4815
  try {
4773
4816
  const status = await this.git.status();
@@ -4822,8 +4865,9 @@ var GitManager = class _GitManager {
4822
4865
  }
4823
4866
  async rebaseOntoBaseInner() {
4824
4867
  await this.git.fetch(this.remote, this.baseBranch);
4868
+ const fetchedTip = (await this.git.revparse(["FETCH_HEAD"])).trim();
4825
4869
  try {
4826
- await this.git.rebase([`${this.remote}/${this.baseBranch}`]);
4870
+ await this.git.rebase([fetchedTip]);
4827
4871
  } catch (err) {
4828
4872
  try {
4829
4873
  const status = await this.git.status();
package/dist/cli/init.js CHANGED
@@ -757,6 +757,36 @@ async function retryTask(taskDir, taskId, error, logger = nullLogger) {
757
757
  });
758
758
  logger.debug("Retrying task", { id: taskId, retryCount, backoffMs });
759
759
  }
760
+ async function requeueFailedTask(taskDir, taskId, logger = nullLogger) {
761
+ const failedPath = path5.join(taskDir, "failed", `${taskId}.json`);
762
+ let content;
763
+ try {
764
+ content = await fs4.readFile(failedPath, "utf-8");
765
+ } catch (err) {
766
+ if (isNotFoundError2(err))
767
+ return { error: "not-found" };
768
+ throw err;
769
+ }
770
+ const original = parseTaskJson(content);
771
+ if (!original)
772
+ return { error: "unparseable" };
773
+ const newTaskId = crypto.randomUUID();
774
+ const newTask = {
775
+ id: newTaskId,
776
+ action: original.action,
777
+ payload: { ...original.payload, requeuedFrom: taskId },
778
+ status: "pending",
779
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
780
+ retryCount: 0,
781
+ maxRetries: original.maxRetries
782
+ };
783
+ const pendingPath = path5.join(taskDir, "pending", `${newTaskId}.json`);
784
+ await atomicWriteFile(pendingPath, JSON.stringify(newTask, null, 2));
785
+ await fs4.unlink(failedPath).catch(() => {
786
+ });
787
+ logger.debug("Requeued failed task", { originalId: taskId, newTaskId });
788
+ return { newTaskId };
789
+ }
760
790
  async function recoverOrphanedTasks(taskDir, maxAgeMs = 5 * 6e4, logger = nullLogger) {
761
791
  const processingDir = path5.join(taskDir, "processing");
762
792
  const pendingDir = path5.join(taskDir, "pending");
@@ -886,6 +916,46 @@ async function getQueueStats(taskDir) {
886
916
  }
887
917
  return stats;
888
918
  }
919
+ async function listCorruptTaskFiles(taskDir, limit = 50, logger = nullLogger) {
920
+ const corruptDir = path5.join(taskDir, "corrupt");
921
+ let files;
922
+ try {
923
+ files = await fs4.readdir(corruptDir);
924
+ } catch (err) {
925
+ if (isNotFoundError2(err))
926
+ return [];
927
+ throw err;
928
+ }
929
+ const entries = [];
930
+ for (const fileName of files.filter((f) => f.endsWith(".json"))) {
931
+ const filePath = path5.join(corruptDir, fileName);
932
+ try {
933
+ const stat = await fs4.stat(filePath);
934
+ entries.push({
935
+ fileName,
936
+ size: stat.size,
937
+ mtime: stat.mtime.toISOString(),
938
+ rawSnippet: await readSnippet(filePath, 500)
939
+ });
940
+ } catch (err) {
941
+ if (isNotFoundError2(err))
942
+ continue;
943
+ logger.debug("Failed to read corrupt task file", { fileName });
944
+ }
945
+ }
946
+ entries.sort((a, b) => new Date(b.mtime).getTime() - new Date(a.mtime).getTime());
947
+ return entries.slice(0, limit);
948
+ }
949
+ async function readSnippet(filePath, maxBytes) {
950
+ const handle = await fs4.open(filePath, "r");
951
+ try {
952
+ const buffer = Buffer.alloc(maxBytes);
953
+ const { bytesRead } = await handle.read(buffer, 0, maxBytes, 0);
954
+ return buffer.subarray(0, bytesRead).toString("utf-8");
955
+ } finally {
956
+ await handle.close();
957
+ }
958
+ }
889
959
  function parseTaskJson(content) {
890
960
  try {
891
961
  const parsed = JSON.parse(content);
@@ -949,8 +1019,10 @@ __export(task_queue_exports, {
949
1019
  getQueueStats: () => getQueueStats,
950
1020
  getTask: () => getTask,
951
1021
  getTaskResult: () => getTask,
1022
+ listCorruptTaskFiles: () => listCorruptTaskFiles,
952
1023
  listTasks: () => listTasks,
953
1024
  recoverOrphanedTasks: () => recoverOrphanedTasks,
1025
+ requeueFailedTask: () => requeueFailedTask,
954
1026
  retryTask: () => retryTask
955
1027
  });
956
1028
  var debugLogger, cmsTaskQueueLogger;
@@ -1 +1 @@
1
- {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/cli/sync.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAmBH,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAA;IAC7C,oDAAoD;IACpD,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,0DAA0D;IAC1D,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED;;;;GAIG;AACH,qBAAa,SAAU,SAAQ,KAAK;gBACtB,OAAO,EAAE,MAAM;CAI5B;AAkeD;;;;GAIG;AACH,wBAAsB,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAsB5F"}
1
+ {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/cli/sync.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAmBH,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAA;IAC7C,oDAAoD;IACpD,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,0DAA0D;IAC1D,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED;;;;GAIG;AACH,qBAAa,SAAU,SAAQ,KAAK;gBACtB,OAAO,EAAE,MAAM;CAI5B;AAqeD;;;;GAIG;AACH,wBAAsB,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAsB5F"}
package/dist/cli/sync.js CHANGED
@@ -49,7 +49,10 @@ async function selectBranch(options, branchesDir) {
49
49
  let branches = [];
50
50
  if (await filePathExists(branchesDir)) {
51
51
  const entries = await fs.readdir(branchesDir, { withFileTypes: true });
52
- branches = entries.filter((e) => e.isDirectory()).map((e) => e.name);
52
+ // Dot-prefixed dirs are never branch workspaces (.canopy-meta, and now
53
+ // .trash-*/.{dirName}.init.lock from the admin branch-health recovery
54
+ // surface) -- same skip rule as BranchRegistry.scanBranchDirectories.
55
+ branches = entries.filter((e) => e.isDirectory() && !e.name.startsWith('.')).map((e) => e.name);
53
56
  }
54
57
  let branchName = options.branch;
55
58
  if (!branchName) {