canopycms 0.0.61-int.75 → 0.0.61

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 (271) hide show
  1. package/dist/ai/handler.js +1 -1
  2. package/dist/ai/handler.js.map +1 -1
  3. package/dist/api/assets.d.ts.map +1 -1
  4. package/dist/api/assets.js +36 -4
  5. package/dist/api/assets.js.map +1 -1
  6. package/dist/api/branch-status.d.ts.map +1 -1
  7. package/dist/api/branch-status.js +56 -0
  8. package/dist/api/branch-status.js.map +1 -1
  9. package/dist/api/branch-withdraw.d.ts.map +1 -1
  10. package/dist/api/branch-withdraw.js +14 -3
  11. package/dist/api/branch-withdraw.js.map +1 -1
  12. package/dist/api/branch.d.ts +31 -2
  13. package/dist/api/branch.d.ts.map +1 -1
  14. package/dist/api/branch.js +252 -13
  15. package/dist/api/branch.js.map +1 -1
  16. package/dist/api/content.d.ts.map +1 -1
  17. package/dist/api/content.js +12 -4
  18. package/dist/api/content.js.map +1 -1
  19. package/dist/api/entries.d.ts.map +1 -1
  20. package/dist/api/entries.js +11 -9
  21. package/dist/api/entries.js.map +1 -1
  22. package/dist/api/guards.d.ts.map +1 -1
  23. package/dist/api/guards.js +12 -5
  24. package/dist/api/guards.js.map +1 -1
  25. package/dist/api/permissions.d.ts +2 -2
  26. package/dist/api/permissions.d.ts.map +1 -1
  27. package/dist/api/permissions.js +51 -3
  28. package/dist/api/permissions.js.map +1 -1
  29. package/dist/api/reference-options.d.ts.map +1 -1
  30. package/dist/api/reference-options.js +10 -17
  31. package/dist/api/reference-options.js.map +1 -1
  32. package/dist/api/resolve-references.d.ts.map +1 -1
  33. package/dist/api/resolve-references.js +3 -1
  34. package/dist/api/resolve-references.js.map +1 -1
  35. package/dist/api/schema.d.ts.map +1 -1
  36. package/dist/api/schema.js +3 -2
  37. package/dist/api/schema.js.map +1 -1
  38. package/dist/api/settings-helpers.d.ts.map +1 -1
  39. package/dist/api/settings-helpers.js +6 -5
  40. package/dist/api/settings-helpers.js.map +1 -1
  41. package/dist/assets/pipeline.d.ts +11 -2
  42. package/dist/assets/pipeline.d.ts.map +1 -1
  43. package/dist/assets/pipeline.js +114 -2
  44. package/dist/assets/pipeline.js.map +1 -1
  45. package/dist/assets/transform-directives.d.ts +18 -0
  46. package/dist/assets/transform-directives.d.ts.map +1 -1
  47. package/dist/assets/transform-directives.js +18 -0
  48. package/dist/assets/transform-directives.js.map +1 -1
  49. package/dist/assets/transform.d.ts.map +1 -1
  50. package/dist/assets/transform.js +1 -10
  51. package/dist/assets/transform.js.map +1 -1
  52. package/dist/auth/types.d.ts +29 -0
  53. package/dist/auth/types.d.ts.map +1 -1
  54. package/dist/authorization/index.d.ts +1 -1
  55. package/dist/authorization/index.d.ts.map +1 -1
  56. package/dist/authorization/index.js +1 -1
  57. package/dist/authorization/index.js.map +1 -1
  58. package/dist/authorization/protected-branch.d.ts +75 -0
  59. package/dist/authorization/protected-branch.d.ts.map +1 -1
  60. package/dist/authorization/protected-branch.js +39 -0
  61. package/dist/authorization/protected-branch.js.map +1 -1
  62. package/dist/branch-registry.d.ts.map +1 -1
  63. package/dist/branch-registry.js +5 -1
  64. package/dist/branch-registry.js.map +1 -1
  65. package/dist/branch-schema-cache.d.ts.map +1 -1
  66. package/dist/branch-schema-cache.js +9 -0
  67. package/dist/branch-schema-cache.js.map +1 -1
  68. package/dist/build/generate-ai-content.js +1 -1
  69. package/dist/build/generate-ai-content.js.map +1 -1
  70. package/dist/cli/cli.js +1442 -828
  71. package/dist/cli/generate-ai-content.js +404 -136
  72. package/dist/cli/init.d.ts +8 -2
  73. package/dist/cli/init.d.ts.map +1 -1
  74. package/dist/cli/init.js +440 -151
  75. package/dist/cli/init.js.map +1 -1
  76. package/dist/cli/project-detect.d.ts +89 -0
  77. package/dist/cli/project-detect.d.ts.map +1 -0
  78. package/dist/cli/project-detect.js +240 -0
  79. package/dist/cli/project-detect.js.map +1 -0
  80. package/dist/cli/template-files/Dockerfile.cms.template +11 -6
  81. package/dist/cli/template-files/cdk-app.ts.template +82 -0
  82. package/dist/cli/template-files/cdk.json.template +9 -0
  83. package/dist/cli/template-files/cms-stack.ts.template +124 -0
  84. package/dist/cli/template-files/deploy-cms.yml.template +125 -13
  85. package/dist/cli/template-files/dockerignore.template +2 -1
  86. package/dist/cli/templates.d.ts +26 -2
  87. package/dist/cli/templates.d.ts.map +1 -1
  88. package/dist/cli/templates.js +36 -4
  89. package/dist/cli/templates.js.map +1 -1
  90. package/dist/config/schemas/config.d.ts +2 -3
  91. package/dist/config/schemas/config.d.ts.map +1 -1
  92. package/dist/config/schemas/config.js +21 -1
  93. package/dist/config/schemas/config.js.map +1 -1
  94. package/dist/config/validation.d.ts +9 -0
  95. package/dist/config/validation.d.ts.map +1 -1
  96. package/dist/config/validation.js +22 -12
  97. package/dist/config/validation.js.map +1 -1
  98. package/dist/content-reader.js +1 -1
  99. package/dist/content-reader.js.map +1 -1
  100. package/dist/content-store.d.ts +11 -0
  101. package/dist/content-store.d.ts.map +1 -1
  102. package/dist/content-store.js +2 -1
  103. package/dist/content-store.js.map +1 -1
  104. package/dist/dev-content-watcher.d.ts.map +1 -1
  105. package/dist/dev-content-watcher.js +4 -1
  106. package/dist/dev-content-watcher.js.map +1 -1
  107. package/dist/editor/BranchManager.d.ts +15 -0
  108. package/dist/editor/BranchManager.d.ts.map +1 -1
  109. package/dist/editor/BranchManager.js +43 -9
  110. package/dist/editor/BranchManager.js.map +1 -1
  111. package/dist/editor/CanopyEditor.d.ts.map +1 -1
  112. package/dist/editor/CanopyEditor.js +2 -2
  113. package/dist/editor/CanopyEditor.js.map +1 -1
  114. package/dist/editor/Editor.d.ts.map +1 -1
  115. package/dist/editor/Editor.js +110 -48
  116. package/dist/editor/Editor.js.map +1 -1
  117. package/dist/editor/admin/SystemHealthPanel.d.ts.map +1 -1
  118. package/dist/editor/admin/SystemHealthPanel.js +9 -8
  119. package/dist/editor/admin/SystemHealthPanel.js.map +1 -1
  120. package/dist/editor/components/EditorHeader.d.ts +6 -0
  121. package/dist/editor/components/EditorHeader.d.ts.map +1 -1
  122. package/dist/editor/components/EditorHeader.js +76 -23
  123. package/dist/editor/components/EditorHeader.js.map +1 -1
  124. package/dist/editor/components/EntryCreateModal.d.ts.map +1 -1
  125. package/dist/editor/components/EntryCreateModal.js +21 -6
  126. package/dist/editor/components/EntryCreateModal.js.map +1 -1
  127. package/dist/editor/context/SWRProvider.d.ts +31 -0
  128. package/dist/editor/context/SWRProvider.d.ts.map +1 -0
  129. package/dist/editor/context/SWRProvider.js +12 -0
  130. package/dist/editor/context/SWRProvider.js.map +1 -0
  131. package/dist/editor/context/index.d.ts +3 -0
  132. package/dist/editor/context/index.d.ts.map +1 -1
  133. package/dist/editor/context/index.js +3 -0
  134. package/dist/editor/context/index.js.map +1 -1
  135. package/dist/editor/editor-utils.d.ts.map +1 -1
  136. package/dist/editor/editor-utils.js +8 -2
  137. package/dist/editor/editor-utils.js.map +1 -1
  138. package/dist/editor/fields/ImageField.d.ts.map +1 -1
  139. package/dist/editor/fields/ImageField.js +27 -3
  140. package/dist/editor/fields/ImageField.js.map +1 -1
  141. package/dist/editor/fields/ReferenceField.d.ts.map +1 -1
  142. package/dist/editor/fields/ReferenceField.js +52 -31
  143. package/dist/editor/fields/ReferenceField.js.map +1 -1
  144. package/dist/editor/hooks/__test__/test-utils.d.ts +38 -3
  145. package/dist/editor/hooks/__test__/test-utils.d.ts.map +1 -1
  146. package/dist/editor/hooks/__test__/test-utils.js +50 -4
  147. package/dist/editor/hooks/__test__/test-utils.js.map +1 -1
  148. package/dist/editor/hooks/index.d.ts +4 -1
  149. package/dist/editor/hooks/index.d.ts.map +1 -1
  150. package/dist/editor/hooks/index.js +4 -1
  151. package/dist/editor/hooks/index.js.map +1 -1
  152. package/dist/editor/hooks/useBranchManager.d.ts +21 -1
  153. package/dist/editor/hooks/useBranchManager.d.ts.map +1 -1
  154. package/dist/editor/hooks/useBranchManager.js +68 -32
  155. package/dist/editor/hooks/useBranchManager.js.map +1 -1
  156. package/dist/editor/hooks/useBranchesData.d.ts +57 -0
  157. package/dist/editor/hooks/useBranchesData.d.ts.map +1 -0
  158. package/dist/editor/hooks/useBranchesData.js +69 -0
  159. package/dist/editor/hooks/useBranchesData.js.map +1 -0
  160. package/dist/editor/hooks/useCommentSystem.d.ts.map +1 -1
  161. package/dist/editor/hooks/useCommentSystem.js +24 -22
  162. package/dist/editor/hooks/useCommentSystem.js.map +1 -1
  163. package/dist/editor/hooks/useCommentsData.d.ts +29 -0
  164. package/dist/editor/hooks/useCommentsData.d.ts.map +1 -0
  165. package/dist/editor/hooks/useCommentsData.js +40 -0
  166. package/dist/editor/hooks/useCommentsData.js.map +1 -0
  167. package/dist/editor/hooks/useDraftManager.d.ts.map +1 -1
  168. package/dist/editor/hooks/useDraftManager.js +32 -18
  169. package/dist/editor/hooks/useDraftManager.js.map +1 -1
  170. package/dist/editor/hooks/useEntriesData.d.ts +35 -0
  171. package/dist/editor/hooks/useEntriesData.d.ts.map +1 -0
  172. package/dist/editor/hooks/useEntriesData.js +96 -0
  173. package/dist/editor/hooks/useEntriesData.js.map +1 -0
  174. package/dist/editor/hooks/useEntryManager.d.ts +8 -15
  175. package/dist/editor/hooks/useEntryManager.d.ts.map +1 -1
  176. package/dist/editor/hooks/useEntryManager.js +259 -117
  177. package/dist/editor/hooks/useEntryManager.js.map +1 -1
  178. package/dist/editor/hooks/usePermissionManager.d.ts +2 -2
  179. package/dist/editor/hooks/usePermissionManager.d.ts.map +1 -1
  180. package/dist/editor/hooks/usePermissionManager.js +11 -9
  181. package/dist/editor/hooks/usePermissionManager.js.map +1 -1
  182. package/dist/editor/hooks/useReferenceResolution.d.ts.map +1 -1
  183. package/dist/editor/hooks/useReferenceResolution.js +24 -1
  184. package/dist/editor/hooks/useReferenceResolution.js.map +1 -1
  185. package/dist/editor/media/MediaLibraryBody.d.ts.map +1 -1
  186. package/dist/editor/media/MediaLibraryBody.js +12 -2
  187. package/dist/editor/media/MediaLibraryBody.js.map +1 -1
  188. package/dist/editor/permission-manager/GroupSelector.d.ts.map +1 -1
  189. package/dist/editor/permission-manager/GroupSelector.js +7 -2
  190. package/dist/editor/permission-manager/GroupSelector.js.map +1 -1
  191. package/dist/editor/permission-manager/hooks/useGroupsAndUsers.d.ts +3 -3
  192. package/dist/editor/permission-manager/hooks/useGroupsAndUsers.d.ts.map +1 -1
  193. package/dist/editor/permission-manager/hooks/useGroupsAndUsers.js +1 -0
  194. package/dist/editor/permission-manager/hooks/useGroupsAndUsers.js.map +1 -1
  195. package/dist/editor/permission-manager/types.d.ts +6 -4
  196. package/dist/editor/permission-manager/types.d.ts.map +1 -1
  197. package/dist/editor/test-setup.js +8 -0
  198. package/dist/editor/test-setup.js.map +1 -1
  199. package/dist/git-manager.d.ts +126 -9
  200. package/dist/git-manager.d.ts.map +1 -1
  201. package/dist/git-manager.js +251 -27
  202. package/dist/git-manager.js.map +1 -1
  203. package/dist/github-service.d.ts.map +1 -1
  204. package/dist/github-service.js +13 -7
  205. package/dist/github-service.js.map +1 -1
  206. package/dist/http/handler.d.ts.map +1 -1
  207. package/dist/http/handler.js +8 -2
  208. package/dist/http/handler.js.map +1 -1
  209. package/dist/operating-mode/client-unsafe-strategy.d.ts.map +1 -1
  210. package/dist/operating-mode/client-unsafe-strategy.js +7 -8
  211. package/dist/operating-mode/client-unsafe-strategy.js.map +1 -1
  212. package/dist/operating-mode/deployment-name.d.ts +28 -0
  213. package/dist/operating-mode/deployment-name.d.ts.map +1 -0
  214. package/dist/operating-mode/deployment-name.js +78 -0
  215. package/dist/operating-mode/deployment-name.js.map +1 -0
  216. package/dist/operating-mode/index.d.ts +5 -1
  217. package/dist/operating-mode/index.d.ts.map +1 -1
  218. package/dist/operating-mode/index.js +7 -1
  219. package/dist/operating-mode/index.js.map +1 -1
  220. package/dist/operating-mode/types.d.ts +13 -3
  221. package/dist/operating-mode/types.d.ts.map +1 -1
  222. package/dist/paths/branch-name.d.ts +38 -0
  223. package/dist/paths/branch-name.d.ts.map +1 -1
  224. package/dist/paths/branch-name.js +46 -0
  225. package/dist/paths/branch-name.js.map +1 -1
  226. package/dist/paths/index.d.ts +1 -1
  227. package/dist/paths/index.d.ts.map +1 -1
  228. package/dist/paths/index.js +1 -1
  229. package/dist/paths/index.js.map +1 -1
  230. package/dist/reference-resolver.d.ts +6 -2
  231. package/dist/reference-resolver.d.ts.map +1 -1
  232. package/dist/reference-resolver.js +8 -1
  233. package/dist/reference-resolver.js.map +1 -1
  234. package/dist/schema/meta-loader.d.ts.map +1 -1
  235. package/dist/schema/meta-loader.js +10 -2
  236. package/dist/schema/meta-loader.js.map +1 -1
  237. package/dist/schema/schema-store.d.ts +11 -2
  238. package/dist/schema/schema-store.d.ts.map +1 -1
  239. package/dist/schema/schema-store.js +23 -11
  240. package/dist/schema/schema-store.js.map +1 -1
  241. package/dist/settings-workspace.d.ts +0 -15
  242. package/dist/settings-workspace.d.ts.map +1 -1
  243. package/dist/settings-workspace.js +97 -1
  244. package/dist/settings-workspace.js.map +1 -1
  245. package/dist/types.d.ts +63 -2
  246. package/dist/types.d.ts.map +1 -1
  247. package/dist/utils/debug.d.ts +11 -0
  248. package/dist/utils/debug.d.ts.map +1 -1
  249. package/dist/utils/debug.js +12 -1
  250. package/dist/utils/debug.js.map +1 -1
  251. package/dist/utils/git.d.ts +38 -0
  252. package/dist/utils/git.d.ts.map +1 -1
  253. package/dist/utils/git.js +69 -0
  254. package/dist/utils/git.js.map +1 -1
  255. package/dist/utils/logger.d.ts +71 -0
  256. package/dist/utils/logger.d.ts.map +1 -0
  257. package/dist/utils/logger.js +85 -0
  258. package/dist/utils/logger.js.map +1 -0
  259. package/dist/validation/entry-type-reference-validator.d.ts +33 -0
  260. package/dist/validation/entry-type-reference-validator.d.ts.map +1 -0
  261. package/dist/validation/entry-type-reference-validator.js +110 -0
  262. package/dist/validation/entry-type-reference-validator.js.map +1 -0
  263. package/dist/worker/cms-worker.d.ts +232 -3
  264. package/dist/worker/cms-worker.d.ts.map +1 -1
  265. package/dist/worker/cms-worker.js +856 -87
  266. package/dist/worker/cms-worker.js.map +1 -1
  267. package/dist/worker/log.d.ts +61 -0
  268. package/dist/worker/log.d.ts.map +1 -0
  269. package/dist/worker/log.js +74 -0
  270. package/dist/worker/log.js.map +1 -0
  271. package/package.json +3 -1
@@ -1,3 +1,4 @@
1
+ export { workerLog, workerLogWarn, workerLogError, installWorkerLogger } from './log';
1
2
  /**
2
3
  * Auth cache refresh function type.
3
4
  * Adopters provide their auth-plugin-specific implementation.
@@ -27,6 +28,25 @@ export interface CmsWorkerConfig {
27
28
  authCacheRefreshInterval?: number;
28
29
  /** Base branch name (default: 'main') */
29
30
  baseBranch?: string;
31
+ /**
32
+ * Deployment name, used to compute THIS worker's own settings branch
33
+ * (`canopycms-settings-{deploymentName}`, default: 'prod' — matches
34
+ * ProdStrategy's mode default in operating-mode/client-unsafe-strategy.ts,
35
+ * the only mode the worker runs in). Two deployments can share one GitHub
36
+ * repo with distinct settings branches; this tells the worker which one it
37
+ * owns, so it never pushes another deployment's settings branch (see
38
+ * `pushSettingsBranches`).
39
+ */
40
+ deploymentName?: string;
41
+ /**
42
+ * Explicit settings branch name, taking precedence over `deploymentName`.
43
+ * Mirrors the strategy's own precedence (`config.settingsBranch` short-circuits
44
+ * `getSettingsBranchName` before `deploymentName` is consulted, see
45
+ * operating-mode/client-unsafe-strategy.ts): an adopter who overrides
46
+ * `settingsBranch` in canopycms.config.ts must set this too, or the worker
47
+ * would own a branch name the Lambda never writes to.
48
+ */
49
+ settingsBranch?: string;
30
50
  /** Max tasks to process per cycle (default: 10) */
31
51
  maxTasksPerCycle?: number;
32
52
  /** Per-task timeout in ms (default: 60000) */
@@ -93,6 +113,7 @@ export declare class CmsWorker {
93
113
  private contentBranchesPath;
94
114
  private baseBranch;
95
115
  private sanitizedBaseBranch;
116
+ private settingsBranchResolved?;
96
117
  private activeTimeouts;
97
118
  private running;
98
119
  private activeOperations;
@@ -115,6 +136,35 @@ export declare class CmsWorker {
115
136
  * syncGit()/processTaskQueue() directly without calling start() first.
116
137
  */
117
138
  private ensureStatusReport;
139
+ /**
140
+ * Resolve this deployment's settings branch, throwing if the infra-stamped
141
+ * deployment name is not a valid git ref component.
142
+ *
143
+ * Routed through the shared resolver, not a local `?? 'prod'`: it is the
144
+ * single definition of the env > config > mode-default precedence the Lambda
145
+ * already follows, and the only place the resolved value is validated.
146
+ * Without it the worker could silently own a different settings branch than
147
+ * the Lambda writing to the same workspace -- and pushSettingsBranches would
148
+ * then report the real branch as foreign and never push it.
149
+ *
150
+ * DEFERRED out of the constructor deliberately, and this is the whole point
151
+ * of the method existing. Resolving there made the throw land during `new
152
+ * CmsWorker(...)` (canopycms-cdk/worker/index.ts constructs before it calls
153
+ * start()), which is BEFORE the only code that writes `lastFatalError` --
154
+ * start()'s catch. The result was billed as "a loud startup exit" but was
155
+ * nothing of the kind: with systemd `Type=simple` + `Restart=always` and no
156
+ * cfn-signal, an invalid deployment name produced an invisible ~5s
157
+ * crash-loop that `cdk deploy` reported as success while the admin panel
158
+ * showed the worker as 'absent' with no fatal error to explain it. Resolving
159
+ * inside start()'s try block instead means the same throw is recorded to
160
+ * worker-status.json and surfaces in the admin panel.
161
+ *
162
+ * Lazy rather than start()-only so the value is still available to unit tests
163
+ * that drive pushSettingsBranches() directly without calling start() -- the
164
+ * same reason ensureStatusReport() above is shaped this way. Idempotent: the
165
+ * resolver is pure, so a later call returns the identical string.
166
+ */
167
+ private ensureSettingsBranch;
118
168
  start(): Promise<void>;
119
169
  stop(): Promise<void>;
120
170
  /**
@@ -183,6 +233,17 @@ export declare class CmsWorker {
183
233
  * guard existed.
184
234
  */
185
235
  private ensureRemoteGit;
236
+ /**
237
+ * Staleness threshold for recoverOrphanedTasks, derived from the
238
+ * configured task timeout rather than fixed: the safety argument for
239
+ * running recovery on every poll cycle is "no legitimately in-flight task
240
+ * can be this old, because executeTaskWithTimeout bounds every attempt by
241
+ * taskTimeoutMs" -- which is only true if this threshold scales with
242
+ * taskTimeoutMs. 2x leaves the same comfortable margin the defaults have
243
+ * (60s timeout vs 5min threshold); the 5-minute floor preserves the
244
+ * long-standing default for a replacement instance's boot window.
245
+ */
246
+ private orphanRecoveryMaxAgeMs;
186
247
  /**
187
248
  * Process queued tasks from Lambda.
188
249
  * Polls .tasks/pending/ directory and executes each task.
@@ -208,16 +269,184 @@ export declare class CmsWorker {
208
269
  private updateBranchMetadata;
209
270
  /**
210
271
  * Update branch metadata after permanent task failure.
211
- * Sets syncStatus to 'sync-failed' with error details.
272
+ * Sets syncStatus to 'sync-failed' and records `error` (already redacted
273
+ * by the caller, processTaskQueue -- see [HIGH-1] there) as
274
+ * syncFailureReason, so the editor can show WHY, not just that it failed.
212
275
  */
213
276
  private updateBranchMetadataOnFailure;
214
277
  private buildGitHubUrl;
278
+ /**
279
+ * The workspace directory for a branch named by its GIT REF name -- the
280
+ * form task payloads carry (`context.branch.name`), not the directory form.
281
+ *
282
+ * These differ for any name outside `[A-Za-z0-9._-]`, `/` being the obvious
283
+ * one: workspaces are provisioned under `sanitizeBranchName(...)` (see
284
+ * paths/branch.ts's `resolveBranchPaths`), so `feature/x` lives in
285
+ * `feature-x`. Joining the raw name instead silently addresses a directory
286
+ * that does not exist -- which for the metadata writers below meant the
287
+ * update was quietly dropped, and for the leased push meant the
288
+ * history-rewrite marker read as absent and the push went out unleased,
289
+ * wedging exactly the branch this workstream exists to unwedge.
290
+ *
291
+ * `name` inside the metadata itself stays the raw ref name; only the path
292
+ * is sanitized.
293
+ */
294
+ private branchWorkspacePath;
295
+ /**
296
+ * What `remote.git` currently holds for `branchRef`, or null when this
297
+ * branch was never published there (never submitted) or the ref is
298
+ * unreadable.
299
+ *
300
+ * Uses the same explicit `--git-dir` shape as verifyBaseBranchExists()
301
+ * above: reading a bare repo that way does not depend on
302
+ * `safe.bareRepository` being permissive, which is why prod code takes
303
+ * this route rather than the config override the test-only `openBareRepo`
304
+ * helper uses.
305
+ */
306
+ private readPublishedSha;
307
+ /**
308
+ * Record that this worker rewrote `expectedSha` out of a branch's already
309
+ * published history (see BranchMetadata.historyRewrittenFrom).
310
+ *
311
+ * Set-once: if a marker is already present it is LEFT ALONE. Across two
312
+ * rebases before any GitHub push lands, GitHub still holds the commit the
313
+ * FIRST rebase replaced, so advancing the marker would aim the lease at a
314
+ * commit GitHub never had and permanently wedge the branch.
315
+ *
316
+ * Re-reads metadata rather than trusting the caller's loop-top snapshot:
317
+ * the task loop runs concurrently with syncGit() (see scheduleLoop) and may
318
+ * have cleared the marker while this branch was rebasing.
319
+ */
320
+ private markHistoryRewritten;
321
+ /**
322
+ * Clear the marker once GitHub is confirmed to hold the rewritten history.
323
+ *
324
+ * Best-effort only in the sense that a failure here destroys nothing: the
325
+ * lease still refuses anything unexpected, and the plain-push fallback only
326
+ * ever fast-forwards. It is NOT harmless. A marker that outlives its
327
+ * episode can wedge the NEXT one -- if the base advances before the stale
328
+ * marker is revisited, the queued push leases a commit GitHub has already
329
+ * moved off, falls back to a plain push of a rebased (non-ancestor)
330
+ * history, and fails permanently with a "something else moved it on
331
+ * GitHub" diagnosis that is false: we did.
332
+ *
333
+ * Tracked, with the concurrent-clear race that can drop a marker
334
+ * mid-arming, in
335
+ * .claude/future-tasks/worker-history-rewrite-marker-races.md.
336
+ */
337
+ private clearHistoryRewrittenMarker;
338
+ /**
339
+ * Publish a branch clone's rebased history into `remote.git`, replacing
340
+ * EXACTLY `expectedSha` and nothing else.
341
+ *
342
+ * The lease is the entire safety argument. `--force-with-lease=<ref>:<sha>`
343
+ * refuses unless `remote.git` still stands at `<sha>`, so this can only
344
+ * ever undo the commit our own rebase rewrote away. Callers must never pass
345
+ * "whatever remote.git currently holds" -- see the arming guard in
346
+ * rebaseActiveBranches() for the interleaving where that would silently
347
+ * delete a reviewer's direct push.
348
+ *
349
+ * Returns whether the push landed. A refused lease means a concurrent
350
+ * Lambda push moved the ref; that is logged and retried by the self-heal
351
+ * pass on a later cycle, never thrown.
352
+ */
353
+ private forcePublishToLocalRemote;
354
+ /**
355
+ * Queue the GitHub hop for a branch whose rewritten history now sits in
356
+ * `remote.git`, so an open PR's head follows the rebase within a cycle
357
+ * instead of waiting for the editor's next submit.
358
+ *
359
+ * Deliberately NOT skipped when a marker is already set: inferring "a task
360
+ * must already be queued" from the marker starves this hop whenever a task
361
+ * was lost, failed permanently, or was never written. Duplicate push tasks
362
+ * are bounded by base-branch advances and are idempotent (a repeat push is
363
+ * a no-op once GitHub holds the tip).
364
+ */
365
+ private enqueueGitHubPush;
366
+ /**
367
+ * Complete a rewrite this worker started but did not finish: get the
368
+ * rebased history into `remote.git` and queued for GitHub.
369
+ *
370
+ * Runs from the rebase loop for any branch carrying a marker, whether or
371
+ * not it is behind base this cycle, so an interrupted publish converges
372
+ * without waiting for the next base-branch advance.
373
+ *
374
+ * Always leases on the MARKER, never on remote.git's current tip -- the
375
+ * marker is the one commit we know our own rebase replaced.
376
+ */
377
+ private reconcilePendingRewrite;
215
378
  private pushBranchToGitHub;
216
379
  /**
217
- * Push any canopycms-settings-* branches from remote.git to GitHub.
218
- * Non-fatal: a no-op push for up-to-date branches just succeeds quietly.
380
+ * Push THIS deployment's own settings branch (`ensureSettingsBranch()`) from
381
+ * remote.git to GitHub. Non-fatal: a no-op push for an up-to-date branch
382
+ * just succeeds quietly.
383
+ *
384
+ * Deliberately narrowed to one branch — this used to push EVERY local
385
+ * branch matching `canopycms-settings-*`. With the tracking-namespace fetch
386
+ * fix (GITHUB_TRACKING_REF_PREFIX), `reconcileTrackedBranches` creates local
387
+ * heads for branches that exist on GitHub, so ANOTHER deployment's settings
388
+ * branch (sharing this same GitHub repo) can legitimately show up as a
389
+ * local head here too. Pushing it would be this deployment shipping
390
+ * settings state it doesn't own.
219
391
  */
220
392
  private pushSettingsBranches;
393
+ /**
394
+ * Bring `refs/heads/*` in `remote.git` toward what was just fetched into
395
+ * `GITHUB_TRACKING_REF_PREFIX` -- WITHOUT ever force-rewinding or deleting
396
+ * a local head. This is the non-destructive replacement for what the old
397
+ * `+refs/heads/*:refs/heads/*` fetch refspec used to do implicitly (and
398
+ * destructively) as part of the fetch itself; see
399
+ * `GITHUB_TRACKING_REF_PREFIX`'s doc comment for the two failure modes
400
+ * that refspec caused.
401
+ *
402
+ * Per tracked branch:
403
+ * - no local `refs/heads/<name>` yet -> create it at the tracked commit
404
+ * (a branch created on GitHub, or by another deployment sharing this
405
+ * GitHub repo, becomes visible locally).
406
+ * - local is a strict ancestor of tracked (behind) -> fast-forward it.
407
+ * - local === tracked -> nothing to do.
408
+ * - tracked is a strict ancestor of local (ahead) -> LEAVE IT ALONE. This
409
+ * is unpushed editor/settings work; the queued push task (or
410
+ * pushSettingsBranches) ships it. This is exactly the branch state the
411
+ * old refspec used to destroy.
412
+ * - neither is an ancestor of the other (diverged) -> LEAVE IT ALONE and
413
+ * count/log it. A real collision (e.g. another deployment moved the
414
+ * same branch name on GitHub); the next push attempt will be rejected
415
+ * non-fast-forward, which is the correct, visible outcome -- this
416
+ * method must never silently pick a winner. The one expected, benign
417
+ * form of this -- our own rebase loop having published a rewrite into
418
+ * remote.git with the GitHub push still queued -- is split out into the
419
+ * `rewritten` bucket so the collision warning stays meaningful.
420
+ *
421
+ * Never deletes a local head: a branch removed on GitHub simply stops
422
+ * being tracked here; the local ref persists until removed through its
423
+ * own explicit path (the sync loop must not be one of them).
424
+ *
425
+ * `remote.git` is bare, so there is no worktree to invalidate by moving
426
+ * these refs -- unlike a non-bare repo, updating the ref that happens to
427
+ * be "checked out" is a non-issue here.
428
+ *
429
+ * Concurrency: `remote.git` is bare and on EFS, and the Lambda pushes into
430
+ * it concurrently (`GitManager.push()`'s `target:target` refspec) while
431
+ * this runs. Every `update-ref` below passes the expected old value (the
432
+ * all-zeros OID for "must not exist yet" on creation, the previously-read
433
+ * SHA for the fast-forward case) so a concurrent Lambda write landing in
434
+ * the gap between the read and the write loses the ref update instead of
435
+ * being silently clobbered -- the branch is simply revisited next cycle.
436
+ */
437
+ private reconcileTrackedBranches;
438
+ /**
439
+ * Whether this branch carries a pending history rewrite -- the rebase loop
440
+ * rewrote already-published history and the GitHub push has not landed yet
441
+ * (see BranchMetadata.historyRewrittenFrom).
442
+ *
443
+ * `branchName` is a git ref name; branch workspaces are directories named
444
+ * with the sanitized form, hence the conversion. Best-effort: a settings
445
+ * branch (no workspace at all), a missing directory or an unreadable
446
+ * branch.json all mean "no known rewrite", which is the conservative
447
+ * answer -- it keeps the branch in the louder `diverged` bucket.
448
+ */
449
+ private hasPendingHistoryRewrite;
221
450
  syncGit(): Promise<void>;
222
451
  /**
223
452
  * [C1] Remove `.trash-*` branch directories (created by the admin purge
@@ -1 +1 @@
1
- {"version":3,"file":"cms-worker.d.ts","sourceRoot":"","sources":["../../src/worker/cms-worker.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cms-worker.d.ts","sourceRoot":"","sources":["../../src/worker/cms-worker.ts"],"names":[],"mappings":"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"}