@caelo-cms/shared 0.11.5 → 0.11.7

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 (72) hide show
  1. package/dist/ai-tools.d.ts +206 -2
  2. package/dist/ai-tools.d.ts.map +1 -1
  3. package/dist/ai-tools.js +23 -9
  4. package/dist/ai-tools.js.map +1 -1
  5. package/dist/change-journal.d.ts +71 -0
  6. package/dist/change-journal.d.ts.map +1 -0
  7. package/dist/change-journal.js +252 -0
  8. package/dist/change-journal.js.map +1 -0
  9. package/dist/content.d.ts +214 -0
  10. package/dist/content.d.ts.map +1 -1
  11. package/dist/content.js +29 -11
  12. package/dist/content.js.map +1 -1
  13. package/dist/index.d.ts +3 -0
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +3 -0
  16. package/dist/index.js.map +1 -1
  17. package/dist/lists/fields.d.ts +5 -0
  18. package/dist/lists/fields.d.ts.map +1 -1
  19. package/dist/lists/fields.js +6 -1
  20. package/dist/lists/fields.js.map +1 -1
  21. package/dist/lists/list-type.d.ts.map +1 -1
  22. package/dist/lists/list-type.js +6 -3
  23. package/dist/lists/list-type.js.map +1 -1
  24. package/dist/lists/page-type.d.ts +1 -0
  25. package/dist/lists/page-type.d.ts.map +1 -1
  26. package/dist/lists/page-type.js +7 -0
  27. package/dist/lists/page-type.js.map +1 -1
  28. package/dist/live-events.d.ts +8 -4
  29. package/dist/live-events.d.ts.map +1 -1
  30. package/dist/live-events.js +18 -3
  31. package/dist/live-events.js.map +1 -1
  32. package/dist/media.d.ts +19 -0
  33. package/dist/media.d.ts.map +1 -1
  34. package/dist/media.js +16 -0
  35. package/dist/media.js.map +1 -1
  36. package/dist/phase-timer.d.ts +43 -2
  37. package/dist/phase-timer.d.ts.map +1 -1
  38. package/dist/phase-timer.js +170 -4
  39. package/dist/phase-timer.js.map +1 -1
  40. package/dist/pool-budget.d.ts +152 -0
  41. package/dist/pool-budget.d.ts.map +1 -0
  42. package/dist/pool-budget.js +151 -0
  43. package/dist/pool-budget.js.map +1 -0
  44. package/dist/stage-status.d.ts +89 -0
  45. package/dist/stage-status.d.ts.map +1 -0
  46. package/dist/stage-status.js +101 -0
  47. package/dist/stage-status.js.map +1 -0
  48. package/dist/themes-errors.js +1 -1
  49. package/dist/themes-errors.js.map +1 -1
  50. package/dist/version.d.ts +2 -2
  51. package/dist/version.js +1 -1
  52. package/package.json +1 -1
  53. package/src/ai-tools.ts +23 -8
  54. package/src/change-journal.ts +325 -0
  55. package/src/content.ts +32 -11
  56. package/src/index.ts +3 -0
  57. package/src/lists/fields.ts +7 -1
  58. package/src/lists/list-fixtures.test.ts +1 -0
  59. package/src/lists/list-type.ts +6 -2
  60. package/src/lists/lists.test.ts +1 -0
  61. package/src/lists/page-type.ts +7 -0
  62. package/src/live-events.ts +18 -3
  63. package/src/media.test.ts +31 -0
  64. package/src/media.ts +17 -0
  65. package/src/phase-timer.test.ts +37 -0
  66. package/src/phase-timer.ts +182 -4
  67. package/src/pool-budget.test.ts +111 -0
  68. package/src/pool-budget.ts +234 -0
  69. package/src/stage-status.test.ts +75 -0
  70. package/src/stage-status.ts +112 -0
  71. package/src/themes-errors.ts +1 -1
  72. package/src/version.ts +1 -1
@@ -0,0 +1,151 @@
1
+ // SPDX-License-Identifier: MPL-2.0
2
+ /**
3
+ * Issue #1254 — the database connection budget of an install.
4
+ *
5
+ * Every Caelo process that talks to Postgres holds connection pools, and
6
+ * they all draw from ONE server-wide `max_connections` (cms_admin and
7
+ * cms_public live on the same server). Before #1254 every pool took Bun's
8
+ * default of 10, so the admin alone asked for `adminMaxInstances × 2 × 10`
9
+ * — exactly the 100 slots of a default install, with nothing left for the
10
+ * gateway, the static generator, migrations or the provider's own agents.
11
+ * Under load the last admin instance to scale up could not connect at all.
12
+ *
13
+ * The budget turns that around: provisioning states how many connections
14
+ * the server has and how many instances may run, every fixed consumer is
15
+ * named as a {@link PoolBudgetReserve}, and what is left is split across
16
+ * the admin instances' cms_admin pools — the pool the write path uses.
17
+ * The admin's cms_public pool is small and fixed: the admin only reads
18
+ * plugin data there and publishes the gateway projection.
19
+ *
20
+ * Why not simply raise the pool: a larger pool only moves the wait from
21
+ * the pool to the server. A pool sized past the budget fails with "too
22
+ * many clients" at the worst moment (scale-out under load) instead of
23
+ * waiting a bounded time for a free connection of its own pool
24
+ * (query-api pool-guard.ts). docs/dev/connection-budget.md has the long
25
+ * version.
26
+ *
27
+ * Pure module — no I/O. Used by the provisioning stacks (which set the
28
+ * resulting env on each service) and re-exported by `@caelo-cms/query-api`.
29
+ */
30
+ /** Env var sizing every pool of a `DatabaseAdapter` (both pools, unless the next one is set). */
31
+ export const DB_POOL_MAX_ENV = "CAELO_DB_POOL_MAX";
32
+ /**
33
+ * Env var sizing the cms_public pool of a `DatabaseAdapter` on its own. It
34
+ * wins over {@link DB_POOL_MAX_ENV} for that pool, so the admin can run a
35
+ * large cms_admin pool next to a small cms_public one.
36
+ */
37
+ export const DB_PUBLIC_POOL_MAX_ENV = "CAELO_DB_PUBLIC_POOL_MAX";
38
+ /** Smallest pool a `DatabaseAdapter` accepts: one connection self-deadlocks it. */
39
+ export const MIN_POOL_MAX = 2;
40
+ /**
41
+ * Smallest cms_admin pool the budget hands an admin instance. Below it a
42
+ * handful of concurrent editors and agents queue on every write; an install
43
+ * whose server cannot afford it must get a larger tier or fewer instances,
44
+ * so {@link computePoolBudget} refuses instead of shipping a starved pool.
45
+ */
46
+ export const ADMIN_POOL_FLOOR = 4;
47
+ /** The admin's cms_public pool: plugin-data reads and the gateway projection. */
48
+ export const ADMIN_PUBLIC_POOL_MAX = 4;
49
+ /** The gateway's only pool (public_role on cms_public), per instance. */
50
+ export const GATEWAY_POOL_MAX = 2;
51
+ /**
52
+ * Each pool of one static-generator subprocess. A build runs in ONE
53
+ * transaction (pool-guard.ts LONG_TRANSACTION_ALLOWLIST) and takes no
54
+ * second checkout, so the minimum pool ({@link MIN_POOL_MAX}) is enough.
55
+ */
56
+ export const GENERATOR_POOL_MAX = 2;
57
+ /**
58
+ * #1267 — the dedicated connection each admin instance keeps open for
59
+ * `LISTEN` on the change journal's wake-up channel. A LISTEN connection is
60
+ * held for the instance's lifetime and can never serve a query of the pool,
61
+ * so it is budgeted outside the pools, one per admin instance.
62
+ */
63
+ export const LISTEN_CONNECTIONS_PER_ADMIN_INSTANCE = 1;
64
+ /**
65
+ * The connection each gateway instance keeps open for `LISTEN
66
+ * caelo_gateway_settings` on cms_public (api-gateway server.ts): outside the
67
+ * gateway's pool, held for the instance's lifetime.
68
+ */
69
+ export const LISTEN_CONNECTIONS_PER_GATEWAY_INSTANCE = 1;
70
+ function positiveInteger(value, name, min) {
71
+ if (!Number.isInteger(value) || value < min) {
72
+ throw new Error(`pool budget: ${name} must be an integer >= ${min} (got ${value})`);
73
+ }
74
+ }
75
+ /**
76
+ * Split `maxConnections` across every process of the install.
77
+ *
78
+ * `adminPoolMax = floor((maxConnections − Σ reserves) / adminMaxInstances)`,
79
+ * where the reserves are the fixed consumers of {@link PoolBudgetInput} plus
80
+ * `gateway = gatewayMaxInstances × GATEWAY_POOL_MAX`,
81
+ * `generator = concurrentBuilds × 2 × GENERATOR_POOL_MAX`,
82
+ * `listen = adminMaxInstances × LISTEN_CONNECTIONS_PER_ADMIN_INSTANCE`,
83
+ * `gateway-listen = gatewayMaxInstances × LISTEN_CONNECTIONS_PER_GATEWAY_INSTANCE` and
84
+ * `admin-public = adminMaxInstances × ADMIN_PUBLIC_POOL_MAX`.
85
+ *
86
+ * @throws Error naming what to change when the server cannot give every
87
+ * admin instance at least {@link ADMIN_POOL_FLOOR} cms_admin connections.
88
+ *
89
+ * @example
90
+ * computePoolBudget({ maxConnections: 100, adminMaxInstances: 5,
91
+ * gatewayMaxInstances: 10, concurrentBuilds: 2, maintenanceReserve: 5,
92
+ * migrationsReserve: 2, jobsReserve: 4 }).adminPoolMax // → 7
93
+ */
94
+ export function computePoolBudget(input) {
95
+ positiveInteger(input.maxConnections, "maxConnections", 1);
96
+ positiveInteger(input.adminMaxInstances, "adminMaxInstances", 1);
97
+ positiveInteger(input.gatewayMaxInstances, "gatewayMaxInstances", 0);
98
+ positiveInteger(input.concurrentBuilds, "concurrentBuilds", 0);
99
+ positiveInteger(input.maintenanceReserve, "maintenanceReserve", 0);
100
+ positiveInteger(input.migrationsReserve, "migrationsReserve", 0);
101
+ positiveInteger(input.jobsReserve, "jobsReserve", 0);
102
+ const reserves = [
103
+ { name: "maintenance", connections: input.maintenanceReserve },
104
+ { name: "migrations", connections: input.migrationsReserve },
105
+ { name: "jobs", connections: input.jobsReserve },
106
+ { name: "generator", connections: input.concurrentBuilds * 2 * GENERATOR_POOL_MAX },
107
+ { name: "gateway", connections: input.gatewayMaxInstances * GATEWAY_POOL_MAX },
108
+ {
109
+ name: "listen",
110
+ connections: input.adminMaxInstances * LISTEN_CONNECTIONS_PER_ADMIN_INSTANCE,
111
+ },
112
+ {
113
+ name: "gateway-listen",
114
+ connections: input.gatewayMaxInstances * LISTEN_CONNECTIONS_PER_GATEWAY_INSTANCE,
115
+ },
116
+ { name: "admin-public", connections: input.adminMaxInstances * ADMIN_PUBLIC_POOL_MAX },
117
+ ];
118
+ const reserved = reserves.reduce((sum, r) => sum + r.connections, 0);
119
+ const forAdmin = input.maxConnections - reserved;
120
+ const adminPoolMax = Math.floor(forAdmin / input.adminMaxInstances);
121
+ if (adminPoolMax < ADMIN_POOL_FLOOR) {
122
+ const needed = reserved + ADMIN_POOL_FLOOR * input.adminMaxInstances;
123
+ const breakdown = reserves.map((r) => `${r.name} ${r.connections}`).join(", ");
124
+ throw new Error(`pool budget: max_connections ${input.maxConnections} cannot give each of ${input.adminMaxInstances} admin instances the minimum of ${ADMIN_POOL_FLOOR} cms_admin connections ` +
125
+ `(reserved: ${breakdown}; ${needed} needed). Raise maxConnections to at least ${needed} (a larger database tier may be required), ` +
126
+ "or lower adminMaxInstances / gatewayMaxInstances.");
127
+ }
128
+ return {
129
+ adminPoolMax,
130
+ adminPublicPoolMax: ADMIN_PUBLIC_POOL_MAX,
131
+ gatewayPoolMax: GATEWAY_POOL_MAX,
132
+ generatorPoolMax: GENERATOR_POOL_MAX,
133
+ reserves,
134
+ unassigned: forAdmin - adminPoolMax * input.adminMaxInstances,
135
+ };
136
+ }
137
+ /**
138
+ * The env that sizes `service`'s pools from `budget`, for the stacks to set.
139
+ * The admin gets both pools; the gateway, whose only pool is cms_public,
140
+ * gets just that one.
141
+ */
142
+ export function poolBudgetEnv(budget, service) {
143
+ if (service === "gateway") {
144
+ return [{ name: DB_PUBLIC_POOL_MAX_ENV, value: String(budget.gatewayPoolMax) }];
145
+ }
146
+ return [
147
+ { name: DB_POOL_MAX_ENV, value: String(budget.adminPoolMax) },
148
+ { name: DB_PUBLIC_POOL_MAX_ENV, value: String(budget.adminPublicPoolMax) },
149
+ ];
150
+ }
151
+ //# sourceMappingURL=pool-budget.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pool-budget.js","sourceRoot":"","sources":["../src/pool-budget.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Issue #1288 — where a Stage's build stands, in one shape for every
3
+ * surface: the `deploy.stage_status` op returns it, the `get_stage_status`
4
+ * AI / MCP tool and the "still running" answers of `stage_changes` and
5
+ * `get_quality_audit` print it, and Settings → Deployments and the Live
6
+ * Edit Staging menu show it.
7
+ *
8
+ * The time left is an estimate with its basis named, never a default
9
+ * number (CLAUDE.md §2): `eta` is null with `etaUnavailable` saying why
10
+ * when nothing measured supports one.
11
+ */
12
+ import { z } from "zod";
13
+ /** Where a Stage run is: waiting, its three steps, or its end. */
14
+ export declare const stagePhaseSchema: z.ZodEnum<{
15
+ succeeded: "succeeded";
16
+ failed: "failed";
17
+ queued: "queued";
18
+ preparing: "preparing";
19
+ building: "building";
20
+ publishing: "publishing";
21
+ }>;
22
+ export type StagePhase = z.infer<typeof stagePhaseSchema>;
23
+ /**
24
+ * What an estimate of the time left rests on:
25
+ * - `this_run_rate`: the pages per second this run has built so far;
26
+ * - `last_successful_run`: how long the recent successful Stages took.
27
+ */
28
+ export declare const stageEtaBasisSchema: z.ZodEnum<{
29
+ this_run_rate: "this_run_rate";
30
+ last_successful_run: "last_successful_run";
31
+ }>;
32
+ export type StageEtaBasis = z.infer<typeof stageEtaBasisSchema>;
33
+ /** An estimate of the time a running Stage still needs. */
34
+ export declare const stageEtaSchema: z.ZodObject<{
35
+ remainingMs: z.ZodNumber;
36
+ basis: z.ZodEnum<{
37
+ this_run_rate: "this_run_rate";
38
+ last_successful_run: "last_successful_run";
39
+ }>;
40
+ includesPublish: z.ZodBoolean;
41
+ }, z.core.$strip>;
42
+ export type StageEta = z.infer<typeof stageEtaSchema>;
43
+ /** One Stage run (a staging site build) as every status surface shows it. */
44
+ export declare const stageStatusRunSchema: z.ZodObject<{
45
+ runId: z.ZodString;
46
+ targetName: z.ZodString;
47
+ status: z.ZodEnum<{
48
+ running: "running";
49
+ succeeded: "succeeded";
50
+ failed: "failed";
51
+ queued: "queued";
52
+ }>;
53
+ phase: z.ZodEnum<{
54
+ succeeded: "succeeded";
55
+ failed: "failed";
56
+ queued: "queued";
57
+ preparing: "preparing";
58
+ building: "building";
59
+ publishing: "publishing";
60
+ }>;
61
+ pagesDone: z.ZodNullable<z.ZodNumber>;
62
+ pagesTotal: z.ZodNullable<z.ZodNumber>;
63
+ startedAt: z.ZodString;
64
+ finishedAt: z.ZodNullable<z.ZodString>;
65
+ elapsedMs: z.ZodNumber;
66
+ error: z.ZodNullable<z.ZodString>;
67
+ failedPhase: z.ZodNullable<z.ZodString>;
68
+ eta: z.ZodNullable<z.ZodObject<{
69
+ remainingMs: z.ZodNumber;
70
+ basis: z.ZodEnum<{
71
+ this_run_rate: "this_run_rate";
72
+ last_successful_run: "last_successful_run";
73
+ }>;
74
+ includesPublish: z.ZodBoolean;
75
+ }, z.core.$strip>>;
76
+ etaUnavailable: z.ZodNullable<z.ZodString>;
77
+ }, z.core.$strip>;
78
+ export type StageStatusRun = z.infer<typeof stageStatusRunSchema>;
79
+ /** A duration for people: "45 s", "1 min 40 s", "12 min". */
80
+ export declare function formatStageDuration(ms: number): string;
81
+ /** "about 1 min 40 s left (from this run's pace)", or why there is no estimate. */
82
+ export declare function describeStageEta(run: Pick<StageStatusRun, "eta" | "etaUnavailable">): string;
83
+ /**
84
+ * One line for people and the AI, e.g. "Building pages 812 of 1,904 —
85
+ * about 1 min 40 s left (from this run's pace)" or "Failed in generator
86
+ * after 1 min 34 s: <reason>".
87
+ */
88
+ export declare function describeStageRun(run: StageStatusRun): string;
89
+ //# sourceMappingURL=stage-status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stage-status.d.ts","sourceRoot":"","sources":["../src/stage-status.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,kEAAkE;AAClE,eAAO,MAAM,gBAAgB;;;;;;;EAO3B,CAAC;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D;;;;GAIG;AACH,eAAO,MAAM,mBAAmB;;;EAAmD,CAAC;AACpF,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE,2DAA2D;AAC3D,eAAO,MAAM,cAAc;;;;;;;iBAKzB,CAAC;AACH,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAEtD,6EAA6E;AAC7E,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAkB/B,CAAC;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE,6DAA6D;AAC7D,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAOtD;AAOD,mFAAmF;AACnF,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,IAAI,CAAC,cAAc,EAAE,KAAK,GAAG,gBAAgB,CAAC,GAAG,MAAM,CAM5F;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,cAAc,GAAG,MAAM,CAgB5D"}
@@ -0,0 +1,101 @@
1
+ // SPDX-License-Identifier: MPL-2.0
2
+ /**
3
+ * Issue #1288 — where a Stage's build stands, in one shape for every
4
+ * surface: the `deploy.stage_status` op returns it, the `get_stage_status`
5
+ * AI / MCP tool and the "still running" answers of `stage_changes` and
6
+ * `get_quality_audit` print it, and Settings → Deployments and the Live
7
+ * Edit Staging menu show it.
8
+ *
9
+ * The time left is an estimate with its basis named, never a default
10
+ * number (CLAUDE.md §2): `eta` is null with `etaUnavailable` saying why
11
+ * when nothing measured supports one.
12
+ */
13
+ import { z } from "zod";
14
+ /** Where a Stage run is: waiting, its three steps, or its end. */
15
+ export const stagePhaseSchema = z.enum([
16
+ "queued",
17
+ "preparing",
18
+ "building",
19
+ "publishing",
20
+ "succeeded",
21
+ "failed",
22
+ ]);
23
+ /**
24
+ * What an estimate of the time left rests on:
25
+ * - `this_run_rate`: the pages per second this run has built so far;
26
+ * - `last_successful_run`: how long the recent successful Stages took.
27
+ */
28
+ export const stageEtaBasisSchema = z.enum(["this_run_rate", "last_successful_run"]);
29
+ /** An estimate of the time a running Stage still needs. */
30
+ export const stageEtaSchema = z.object({
31
+ remainingMs: z.number().int().nonnegative(),
32
+ basis: stageEtaBasisSchema,
33
+ /** False when no successful Stage recorded how long publishing takes: the estimate covers the pages only. */
34
+ includesPublish: z.boolean(),
35
+ });
36
+ /** One Stage run (a staging site build) as every status surface shows it. */
37
+ export const stageStatusRunSchema = z.object({
38
+ runId: z.string(),
39
+ targetName: z.string(),
40
+ status: z.enum(["queued", "running", "succeeded", "failed"]),
41
+ phase: stagePhaseSchema,
42
+ pagesDone: z.number().int().nonnegative().nullable(),
43
+ pagesTotal: z.number().int().nonnegative().nullable(),
44
+ startedAt: z.string(),
45
+ finishedAt: z.string().nullable(),
46
+ /** Run time so far (running) or in total (finished). */
47
+ elapsedMs: z.number().int().nonnegative(),
48
+ /** The failure reason of a failed run. */
49
+ error: z.string().nullable(),
50
+ /** The step a failed run stopped in (`generator`, `publish` …), when recorded. */
51
+ failedPhase: z.string().nullable(),
52
+ eta: stageEtaSchema.nullable(),
53
+ /** Why there is no estimate for a queued or running run; null otherwise. */
54
+ etaUnavailable: z.string().nullable(),
55
+ });
56
+ /** A duration for people: "45 s", "1 min 40 s", "12 min". */
57
+ export function formatStageDuration(ms) {
58
+ const s = Math.max(0, Math.round(ms / 1000));
59
+ if (s < 60)
60
+ return `${s} s`;
61
+ const min = Math.floor(s / 60);
62
+ const rest = s % 60;
63
+ if (min >= 10 || rest === 0)
64
+ return `${min} min`;
65
+ return `${min} min ${rest} s`;
66
+ }
67
+ const BASIS_TEXT = {
68
+ this_run_rate: "from this run's pace",
69
+ last_successful_run: "from recent successful Stages",
70
+ };
71
+ /** "about 1 min 40 s left (from this run's pace)", or why there is no estimate. */
72
+ export function describeStageEta(run) {
73
+ if (run.eta) {
74
+ const pagesOnly = run.eta.includesPublish ? "" : ", pages only — publishing time unknown";
75
+ return `about ${formatStageDuration(run.eta.remainingMs)} left (${BASIS_TEXT[run.eta.basis]}${pagesOnly})`;
76
+ }
77
+ return `no estimate: ${run.etaUnavailable ?? "nothing measured yet"}`;
78
+ }
79
+ /**
80
+ * One line for people and the AI, e.g. "Building pages 812 of 1,904 —
81
+ * about 1 min 40 s left (from this run's pace)" or "Failed in generator
82
+ * after 1 min 34 s: <reason>".
83
+ */
84
+ export function describeStageRun(run) {
85
+ const n = (v) => v.toLocaleString("en-US");
86
+ switch (run.phase) {
87
+ case "queued":
88
+ return `Queued — ${describeStageEta(run)}`;
89
+ case "preparing":
90
+ return `Preparing the build (${formatStageDuration(run.elapsedMs)} so far) — ${describeStageEta(run)}`;
91
+ case "building":
92
+ return `Building pages ${n(run.pagesDone ?? 0)} of ${n(run.pagesTotal ?? 0)} — ${describeStageEta(run)}`;
93
+ case "publishing":
94
+ return `All ${n(run.pagesTotal ?? 0)} pages built, publishing to staging — ${describeStageEta(run)}`;
95
+ case "succeeded":
96
+ return `Succeeded in ${formatStageDuration(run.elapsedMs)}${run.pagesTotal === null ? "" : ` (${n(run.pagesTotal)} pages)`}`;
97
+ case "failed":
98
+ return `Failed${run.failedPhase ? ` in ${run.failedPhase}` : ""} after ${formatStageDuration(run.elapsedMs)}: ${run.error ?? "no reason recorded"}`;
99
+ }
100
+ }
101
+ //# sourceMappingURL=stage-status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stage-status.js","sourceRoot":"","sources":["../src/stage-status.ts"],"names":[],"mappings":"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"}
@@ -160,7 +160,7 @@ export class TokenCategoryMismatch extends Error {
160
160
  expected;
161
161
  got;
162
162
  constructor(canonicalPath, expected, got) {
163
- super(`TokenCategoryMismatch: '${canonicalPath}' expects a ${expected} value, got a ${got} — re-send with a value matching ${expected}.`);
163
+ super(`TokenCategoryMismatch: '${canonicalPath}' expects a ${expected} value, got a ${got} — use a value matching ${expected}.`);
164
164
  this.name = "TokenCategoryMismatch";
165
165
  this.canonicalPath = canonicalPath;
166
166
  this.expected = expected;
@@ -1 +1 @@
1
- {"version":3,"file":"themes-errors.js","sourceRoot":"","sources":["../src/themes-errors.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"themes-errors.js","sourceRoot":"","sources":["../src/themes-errors.ts"],"names":[],"mappings":"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"}
package/dist/version.d.ts CHANGED
@@ -19,7 +19,7 @@
19
19
  * Format: SemVer 2.0.0. Pre-1.0 minor bumps are breaking; post-1.0
20
20
  * follow standard SemVer.
21
21
  */
22
- export declare const CAELO_VERSION = "0.11.5";
22
+ export declare const CAELO_VERSION = "0.11.7";
23
23
  /**
24
24
  * Deprecated alias for back-compat — early P17 work spelled this
25
25
  * `CALEO_VERSION` (typo of "Caelo"). New code should import
@@ -31,7 +31,7 @@ export declare const CAELO_VERSION = "0.11.5";
31
31
  *
32
32
  * @deprecated use CAELO_VERSION
33
33
  */
34
- export declare const CALEO_VERSION = "0.11.5";
34
+ export declare const CALEO_VERSION = "0.11.7";
35
35
  /**
36
36
  * Parsed shape — major/minor/patch + optional pre-release tag.
37
37
  * Stable interface for callers that need to feature-gate (rare —
package/dist/version.js CHANGED
@@ -20,7 +20,7 @@
20
20
  * Format: SemVer 2.0.0. Pre-1.0 minor bumps are breaking; post-1.0
21
21
  * follow standard SemVer.
22
22
  */
23
- export const CAELO_VERSION = "0.11.5";
23
+ export const CAELO_VERSION = "0.11.7";
24
24
  /**
25
25
  * Deprecated alias for back-compat — early P17 work spelled this
26
26
  * `CALEO_VERSION` (typo of "Caelo"). New code should import
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@caelo-cms/shared",
3
- "version": "0.11.5",
3
+ "version": "0.11.7",
4
4
  "private": false,
5
5
  "license": "MPL-2.0",
6
6
  "description": "Shared Zod schemas + types + the two-pass HTML composer used by every Caelo CMS workspace package. Stable enough for plugin authors and embedders to depend on directly.",
package/src/ai-tools.ts CHANGED
@@ -19,6 +19,7 @@ import {
19
19
  forkPlacementContentSchema,
20
20
  type ModuleField,
21
21
  moduleFieldSchema,
22
+ newPageTypeSchema,
22
23
  pageShortTitleSchema,
23
24
  pageTypeSlugSchema,
24
25
  setPlacementContentSchema,
@@ -333,6 +334,13 @@ export const chatCreateSessionInput = z
333
334
  * draft: an explicit experiment ("try a redesign") or a site migration.
334
335
  */
335
336
  isolation: z.enum(["experiment", "migration"]).optional(),
337
+ /**
338
+ * Issue #1253 — the session is an external agent's (one chat per
339
+ * agent): the client app it works for ("Claude Code", a token's label).
340
+ * The chat list groups such chats per client, and Live Edit never picks
341
+ * one as the operator's own chat.
342
+ */
343
+ agentClient: z.string().min(1).max(200).optional(),
336
344
  })
337
345
  .strict();
338
346
 
@@ -584,8 +592,10 @@ export const createTemplateToolInput = z
584
592
  html: sourceTextArg(z.string().min(1).max(2_000_000), "html"),
585
593
  css: sourceTextArg(z.string().max(2_000_000), "css").default(""),
586
594
  layoutId: z.string().uuid().optional(),
587
- /** Epic #1107 — the page type (slug) this template serves; omit for the site default. */
595
+ /** #1276 — exactly one of: the existing page type this template serves… */
588
596
  pageType: pageTypeSlugSchema.optional(),
597
+ /** …or a new page type created with this template as its default. */
598
+ newPageType: newPageTypeSchema.optional(),
589
599
  // Optional block-set metadata, symmetric with create_layout. Omit to
590
600
  // auto-derive blocks from <caelo-slot> tags; pass to set displayName /
591
601
  // position (each name must match a slot). Enforced op-side in
@@ -650,15 +660,12 @@ export const createLayoutToolInput = z
650
660
  })
651
661
  .strict();
652
662
 
663
+ /** #1276 — the default layout only: there is no default template or page type. */
653
664
  export const setSiteDefaultsToolInput = z
654
665
  .object({
655
- defaultLayoutSlug: slugInputSchema.optional(),
656
- defaultTemplateSlug: slugInputSchema.optional(),
666
+ defaultLayoutSlug: slugInputSchema,
657
667
  })
658
- .strict()
659
- .refine((v) => v.defaultLayoutSlug !== undefined || v.defaultTemplateSlug !== undefined, {
660
- message: "must provide at least one of defaultLayoutSlug, defaultTemplateSlug",
661
- });
668
+ .strict();
662
669
 
663
670
  /**
664
671
  * P6.7.7 — content-ops follow-ups: clone a page, swap a page's
@@ -674,6 +681,8 @@ export const duplicatePageToolInput = z
674
681
  /** #1142 — the copy's breadcrumb label; omitted = newTitle when given, else the source's. */
675
682
  newShortTitle: pageShortTitleSchema.optional(),
676
683
  targetTemplateId: z.string().uuid().optional(),
684
+ /** #1276 — the copy's page type (slug); omitted = the source's. */
685
+ pageType: pageTypeSlugSchema.optional(),
677
686
  /** Where the copy sits: a parent page id, or null for the top level.
678
687
  * Omitted = next to the source (same parent). */
679
688
  newParentPageId: z.string().uuid().nullable().optional(),
@@ -1073,7 +1082,13 @@ export const bootstrapSiteScaffoldToolInput = z
1073
1082
  templateSlug: z.string().min(1).max(120).optional(),
1074
1083
  /** Display name for the new template. Defaults to `Home template`. */
1075
1084
  templateDisplayName: z.string().min(1).max(256).optional(),
1076
- /** Whether to pin the new layout+template as site_defaults. Defaults to true. */
1085
+ /**
1086
+ * #1276 — the page type the new template serves (every template has
1087
+ * one). An existing slug joins that type; else the type is created
1088
+ * with the template. Defaults to the `home` page type.
1089
+ */
1090
+ templatePageType: newPageTypeSchema.optional(),
1091
+ /** Whether to pin the new layout as the site's default layout. Defaults to true. */
1077
1092
  setAsDefaults: z.boolean().optional(),
1078
1093
  })
1079
1094
  .strict();