hubspot-cms-sync 0.1.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 (40) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +52 -0
  3. package/bin/hubspot-cms-sync.mjs +115 -0
  4. package/docs/CONFIGURATION.md +83 -0
  5. package/docs/GITHUB_ACTIONS.md +70 -0
  6. package/docs/MIGRATION_PLAN.md +361 -0
  7. package/docs/PLAN_REVIEW.md +42 -0
  8. package/docs/SKILL_DISTRIBUTION.md +79 -0
  9. package/examples/github-actions/ci.yml +56 -0
  10. package/examples/github-actions/preview.yml +71 -0
  11. package/examples/github-actions/publish.yml +82 -0
  12. package/examples/hubspot-cms-sync.config.mjs +45 -0
  13. package/examples/site.manifest.json +19 -0
  14. package/package.json +41 -0
  15. package/skill/SKILL.md +54 -0
  16. package/skill/references/commands.md +54 -0
  17. package/skill/references/config.md +25 -0
  18. package/skill/references/failures.md +58 -0
  19. package/skill/references/github-actions.md +56 -0
  20. package/skill/references/screenshots-and-fidelity.md +33 -0
  21. package/src/adapters/assets.mjs +576 -0
  22. package/src/adapters/blog.mjs +921 -0
  23. package/src/adapters/content.mjs +213 -0
  24. package/src/adapters/forms.mjs +569 -0
  25. package/src/adapters/pages.mjs +463 -0
  26. package/src/adapters/theme.mjs +503 -0
  27. package/src/config.mjs +113 -0
  28. package/src/corpus-scan.mjs +248 -0
  29. package/src/cta-inventory.mjs +352 -0
  30. package/src/index.mjs +3 -0
  31. package/src/lib/canonical.mjs +234 -0
  32. package/src/lib/hub.mjs +197 -0
  33. package/src/lib/orchestrate.mjs +141 -0
  34. package/src/lib/refs.mjs +398 -0
  35. package/src/lib/sync-state.mjs +86 -0
  36. package/src/manifest.mjs +353 -0
  37. package/src/preflight.mjs +385 -0
  38. package/src/pull.mjs +99 -0
  39. package/src/push.mjs +354 -0
  40. package/src/republish.mjs +102 -0
@@ -0,0 +1,42 @@
1
+ # Plan Review Notes
2
+
3
+ This captures the read-only Claude review of the initial extraction plan.
4
+
5
+ ## Critical Findings
6
+
7
+ 1. **Move the tests with the engine.** The website repo unit/integration tests
8
+ import `sync/**` directly. If the website deletes local sync code before the
9
+ tests move or repoint to package exports, `npm run test:unit` will fail.
10
+
11
+ 2. **Move the corpus scanner.** `hcms corpus` depends on
12
+ `scripts/corpus-scan.mjs`, which lives outside `sync/` and was missing from
13
+ the initial inventory.
14
+
15
+ 3. **Make the read-only guard config-driven.** The current single hardcoded
16
+ `READ_ONLY_PORTAL = '529456'` must become `config.readOnlyPortalIds` while
17
+ preserving fail-closed behavior.
18
+
19
+ 4. **Thread config explicitly.** Several modules resolve paths from `__dirname`;
20
+ that will point into the npm package once installed. Build a resolved config
21
+ object once in the CLI and pass it into commands/libs/adapters instead of using
22
+ package-relative roots or global mutable config.
23
+
24
+ 5. **Scrub publish artifacts.** Docs/examples currently mention private portal
25
+ IDs. Before npm publication, scrub all shipped docs/examples or exclude them
26
+ from `package.json#files`.
27
+
28
+ ## Plan Updates Made
29
+
30
+ - Added `scripts/corpus-scan.mjs`, `test/unit/**`, and `test/integration/**` to
31
+ the migration inventory.
32
+ - Added explicit root/config threading requirements and named the affected
33
+ modules.
34
+ - Added acceptance gates for config loader behavior, known portal IDs, and
35
+ read-only portal arrays.
36
+ - Added v1 limitations for CTA/menu producers, legacy asset hosts, and global
37
+ transaction limits.
38
+ - Aligned the example config with the documented schema.
39
+ - Added `prepublishOnly` placeholder guard in `package.json`.
40
+ - Updated the skill plan to keep the deterministic engine in npm and use the
41
+ skill only as an agent workflow wrapper.
42
+
@@ -0,0 +1,79 @@
1
+ # Skill Distribution Plan
2
+
3
+ The Codex skill should be a companion to the npm CLI, not a replacement for it.
4
+
5
+ ## Skill Purpose
6
+
7
+ Help an agent operate `hubspot-cms-sync` correctly inside a project:
8
+
9
+ - inspect config and manifest
10
+ - run preflight and corpus checks
11
+ - perform pull/push/republish flows
12
+ - interpret common failures
13
+ - manage preview/deployment PR gates
14
+ - capture and compare screenshots through the consuming repo's configured tests
15
+
16
+ The npm CLI owns deterministic behavior. The skill owns agent procedure,
17
+ interpretation, and safe sequencing.
18
+
19
+ ## Proposed Skill Layout
20
+
21
+ ```text
22
+ hubspot-cms-sync/
23
+ ├── SKILL.md
24
+ └── references/
25
+ ├── commands.md
26
+ ├── config.md
27
+ ├── failures.md
28
+ ├── github-actions.md
29
+ └── screenshots-and-fidelity.md
30
+ ```
31
+
32
+ Do not bundle the full sync implementation into the skill. The deterministic
33
+ engine lives in npm.
34
+
35
+ `SKILL.md` with YAML frontmatter is the portable core. Agent-specific metadata
36
+ files such as `agents/openai.yaml` can be generated later for marketplaces that
37
+ need them, but they should not be the primary source of truth.
38
+
39
+ ## SKILL.md Scope
40
+
41
+ The skill body should stay short:
42
+
43
+ 1. Confirm `hubspot-cms-sync` / `hcms` is installed.
44
+ 2. Read `hubspot-cms-sync.config.mjs`.
45
+ 3. Run `hcms doctor` before risky operations.
46
+ 4. For pull: run pull, corpus, git diff, and summarize.
47
+ 5. For push: run corpus, preflight, plan, push, republish if needed, verify.
48
+ 6. For CI failures: inspect logs, classify failure, rerun the minimum command.
49
+ 7. Never bypass read-only portal guards.
50
+ 8. Surface v1 engine limits clearly: surviving `@cta:*` or `@menu:*` refs fail
51
+ closed until producer adapters exist; global HubSpot writes are rerun-to-
52
+ convergence, not transactional rollback.
53
+
54
+ ## References
55
+
56
+ - `commands.md`: command matrix and expected outputs.
57
+ - `config.md`: config schema and examples.
58
+ - `failures.md`: HubSpot API failures and remediation text.
59
+ - `github-actions.md`: environment secrets, preview, deploy, PR gates.
60
+ - `screenshots-and-fidelity.md`: Playwright screenshot workflows and baseline
61
+ update rules.
62
+
63
+ ## Example User Prompts
64
+
65
+ - "Pull HubSpot prod into git and summarize the diff."
66
+ - "Deploy this PR to the HubSpot preview sandbox and run fidelity checks."
67
+ - "Why did `hcms preflight dev` fail?"
68
+ - "Republish all live pages after this template change."
69
+ - "Set up HubSpot CMS sync in this repo."
70
+
71
+ ## Skill Guardrails
72
+
73
+ - The skill must not tell the agent to edit `.sync-state` manually.
74
+ - The skill must not suggest pushing to a read-only portal.
75
+ - The skill should prefer `hcms push --dry-run` and `hcms preflight` before any write.
76
+ - The skill should report verification gaps clearly if credentials or a live
77
+ preview URL are unavailable.
78
+ - The skill should source common failure explanations from CLI output and
79
+ package references, not invent parallel remediation text.
@@ -0,0 +1,56 @@
1
+ name: HubSpot CMS Sync CI
2
+
3
+ on:
4
+ pull_request:
5
+ branches: [main]
6
+ push:
7
+ branches: [main]
8
+
9
+ permissions:
10
+ contents: read
11
+
12
+ concurrency:
13
+ group: hcms-ci-${{ github.workflow }}-${{ github.ref }}
14
+ cancel-in-progress: true
15
+
16
+ env:
17
+ HUBSPOT_KEY_DIR: ${{ runner.temp }}/hubspot-keys
18
+ HCMS_TARGET: dev
19
+
20
+ jobs:
21
+ hcms-ci:
22
+ name: Validate HubSpot CMS sync inputs
23
+ runs-on: ubuntu-latest
24
+
25
+ steps:
26
+ - name: Check out repository
27
+ uses: actions/checkout@v4
28
+
29
+ - name: Set up Node.js
30
+ uses: actions/setup-node@v4
31
+ with:
32
+ node-version: 22
33
+ cache: npm
34
+
35
+ - name: Install project dependencies
36
+ run: npm ci
37
+
38
+ - name: Hydrate read-only HubSpot credentials
39
+ env:
40
+ DEV_TOKEN: ${{ secrets.HUBSPOT_DEV_PRIVATE_APP_TOKEN }}
41
+ run: |
42
+ mkdir -p "$HUBSPOT_KEY_DIR"
43
+ token_path="$HUBSPOT_KEY_DIR/dev.private-app-token"
44
+ printf '%s' "$DEV_TOKEN" > "$token_path"
45
+ chmod 600 "$token_path"
46
+
47
+ - name: Run sync doctor
48
+ run: npx --yes hubspot-cms-sync@latest doctor --root .
49
+
50
+ - name: Validate local corpus
51
+ run: npx --yes hubspot-cms-sync@latest corpus --root .
52
+
53
+ - name: Run read-only preflight
54
+ run: |
55
+ npx --yes hubspot-cms-sync@latest preflight \
56
+ "$HCMS_TARGET" --root . --read-only
@@ -0,0 +1,71 @@
1
+ name: HubSpot CMS Sync Preview
2
+
3
+ on:
4
+ pull_request:
5
+ types: [opened, synchronize, reopened, ready_for_review]
6
+ branches: [main]
7
+
8
+ permissions:
9
+ contents: read
10
+ pull-requests: write
11
+
12
+ concurrency:
13
+ group: hcms-preview-pr-${{ github.event.pull_request.number }}
14
+ cancel-in-progress: true
15
+
16
+ env:
17
+ HUBSPOT_KEY_DIR: ${{ runner.temp }}/hubspot-keys
18
+ HCMS_TARGET: preview
19
+ SITE_BASE_URL: ${{ secrets.PREVIEW_SITE_BASE_URL }}
20
+
21
+ jobs:
22
+ preview:
23
+ name: Deploy PR preview
24
+ runs-on: ubuntu-latest
25
+ if: ${{ !github.event.pull_request.draft }}
26
+
27
+ steps:
28
+ - name: Check out repository
29
+ uses: actions/checkout@v4
30
+
31
+ - name: Set up Node.js
32
+ uses: actions/setup-node@v4
33
+ with:
34
+ node-version: 22
35
+ cache: npm
36
+
37
+ - name: Install project dependencies
38
+ run: npm ci
39
+
40
+ - name: Hydrate preview HubSpot credentials
41
+ env:
42
+ PREVIEW_TOKEN: ${{ secrets.HUBSPOT_PREVIEW_PRIVATE_APP_TOKEN }}
43
+ run: |
44
+ mkdir -p "$HUBSPOT_KEY_DIR"
45
+ token_path="$HUBSPOT_KEY_DIR/preview.private-app-token"
46
+ printf '%s' "$PREVIEW_TOKEN" > "$token_path"
47
+ chmod 600 "$token_path"
48
+
49
+ - name: Validate preview deployment plan
50
+ run: |
51
+ npx --yes hubspot-cms-sync@latest doctor --root .
52
+ npx --yes hubspot-cms-sync@latest corpus --root .
53
+ npx --yes hubspot-cms-sync@latest preflight "$HCMS_TARGET" --root .
54
+ npx --yes hubspot-cms-sync@latest plan \
55
+ "$HCMS_TARGET" --root . --out .hcms/preview-plan.md
56
+
57
+ - name: Push preview content
58
+ run: |
59
+ npx --yes hubspot-cms-sync@latest push \
60
+ "$HCMS_TARGET" --root . --publish
61
+
62
+ - name: Verify preview
63
+ run: npx --yes hubspot-cms-sync@latest verify "$HCMS_TARGET" --root .
64
+
65
+ - name: Upload preview plan
66
+ if: ${{ always() }}
67
+ uses: actions/upload-artifact@v4
68
+ with:
69
+ name: hcms-preview-plan
70
+ path: .hcms/preview-plan.md
71
+ if-no-files-found: ignore
@@ -0,0 +1,82 @@
1
+ name: HubSpot CMS Sync Publish
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ inputs:
6
+ target:
7
+ description: HubSpot sync target from the consuming repo config
8
+ required: true
9
+ default: prod
10
+ type: choice
11
+ options:
12
+ - prod
13
+ - staging
14
+ dry_run:
15
+ description: Build and validate the plan without writing to HubSpot
16
+ required: true
17
+ default: true
18
+ type: boolean
19
+
20
+ permissions:
21
+ contents: read
22
+ deployments: write
23
+
24
+ concurrency:
25
+ group: hcms-publish-${{ inputs.target }}
26
+ cancel-in-progress: false
27
+
28
+ env:
29
+ HUBSPOT_KEY_DIR: ${{ runner.temp }}/hubspot-keys
30
+ HCMS_TARGET: ${{ inputs.target }}
31
+ SITE_BASE_URL: ${{ secrets.SITE_BASE_URL }}
32
+
33
+ jobs:
34
+ publish:
35
+ name: Publish HubSpot CMS target
36
+ runs-on: ubuntu-latest
37
+ environment: ${{ inputs.target }}
38
+
39
+ steps:
40
+ - name: Check out repository
41
+ uses: actions/checkout@v4
42
+
43
+ - name: Set up Node.js
44
+ uses: actions/setup-node@v4
45
+ with:
46
+ node-version: 22
47
+ cache: npm
48
+
49
+ - name: Install project dependencies
50
+ run: npm ci
51
+
52
+ - name: Hydrate target HubSpot credentials
53
+ env:
54
+ PROD_TOKEN: ${{ secrets.HUBSPOT_PROD_PRIVATE_APP_TOKEN }}
55
+ run: |
56
+ mkdir -p "$HUBSPOT_KEY_DIR"
57
+ token_path="$HUBSPOT_KEY_DIR/prod.private-app-token"
58
+ printf '%s' "$PROD_TOKEN" > "$token_path"
59
+ chmod 600 "$token_path"
60
+
61
+ - name: Build publish plan
62
+ run: |
63
+ npx --yes hubspot-cms-sync@latest doctor --root .
64
+ npx --yes hubspot-cms-sync@latest corpus --root .
65
+ npx --yes hubspot-cms-sync@latest preflight "$HCMS_TARGET" --root .
66
+ npx --yes hubspot-cms-sync@latest plan \
67
+ "$HCMS_TARGET" --root . --out .hcms/publish-plan.md
68
+
69
+ - name: Publish to HubSpot
70
+ if: ${{ !inputs.dry_run }}
71
+ run: |
72
+ npx --yes hubspot-cms-sync@latest push \
73
+ "$HCMS_TARGET" --root . --publish
74
+ npx --yes hubspot-cms-sync@latest verify "$HCMS_TARGET" --root .
75
+
76
+ - name: Upload publish plan
77
+ if: ${{ always() }}
78
+ uses: actions/upload-artifact@v4
79
+ with:
80
+ name: hcms-publish-plan-${{ inputs.target }}
81
+ path: .hcms/publish-plan.md
82
+ if-no-files-found: ignore
@@ -0,0 +1,45 @@
1
+ export default {
2
+ accountsFile: 'sync/accounts.json',
3
+ keyDirEnv: 'HUBSPOT_KEY_DIR',
4
+ contentDir: 'content',
5
+ syncStateDir: '.sync-state',
6
+ manifestPath: 'site.manifest.json',
7
+ readOnlyPortalIds: [],
8
+ knownPortalIds: [],
9
+ assetHosts: {
10
+ canonicalizeHostPatterns: [
11
+ 'hubfs',
12
+ 'hubspotusercontent',
13
+ 'cdn\\d*\\.hubspot\\.net'
14
+ ],
15
+ legacySiteHosts: []
16
+ },
17
+ adapters: {
18
+ externalDirs: []
19
+ },
20
+ theme: {
21
+ name: 'example-theme',
22
+ dirs: ['templates', 'modules', 'css', 'js', 'images'],
23
+ files: ['theme.json', 'fields.json']
24
+ },
25
+ blog: {
26
+ slug: 'blog',
27
+ itemTemplate: 'example-theme/templates/blog-post.html',
28
+ listingTemplate: 'example-theme/templates/blog.html'
29
+ },
30
+ uiGated: [
31
+ 'blogContainerCreate',
32
+ 'domainConnect',
33
+ 'homepageDesignation',
34
+ 'themeSettingsValues',
35
+ 'nativeMenus'
36
+ ],
37
+ verification: {
38
+ baseUrlEnv: 'SITE_BASE_URL',
39
+ commands: {
40
+ unit: 'npm run test:unit',
41
+ corpus: 'hcms corpus',
42
+ playwright: 'npx playwright test verify/fidelity.spec.mjs verify/forms.spec.mjs verify/links.spec.mjs'
43
+ }
44
+ }
45
+ };
@@ -0,0 +1,19 @@
1
+ {
2
+ "theme": {
3
+ "name": "example-theme"
4
+ },
5
+ "blog": {
6
+ "slug": "blog",
7
+ "itemTemplate": "example-theme/templates/blog-post.html",
8
+ "listingTemplate": "example-theme/templates/blog.html"
9
+ },
10
+ "forms": [],
11
+ "pages": [],
12
+ "uiGated": [
13
+ "blogContainerCreate",
14
+ "domainConnect",
15
+ "homepageDesignation",
16
+ "themeSettingsValues",
17
+ "nativeMenus"
18
+ ]
19
+ }
package/package.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "hubspot-cms-sync",
3
+ "version": "0.1.0",
4
+ "description": "Git-backed bidirectional sync for HubSpot CMS themes, content, blogs, forms, and assets.",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "engines": {
8
+ "node": ">=20.10.0",
9
+ "npm": ">=10"
10
+ },
11
+ "bin": {
12
+ "hubspot-cms-sync": "./bin/hubspot-cms-sync.mjs",
13
+ "hcms": "./bin/hubspot-cms-sync.mjs"
14
+ },
15
+ "exports": {
16
+ ".": "./src/index.mjs",
17
+ "./adapters/*": "./src/adapters/*.mjs",
18
+ "./lib/*": "./src/lib/*.mjs",
19
+ "./manifest": "./src/manifest.mjs",
20
+ "./preflight": "./src/preflight.mjs",
21
+ "./cta-inventory": "./src/cta-inventory.mjs",
22
+ "./corpus-scan": "./src/corpus-scan.mjs"
23
+ },
24
+ "files": [
25
+ "bin/",
26
+ "src/",
27
+ "docs/",
28
+ "examples/",
29
+ "skill/",
30
+ "README.md",
31
+ "LICENSE"
32
+ ],
33
+ "scripts": {
34
+ "test": "node --test test/**/*.test.mjs",
35
+ "test:unit": "node --test test/unit/*.test.mjs test/integration/corpus.test.mjs",
36
+ "test:integration": "RUN_INTEGRATION=1 node --test test/integration/roundtrip.test.mjs",
37
+ "lint": "node --check bin/hubspot-cms-sync.mjs && node bin/hubspot-cms-sync.mjs --help >/dev/null",
38
+ "prepare": "npm run lint",
39
+ "prepublishOnly": "npm test && npm run lint && npm pack --dry-run"
40
+ }
41
+ }
package/skill/SKILL.md ADDED
@@ -0,0 +1,54 @@
1
+ ---
2
+ name: hubspot-cms-sync
3
+ description: Use when operating the hubspot-cms-sync CLI in a repository: inspect config and manifest files, run doctor/corpus/preflight/pull/push/republish/verify flows, debug GitHub Actions failures, and safely manage HubSpot CMS preview or publish workflows.
4
+ ---
5
+
6
+ # HubSpot CMS Sync
7
+
8
+ Use this skill to operate `hubspot-cms-sync` or `hcms` inside a consuming repo.
9
+ The CLI owns deterministic sync behavior; the agent owns sequencing,
10
+ interpretation, and clear reporting.
11
+
12
+ ## First Checks
13
+
14
+ 1. Confirm the repo has `hubspot-cms-sync.config.mjs` and `site.manifest.json`.
15
+ 2. Confirm `hubspot-cms-sync` or `hcms` is available. If not, use the package
16
+ command documented by the repo.
17
+ 3. Read the config before choosing targets, credential environment variables, or
18
+ verification commands.
19
+ 4. Run `hcms doctor` before risky operations.
20
+ 5. Never bypass read-only portal guards or write to a production portal from a
21
+ pull request workflow.
22
+
23
+ ## Common Flows
24
+
25
+ - Pull: run `hcms pull <target>`, `hcms corpus`, inspect `git diff`, then
26
+ summarize content changes and verification gaps.
27
+ - Push: run `hcms corpus`, `hcms preflight <target>`, `hcms push <target> --dry-run`,
28
+ then `hcms push <target> --publish` only after the checks match intent.
29
+ - Republish: run `hcms preflight <target>`, then `hcms republish <target>` with
30
+ the narrowest flags needed.
31
+ - Verify: use the consuming repo's configured tests after the CLI checks pass.
32
+ - CI failure: inspect logs, classify the failure, rerun the smallest local
33
+ command that reproduces it, and avoid broad retries until the cause is known.
34
+
35
+ ## References
36
+
37
+ Load only the reference needed for the task:
38
+
39
+ - `references/commands.md`: command matrix and expected sequencing.
40
+ - `references/config.md`: config and manifest fields to inspect.
41
+ - `references/failures.md`: common failure classes and remediation.
42
+ - `references/github-actions.md`: CI, preview, and publish workflow policy.
43
+ - `references/screenshots-and-fidelity.md`: visual verification workflows.
44
+
45
+ ## Guardrails
46
+
47
+ - Do not edit `.sync-state` by hand.
48
+ - Do not suggest pushing to a configured read-only portal.
49
+ - Prefer `hcms push --dry-run` and `hcms preflight` before any write.
50
+ - Report missing credentials or preview URLs as verification gaps.
51
+ - Treat surviving `@cta:*` or `@menu:*` references as closed failures until
52
+ producer adapters exist.
53
+ - Treat HubSpot writes as rerun-to-convergence operations, not transactional
54
+ rollbacks.
@@ -0,0 +1,54 @@
1
+ # Command Reference
2
+
3
+ Commands are shown with the short alias `hcms`. Use `hubspot-cms-sync` if the
4
+ repo has not installed the alias.
5
+
6
+ ## Inspection
7
+
8
+ - `hcms doctor`: validate config, credentials, target definitions, and local
9
+ filesystem assumptions.
10
+ - `hcms corpus`: validate the local content corpus and adapter references.
11
+ - `hcms push <target> --dry-run`: produce a write plan without applying it.
12
+
13
+ ## Pull
14
+
15
+ Use pull when HubSpot is the source of truth for the current task.
16
+
17
+ ```bash
18
+ hcms doctor
19
+ hcms pull <target>
20
+ hcms corpus
21
+ git diff --stat
22
+ git diff
23
+ ```
24
+
25
+ Summarize changed files, content objects, and any verification that could not be
26
+ run.
27
+
28
+ ## Push
29
+
30
+ Use push when git is the source of truth and the target is write-capable.
31
+
32
+ ```bash
33
+ hcms doctor
34
+ hcms corpus
35
+ hcms preflight <target>
36
+ hcms push <target> --dry-run
37
+ hcms push <target> --publish
38
+ the consuming repo verification commands
39
+ ```
40
+
41
+ Stop before `push` if preflight or plan output indicates a read-only portal,
42
+ unresolved dependency, missing credential, or unexpected destructive change.
43
+
44
+ ## Republish
45
+
46
+ Use the narrowest republish scope that satisfies the change.
47
+
48
+ ```bash
49
+ hcms preflight <target>
50
+ hcms republish <target> --all
51
+ the consuming repo verification commands
52
+ ```
53
+
54
+ Prefer explicit page, blog, or template scopes when the CLI supports them.
@@ -0,0 +1,25 @@
1
+ # Config And Manifest Reference
2
+
3
+ Read `hubspot-cms-sync.config.mjs` before selecting targets or commands.
4
+
5
+ Key fields:
6
+
7
+ - `accountsFile`: maps target names to HubSpot account details.
8
+ - `keyDirEnv`: environment variable pointing at hydrated credentials.
9
+ - `contentDir`: local CMS content directory.
10
+ - `syncStateDir`: local sync state directory; do not edit by hand.
11
+ - `manifestPath`: path to `site.manifest.json`.
12
+ - `readOnlyPortalIds`: portals that must never receive writes.
13
+ - `knownPortalIds`: expected portal allowlist.
14
+ - `assetHosts`: host canonicalization policy for HubSpot assets.
15
+ - `adapters.externalDirs`: optional consumer-owned adapters.
16
+ - `theme`: theme directory and file layout.
17
+ - `blog`: blog slug and template mapping.
18
+ - `uiGated`: operations that require HubSpot UI action.
19
+ - `verification`: base URL environment variable and repo-specific test commands.
20
+
21
+ `site.manifest.json` is the deployment surface for theme, blog, forms, pages,
22
+ and UI-gated operations. If the manifest and config disagree, stop and ask for
23
+ the intended source of truth.
24
+
25
+ Use paths relative to the repo root unless the config explicitly says otherwise.
@@ -0,0 +1,58 @@
1
+ # Failure Reference
2
+
3
+ Prefer the CLI's error text and remediation output. Use this file to classify
4
+ failures and choose the next diagnostic step.
5
+
6
+ ## Configuration
7
+
8
+ Symptoms:
9
+
10
+ - Missing `hubspot-cms-sync.config.mjs`.
11
+ - Invalid config shape.
12
+ - Target name is not present in `accountsFile`.
13
+ - `keyDirEnv` is unset or points at missing credentials.
14
+
15
+ Action: fix config or CI secret hydration before retrying sync commands.
16
+
17
+ ## Read-Only Portal
18
+
19
+ Symptoms:
20
+
21
+ - Target portal ID is listed in `readOnlyPortalIds`.
22
+ - Preflight blocks write operations.
23
+
24
+ Action: do not bypass the guard. Choose a write-capable preview target or ask
25
+ for an explicit config change.
26
+
27
+ ## Dependency References
28
+
29
+ Symptoms:
30
+
31
+ - Surviving `@cta:*` or `@menu:*` references.
32
+ - Missing producer adapter output.
33
+ - Manifest objects refer to absent content.
34
+
35
+ Action: fail closed until the producer adapter or source content exists.
36
+
37
+ ## HubSpot API
38
+
39
+ Symptoms:
40
+
41
+ - Authentication failure.
42
+ - Rate limit or transient 5xx response.
43
+ - Validation error from a HubSpot object endpoint.
44
+
45
+ Action: distinguish credential/config failures from transient API failures. For
46
+ transient failures, retry the smallest failed operation. For validation errors,
47
+ fix the source object or adapter output.
48
+
49
+ ## Verification
50
+
51
+ Symptoms:
52
+
53
+ - Missing `SITE_BASE_URL` or configured base URL env var.
54
+ - Playwright or link checks cannot reach the preview.
55
+ - Screenshots differ after a template or module change.
56
+
57
+ Action: report unavailable verification separately from failed verification.
58
+ When screenshots differ, include the affected page and artifact path.
@@ -0,0 +1,56 @@
1
+ # GitHub Actions Reference
2
+
3
+ Use the repository's workflow files first. If adding new workflows, start from
4
+ the package examples:
5
+
6
+ - `examples/github-actions/ci.yml`
7
+ - `examples/github-actions/preview.yml`
8
+ - `examples/github-actions/publish.yml`
9
+
10
+ ## CI
11
+
12
+ CI should be read-only. It can run:
13
+
14
+ ```bash
15
+ hcms doctor
16
+ hcms corpus
17
+ hcms preflight <non-prod-target> --read-only
18
+ ```
19
+
20
+ Do not expose production credentials to `pull_request` events.
21
+
22
+ ## Preview
23
+
24
+ Preview workflows should use a non-prod HubSpot target and PR-level
25
+ concurrency.
26
+
27
+ Typical sequence:
28
+
29
+ ```bash
30
+ hcms doctor
31
+ hcms corpus
32
+ hcms preflight preview
33
+ hcms push preview --dry-run
34
+ hcms push preview --publish
35
+ the preview verification commands
36
+ ```
37
+
38
+ Upload the plan and verification artifacts when available.
39
+
40
+ ## Publish
41
+
42
+ Publish workflows should be manual or release-driven and protected by a GitHub
43
+ Environment.
44
+
45
+ Typical sequence:
46
+
47
+ ```bash
48
+ hcms doctor
49
+ hcms corpus
50
+ hcms preflight prod
51
+ hcms push prod --dry-run
52
+ hcms push prod --publish
53
+ the production verification commands
54
+ ```
55
+
56
+ Keep a dry-run option for validating the plan without writing to HubSpot.