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.
- package/dist/api/__test__/mock-client.d.ts +29 -0
- package/dist/api/__test__/mock-client.d.ts.map +1 -1
- package/dist/api/__test__/mock-client.js +51 -0
- package/dist/api/__test__/mock-client.js.map +1 -1
- package/dist/api/admin-branch-health.d.ts +65 -0
- package/dist/api/admin-branch-health.d.ts.map +1 -0
- package/dist/api/admin-branch-health.js +448 -0
- package/dist/api/admin-branch-health.js.map +1 -0
- package/dist/api/admin.d.ts +136 -0
- package/dist/api/admin.d.ts.map +1 -0
- package/dist/api/admin.js +338 -0
- package/dist/api/admin.js.map +1 -0
- package/dist/api/assets.d.ts.map +1 -1
- package/dist/api/assets.js +4 -0
- package/dist/api/assets.js.map +1 -1
- package/dist/api/branch-merge.d.ts +6 -0
- package/dist/api/branch-merge.d.ts.map +1 -1
- package/dist/api/branch-merge.js +13 -3
- package/dist/api/branch-merge.js.map +1 -1
- package/dist/api/branch-status.d.ts.map +1 -1
- package/dist/api/branch-status.js +15 -5
- package/dist/api/branch-status.js.map +1 -1
- package/dist/api/branch-withdraw.d.ts +6 -0
- package/dist/api/branch-withdraw.d.ts.map +1 -1
- package/dist/api/branch-withdraw.js +15 -3
- package/dist/api/branch-withdraw.js.map +1 -1
- package/dist/api/branch.d.ts +11 -1
- package/dist/api/branch.d.ts.map +1 -1
- package/dist/api/branch.js +70 -4
- package/dist/api/branch.js.map +1 -1
- package/dist/api/client.d.ts +34 -0
- package/dist/api/client.d.ts.map +1 -1
- package/dist/api/client.js +47 -0
- package/dist/api/client.js.map +1 -1
- package/dist/api/comments.d.ts.map +1 -1
- package/dist/api/comments.js +4 -0
- package/dist/api/comments.js.map +1 -1
- package/dist/api/content.d.ts.map +1 -1
- package/dist/api/content.js +4 -4
- package/dist/api/content.js.map +1 -1
- package/dist/api/entries.js +1 -1
- package/dist/api/entries.js.map +1 -1
- package/dist/api/github-sync.d.ts.map +1 -1
- package/dist/api/github-sync.js +14 -3
- package/dist/api/github-sync.js.map +1 -1
- package/dist/api/guards.d.ts +7 -1
- package/dist/api/guards.d.ts.map +1 -1
- package/dist/api/guards.js +54 -0
- package/dist/api/guards.js.map +1 -1
- package/dist/api/index.d.ts +1 -0
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +0 -1
- package/dist/api/index.js.map +1 -1
- package/dist/api/schema.js +7 -7
- package/dist/api/schema.js.map +1 -1
- package/dist/authorization/branch.d.ts +14 -1
- package/dist/authorization/branch.d.ts.map +1 -1
- package/dist/authorization/branch.js +5 -3
- package/dist/authorization/branch.js.map +1 -1
- package/dist/authorization/index.d.ts +1 -0
- package/dist/authorization/index.d.ts.map +1 -1
- package/dist/authorization/index.js +2 -0
- package/dist/authorization/index.js.map +1 -1
- package/dist/authorization/protected-branch.d.ts +39 -0
- package/dist/authorization/protected-branch.d.ts.map +1 -0
- package/dist/authorization/protected-branch.js +43 -0
- package/dist/authorization/protected-branch.js.map +1 -0
- package/dist/branch-health.d.ts +78 -0
- package/dist/branch-health.d.ts.map +1 -0
- package/dist/branch-health.js +151 -0
- package/dist/branch-health.js.map +1 -0
- package/dist/branch-metadata.d.ts +20 -0
- package/dist/branch-metadata.d.ts.map +1 -1
- package/dist/branch-metadata.js +21 -1
- package/dist/branch-metadata.js.map +1 -1
- package/dist/branch-registry.d.ts.map +1 -1
- package/dist/branch-registry.js +13 -1
- package/dist/branch-registry.js.map +1 -1
- package/dist/cli/cli.js +154 -13
- package/dist/cli/generate-ai-content.js +54 -10
- package/dist/cli/init.js +72 -0
- package/dist/cli/sync.d.ts.map +1 -1
- package/dist/cli/sync.js +4 -1
- package/dist/cli/sync.js.map +1 -1
- package/dist/content-store.d.ts +16 -0
- package/dist/content-store.d.ts.map +1 -1
- package/dist/content-store.js +22 -6
- package/dist/content-store.js.map +1 -1
- package/dist/editor/BranchManager.d.ts +9 -1
- package/dist/editor/BranchManager.d.ts.map +1 -1
- package/dist/editor/BranchManager.js +20 -9
- package/dist/editor/BranchManager.js.map +1 -1
- package/dist/editor/CommentsPanel.d.ts.map +1 -1
- package/dist/editor/CommentsPanel.js +4 -12
- package/dist/editor/CommentsPanel.js.map +1 -1
- package/dist/editor/Editor.d.ts.map +1 -1
- package/dist/editor/Editor.js +46 -10
- package/dist/editor/Editor.js.map +1 -1
- package/dist/editor/EntryNavigator.d.ts +7 -0
- package/dist/editor/EntryNavigator.d.ts.map +1 -1
- package/dist/editor/EntryNavigator.js +17 -5
- package/dist/editor/EntryNavigator.js.map +1 -1
- package/dist/editor/FormRenderer.d.ts.map +1 -1
- package/dist/editor/FormRenderer.js +4 -0
- package/dist/editor/FormRenderer.js.map +1 -1
- package/dist/editor/admin/SystemHealthPanel.d.ts +6 -0
- package/dist/editor/admin/SystemHealthPanel.d.ts.map +1 -0
- package/dist/editor/admin/SystemHealthPanel.js +234 -0
- package/dist/editor/admin/SystemHealthPanel.js.map +1 -0
- package/dist/editor/admin/useSystemHealth.d.ts +40 -0
- package/dist/editor/admin/useSystemHealth.d.ts.map +1 -0
- package/dist/editor/admin/useSystemHealth.js +205 -0
- package/dist/editor/admin/useSystemHealth.js.map +1 -0
- package/dist/editor/comments/FieldWrapper.d.ts.map +1 -1
- package/dist/editor/comments/FieldWrapper.js +1 -1
- package/dist/editor/comments/FieldWrapper.js.map +1 -1
- package/dist/editor/comments/InlineCommentThread.d.ts.map +1 -1
- package/dist/editor/comments/InlineCommentThread.js +2 -21
- package/dist/editor/comments/InlineCommentThread.js.map +1 -1
- package/dist/editor/comments/ThreadCarousel.d.ts +2 -0
- package/dist/editor/comments/ThreadCarousel.d.ts.map +1 -1
- package/dist/editor/comments/ThreadCarousel.js +5 -2
- package/dist/editor/comments/ThreadCarousel.js.map +1 -1
- package/dist/editor/components/EditorHeader.d.ts +11 -0
- package/dist/editor/components/EditorHeader.d.ts.map +1 -1
- package/dist/editor/components/EditorHeader.js +75 -41
- package/dist/editor/components/EditorHeader.js.map +1 -1
- package/dist/editor/components/EditorSidebar.d.ts +7 -1
- package/dist/editor/components/EditorSidebar.d.ts.map +1 -1
- package/dist/editor/components/EditorSidebar.js +3 -3
- package/dist/editor/components/EditorSidebar.js.map +1 -1
- package/dist/editor/fields/ImageField.d.ts.map +1 -1
- package/dist/editor/fields/ImageField.js +4 -1
- package/dist/editor/fields/ImageField.js.map +1 -1
- package/dist/editor/fields/StringListField.d.ts +20 -0
- package/dist/editor/fields/StringListField.d.ts.map +1 -0
- package/dist/editor/fields/StringListField.js +25 -0
- package/dist/editor/fields/StringListField.js.map +1 -0
- package/dist/editor/hooks/useBranchActions.d.ts.map +1 -1
- package/dist/editor/hooks/useBranchActions.js +8 -2
- package/dist/editor/hooks/useBranchActions.js.map +1 -1
- package/dist/editor/hooks/useBranchManager.d.ts +12 -3
- package/dist/editor/hooks/useBranchManager.d.ts.map +1 -1
- package/dist/editor/hooks/useBranchManager.js +16 -1
- package/dist/editor/hooks/useBranchManager.js.map +1 -1
- package/dist/editor/hooks/useDraftManager.d.ts +7 -0
- package/dist/editor/hooks/useDraftManager.d.ts.map +1 -1
- package/dist/editor/hooks/useDraftManager.js +57 -3
- package/dist/editor/hooks/useDraftManager.js.map +1 -1
- package/dist/editor/hooks/useEntryManager.d.ts.map +1 -1
- package/dist/editor/hooks/useEntryManager.js +25 -7
- package/dist/editor/hooks/useEntryManager.js.map +1 -1
- package/dist/editor/media/AssetCard.d.ts.map +1 -1
- package/dist/editor/media/AssetCard.js +23 -2
- package/dist/editor/media/AssetCard.js.map +1 -1
- package/dist/editor/relative-time.d.ts +8 -0
- package/dist/editor/relative-time.d.ts.map +1 -0
- package/dist/editor/relative-time.js +26 -0
- package/dist/editor/relative-time.js.map +1 -0
- package/dist/git-manager.d.ts.map +1 -1
- package/dist/git-manager.js +10 -2
- package/dist/git-manager.js.map +1 -1
- package/dist/http/handler.d.ts.map +1 -1
- package/dist/http/handler.js +20 -9
- package/dist/http/handler.js.map +1 -1
- package/dist/http/router.d.ts.map +1 -1
- package/dist/http/router.js +2 -0
- package/dist/http/router.js.map +1 -1
- package/dist/paths/branch-name.d.ts +20 -0
- package/dist/paths/branch-name.d.ts.map +1 -0
- package/dist/paths/branch-name.js +24 -0
- package/dist/paths/branch-name.js.map +1 -0
- package/dist/paths/branch.d.ts +2 -8
- package/dist/paths/branch.d.ts.map +1 -1
- package/dist/paths/branch.js +6 -12
- package/dist/paths/branch.js.map +1 -1
- package/dist/paths/index.d.ts +2 -1
- package/dist/paths/index.d.ts.map +1 -1
- package/dist/paths/index.js +4 -1
- package/dist/paths/index.js.map +1 -1
- package/dist/services.js +9 -1
- package/dist/services.js.map +1 -1
- package/dist/task-queue/index.d.ts +2 -2
- package/dist/task-queue/index.d.ts.map +1 -1
- package/dist/task-queue/index.js +1 -1
- package/dist/task-queue/index.js.map +1 -1
- package/dist/task-queue/task-queue.d.ts +37 -1
- package/dist/task-queue/task-queue.d.ts.map +1 -1
- package/dist/task-queue/task-queue.js +104 -0
- package/dist/task-queue/task-queue.js.map +1 -1
- package/dist/task-queue/types.d.ts +11 -0
- package/dist/task-queue/types.d.ts.map +1 -1
- package/dist/types.d.ts +41 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/occ-json-write.d.ts.map +1 -1
- package/dist/utils/occ-json-write.js +7 -0
- package/dist/utils/occ-json-write.js.map +1 -1
- package/dist/utils/provisioning-lock.d.ts +19 -0
- package/dist/utils/provisioning-lock.d.ts.map +1 -1
- package/dist/utils/provisioning-lock.js +26 -0
- package/dist/utils/provisioning-lock.js.map +1 -1
- package/dist/validation/reference-validator.d.ts +17 -1
- package/dist/validation/reference-validator.d.ts.map +1 -1
- package/dist/validation/reference-validator.js +33 -10
- package/dist/validation/reference-validator.js.map +1 -1
- package/dist/worker/cms-worker.d.ts +38 -0
- package/dist/worker/cms-worker.d.ts.map +1 -1
- package/dist/worker/cms-worker.js +328 -25
- package/dist/worker/cms-worker.js.map +1 -1
- package/dist/worker/task-queue.d.ts +3 -3
- package/dist/worker/task-queue.d.ts.map +1 -1
- package/dist/worker/task-queue.js +2 -2
- package/dist/worker/task-queue.js.map +1 -1
- package/dist/worker/worker-status.d.ts +48 -0
- package/dist/worker/worker-status.d.ts.map +1 -0
- package/dist/worker/worker-status.js +53 -0
- package/dist/worker/worker-status.js.map +1 -0
- 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
|
-
|
|
5545
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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([
|
|
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([
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
2648
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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([
|
|
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([
|
|
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;
|
package/dist/cli/sync.d.ts.map
CHANGED
|
@@ -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;
|
|
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
|
-
|
|
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) {
|