canopycms 0.0.67 → 0.0.68-int.93
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/handler.js +8 -0
- package/dist/api/admin-branch-health.js +12 -7
- package/dist/api/admin.d.ts +8 -8
- package/dist/api/branch-status.js +6 -2
- package/dist/api/client.d.ts +12 -0
- package/dist/api/client.js +35 -11
- package/dist/api/content.d.ts +6 -5
- package/dist/api/content.js +38 -39
- package/dist/api/entries.js +6 -8
- package/dist/api/github-sync.d.ts +10 -1
- package/dist/api/github-sync.js +20 -10
- package/dist/api/reference-options.js +1 -1
- package/dist/api/request-url.d.ts +8 -0
- package/dist/api/request-url.js +15 -0
- package/dist/api/resolve-references.js +2 -2
- package/dist/api/settings-helpers.d.ts +1 -1
- package/dist/api/settings-helpers.js +1 -4
- package/dist/authorization/content.d.ts +5 -4
- package/dist/authorization/content.js +5 -5
- package/dist/authorization/path.d.ts +11 -6
- package/dist/authorization/path.js +11 -6
- package/dist/authorization/types.d.ts +2 -2
- package/dist/branch-health.js +3 -3
- package/dist/branch-schema-cache.d.ts +5 -3
- package/dist/branch-schema-cache.js +29 -11
- package/dist/branch-workspace.js +2 -2
- package/dist/cli/cli.js +285 -168
- package/dist/cli/generate-ai-content.js +190 -109
- package/dist/cli/github-app-manifest.d.ts +4 -3
- package/dist/cli/github-app-manifest.js +4 -3
- package/dist/cli/init.js +15 -10
- package/dist/cli/sync.js +15 -13
- package/dist/config/schemas/config.d.ts +6 -3
- package/dist/config/schemas/config.js +3 -1
- package/dist/config/schemas/field.js +1 -0
- package/dist/config/types.d.ts +11 -2
- package/dist/config/validation.d.ts +6 -0
- package/dist/config/validation.js +37 -0
- package/dist/content-listing.d.ts +2 -2
- package/dist/content-listing.js +3 -3
- package/dist/content-reader.js +4 -4
- package/dist/content-store.d.ts +2 -0
- package/dist/content-store.js +2 -1
- package/dist/content-tree.js +1 -1
- package/dist/context.d.ts +16 -7
- package/dist/context.js +116 -67
- package/dist/editor/Editor.js +4 -4
- package/dist/editor/FormRenderer.js +20 -5
- package/dist/editor/admin/SystemHealthPanel.js +37 -6
- package/dist/editor/components/NoEditPermissionNotice.d.ts +10 -0
- package/dist/editor/components/NoEditPermissionNotice.js +17 -0
- package/dist/editor/hooks/useBranchesData.js +3 -1
- package/dist/editor/hooks/useDraftManager.d.ts +1 -1
- package/dist/editor/hooks/useDraftManager.js +2 -1
- package/dist/editor/hooks/useEntriesData.js +2 -2
- package/dist/editor/hooks/useEntryManager.js +17 -11
- package/dist/entry-schema-registry.js +2 -1
- package/dist/git-manager.d.ts +20 -0
- package/dist/git-manager.js +50 -4
- package/dist/github-service.d.ts +8 -0
- package/dist/github-service.js +5 -1
- package/dist/http/handler.js +24 -9
- package/dist/http/index.d.ts +2 -0
- package/dist/http/index.js +2 -0
- package/dist/http/router.d.ts +2 -0
- package/dist/http/router.js +2 -1
- package/dist/http/worker-not-ready.d.ts +9 -0
- package/dist/http/worker-not-ready.js +17 -0
- package/dist/operating-mode/client-unsafe-strategy.js +0 -6
- package/dist/operating-mode/types.d.ts +0 -3
- package/dist/paths/index.d.ts +1 -1
- package/dist/paths/index.js +1 -1
- package/dist/paths/normalize.d.ts +7 -0
- package/dist/paths/normalize.js +9 -0
- package/dist/reference-resolver.d.ts +3 -3
- package/dist/reference-resolver.js +3 -2
- package/dist/resolve-canopy-user.js +2 -1
- package/dist/services.d.ts +12 -5
- package/dist/services.js +56 -56
- package/dist/settings-workspace.js +36 -0
- package/dist/static/seo.d.ts +2 -14
- package/dist/static/seo.js +2 -25
- package/dist/submission-attribution.d.ts +73 -0
- package/dist/submission-attribution.js +221 -0
- package/dist/sync-core.js +7 -8
- package/dist/types.d.ts +23 -2
- package/dist/utils/content-write-lock.d.ts +3 -7
- package/dist/utils/content-write-lock.js +6 -4
- package/dist/utils/debug.d.ts +8 -0
- package/dist/utils/debug.js +10 -2
- package/dist/utils/git.d.ts +28 -0
- package/dist/utils/git.js +38 -0
- package/dist/utils/provisioning-lock.d.ts +15 -5
- package/dist/utils/provisioning-lock.js +31 -11
- package/dist/utils/request-timing.d.ts +25 -0
- package/dist/utils/request-timing.js +101 -0
- package/dist/utils/url-prefix.d.ts +15 -0
- package/dist/utils/url-prefix.js +26 -0
- package/dist/worker/canopy-state.d.ts +45 -0
- package/dist/worker/canopy-state.js +75 -0
- package/dist/worker/git-sync.d.ts +4 -2
- package/dist/worker/git-sync.js +111 -24
- package/dist/worker/provisioned-workspace.d.ts +35 -0
- package/dist/worker/provisioned-workspace.js +50 -0
- package/dist/worker/rebase.js +75 -12
- package/dist/worker/task-runner.js +39 -4
- package/package.json +1 -1
|
@@ -3,10 +3,10 @@ import { simpleGit } from 'simple-git';
|
|
|
3
3
|
import { completeTask, dequeueTask, failTask, recoverOrphanedTasks, retryTask, } from '../task-queue/cms-task-queue.js';
|
|
4
4
|
import { createOrUpdatePullRequest } from '../github-service.js';
|
|
5
5
|
import { BranchMetadataFileManager, getBranchMetadataFileManager } from '../branch-metadata.js';
|
|
6
|
-
import { sanitizeBranchName } from '../paths/branch-name.js';
|
|
6
|
+
import { sanitizeBranchName, RESERVED_SETTINGS_BRANCH_PREFIX } from '../paths/branch-name.js';
|
|
7
7
|
import { gitNetworkChildEnv } from '../git-manager.js';
|
|
8
8
|
import { getErrorMessage, redactCredentials } from '../utils/error.js';
|
|
9
|
-
import { isNonFastForwardRejection, isStaleLeaseRejection } from '../utils/git.js';
|
|
9
|
+
import { isNonFastForwardRejection, isStaleLeaseRejection, workflowPushRefusalFile, } from '../utils/git.js';
|
|
10
10
|
import { clearHistoryRewrittenMarker, readPublishedSha } from './history-rewrite.js';
|
|
11
11
|
import { writeWorkerStatus } from '../task-queue/worker-status.js';
|
|
12
12
|
import { workerLog, workerLogError } from './log.js';
|
|
@@ -90,6 +90,15 @@ function isRateLimitSignal403(err) {
|
|
|
90
90
|
return false;
|
|
91
91
|
}
|
|
92
92
|
// Payload validation helpers — fail fast with clear errors instead of silent `as` casts
|
|
93
|
+
/**
|
|
94
|
+
* Whether `branch` carries the reserved settings-branch prefix. Matching on the prefix
|
|
95
|
+
* alone, never on a configured name, is what keeps a content branch out: branch creation
|
|
96
|
+
* rejects the prefix, while a configured name the worker and API disagree on could be a
|
|
97
|
+
* content branch's.
|
|
98
|
+
*/
|
|
99
|
+
function isSettingsBranch(branch) {
|
|
100
|
+
return branch.startsWith(RESERVED_SETTINGS_BRANCH_PREFIX);
|
|
101
|
+
}
|
|
93
102
|
function requireString(payload, key) {
|
|
94
103
|
const val = payload[key];
|
|
95
104
|
if (typeof val !== 'string')
|
|
@@ -282,6 +291,13 @@ export async function executeTask(ctx, task, signal) {
|
|
|
282
291
|
if (sanitizeBranchName(branch) === ctx.sanitizedBaseBranch) {
|
|
283
292
|
throw new PermanentTaskError(`Refusing to push-and-create-or-update-pr for "${branch}": it is the base branch -- submitting the base branch is never valid`);
|
|
284
293
|
}
|
|
294
|
+
// The settings branch is an orphan with no history in common with the
|
|
295
|
+
// base, so GitHub 422s a PR for it: push it and stop.
|
|
296
|
+
if (isSettingsBranch(branch)) {
|
|
297
|
+
await ctx.pushBranchToGitHub(branch);
|
|
298
|
+
workerLog(`Pushed settings branch ${branch}; settings branches never get a PR`);
|
|
299
|
+
return { pushed: true };
|
|
300
|
+
}
|
|
285
301
|
await ctx.pushBranchToGitHub(branch);
|
|
286
302
|
const result = await createOrUpdatePullRequest({
|
|
287
303
|
octokit: ctx.octokit(),
|
|
@@ -291,9 +307,9 @@ export async function executeTask(ctx, task, signal) {
|
|
|
291
307
|
base,
|
|
292
308
|
title: optionalString(payload, 'title', `Submit ${branch}`),
|
|
293
309
|
body: optionalString(payload, 'body', ''),
|
|
294
|
-
// Content submits (api/github-sync.ts) set
|
|
295
|
-
// syncs (services.ts) deliberately don't.
|
|
310
|
+
// Content submits (api/github-sync.ts) set both.
|
|
296
311
|
markReadyIfDraft: payload.markReadyIfDraft === true,
|
|
312
|
+
mergeSectionIntoBody: payload.mergeSectionIntoBody === true,
|
|
297
313
|
signal,
|
|
298
314
|
});
|
|
299
315
|
workerLog(result.created
|
|
@@ -415,6 +431,23 @@ async function updateBranchMetadataOnFailure(ctx, task, error) {
|
|
|
415
431
|
workerLogError(`Failed to update failure metadata for ${branch}:`, err instanceof Error ? err.message : err);
|
|
416
432
|
}
|
|
417
433
|
}
|
|
434
|
+
/**
|
|
435
|
+
* Fail fast when GitHub refused the push for adding workflow content it does not already hold: the
|
|
436
|
+
* worker's credential deliberately lacks the workflows permission, so the identical push can never
|
|
437
|
+
* succeed. Rebasing onto a base that changed a workflow does not trigger it; a workflow edit made
|
|
438
|
+
* outside the editor, auto-merged by the rebase with a base change to the same file, does.
|
|
439
|
+
*/
|
|
440
|
+
function throwIfWorkflowRefusal(branch, message) {
|
|
441
|
+
const file = workflowPushRefusalFile(message);
|
|
442
|
+
if (file === null)
|
|
443
|
+
return;
|
|
444
|
+
throw new PermanentTaskError(`Push refused for branch "${branch}": it would put a version of ${file} on GitHub that ` +
|
|
445
|
+
`GitHub does not already have, and this deployment's GitHub credential is deliberately not ` +
|
|
446
|
+
`allowed to change workflow files. Such a change usually comes from outside the editor, ` +
|
|
447
|
+
`such as a direct push to this branch. Nothing was pushed, and ` +
|
|
448
|
+
`retrying will not help until a developer with permission to change workflow files ` +
|
|
449
|
+
`resolves it on GitHub.`);
|
|
450
|
+
}
|
|
418
451
|
export async function pushBranchToGitHub(ctx, branch) {
|
|
419
452
|
const git = simpleGit({
|
|
420
453
|
baseDir: ctx.remoteGitPath,
|
|
@@ -473,6 +506,7 @@ export async function pushBranchToGitHub(ctx, branch) {
|
|
|
473
506
|
}
|
|
474
507
|
catch (err) {
|
|
475
508
|
const message = getErrorMessage(err);
|
|
509
|
+
throwIfWorkflowRefusal(branch, message);
|
|
476
510
|
// A refused lease means GitHub is not at the commit we rewrote, so the
|
|
477
511
|
// marker is stale -- routine, not exceptional: tasks are re-run after a
|
|
478
512
|
// crash (recoverOrphanedTasks) and the marker survives any failure to
|
|
@@ -494,6 +528,7 @@ export async function pushBranchToGitHub(ctx, branch) {
|
|
|
494
528
|
}
|
|
495
529
|
catch (retryErr) {
|
|
496
530
|
const retryMessage = getErrorMessage(retryErr);
|
|
531
|
+
throwIfWorkflowRefusal(branch, retryMessage);
|
|
497
532
|
if (isNonFastForwardRejection(retryMessage)) {
|
|
498
533
|
throw new PermanentTaskError(`Push rejected for branch "${branch}": GitHub's tip is neither the commit this ` +
|
|
499
534
|
`deployment last published nor an ancestor of what it is pushing, so the branch ` +
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"//": "@codemirror/language, @lezer/highlight: workaround — @mdxeditor/editor uses cm6-theme-basic-light which peer-requires these but mdxeditor doesn't declare them as dependencies",
|
|
3
3
|
"name": "canopycms",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.68-int.93",
|
|
5
5
|
"description": "CanopyCMS core package: schema-driven content, branch-aware editing, and editor UI for Next.js.",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|