canopycms 0.0.26 → 0.0.28
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/ai/generate.d.ts +3 -0
- package/dist/ai/generate.d.ts.map +1 -1
- package/dist/ai/generate.js +19 -7
- package/dist/ai/generate.js.map +1 -1
- package/dist/ai/handler.d.ts.map +1 -1
- package/dist/ai/handler.js +1 -0
- package/dist/ai/handler.js.map +1 -1
- package/dist/ai/json-to-markdown.js +1 -1
- package/dist/ai/json-to-markdown.js.map +1 -1
- package/dist/api/content.d.ts +10 -4
- package/dist/api/content.d.ts.map +1 -1
- package/dist/api/content.js +24 -12
- package/dist/api/content.js.map +1 -1
- package/dist/api/schema.d.ts +42 -42
- package/dist/build/generate-ai-content.d.ts.map +1 -1
- package/dist/build/generate-ai-content.js +1 -0
- package/dist/build/generate-ai-content.js.map +1 -1
- package/dist/cli/generate-ai-content.js +313 -157
- package/dist/cli/init.js +3 -2
- package/dist/client.d.ts +2 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +1 -0
- package/dist/client.js.map +1 -1
- package/dist/config/helpers.d.ts.map +1 -1
- package/dist/config/helpers.js +2 -1
- package/dist/config/helpers.js.map +1 -1
- package/dist/config/schemas/collection.d.ts +14 -14
- package/dist/config/schemas/collection.js +1 -1
- package/dist/config/schemas/collection.js.map +1 -1
- package/dist/config/schemas/config.d.ts +17 -13
- package/dist/config/schemas/config.d.ts.map +1 -1
- package/dist/config/schemas/config.js +1 -0
- package/dist/config/schemas/config.js.map +1 -1
- package/dist/config/types.d.ts +7 -2
- package/dist/config/types.d.ts.map +1 -1
- package/dist/config/types.js.map +1 -1
- package/dist/content-listing.d.ts +2 -2
- package/dist/content-listing.d.ts.map +1 -1
- package/dist/content-listing.js +6 -2
- package/dist/content-listing.js.map +1 -1
- package/dist/content-reader.d.ts +2 -0
- package/dist/content-reader.d.ts.map +1 -1
- package/dist/content-reader.js +13 -4
- package/dist/content-reader.js.map +1 -1
- package/dist/content-store.d.ts +8 -1
- package/dist/content-store.d.ts.map +1 -1
- package/dist/content-store.js +47 -39
- package/dist/content-store.js.map +1 -1
- package/dist/editor/CanopyEditor.d.ts.map +1 -1
- package/dist/editor/CanopyEditor.js +1 -1
- package/dist/editor/CanopyEditor.js.map +1 -1
- package/dist/editor/Editor.d.ts +1 -0
- package/dist/editor/Editor.d.ts.map +1 -1
- package/dist/editor/Editor.js +32 -9
- package/dist/editor/Editor.js.map +1 -1
- package/dist/editor/components/EntryCreateModal.d.ts +1 -1
- package/dist/editor/components/EntryCreateModal.d.ts.map +1 -1
- package/dist/editor/editor-utils.d.ts.map +1 -1
- package/dist/editor/editor-utils.js +4 -3
- package/dist/editor/editor-utils.js.map +1 -1
- package/dist/editor/fields/MarkdownField.d.ts.map +1 -1
- package/dist/editor/fields/MarkdownField.js +8 -2
- package/dist/editor/fields/MarkdownField.js.map +1 -1
- package/dist/editor/fields/entry-link/EntryLinkContext.d.ts +20 -0
- package/dist/editor/fields/entry-link/EntryLinkContext.d.ts.map +1 -0
- package/dist/editor/fields/entry-link/EntryLinkContext.js +12 -0
- package/dist/editor/fields/entry-link/EntryLinkContext.js.map +1 -0
- package/dist/editor/fields/entry-link/InsertEntryLink.d.ts +16 -0
- package/dist/editor/fields/entry-link/InsertEntryLink.d.ts.map +1 -0
- package/dist/editor/fields/entry-link/InsertEntryLink.js +62 -0
- package/dist/editor/fields/entry-link/InsertEntryLink.js.map +1 -0
- package/dist/editor/fields/entry-link/index.d.ts +3 -0
- package/dist/editor/fields/entry-link/index.d.ts.map +1 -0
- package/dist/editor/fields/entry-link/index.js +3 -0
- package/dist/editor/fields/entry-link/index.js.map +1 -0
- package/dist/editor/hooks/useEntryLinkResolution.d.ts +26 -0
- package/dist/editor/hooks/useEntryLinkResolution.d.ts.map +1 -0
- package/dist/editor/hooks/useEntryLinkResolution.js +96 -0
- package/dist/editor/hooks/useEntryLinkResolution.js.map +1 -0
- package/dist/editor/hooks/useEntryManager.d.ts.map +1 -1
- package/dist/editor/hooks/useEntryManager.js +4 -1
- package/dist/editor/hooks/useEntryManager.js.map +1 -1
- package/dist/editor/schema-editor/EntryTypeEditor.d.ts.map +1 -1
- package/dist/editor/schema-editor/EntryTypeEditor.js +2 -1
- package/dist/editor/schema-editor/EntryTypeEditor.js.map +1 -1
- package/dist/entry-link-resolver.d.ts +67 -0
- package/dist/entry-link-resolver.d.ts.map +1 -0
- package/dist/entry-link-resolver.js +226 -0
- package/dist/entry-link-resolver.js.map +1 -0
- package/dist/schema/meta-loader.d.ts +1 -1
- package/dist/schema/meta-loader.d.ts.map +1 -1
- package/dist/schema/meta-loader.js +1 -1
- package/dist/schema/meta-loader.js.map +1 -1
- package/dist/schema/schema-store.d.ts +21 -21
- package/dist/schema/schema-store.js +2 -2
- package/dist/schema/schema-store.js.map +1 -1
- package/dist/server.d.ts +3 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +2 -0
- package/dist/server.js.map +1 -1
- package/dist/utils/entry-url.d.ts +21 -0
- package/dist/utils/entry-url.d.ts.map +1 -0
- package/dist/utils/entry-url.js +41 -0
- package/dist/utils/entry-url.js.map +1 -0
- package/dist/utils/format.d.ts +6 -2
- package/dist/utils/format.d.ts.map +1 -1
- package/dist/utils/format.js +10 -2
- package/dist/utils/format.js.map +1 -1
- package/dist/validation/entry-link-validator.d.ts +27 -0
- package/dist/validation/entry-link-validator.d.ts.map +1 -0
- package/dist/validation/entry-link-validator.js +49 -0
- package/dist/validation/entry-link-validator.js.map +1 -0
- package/package.json +3 -2
|
@@ -23,6 +23,15 @@ function createLogicalPath(...segments) {
|
|
|
23
23
|
}
|
|
24
24
|
return normalized;
|
|
25
25
|
}
|
|
26
|
+
function trimSlashes(path13) {
|
|
27
|
+
let start = 0;
|
|
28
|
+
let end = path13.length;
|
|
29
|
+
while (start < end && path13[start] === "/")
|
|
30
|
+
start++;
|
|
31
|
+
while (end > start && path13[end - 1] === "/")
|
|
32
|
+
end--;
|
|
33
|
+
return path13.slice(start, end);
|
|
34
|
+
}
|
|
26
35
|
var init_normalize = __esm({
|
|
27
36
|
"dist/paths/normalize.js"() {
|
|
28
37
|
"use strict";
|
|
@@ -237,7 +246,7 @@ var init_collection = __esm({
|
|
|
237
246
|
}).transform((val) => val.split(/[\\/]+/).filter(Boolean).join("/"));
|
|
238
247
|
entryTypeSchema = z2.object({
|
|
239
248
|
name: z2.string().min(1),
|
|
240
|
-
format: z2.enum(["md", "mdx", "json"]),
|
|
249
|
+
format: z2.enum(["md", "mdx", "json", "yaml"]),
|
|
241
250
|
schema: z2.array(z2.lazy(() => fieldSchema)).min(1),
|
|
242
251
|
label: z2.string().optional(),
|
|
243
252
|
description: z2.string().optional(),
|
|
@@ -348,7 +357,8 @@ var init_config = __esm({
|
|
|
348
357
|
contentRoot: contentRootSchema.default("content"),
|
|
349
358
|
sourceRoot: sourceRootSchema.optional(),
|
|
350
359
|
editor: editorConfigSchema.optional(),
|
|
351
|
-
authPlugin: z4.custom().optional()
|
|
360
|
+
authPlugin: z4.custom().optional(),
|
|
361
|
+
entryLinkUrl: z4.custom().optional()
|
|
352
362
|
});
|
|
353
363
|
DEFAULT_PROD_WORKSPACE = "/mnt/efs/workspace";
|
|
354
364
|
}
|
|
@@ -691,6 +701,7 @@ import path11 from "node:path";
|
|
|
691
701
|
import fs4 from "node:fs/promises";
|
|
692
702
|
import path5 from "node:path";
|
|
693
703
|
import matter from "gray-matter";
|
|
704
|
+
import { parse as yamlParse, stringify as yamlStringify } from "yaml";
|
|
694
705
|
|
|
695
706
|
// dist/utils/atomic-write.js
|
|
696
707
|
import fs from "node:fs/promises";
|
|
@@ -1046,8 +1057,12 @@ var getFormatExtension = (format) => {
|
|
|
1046
1057
|
return ".md";
|
|
1047
1058
|
if (format === "mdx")
|
|
1048
1059
|
return ".mdx";
|
|
1060
|
+
if (format === "yaml")
|
|
1061
|
+
return ".yaml";
|
|
1049
1062
|
return ".json";
|
|
1050
1063
|
};
|
|
1064
|
+
var isDataOnlyFormat = (format) => format === "json" || format === "yaml";
|
|
1065
|
+
var asRecord = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
1051
1066
|
|
|
1052
1067
|
// dist/paths/index.js
|
|
1053
1068
|
init_normalize();
|
|
@@ -1288,7 +1303,7 @@ var ContentStore = class {
|
|
|
1288
1303
|
fields = defaultEntry?.schema || [];
|
|
1289
1304
|
}
|
|
1290
1305
|
if (format === "json") {
|
|
1291
|
-
const data = JSON.parse(raw);
|
|
1306
|
+
const data = asRecord(JSON.parse(raw));
|
|
1292
1307
|
doc = {
|
|
1293
1308
|
collection: schemaItem.logicalPath,
|
|
1294
1309
|
collectionName: schemaItem.name,
|
|
@@ -1297,6 +1312,16 @@ var ContentStore = class {
|
|
|
1297
1312
|
relativePath,
|
|
1298
1313
|
absolutePath
|
|
1299
1314
|
};
|
|
1315
|
+
} else if (format === "yaml") {
|
|
1316
|
+
const data = asRecord(yamlParse(raw));
|
|
1317
|
+
doc = {
|
|
1318
|
+
collection: schemaItem.logicalPath,
|
|
1319
|
+
collectionName: schemaItem.name,
|
|
1320
|
+
format: "yaml",
|
|
1321
|
+
data,
|
|
1322
|
+
relativePath,
|
|
1323
|
+
absolutePath
|
|
1324
|
+
};
|
|
1300
1325
|
} else {
|
|
1301
1326
|
const parsed = matter(raw);
|
|
1302
1327
|
doc = {
|
|
@@ -1343,25 +1368,28 @@ var ContentStore = class {
|
|
|
1343
1368
|
entryTypeName
|
|
1344
1369
|
});
|
|
1345
1370
|
await fs4.mkdir(path5.dirname(absolutePath), { recursive: true });
|
|
1371
|
+
const updateIdIndex = () => {
|
|
1372
|
+
if (!id)
|
|
1373
|
+
return;
|
|
1374
|
+
const existing = idIndex.findById(id);
|
|
1375
|
+
if (existing) {
|
|
1376
|
+
if (existing.relativePath !== relativePath) {
|
|
1377
|
+
idIndex.updatePath(existing.id, relativePath);
|
|
1378
|
+
}
|
|
1379
|
+
} else {
|
|
1380
|
+
idIndex.add({
|
|
1381
|
+
type: "entry",
|
|
1382
|
+
relativePath,
|
|
1383
|
+
collection: collectionPath,
|
|
1384
|
+
slug: slug || void 0
|
|
1385
|
+
});
|
|
1386
|
+
}
|
|
1387
|
+
};
|
|
1346
1388
|
if (input.format === "json") {
|
|
1347
1389
|
const json = JSON.stringify(input.data ?? {}, null, 2);
|
|
1348
1390
|
await atomicWriteFile(absolutePath, `${json}
|
|
1349
1391
|
`);
|
|
1350
|
-
|
|
1351
|
-
const existing = idIndex.findById(id);
|
|
1352
|
-
if (existing) {
|
|
1353
|
-
if (existing.relativePath !== relativePath) {
|
|
1354
|
-
idIndex.updatePath(existing.id, relativePath);
|
|
1355
|
-
}
|
|
1356
|
-
} else {
|
|
1357
|
-
idIndex.add({
|
|
1358
|
-
type: "entry",
|
|
1359
|
-
relativePath,
|
|
1360
|
-
collection: collectionPath,
|
|
1361
|
-
slug: slug || void 0
|
|
1362
|
-
});
|
|
1363
|
-
}
|
|
1364
|
-
}
|
|
1392
|
+
updateIdIndex();
|
|
1365
1393
|
return {
|
|
1366
1394
|
collection: schemaItem.logicalPath,
|
|
1367
1395
|
collectionName: schemaItem.name,
|
|
@@ -1371,23 +1399,22 @@ var ContentStore = class {
|
|
|
1371
1399
|
absolutePath
|
|
1372
1400
|
};
|
|
1373
1401
|
}
|
|
1402
|
+
if (input.format === "yaml") {
|
|
1403
|
+
const yaml = yamlStringify(input.data ?? {});
|
|
1404
|
+
await atomicWriteFile(absolutePath, yaml);
|
|
1405
|
+
updateIdIndex();
|
|
1406
|
+
return {
|
|
1407
|
+
collection: schemaItem.logicalPath,
|
|
1408
|
+
collectionName: schemaItem.name,
|
|
1409
|
+
format: "yaml",
|
|
1410
|
+
data: input.data ?? {},
|
|
1411
|
+
relativePath,
|
|
1412
|
+
absolutePath
|
|
1413
|
+
};
|
|
1414
|
+
}
|
|
1374
1415
|
const file = matter.stringify(input.body, input.data ?? {});
|
|
1375
1416
|
await atomicWriteFile(absolutePath, file);
|
|
1376
|
-
|
|
1377
|
-
const existing = idIndex.findById(id);
|
|
1378
|
-
if (existing) {
|
|
1379
|
-
if (existing.relativePath !== relativePath) {
|
|
1380
|
-
idIndex.updatePath(existing.id, relativePath);
|
|
1381
|
-
}
|
|
1382
|
-
} else {
|
|
1383
|
-
idIndex.add({
|
|
1384
|
-
type: "entry",
|
|
1385
|
-
relativePath,
|
|
1386
|
-
collection: collectionPath,
|
|
1387
|
-
slug: slug || void 0
|
|
1388
|
-
});
|
|
1389
|
-
}
|
|
1390
|
-
}
|
|
1417
|
+
updateIdIndex();
|
|
1391
1418
|
return {
|
|
1392
1419
|
collection: schemaItem.logicalPath,
|
|
1393
1420
|
collectionName: schemaItem.name,
|
|
@@ -1613,7 +1640,7 @@ import { z as z6 } from "zod";
|
|
|
1613
1640
|
import chokidar from "chokidar";
|
|
1614
1641
|
var entryTypeMetaSchema = z6.object({
|
|
1615
1642
|
name: z6.string().min(1),
|
|
1616
|
-
format: z6.enum(["md", "mdx", "json"]),
|
|
1643
|
+
format: z6.enum(["md", "mdx", "json", "yaml"]),
|
|
1617
1644
|
schema: z6.string().min(1),
|
|
1618
1645
|
// Entry schema registry key (validated at resolution time)
|
|
1619
1646
|
label: z6.string().optional(),
|
|
@@ -2366,10 +2393,223 @@ function yamlValue(value) {
|
|
|
2366
2393
|
return value;
|
|
2367
2394
|
}
|
|
2368
2395
|
|
|
2396
|
+
// dist/utils/debug.js
|
|
2397
|
+
var LOG_LEVELS = {
|
|
2398
|
+
DEBUG: 0,
|
|
2399
|
+
INFO: 1,
|
|
2400
|
+
WARN: 2,
|
|
2401
|
+
ERROR: 3
|
|
2402
|
+
};
|
|
2403
|
+
var DebugLogger = class {
|
|
2404
|
+
constructor(options = {}) {
|
|
2405
|
+
this.timers = /* @__PURE__ */ new Map();
|
|
2406
|
+
this.options = options;
|
|
2407
|
+
}
|
|
2408
|
+
shouldLog(level) {
|
|
2409
|
+
const enabled = this.options.enabled ?? process.env.CANOPYCMS_DEBUG === "true";
|
|
2410
|
+
if (!enabled)
|
|
2411
|
+
return false;
|
|
2412
|
+
const minLevel = this.options.minLevel ?? "DEBUG";
|
|
2413
|
+
return LOG_LEVELS[level] >= LOG_LEVELS[minLevel];
|
|
2414
|
+
}
|
|
2415
|
+
formatMessage(level, category, message) {
|
|
2416
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
2417
|
+
const prefix = this.options.prefix ?? "CanopyCMS";
|
|
2418
|
+
return `[${timestamp}] [${prefix}:${category}] [${level}] ${message}`;
|
|
2419
|
+
}
|
|
2420
|
+
debug(category, message, data) {
|
|
2421
|
+
if (this.shouldLog("DEBUG")) {
|
|
2422
|
+
console.log(this.formatMessage("DEBUG", category, message), data ?? "");
|
|
2423
|
+
}
|
|
2424
|
+
}
|
|
2425
|
+
info(category, message, data) {
|
|
2426
|
+
if (this.shouldLog("INFO")) {
|
|
2427
|
+
console.log(this.formatMessage("INFO", category, message), data ?? "");
|
|
2428
|
+
}
|
|
2429
|
+
}
|
|
2430
|
+
warn(category, message, data) {
|
|
2431
|
+
if (this.shouldLog("WARN")) {
|
|
2432
|
+
console.warn(this.formatMessage("WARN", category, message), data ?? "");
|
|
2433
|
+
}
|
|
2434
|
+
}
|
|
2435
|
+
error(category, message, data) {
|
|
2436
|
+
const msg = this.formatMessage("ERROR", category, message);
|
|
2437
|
+
if (this.shouldLog("ERROR")) {
|
|
2438
|
+
console.error(msg, data ?? "");
|
|
2439
|
+
}
|
|
2440
|
+
const throwOnError = this.options.throwOnError ?? false;
|
|
2441
|
+
if (throwOnError) {
|
|
2442
|
+
const errorMsg = data ? `${message}: ${JSON.stringify(data)}` : message;
|
|
2443
|
+
throw new Error(errorMsg);
|
|
2444
|
+
}
|
|
2445
|
+
}
|
|
2446
|
+
/**
|
|
2447
|
+
* Start timing an operation
|
|
2448
|
+
*/
|
|
2449
|
+
time(label) {
|
|
2450
|
+
this.timers.set(label, Date.now());
|
|
2451
|
+
}
|
|
2452
|
+
/**
|
|
2453
|
+
* End timing an operation and log the duration
|
|
2454
|
+
*/
|
|
2455
|
+
timeEnd(category, label) {
|
|
2456
|
+
const start = this.timers.get(label);
|
|
2457
|
+
if (start === void 0) {
|
|
2458
|
+
this.warn(category, `Timer '${label}' does not exist`);
|
|
2459
|
+
return;
|
|
2460
|
+
}
|
|
2461
|
+
const duration = Date.now() - start;
|
|
2462
|
+
this.timers.delete(label);
|
|
2463
|
+
this.debug(category, `${label} completed`, { durationMs: duration });
|
|
2464
|
+
return duration;
|
|
2465
|
+
}
|
|
2466
|
+
/**
|
|
2467
|
+
* Wrap an async function with automatic timing
|
|
2468
|
+
*/
|
|
2469
|
+
async timed(category, label, fn) {
|
|
2470
|
+
this.time(label);
|
|
2471
|
+
try {
|
|
2472
|
+
return await fn();
|
|
2473
|
+
} finally {
|
|
2474
|
+
this.timeEnd(category, label);
|
|
2475
|
+
}
|
|
2476
|
+
}
|
|
2477
|
+
};
|
|
2478
|
+
function createDebugLogger(options) {
|
|
2479
|
+
return new DebugLogger(options);
|
|
2480
|
+
}
|
|
2481
|
+
var testLogger = createDebugLogger({
|
|
2482
|
+
enabled: process.env.E2E_DEBUG === "true",
|
|
2483
|
+
prefix: "E2E",
|
|
2484
|
+
throwOnError: false
|
|
2485
|
+
});
|
|
2486
|
+
|
|
2487
|
+
// dist/utils/entry-url.js
|
|
2488
|
+
init_normalize();
|
|
2489
|
+
function computeEntryUrl(collection, slug, contentRoot) {
|
|
2490
|
+
const root = trimSlashes(contentRoot);
|
|
2491
|
+
let stripped = collection;
|
|
2492
|
+
if (root && collection.startsWith(`${root}/`)) {
|
|
2493
|
+
stripped = collection.slice(root.length + 1);
|
|
2494
|
+
} else if (collection === root) {
|
|
2495
|
+
stripped = "";
|
|
2496
|
+
}
|
|
2497
|
+
const segments = stripped.split("/").filter(Boolean);
|
|
2498
|
+
if (slug && slug !== "index") {
|
|
2499
|
+
segments.push(slug);
|
|
2500
|
+
}
|
|
2501
|
+
const path13 = segments.length > 0 ? `/${segments.join("/")}` : "/";
|
|
2502
|
+
return path13.toLowerCase();
|
|
2503
|
+
}
|
|
2504
|
+
|
|
2505
|
+
// dist/entry-link-resolver.js
|
|
2506
|
+
var log = createDebugLogger({ prefix: "EntryLinks" });
|
|
2507
|
+
var BASE58_CHAR = "[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]";
|
|
2508
|
+
var ENTRY_LINK_PATTERN = new RegExp(`entry:(${BASE58_CHAR}{12})(#[^\\s)>"']*)?`, "g");
|
|
2509
|
+
function resolveEntryUrl(location, contentRoot) {
|
|
2510
|
+
return computeEntryUrl(location.collection ?? "", location.slug ?? "", contentRoot);
|
|
2511
|
+
}
|
|
2512
|
+
function resolveEntryLinksInText(text, idIndex, contentRoot, customResolver) {
|
|
2513
|
+
const parts = splitByCodeRegions(text);
|
|
2514
|
+
return parts.map((part) => {
|
|
2515
|
+
if (part.isCode)
|
|
2516
|
+
return part.text;
|
|
2517
|
+
return part.text.replace(ENTRY_LINK_PATTERN, (_match, id, anchor) => {
|
|
2518
|
+
const location = idIndex.findById(id);
|
|
2519
|
+
if (!location || location.type !== "entry" || !location.collection || !location.slug) {
|
|
2520
|
+
log.warn("resolve", `Entry link target not found: entry:${id}`);
|
|
2521
|
+
return anchor ?? "#";
|
|
2522
|
+
}
|
|
2523
|
+
let url;
|
|
2524
|
+
if (customResolver) {
|
|
2525
|
+
url = customResolver({
|
|
2526
|
+
collection: location.collection,
|
|
2527
|
+
slug: location.slug,
|
|
2528
|
+
id
|
|
2529
|
+
});
|
|
2530
|
+
} else {
|
|
2531
|
+
url = resolveEntryUrl(location, contentRoot);
|
|
2532
|
+
}
|
|
2533
|
+
return `${url}${anchor ?? ""}`;
|
|
2534
|
+
});
|
|
2535
|
+
}).join("");
|
|
2536
|
+
}
|
|
2537
|
+
function splitByCodeRegions(text) {
|
|
2538
|
+
const parts = [];
|
|
2539
|
+
let current = "";
|
|
2540
|
+
let i = 0;
|
|
2541
|
+
while (i < text.length) {
|
|
2542
|
+
if ((text[i] === "`" || text[i] === "~") && i + 2 < text.length && text[i + 1] === text[i] && text[i + 2] === text[i]) {
|
|
2543
|
+
const fence = text[i];
|
|
2544
|
+
let fenceLen = 0;
|
|
2545
|
+
while (i + fenceLen < text.length && text[i + fenceLen] === fence)
|
|
2546
|
+
fenceLen++;
|
|
2547
|
+
const lineEnd = text.indexOf("\n", i + fenceLen);
|
|
2548
|
+
if (lineEnd === -1) {
|
|
2549
|
+
if (current)
|
|
2550
|
+
parts.push({ text: current, isCode: false });
|
|
2551
|
+
parts.push({ text: text.slice(i), isCode: true });
|
|
2552
|
+
return parts;
|
|
2553
|
+
}
|
|
2554
|
+
const closingPattern = fence.repeat(fenceLen);
|
|
2555
|
+
let closeStart = lineEnd + 1;
|
|
2556
|
+
let found = false;
|
|
2557
|
+
while (closeStart < text.length) {
|
|
2558
|
+
const nextNewline = text.indexOf("\n", closeStart);
|
|
2559
|
+
const lineContent = nextNewline === -1 ? text.slice(closeStart) : text.slice(closeStart, nextNewline);
|
|
2560
|
+
if (lineContent.trim().startsWith(closingPattern)) {
|
|
2561
|
+
const endPos = nextNewline === -1 ? text.length : nextNewline + 1;
|
|
2562
|
+
if (current)
|
|
2563
|
+
parts.push({ text: current, isCode: false });
|
|
2564
|
+
current = "";
|
|
2565
|
+
parts.push({ text: text.slice(i, endPos), isCode: true });
|
|
2566
|
+
i = endPos;
|
|
2567
|
+
found = true;
|
|
2568
|
+
break;
|
|
2569
|
+
}
|
|
2570
|
+
if (nextNewline === -1)
|
|
2571
|
+
break;
|
|
2572
|
+
closeStart = nextNewline + 1;
|
|
2573
|
+
}
|
|
2574
|
+
if (!found) {
|
|
2575
|
+
if (current)
|
|
2576
|
+
parts.push({ text: current, isCode: false });
|
|
2577
|
+
parts.push({ text: text.slice(i), isCode: true });
|
|
2578
|
+
return parts;
|
|
2579
|
+
}
|
|
2580
|
+
continue;
|
|
2581
|
+
}
|
|
2582
|
+
if (text[i] === "`") {
|
|
2583
|
+
let ticks = 0;
|
|
2584
|
+
while (i + ticks < text.length && text[i + ticks] === "`")
|
|
2585
|
+
ticks++;
|
|
2586
|
+
const closer = "`".repeat(ticks);
|
|
2587
|
+
const closeIdx = text.indexOf(closer, i + ticks);
|
|
2588
|
+
if (closeIdx !== -1) {
|
|
2589
|
+
if (current)
|
|
2590
|
+
parts.push({ text: current, isCode: false });
|
|
2591
|
+
current = "";
|
|
2592
|
+
parts.push({ text: text.slice(i, closeIdx + ticks), isCode: true });
|
|
2593
|
+
i = closeIdx + ticks;
|
|
2594
|
+
continue;
|
|
2595
|
+
}
|
|
2596
|
+
current += text.slice(i, i + ticks);
|
|
2597
|
+
i += ticks;
|
|
2598
|
+
continue;
|
|
2599
|
+
}
|
|
2600
|
+
current += text[i];
|
|
2601
|
+
i++;
|
|
2602
|
+
}
|
|
2603
|
+
if (current)
|
|
2604
|
+
parts.push({ text: current, isCode: false });
|
|
2605
|
+
return parts;
|
|
2606
|
+
}
|
|
2607
|
+
|
|
2369
2608
|
// dist/ai/generate.js
|
|
2370
2609
|
async function generateAIContent(options) {
|
|
2371
|
-
const { store, flatSchema, contentRoot, config } = options;
|
|
2610
|
+
const { store, flatSchema, contentRoot, config, entryLinkUrl } = options;
|
|
2372
2611
|
const files = /* @__PURE__ */ new Map();
|
|
2612
|
+
const idIndex = await store.idIndex();
|
|
2373
2613
|
const collections = flatSchema.filter((item) => item.type === "collection");
|
|
2374
2614
|
const allEntries = [];
|
|
2375
2615
|
const manifestCollections = [];
|
|
@@ -2381,7 +2621,7 @@ async function generateAIContent(options) {
|
|
|
2381
2621
|
continue;
|
|
2382
2622
|
if (collection.parentPath && collection.parentPath !== contentRoot)
|
|
2383
2623
|
continue;
|
|
2384
|
-
const collectionResult = await processCollection(store, collection, flatSchema, contentRoot, config);
|
|
2624
|
+
const collectionResult = await processCollection(store, collection, flatSchema, contentRoot, config, idIndex, entryLinkUrl);
|
|
2385
2625
|
allEntries.push(...collectionResult.entries);
|
|
2386
2626
|
for (const [filePath, content] of collectionResult.files) {
|
|
2387
2627
|
files.set(filePath, content);
|
|
@@ -2390,7 +2630,7 @@ async function generateAIContent(options) {
|
|
|
2390
2630
|
}
|
|
2391
2631
|
const rootCollection = collections.find((c) => c.logicalPath === contentRoot);
|
|
2392
2632
|
if (rootCollection?.entries) {
|
|
2393
|
-
const rootResult = await processRootEntries(store, rootCollection, contentRoot, config);
|
|
2633
|
+
const rootResult = await processRootEntries(store, rootCollection, contentRoot, config, idIndex, entryLinkUrl);
|
|
2394
2634
|
allEntries.push(...rootResult.entries);
|
|
2395
2635
|
for (const [filePath, content] of rootResult.files) {
|
|
2396
2636
|
files.set(filePath, content);
|
|
@@ -2426,7 +2666,7 @@ async function generateAIContent(options) {
|
|
|
2426
2666
|
files.set("manifest.json", JSON.stringify(manifest, null, 2));
|
|
2427
2667
|
return { manifest, files };
|
|
2428
2668
|
}
|
|
2429
|
-
async function processCollection(store, collection, flatSchema, contentRoot, config) {
|
|
2669
|
+
async function processCollection(store, collection, flatSchema, contentRoot, config, idIndex, entryLinkUrl) {
|
|
2430
2670
|
const files = /* @__PURE__ */ new Map();
|
|
2431
2671
|
const entries = [];
|
|
2432
2672
|
const cleanPath = stripContentRoot(collection.logicalPath, contentRoot);
|
|
@@ -2447,6 +2687,9 @@ async function processCollection(store, collection, flatSchema, contentRoot, con
|
|
|
2447
2687
|
resolveReferences: false
|
|
2448
2688
|
});
|
|
2449
2689
|
const aiEntry = docToAIEntry(doc, listEntry.slug, entryTypeName, entryTypeConfig, cleanPath);
|
|
2690
|
+
if (aiEntry.body && idIndex) {
|
|
2691
|
+
aiEntry.body = resolveEntryLinksInText(aiEntry.body, idIndex, contentRoot, entryLinkUrl);
|
|
2692
|
+
}
|
|
2450
2693
|
if (config?.exclude?.where?.(aiEntry))
|
|
2451
2694
|
continue;
|
|
2452
2695
|
entries.push(aiEntry);
|
|
@@ -2468,7 +2711,7 @@ async function processCollection(store, collection, flatSchema, contentRoot, con
|
|
|
2468
2711
|
for (const sub of subcollections) {
|
|
2469
2712
|
if (isCollectionExcluded(sub.logicalPath, contentRoot, config))
|
|
2470
2713
|
continue;
|
|
2471
|
-
const subResult = await processCollection(store, sub, flatSchema, contentRoot, config);
|
|
2714
|
+
const subResult = await processCollection(store, sub, flatSchema, contentRoot, config, idIndex, entryLinkUrl);
|
|
2472
2715
|
entries.push(...subResult.entries);
|
|
2473
2716
|
for (const [filePath, content] of subResult.files) {
|
|
2474
2717
|
files.set(filePath, content);
|
|
@@ -2492,7 +2735,7 @@ async function processCollection(store, collection, flatSchema, contentRoot, con
|
|
|
2492
2735
|
};
|
|
2493
2736
|
return { entries, files, manifestCollection };
|
|
2494
2737
|
}
|
|
2495
|
-
async function processRootEntries(store, rootCollection, contentRoot, config) {
|
|
2738
|
+
async function processRootEntries(store, rootCollection, contentRoot, config, idIndex, entryLinkUrl) {
|
|
2496
2739
|
const files = /* @__PURE__ */ new Map();
|
|
2497
2740
|
const entries = [];
|
|
2498
2741
|
const manifestEntries = [];
|
|
@@ -2512,6 +2755,9 @@ async function processRootEntries(store, rootCollection, contentRoot, config) {
|
|
|
2512
2755
|
resolveReferences: false
|
|
2513
2756
|
});
|
|
2514
2757
|
const aiEntry = docToAIEntry(doc, listEntry.slug, entryTypeName, entryTypeConfig, "");
|
|
2758
|
+
if (aiEntry.body && idIndex) {
|
|
2759
|
+
aiEntry.body = resolveEntryLinksInText(aiEntry.body, idIndex, contentRoot, entryLinkUrl);
|
|
2760
|
+
}
|
|
2515
2761
|
if (config?.exclude?.where?.(aiEntry))
|
|
2516
2762
|
continue;
|
|
2517
2763
|
entries.push(aiEntry);
|
|
@@ -2556,7 +2802,7 @@ function docToAIEntry(doc, slug, entryTypeName, entryTypeConfig, cleanCollection
|
|
|
2556
2802
|
entryType: entryTypeName,
|
|
2557
2803
|
format: doc.format,
|
|
2558
2804
|
data: doc.data,
|
|
2559
|
-
body: doc.format
|
|
2805
|
+
body: !isDataOnlyFormat(doc.format) ? doc.body : void 0,
|
|
2560
2806
|
fields: entryTypeConfig.schema
|
|
2561
2807
|
};
|
|
2562
2808
|
}
|
|
@@ -2902,97 +3148,6 @@ import fs9 from "node:fs/promises";
|
|
|
2902
3148
|
import path10 from "node:path";
|
|
2903
3149
|
import { simpleGit as simpleGit2 } from "simple-git";
|
|
2904
3150
|
|
|
2905
|
-
// dist/utils/debug.js
|
|
2906
|
-
var LOG_LEVELS = {
|
|
2907
|
-
DEBUG: 0,
|
|
2908
|
-
INFO: 1,
|
|
2909
|
-
WARN: 2,
|
|
2910
|
-
ERROR: 3
|
|
2911
|
-
};
|
|
2912
|
-
var DebugLogger = class {
|
|
2913
|
-
constructor(options = {}) {
|
|
2914
|
-
this.timers = /* @__PURE__ */ new Map();
|
|
2915
|
-
this.options = options;
|
|
2916
|
-
}
|
|
2917
|
-
shouldLog(level) {
|
|
2918
|
-
const enabled = this.options.enabled ?? process.env.CANOPYCMS_DEBUG === "true";
|
|
2919
|
-
if (!enabled)
|
|
2920
|
-
return false;
|
|
2921
|
-
const minLevel = this.options.minLevel ?? "DEBUG";
|
|
2922
|
-
return LOG_LEVELS[level] >= LOG_LEVELS[minLevel];
|
|
2923
|
-
}
|
|
2924
|
-
formatMessage(level, category, message) {
|
|
2925
|
-
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
2926
|
-
const prefix = this.options.prefix ?? "CanopyCMS";
|
|
2927
|
-
return `[${timestamp}] [${prefix}:${category}] [${level}] ${message}`;
|
|
2928
|
-
}
|
|
2929
|
-
debug(category, message, data) {
|
|
2930
|
-
if (this.shouldLog("DEBUG")) {
|
|
2931
|
-
console.log(this.formatMessage("DEBUG", category, message), data ?? "");
|
|
2932
|
-
}
|
|
2933
|
-
}
|
|
2934
|
-
info(category, message, data) {
|
|
2935
|
-
if (this.shouldLog("INFO")) {
|
|
2936
|
-
console.log(this.formatMessage("INFO", category, message), data ?? "");
|
|
2937
|
-
}
|
|
2938
|
-
}
|
|
2939
|
-
warn(category, message, data) {
|
|
2940
|
-
if (this.shouldLog("WARN")) {
|
|
2941
|
-
console.warn(this.formatMessage("WARN", category, message), data ?? "");
|
|
2942
|
-
}
|
|
2943
|
-
}
|
|
2944
|
-
error(category, message, data) {
|
|
2945
|
-
const msg = this.formatMessage("ERROR", category, message);
|
|
2946
|
-
if (this.shouldLog("ERROR")) {
|
|
2947
|
-
console.error(msg, data ?? "");
|
|
2948
|
-
}
|
|
2949
|
-
const throwOnError = this.options.throwOnError ?? false;
|
|
2950
|
-
if (throwOnError) {
|
|
2951
|
-
const errorMsg = data ? `${message}: ${JSON.stringify(data)}` : message;
|
|
2952
|
-
throw new Error(errorMsg);
|
|
2953
|
-
}
|
|
2954
|
-
}
|
|
2955
|
-
/**
|
|
2956
|
-
* Start timing an operation
|
|
2957
|
-
*/
|
|
2958
|
-
time(label) {
|
|
2959
|
-
this.timers.set(label, Date.now());
|
|
2960
|
-
}
|
|
2961
|
-
/**
|
|
2962
|
-
* End timing an operation and log the duration
|
|
2963
|
-
*/
|
|
2964
|
-
timeEnd(category, label) {
|
|
2965
|
-
const start = this.timers.get(label);
|
|
2966
|
-
if (start === void 0) {
|
|
2967
|
-
this.warn(category, `Timer '${label}' does not exist`);
|
|
2968
|
-
return;
|
|
2969
|
-
}
|
|
2970
|
-
const duration = Date.now() - start;
|
|
2971
|
-
this.timers.delete(label);
|
|
2972
|
-
this.debug(category, `${label} completed`, { durationMs: duration });
|
|
2973
|
-
return duration;
|
|
2974
|
-
}
|
|
2975
|
-
/**
|
|
2976
|
-
* Wrap an async function with automatic timing
|
|
2977
|
-
*/
|
|
2978
|
-
async timed(category, label, fn) {
|
|
2979
|
-
this.time(label);
|
|
2980
|
-
try {
|
|
2981
|
-
return await fn();
|
|
2982
|
-
} finally {
|
|
2983
|
-
this.timeEnd(category, label);
|
|
2984
|
-
}
|
|
2985
|
-
}
|
|
2986
|
-
};
|
|
2987
|
-
function createDebugLogger(options) {
|
|
2988
|
-
return new DebugLogger(options);
|
|
2989
|
-
}
|
|
2990
|
-
var testLogger = createDebugLogger({
|
|
2991
|
-
enabled: process.env.E2E_DEBUG === "true",
|
|
2992
|
-
prefix: "E2E",
|
|
2993
|
-
throwOnError: false
|
|
2994
|
-
});
|
|
2995
|
-
|
|
2996
3151
|
// dist/utils/git.js
|
|
2997
3152
|
import { simpleGit } from "simple-git";
|
|
2998
3153
|
async function detectHeadBranch(repoRoot, fallback = "main") {
|
|
@@ -3006,7 +3161,7 @@ async function detectHeadBranch(repoRoot, fallback = "main") {
|
|
|
3006
3161
|
}
|
|
3007
3162
|
|
|
3008
3163
|
// dist/git-manager.js
|
|
3009
|
-
var
|
|
3164
|
+
var log2 = createDebugLogger({ prefix: "GitManager" });
|
|
3010
3165
|
var remoteInitLocks = /* @__PURE__ */ new Map();
|
|
3011
3166
|
var GitManager = class _GitManager {
|
|
3012
3167
|
constructor(options, gitOptions) {
|
|
@@ -3017,14 +3172,14 @@ var GitManager = class _GitManager {
|
|
|
3017
3172
|
this.git.env("GIT_CEILING_DIRECTORIES", path10.dirname(this.repoPath));
|
|
3018
3173
|
}
|
|
3019
3174
|
static async cloneRepo(remoteUrl, targetPath, baseBranch = "main") {
|
|
3020
|
-
|
|
3175
|
+
log2.debug("git", "Cloning repository", {
|
|
3021
3176
|
remoteUrl,
|
|
3022
3177
|
targetPath,
|
|
3023
3178
|
baseBranch
|
|
3024
3179
|
});
|
|
3025
3180
|
const git = simpleGit2();
|
|
3026
3181
|
await git.clone(remoteUrl, targetPath, ["--branch", baseBranch, "--single-branch"]);
|
|
3027
|
-
|
|
3182
|
+
log2.debug("git", "Clone complete");
|
|
3028
3183
|
}
|
|
3029
3184
|
/**
|
|
3030
3185
|
* Initializes a local bare git repository to simulate a remote for dev mode.
|
|
@@ -3040,32 +3195,32 @@ var GitManager = class _GitManager {
|
|
|
3040
3195
|
static async ensureLocalSimulatedRemote(options) {
|
|
3041
3196
|
const existingLock = remoteInitLocks.get(options.remotePath);
|
|
3042
3197
|
if (existingLock) {
|
|
3043
|
-
|
|
3198
|
+
log2.debug("git", "Waiting for existing remote initialization", {
|
|
3044
3199
|
remotePath: options.remotePath
|
|
3045
3200
|
});
|
|
3046
3201
|
await existingLock;
|
|
3047
3202
|
try {
|
|
3048
3203
|
const stat = await fs9.stat(options.remotePath);
|
|
3049
3204
|
if (stat.isDirectory()) {
|
|
3050
|
-
|
|
3205
|
+
log2.debug("git", "Remote exists after waiting for lock");
|
|
3051
3206
|
return;
|
|
3052
3207
|
}
|
|
3053
3208
|
} catch (err) {
|
|
3054
3209
|
if (!isNotFoundError(err))
|
|
3055
3210
|
throw err;
|
|
3056
|
-
|
|
3211
|
+
log2.debug("git", "Remote does not exist after lock, will retry initialization");
|
|
3057
3212
|
}
|
|
3058
3213
|
}
|
|
3059
|
-
const lockPromise =
|
|
3214
|
+
const lockPromise = log2.timed("git", "ensureLocalSimulatedRemote", async () => {
|
|
3060
3215
|
try {
|
|
3061
|
-
|
|
3216
|
+
log2.debug("git", "Initializing local simulated remote", {
|
|
3062
3217
|
remotePath: options.remotePath,
|
|
3063
3218
|
baseBranch: options.baseBranch
|
|
3064
3219
|
});
|
|
3065
3220
|
try {
|
|
3066
3221
|
const stat = await fs9.stat(options.remotePath);
|
|
3067
3222
|
if (stat.isDirectory()) {
|
|
3068
|
-
|
|
3223
|
+
log2.debug("git", "Remote already exists, skipping");
|
|
3069
3224
|
return;
|
|
3070
3225
|
}
|
|
3071
3226
|
} catch (err) {
|
|
@@ -3088,8 +3243,8 @@ var GitManager = class _GitManager {
|
|
|
3088
3243
|
}
|
|
3089
3244
|
let hasCommits = false;
|
|
3090
3245
|
try {
|
|
3091
|
-
const
|
|
3092
|
-
hasCommits =
|
|
3246
|
+
const log4 = await sourceGit.log(["-1"]);
|
|
3247
|
+
hasCommits = log4.total > 0;
|
|
3093
3248
|
} catch {
|
|
3094
3249
|
hasCommits = false;
|
|
3095
3250
|
}
|
|
@@ -3100,7 +3255,7 @@ var GitManager = class _GitManager {
|
|
|
3100
3255
|
if (!branches.all.includes(options.baseBranch)) {
|
|
3101
3256
|
throw new Error(`Cannot initialize local simulated remote: base branch '${options.baseBranch}' does not exist locally. Please checkout '${options.baseBranch}' first or provide an explicit remoteUrl.`);
|
|
3102
3257
|
}
|
|
3103
|
-
|
|
3258
|
+
log2.debug("git", "Creating bare remote repository");
|
|
3104
3259
|
await fs9.mkdir(path10.dirname(options.remotePath), { recursive: true });
|
|
3105
3260
|
await simpleGit2().raw([
|
|
3106
3261
|
"init",
|
|
@@ -3140,7 +3295,7 @@ var GitManager = class _GitManager {
|
|
|
3140
3295
|
} catch {
|
|
3141
3296
|
}
|
|
3142
3297
|
}
|
|
3143
|
-
|
|
3298
|
+
log2.debug("git", "Remote initialization complete");
|
|
3144
3299
|
} finally {
|
|
3145
3300
|
remoteInitLocks.delete(options.remotePath);
|
|
3146
3301
|
}
|
|
@@ -3209,7 +3364,7 @@ var GitManager = class _GitManager {
|
|
|
3209
3364
|
try {
|
|
3210
3365
|
const stat = await fs9.stat(config.autoDetectRemotePath);
|
|
3211
3366
|
if (stat.isDirectory()) {
|
|
3212
|
-
|
|
3367
|
+
log2.debug("git", "Auto-detected local remote", {
|
|
3213
3368
|
path: config.autoDetectRemotePath
|
|
3214
3369
|
});
|
|
3215
3370
|
return config.autoDetectRemotePath;
|
|
@@ -3262,7 +3417,7 @@ var GitManager = class _GitManager {
|
|
|
3262
3417
|
try {
|
|
3263
3418
|
const stat = await fs9.stat(gitPath);
|
|
3264
3419
|
if (stat.isDirectory()) {
|
|
3265
|
-
|
|
3420
|
+
log2.debug("git", "Removing corrupt .git directory", {
|
|
3266
3421
|
workspacePath: options.workspacePath
|
|
3267
3422
|
});
|
|
3268
3423
|
await fs9.rm(gitPath, { recursive: true });
|
|
@@ -3300,7 +3455,7 @@ var GitManager = class _GitManager {
|
|
|
3300
3455
|
await git.git.addConfig("canopycms.managed", "true");
|
|
3301
3456
|
await git.git.addConfig("user.name", options.gitBotAuthorName);
|
|
3302
3457
|
await git.git.addConfig("user.email", options.gitBotAuthorEmail);
|
|
3303
|
-
|
|
3458
|
+
log2.debug("git", "Marked workspace as CanopyCMS-managed", {
|
|
3304
3459
|
workspacePath: options.workspacePath
|
|
3305
3460
|
});
|
|
3306
3461
|
if (!justCloned) {
|
|
@@ -3463,13 +3618,13 @@ var GitManager = class _GitManager {
|
|
|
3463
3618
|
}
|
|
3464
3619
|
const lines = content.split("\n");
|
|
3465
3620
|
if (lines.some((line) => line.trim() === pattern)) {
|
|
3466
|
-
|
|
3621
|
+
log2.debug("git", "Pattern already in .git/info/exclude", { pattern });
|
|
3467
3622
|
return;
|
|
3468
3623
|
}
|
|
3469
3624
|
const needsLeadingNewline = content.length > 0 && !content.endsWith("\n");
|
|
3470
3625
|
const newContent = content + (needsLeadingNewline ? "\n" : "") + pattern + "\n";
|
|
3471
3626
|
await fs9.writeFile(excludePath, newContent, "utf-8");
|
|
3472
|
-
|
|
3627
|
+
log2.debug("git", "Added pattern to .git/info/exclude", { pattern });
|
|
3473
3628
|
}
|
|
3474
3629
|
/**
|
|
3475
3630
|
* Create an orphan branch for settings (permissions/groups).
|
|
@@ -3483,10 +3638,10 @@ var GitManager = class _GitManager {
|
|
|
3483
3638
|
* @param initialFiles - Files to commit to the new branch (e.g., { 'permissions.json': '{}', 'groups.json': '{}' })
|
|
3484
3639
|
*/
|
|
3485
3640
|
async createOrphanSettingsBranch(branchName, initialFiles) {
|
|
3486
|
-
|
|
3641
|
+
log2.debug("git", "Creating orphan settings branch", { branchName });
|
|
3487
3642
|
const branches = await this.git.branch();
|
|
3488
3643
|
if (branches.all.includes(branchName)) {
|
|
3489
|
-
|
|
3644
|
+
log2.debug("git", "Orphan branch already exists", { branchName });
|
|
3490
3645
|
await this.git.checkout(branchName);
|
|
3491
3646
|
return;
|
|
3492
3647
|
}
|
|
@@ -3502,19 +3657,19 @@ var GitManager = class _GitManager {
|
|
|
3502
3657
|
await this.git.add(filePath);
|
|
3503
3658
|
}
|
|
3504
3659
|
await this.git.commit("Initialize settings branch", ["--allow-empty"]);
|
|
3505
|
-
|
|
3660
|
+
log2.debug("git", "Orphan settings branch created", { branchName });
|
|
3506
3661
|
}
|
|
3507
3662
|
};
|
|
3508
3663
|
|
|
3509
3664
|
// dist/branch-workspace.js
|
|
3510
|
-
var
|
|
3665
|
+
var log3 = createDebugLogger({ prefix: "BranchWorkspace" });
|
|
3511
3666
|
var workspaceInitLocks = /* @__PURE__ */ new Map();
|
|
3512
3667
|
var BranchWorkspaceManager = class {
|
|
3513
3668
|
constructor(config) {
|
|
3514
3669
|
this.config = config;
|
|
3515
3670
|
}
|
|
3516
3671
|
async ensureGitWorkspace(options) {
|
|
3517
|
-
return
|
|
3672
|
+
return log3.timed("workspace", "ensureGitWorkspace", async () => {
|
|
3518
3673
|
const existingLock = workspaceInitLocks.get(options.branchRoot);
|
|
3519
3674
|
if (existingLock) {
|
|
3520
3675
|
await existingLock;
|
|
@@ -3522,7 +3677,7 @@ var BranchWorkspaceManager = class {
|
|
|
3522
3677
|
}
|
|
3523
3678
|
const lockPromise = (async () => {
|
|
3524
3679
|
try {
|
|
3525
|
-
|
|
3680
|
+
log3.debug("workspace", "Ensuring git workspace", {
|
|
3526
3681
|
branchName: options.branchName,
|
|
3527
3682
|
mode: options.mode
|
|
3528
3683
|
});
|
|
@@ -3651,7 +3806,8 @@ async function generateAIContentFiles(options) {
|
|
|
3651
3806
|
store,
|
|
3652
3807
|
flatSchema,
|
|
3653
3808
|
contentRoot: contentRootName,
|
|
3654
|
-
config: aiConfig
|
|
3809
|
+
config: aiConfig,
|
|
3810
|
+
entryLinkUrl: config.entryLinkUrl
|
|
3655
3811
|
});
|
|
3656
3812
|
const absoluteOutputDir = path11.resolve(outputDir) + path11.sep;
|
|
3657
3813
|
let fileCount = 0;
|