@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,112 @@
1
+ // SPDX-License-Identifier: MPL-2.0
2
+
3
+ /**
4
+ * Issue #1288 — where a Stage's build stands, in one shape for every
5
+ * surface: the `deploy.stage_status` op returns it, the `get_stage_status`
6
+ * AI / MCP tool and the "still running" answers of `stage_changes` and
7
+ * `get_quality_audit` print it, and Settings → Deployments and the Live
8
+ * Edit Staging menu show it.
9
+ *
10
+ * The time left is an estimate with its basis named, never a default
11
+ * number (CLAUDE.md §2): `eta` is null with `etaUnavailable` saying why
12
+ * when nothing measured supports one.
13
+ */
14
+
15
+ import { z } from "zod";
16
+
17
+ /** Where a Stage run is: waiting, its three steps, or its end. */
18
+ export const stagePhaseSchema = z.enum([
19
+ "queued",
20
+ "preparing",
21
+ "building",
22
+ "publishing",
23
+ "succeeded",
24
+ "failed",
25
+ ]);
26
+ export type StagePhase = z.infer<typeof stagePhaseSchema>;
27
+
28
+ /**
29
+ * What an estimate of the time left rests on:
30
+ * - `this_run_rate`: the pages per second this run has built so far;
31
+ * - `last_successful_run`: how long the recent successful Stages took.
32
+ */
33
+ export const stageEtaBasisSchema = z.enum(["this_run_rate", "last_successful_run"]);
34
+ export type StageEtaBasis = z.infer<typeof stageEtaBasisSchema>;
35
+
36
+ /** An estimate of the time a running Stage still needs. */
37
+ export const stageEtaSchema = z.object({
38
+ remainingMs: z.number().int().nonnegative(),
39
+ basis: stageEtaBasisSchema,
40
+ /** False when no successful Stage recorded how long publishing takes: the estimate covers the pages only. */
41
+ includesPublish: z.boolean(),
42
+ });
43
+ export type StageEta = z.infer<typeof stageEtaSchema>;
44
+
45
+ /** One Stage run (a staging site build) as every status surface shows it. */
46
+ export const stageStatusRunSchema = z.object({
47
+ runId: z.string(),
48
+ targetName: z.string(),
49
+ status: z.enum(["queued", "running", "succeeded", "failed"]),
50
+ phase: stagePhaseSchema,
51
+ pagesDone: z.number().int().nonnegative().nullable(),
52
+ pagesTotal: z.number().int().nonnegative().nullable(),
53
+ startedAt: z.string(),
54
+ finishedAt: z.string().nullable(),
55
+ /** Run time so far (running) or in total (finished). */
56
+ elapsedMs: z.number().int().nonnegative(),
57
+ /** The failure reason of a failed run. */
58
+ error: z.string().nullable(),
59
+ /** The step a failed run stopped in (`generator`, `publish` …), when recorded. */
60
+ failedPhase: z.string().nullable(),
61
+ eta: stageEtaSchema.nullable(),
62
+ /** Why there is no estimate for a queued or running run; null otherwise. */
63
+ etaUnavailable: z.string().nullable(),
64
+ });
65
+ export type StageStatusRun = z.infer<typeof stageStatusRunSchema>;
66
+
67
+ /** A duration for people: "45 s", "1 min 40 s", "12 min". */
68
+ export function formatStageDuration(ms: number): string {
69
+ const s = Math.max(0, Math.round(ms / 1000));
70
+ if (s < 60) return `${s} s`;
71
+ const min = Math.floor(s / 60);
72
+ const rest = s % 60;
73
+ if (min >= 10 || rest === 0) return `${min} min`;
74
+ return `${min} min ${rest} s`;
75
+ }
76
+
77
+ const BASIS_TEXT: Record<StageEtaBasis, string> = {
78
+ this_run_rate: "from this run's pace",
79
+ last_successful_run: "from recent successful Stages",
80
+ };
81
+
82
+ /** "about 1 min 40 s left (from this run's pace)", or why there is no estimate. */
83
+ export function describeStageEta(run: Pick<StageStatusRun, "eta" | "etaUnavailable">): string {
84
+ if (run.eta) {
85
+ const pagesOnly = run.eta.includesPublish ? "" : ", pages only — publishing time unknown";
86
+ return `about ${formatStageDuration(run.eta.remainingMs)} left (${BASIS_TEXT[run.eta.basis]}${pagesOnly})`;
87
+ }
88
+ return `no estimate: ${run.etaUnavailable ?? "nothing measured yet"}`;
89
+ }
90
+
91
+ /**
92
+ * One line for people and the AI, e.g. "Building pages 812 of 1,904 —
93
+ * about 1 min 40 s left (from this run's pace)" or "Failed in generator
94
+ * after 1 min 34 s: <reason>".
95
+ */
96
+ export function describeStageRun(run: StageStatusRun): string {
97
+ const n = (v: number) => v.toLocaleString("en-US");
98
+ switch (run.phase) {
99
+ case "queued":
100
+ return `Queued — ${describeStageEta(run)}`;
101
+ case "preparing":
102
+ return `Preparing the build (${formatStageDuration(run.elapsedMs)} so far) — ${describeStageEta(run)}`;
103
+ case "building":
104
+ return `Building pages ${n(run.pagesDone ?? 0)} of ${n(run.pagesTotal ?? 0)} — ${describeStageEta(run)}`;
105
+ case "publishing":
106
+ return `All ${n(run.pagesTotal ?? 0)} pages built, publishing to staging — ${describeStageEta(run)}`;
107
+ case "succeeded":
108
+ return `Succeeded in ${formatStageDuration(run.elapsedMs)}${run.pagesTotal === null ? "" : ` (${n(run.pagesTotal)} pages)`}`;
109
+ case "failed":
110
+ return `Failed${run.failedPhase ? ` in ${run.failedPhase}` : ""} after ${formatStageDuration(run.elapsedMs)}: ${run.error ?? "no reason recorded"}`;
111
+ }
112
+ }
@@ -189,7 +189,7 @@ export class TokenCategoryMismatch extends Error {
189
189
  readonly got: string;
190
190
  constructor(canonicalPath: string, expected: string, got: string) {
191
191
  super(
192
- `TokenCategoryMismatch: '${canonicalPath}' expects a ${expected} value, got a ${got} — re-send with a value matching ${expected}.`,
192
+ `TokenCategoryMismatch: '${canonicalPath}' expects a ${expected} value, got a ${got} — use a value matching ${expected}.`,
193
193
  );
194
194
  this.name = "TokenCategoryMismatch";
195
195
  this.canonicalPath = canonicalPath;
package/src/version.ts CHANGED
@@ -22,7 +22,7 @@
22
22
  * follow standard SemVer.
23
23
  */
24
24
 
25
- export const CAELO_VERSION = "0.11.5";
25
+ export const CAELO_VERSION = "0.11.7";
26
26
 
27
27
  /**
28
28
  * Deprecated alias for back-compat — early P17 work spelled this