@decocms/start 2.17.0 → 2.18.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@decocms/start",
3
- "version": "2.17.0",
3
+ "version": "2.18.0",
4
4
  "type": "module",
5
5
  "description": "Deco framework for TanStack Start - CMS bridge, admin protocol, hooks, schema generation",
6
6
  "main": "./src/index.ts",
@@ -18,6 +18,7 @@ import { generateCommerceLoaders } from "./templates/commerce-loaders";
18
18
  import { generateSectionLoaders } from "./templates/section-loaders";
19
19
  import { generateCacheConfig } from "./templates/cache-config";
20
20
  import { generateSdkFiles } from "./templates/sdk-gen";
21
+ import { generateMigrationPolicyPointerRule } from "./templates/cursor-rules";
21
22
  // `lib-utils` is imported lazily — see end of phase-cleanup. Eager
22
23
  // generation of all 11 shims left every site with dead code that had
23
24
  // to be cleaned up by hand.
@@ -139,6 +140,17 @@ export function scaffold(ctx: MigrationContext): void {
139
140
  writeFile(ctx, "src/components/ui/Theme.tsx", generateSiteThemeComponent());
140
141
  }
141
142
 
143
+ // Migration tooling policy pointer rule (D1–D5 + priorities).
144
+ // The canonical rule lives in decocms/deco-start; this is a tiny
145
+ // pointer that loads on every Cursor session in the migrated site
146
+ // so agents working on the site know where the policy is and what
147
+ // it means here. See MIGRATION_TOOLING_PLAN.md (Wave 12-H).
148
+ writeFile(
149
+ ctx,
150
+ ".cursor/rules/migration-tooling-policy.mdc",
151
+ generateMigrationPolicyPointerRule(ctx.siteName),
152
+ );
153
+
142
154
  // Create public/ directory
143
155
  if (!ctx.dryRun) {
144
156
  fs.mkdirSync(path.join(ctx.sourceDir, "public"), { recursive: true });
@@ -0,0 +1,59 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { generateMigrationPolicyPointerRule } from "./cursor-rules";
3
+
4
+ describe("generateMigrationPolicyPointerRule", () => {
5
+ const body = generateMigrationPolicyPointerRule("acme");
6
+
7
+ it("emits a Cursor MDC rule with alwaysApply: true frontmatter", () => {
8
+ expect(body.startsWith("---\n")).toBe(true);
9
+ expect(body).toContain("alwaysApply: true");
10
+ expect(body).toContain("description:");
11
+ });
12
+
13
+ it("interpolates the site name into the body", () => {
14
+ expect(body).toContain("`acme`");
15
+ });
16
+
17
+ it("links to the canonical rule and plan in decocms/deco-start", () => {
18
+ expect(body).toContain(
19
+ "https://github.com/decocms/deco-start/blob/main/.cursor/rules/migration-tooling-policy.mdc",
20
+ );
21
+ expect(body).toContain(
22
+ "https://github.com/decocms/deco-start/blob/main/MIGRATION_TOOLING_PLAN.md",
23
+ );
24
+ });
25
+
26
+ it("documents D1–D5 by ID, not just by name", () => {
27
+ expect(body).toContain("**D1**");
28
+ expect(body).toContain("**D2**");
29
+ expect(body).toContain("**D3**");
30
+ expect(body).toContain("**D4**");
31
+ expect(body).toContain("**D5**");
32
+ });
33
+
34
+ it("points at the post-cleanup --fix command rather than restating policy", () => {
35
+ expect(body).toContain("deco-post-cleanup --fix");
36
+ expect(body).toContain("deco-post-cleanup --strict");
37
+ });
38
+
39
+ it("does NOT restate the canonical rule body verbatim (pointer, not a copy)", () => {
40
+ // Length budget: pointer must stay short to discourage drift.
41
+ // The canonical rule in decocms/deco-start is ~110 lines / 4–5 KB;
42
+ // the pointer must be substantially smaller than a copy.
43
+ expect(body.length).toBeLessThan(3000);
44
+ });
45
+
46
+ it("is deterministic — same site name, same output", () => {
47
+ const a = generateMigrationPolicyPointerRule("foo");
48
+ const b = generateMigrationPolicyPointerRule("foo");
49
+ expect(a).toBe(b);
50
+ });
51
+
52
+ it("escapes nothing weird from siteName — siteName is used as a label only", () => {
53
+ // We don't sanitise; we trust the migration script to pass a real
54
+ // package name. But verify nothing surprising happens with hyphens
55
+ // (a common shape, e.g. "casaevideo-storefront").
56
+ const out = generateMigrationPolicyPointerRule("casaevideo-storefront");
57
+ expect(out).toContain("`casaevideo-storefront`");
58
+ });
59
+ });
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Cursor rule scaffolding for migrated sites.
3
+ *
4
+ * The canonical migration tooling policy (D1–D5, priorities, process)
5
+ * lives in `decocms/deco-start`. We don't duplicate it into every site
6
+ * — that would drift the moment the canonical changes. Instead the
7
+ * migration scaffolds a tiny pointer rule, marked `alwaysApply: true`,
8
+ * that loads on every agent session inside the migrated site and tells
9
+ * the agent where the real policy lives.
10
+ *
11
+ * Closes Wave 12-H from MIGRATION_TOOLING_PLAN.md.
12
+ */
13
+
14
+ /**
15
+ * Generate the contents of `.cursor/rules/migration-tooling-policy.mdc`
16
+ * for a freshly migrated site. Pure function: `siteName` is the only
17
+ * input that influences the body, and only as a friendly mention.
18
+ */
19
+ export function generateMigrationPolicyPointerRule(
20
+ siteName: string,
21
+ ): string {
22
+ return `---
23
+ description: Pointer to the canonical migration tooling policy (D1–D5, PR-only, etc.). Always loaded.
24
+ alwaysApply: true
25
+ ---
26
+
27
+ # Migration Tooling Policy — Pointer
28
+
29
+ > This site (\`${siteName}\`) was generated by the \`@decocms/start\`
30
+ > migration script. The canonical policy that governs how the migration
31
+ > tooling, framework (\`@decocms/start\`), and commerce layer
32
+ > (\`@decocms/apps\`) evolve lives **upstream**, not in this repo.
33
+
34
+ ## Where to read
35
+
36
+ - **Rule (always-applied) — full text:**
37
+ https://github.com/decocms/deco-start/blob/main/.cursor/rules/migration-tooling-policy.mdc
38
+ - **Plan (living tracker, decisions + waves):**
39
+ https://github.com/decocms/deco-start/blob/main/MIGRATION_TOOLING_PLAN.md
40
+ - **Migration skill (phase playbook):**
41
+ \`@decocms/start/.agents/skills/deco-to-tanstack-migration\`
42
+
43
+ ## What you need to know in this site
44
+
45
+ | ID | Decision | What it means here |
46
+ |----|----------|--------------------|
47
+ | **D1** | Force convergence — no fork runtime support | Site customisations live in \`src/apps/local/\` or open a PR to \`@decocms/apps\`. Don't wrap framework/commerce code in soft adapters. |
48
+ | **D2** | Rewrite HTMX on migration | If you find HTMX residue, rewrite to React. Don't bring back \`hx-*\` runtime. |
49
+ | **D3** | Generated stubs throw at runtime | If a \`~/lib/vtex-*\` import comes from a stub that returns \`null\` / \`{}\` / identity-cast, replace it. \`npx -p @decocms/start deco-post-cleanup --fix\` does the safe swaps automatically. |
50
+ | **D4** | Site-local apps by default, promote at 3+ sites | Don't try to upstream a pattern that has only shipped here. Build it twice in different sites first, then PR it to \`@decocms/apps\`. |
51
+ | **D5** | Failed migrations: \`rm -rf\` and re-run | No restart-mode magic. If the migration goes sideways, blow away the working tree and run again. |
52
+
53
+ ## How to find issues this rule wants you to fix
54
+
55
+ \`\`\`bash
56
+ npx -p @decocms/start deco-post-cleanup # audit only
57
+ npx -p @decocms/start deco-post-cleanup --fix # auto-fix the safe rules
58
+ npx -p @decocms/start deco-post-cleanup --strict # exit 1 on any finding (CI)
59
+ \`\`\`
60
+
61
+ ## Process
62
+
63
+ - **PR-only.** No direct pushes to \`main\`. Self-merge after green CI is fine.
64
+ - **Conventional commits** (\`feat\`, \`fix\`, \`chore\`, \`docs\`, \`refactor\`, \`test\`, \`perf\`).
65
+ - **CI must be green before merge.**
66
+ - When the canonical rule changes upstream, update this pointer if any
67
+ link or table heading goes stale. Keep it short — body content lives
68
+ upstream.
69
+ `;
70
+ }