canopycms 0.7.1 → 0.8.0

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 (147) hide show
  1. package/CHANGELOG.md +187 -47
  2. package/dist/api/admin-branch-health.js +47 -20
  3. package/dist/api/admin.d.ts +13 -1
  4. package/dist/api/admin.js +14 -24
  5. package/dist/api/branch-changes.d.ts +87 -0
  6. package/dist/api/branch-changes.js +269 -0
  7. package/dist/api/branch-entry-changes.d.ts +83 -0
  8. package/dist/api/branch-entry-changes.js +262 -0
  9. package/dist/api/branch-merge.js +2 -2
  10. package/dist/api/branch-review.js +35 -4
  11. package/dist/api/branch-status.js +14 -5
  12. package/dist/api/branch-withdraw.js +7 -0
  13. package/dist/api/branch.d.ts +13 -1
  14. package/dist/api/branch.js +171 -97
  15. package/dist/api/client.d.ts +15 -0
  16. package/dist/api/client.js +13 -1
  17. package/dist/api/content.d.ts +18 -18
  18. package/dist/api/content.js +1 -1
  19. package/dist/api/github-sync.js +7 -3
  20. package/dist/api/groups.d.ts +4 -4
  21. package/dist/api/pr-comment-sync.d.ts +9 -8
  22. package/dist/api/pr-comment-sync.js +23 -13
  23. package/dist/api/routes.js +4 -0
  24. package/dist/api/types.d.ts +3 -1
  25. package/dist/authorization/groups/schema.d.ts +4 -4
  26. package/dist/authorization/protected-branch.d.ts +3 -3
  27. package/dist/authorization/protected-branch.js +3 -3
  28. package/dist/branch-metadata-file.d.ts +84 -0
  29. package/dist/branch-metadata-file.js +9 -0
  30. package/dist/branch-metadata.d.ts +4 -4
  31. package/dist/branch-metadata.js +4 -5
  32. package/dist/branch-param.d.ts +24 -0
  33. package/dist/branch-param.js +87 -0
  34. package/dist/branch-provisioning.d.ts +6 -3
  35. package/dist/branch-provisioning.js +12 -10
  36. package/dist/branch-registry.d.ts +6 -0
  37. package/dist/branch-registry.js +12 -3
  38. package/dist/branch-workspace.js +22 -15
  39. package/dist/cli/cli.js +1060 -172
  40. package/dist/cli/generate-ai-content.js +732 -101
  41. package/dist/cli/init.js +126 -0
  42. package/dist/comment-store.d.ts +3 -0
  43. package/dist/comment-store.js +4 -1
  44. package/dist/config/schemas/config.d.ts +3 -0
  45. package/dist/config/schemas/config.js +2 -0
  46. package/dist/config/types.d.ts +11 -0
  47. package/dist/content-id-index.d.ts +5 -0
  48. package/dist/content-id-index.js +1 -1
  49. package/dist/content-listing.d.ts +53 -0
  50. package/dist/content-listing.js +123 -27
  51. package/dist/content-reader.js +23 -16
  52. package/dist/context.js +8 -7
  53. package/dist/editor/BranchManager.d.ts +7 -3
  54. package/dist/editor/BranchManager.js +51 -6
  55. package/dist/editor/Editor.js +166 -34
  56. package/dist/editor/EntryNavigator.d.ts +34 -10
  57. package/dist/editor/EntryNavigator.js +185 -29
  58. package/dist/editor/admin/SystemHealthPanel.js +36 -1
  59. package/dist/editor/admin/useSystemHealth.js +1 -0
  60. package/dist/editor/branch-names.d.ts +43 -0
  61. package/dist/editor/branch-names.js +75 -0
  62. package/dist/editor/components/BranchPill.d.ts +2 -2
  63. package/dist/editor/components/BranchPill.js +2 -2
  64. package/dist/editor/components/EditorHeader.d.ts +3 -1
  65. package/dist/editor/components/EditorHeader.js +2 -2
  66. package/dist/editor/components/EntryChangesDrawer.d.ts +51 -0
  67. package/dist/editor/components/EntryChangesDrawer.js +363 -0
  68. package/dist/editor/components/EntryChangesSkeleton.d.ts +9 -0
  69. package/dist/editor/components/EntryChangesSkeleton.js +7 -0
  70. package/dist/editor/components/EntryHeader.d.ts +9 -1
  71. package/dist/editor/components/EntryHeader.js +25 -3
  72. package/dist/editor/components/LazyEntryChangesDrawer.d.ts +16 -0
  73. package/dist/editor/components/LazyEntryChangesDrawer.js +45 -0
  74. package/dist/editor/components/ReviewDialogs.js +3 -3
  75. package/dist/editor/context/ApiClientContext.d.ts +9 -0
  76. package/dist/editor/context/ApiClientContext.js +26 -2
  77. package/dist/editor/context/index.d.ts +1 -1
  78. package/dist/editor/context/index.js +1 -1
  79. package/dist/editor/copy.d.ts +1 -0
  80. package/dist/editor/copy.js +1 -0
  81. package/dist/editor/editor-utils.d.ts +2 -0
  82. package/dist/editor/editor-utils.js +15 -0
  83. package/dist/editor/entry-diff.d.ts +143 -0
  84. package/dist/editor/entry-diff.js +593 -0
  85. package/dist/editor/hooks/create-branch-request.d.ts +11 -1
  86. package/dist/editor/hooks/create-branch-request.js +16 -6
  87. package/dist/editor/hooks/useBranchActions.d.ts +19 -2
  88. package/dist/editor/hooks/useBranchActions.js +29 -20
  89. package/dist/editor/hooks/useBranchChangesData.d.ts +57 -0
  90. package/dist/editor/hooks/useBranchChangesData.js +134 -0
  91. package/dist/editor/hooks/useBranchManager.d.ts +16 -0
  92. package/dist/editor/hooks/useBranchManager.js +142 -54
  93. package/dist/editor/hooks/useDraftManager.js +6 -2
  94. package/dist/editor/hooks/useEntryManager.d.ts +18 -2
  95. package/dist/editor/hooks/useEntryManager.js +36 -10
  96. package/dist/editor/utils/editor-errors.d.ts +5 -2
  97. package/dist/git-manager.d.ts +71 -0
  98. package/dist/git-manager.js +270 -1
  99. package/dist/http/handler.js +11 -9
  100. package/dist/operating-mode/branch-namespace-fixtures.d.ts +17 -0
  101. package/dist/operating-mode/branch-namespace-fixtures.js +65 -0
  102. package/dist/operating-mode/branch-namespace.d.ts +34 -0
  103. package/dist/operating-mode/branch-namespace.js +121 -0
  104. package/dist/operating-mode/client-unsafe-strategy.js +7 -0
  105. package/dist/operating-mode/types.d.ts +8 -0
  106. package/dist/paths/branch-name.d.ts +11 -19
  107. package/dist/paths/branch-name.js +17 -27
  108. package/dist/paths/index.d.ts +2 -2
  109. package/dist/paths/index.js +2 -2
  110. package/dist/paths/resolve.d.ts +0 -1
  111. package/dist/paths/resolve.js +0 -1
  112. package/dist/paths/validation.d.ts +40 -1
  113. package/dist/paths/validation.js +83 -4
  114. package/dist/pr-comments.d.ts +17 -9
  115. package/dist/pr-comments.js +53 -15
  116. package/dist/services.js +2 -1
  117. package/dist/submission-attribution.d.ts +22 -0
  118. package/dist/submission-attribution.js +62 -6
  119. package/dist/task-queue/worker-status.d.ts +6 -1
  120. package/dist/task-queue/worker-status.js +23 -2
  121. package/dist/types.d.ts +59 -0
  122. package/dist/version.d.ts +1 -1
  123. package/dist/version.js +1 -1
  124. package/dist/worker/branch-policy.d.ts +111 -16
  125. package/dist/worker/branch-policy.js +222 -17
  126. package/dist/worker/cms-worker.d.ts +24 -2
  127. package/dist/worker/cms-worker.js +35 -24
  128. package/dist/worker/git-sync.d.ts +3 -3
  129. package/dist/worker/git-sync.js +42 -1
  130. package/dist/worker/github-gateway-http.js +2 -2
  131. package/dist/worker/github-gateway-wire.d.ts +40 -25
  132. package/dist/worker/github-gateway-wire.js +14 -3
  133. package/dist/worker/github-gateway.d.ts +17 -6
  134. package/dist/worker/github-gateway.js +62 -6
  135. package/dist/worker/github-mirror.d.ts +7 -4
  136. package/dist/worker/github-mirror.js +27 -16
  137. package/dist/worker/history-rewrite.d.ts +23 -10
  138. package/dist/worker/history-rewrite.js +43 -20
  139. package/dist/worker/legacy-branch-fixtures.d.ts +21 -0
  140. package/dist/worker/legacy-branch-fixtures.js +71 -0
  141. package/dist/worker/rebase.d.ts +2 -1
  142. package/dist/worker/rebase.js +93 -36
  143. package/dist/worker/task-runner.d.ts +4 -1
  144. package/dist/worker/task-runner.js +77 -48
  145. package/dist/worker/unpublishable-branches.d.ts +34 -0
  146. package/dist/worker/unpublishable-branches.js +182 -0
  147. package/package.json +2 -1
@@ -1,8 +1,9 @@
1
1
  import fs from 'node:fs/promises';
2
2
  import path from 'node:path';
3
- import { BranchPathError, isSettingsBranchName, resolveBranchPath } from './paths/index.js';
3
+ import { BranchPathError, isSettingsBranchName, parseBranchRef, resolveBranchPath } from './paths/index.js';
4
4
  import { buildInitialBranchMetadata, loadBranchContext } from './branch-metadata.js';
5
5
  import { BRANCH_META_DIR, BRANCH_META_FILE, readBranchMetadataFile } from './branch-metadata-file.js';
6
+ import { shortNameOf } from './branch-param.js';
6
7
  import { BranchRegistry } from './branch-registry.js';
7
8
  import { BranchDirOccupiedError, BranchProvisioningBusyError, CREATE_RESIDUE_MIN_QUIET_MS, classifyFinalDir, removeLeftoverDir, lockBranchName, publishStaging, quietAgeMs, stageBranchWorkspace, } from './branch-provisioning.js';
8
9
  import { recordSparseCone, sparseConeFor } from './branch-sparse.js';
@@ -49,12 +50,17 @@ export class BranchWorkspaceManager {
49
50
  if (isSettingsBranchName(options.branchName, operatingStrategy(options.mode).getSettingsBranchName(this.config))) {
50
51
  throw new BranchPathError('Settings branches are not content branches');
51
52
  }
52
- const { branchRoot, baseRoot, branchName: safeName } = resolveBranchPath(options);
53
+ // The name reaches git and branch.json as given; only the directory is sanitized.
54
+ const named = parseBranchRef(options.branchName);
55
+ if (!named.ok)
56
+ throw new BranchPathError(named.error);
57
+ const { branchRoot, baseRoot } = resolveBranchPath(options);
53
58
  const paths = {
54
59
  branchRoot,
55
60
  baseRoot,
56
61
  dirName: path.basename(branchRoot),
57
- safeName,
62
+ ref: options.branchName,
63
+ shortName: shortNameOf({ ...this.config, mode: options.mode }, options.branchName),
58
64
  };
59
65
  const existing = await readBranchMetadataFile(branchRoot);
60
66
  if (existing) {
@@ -73,7 +79,7 @@ export class BranchWorkspaceManager {
73
79
  }
74
80
  }
75
81
  async provisionUnshared(options, paths) {
76
- const { branchRoot, baseRoot, dirName } = paths;
82
+ const { branchRoot, baseRoot, dirName, shortName } = paths;
77
83
  await fs.mkdir(baseRoot, { recursive: true });
78
84
  // Resolve the fork point once so the clone and the recorded metadata agree, and the remote
79
85
  // before any clone is paid for.
@@ -93,7 +99,7 @@ export class BranchWorkspaceManager {
93
99
  });
94
100
  const metadata = buildInitialBranchMetadata({
95
101
  branch: {
96
- name: paths.safeName,
102
+ name: paths.ref,
97
103
  title: options.title,
98
104
  description: options.description,
99
105
  access: options.access,
@@ -107,7 +113,7 @@ export class BranchWorkspaceManager {
107
113
  if (state.kind === 'live' || state.kind === 'corrupt')
108
114
  return this.existing(paths);
109
115
  if (state.kind === 'protected')
110
- throw new BranchProvisioningBusyError(dirName);
116
+ throw new BranchProvisioningBusyError(dirName, shortName);
111
117
  if (state.kind === 'foreign') {
112
118
  // dev's CLI sync builds a branch workspace by `git init` and real commits, with no
113
119
  // remote and no branch.json; it is adopted where it is.
@@ -116,7 +122,7 @@ export class BranchWorkspaceManager {
116
122
  return this.adoptInPlace(options, paths, baseBranch, metadata);
117
123
  }
118
124
  if (state.kind === 'residue' && (await this.recentlyActive(paths))) {
119
- throw new BranchProvisioningBusyError(dirName);
125
+ throw new BranchProvisioningBusyError(dirName, shortName);
120
126
  }
121
127
  const sparseCone = sparseConeFor(this.config.contentRoot);
122
128
  await recordSparseCone(baseRoot, sparseCone).catch((err) => {
@@ -142,11 +148,11 @@ export class BranchWorkspaceManager {
142
148
  return outcome;
143
149
  }
144
150
  async stageAndPublish(paths, run) {
145
- const { branchRoot, baseRoot, dirName } = paths;
151
+ const { branchRoot, baseRoot, dirName, shortName } = paths;
146
152
  const staged = await stageBranchWorkspace({
147
153
  baseRoot,
148
154
  dirName,
149
- branchName: paths.safeName,
155
+ branchName: paths.ref,
150
156
  baseBranch: run.baseBranch,
151
157
  remoteUrl: run.remoteUrl,
152
158
  clone: {
@@ -166,6 +172,7 @@ export class BranchWorkspaceManager {
166
172
  published = await run.provisionLog.step('publish', () => publishStaging({
167
173
  baseRoot,
168
174
  dirName,
175
+ shortName,
169
176
  stagingPath: staged.stagingPath,
170
177
  writeId: staged.meta.writeId,
171
178
  expectedRemoteUrl: run.remoteUrl,
@@ -186,16 +193,16 @@ export class BranchWorkspaceManager {
186
193
  * is, given branch.json under the branch's lock.
187
194
  */
188
195
  async adoptInPlace(options, paths, baseBranch, metadata) {
189
- const { branchRoot, baseRoot, dirName } = paths;
196
+ const { branchRoot, baseRoot, dirName, shortName } = paths;
190
197
  const provisionLog = new ProvisionLog(dirName);
191
198
  let created = false;
192
199
  try {
193
- const release = await provisionLog.step('lock', () => lockBranchName(baseRoot, dirName));
200
+ const release = await provisionLog.step('lock', () => lockBranchName(baseRoot, dirName, shortName));
194
201
  try {
195
202
  if (!(await readBranchMetadataFile(branchRoot))) {
196
203
  await GitManager.initializeWorkspace({
197
204
  workspacePath: branchRoot,
198
- branchName: paths.safeName,
205
+ branchName: paths.ref,
199
206
  mode: options.mode,
200
207
  baseBranch,
201
208
  sourceRoot: this.config.sourceRoot,
@@ -231,7 +238,7 @@ export class BranchWorkspaceManager {
231
238
  return this.existing(paths);
232
239
  const meta = await readBranchMetadataFile(branchRoot);
233
240
  if (!meta)
234
- throw new BranchProvisioningBusyError(dirName);
241
+ throw new BranchProvisioningBusyError(dirName, shortName);
235
242
  return { kind: 'created', context: { branch: meta.branch, branchRoot, baseRoot } };
236
243
  }
237
244
  /** Whether residue at the branch path may still belong to a live process. */
@@ -241,10 +248,10 @@ export class BranchWorkspaceManager {
241
248
  return true;
242
249
  return (await quietAgeMs(branchRoot)) < CREATE_RESIDUE_MIN_QUIET_MS;
243
250
  }
244
- async existing({ branchRoot, baseRoot, dirName, }) {
251
+ async existing({ branchRoot, baseRoot, dirName, shortName, }) {
245
252
  const meta = await readBranchMetadataFile(branchRoot);
246
253
  if (!meta)
247
- throw new BranchProvisioningBusyError(dirName);
254
+ throw new BranchProvisioningBusyError(dirName, shortName);
248
255
  return { kind: 'exists', context: { branch: meta.branch, branchRoot, baseRoot } };
249
256
  }
250
257
  }