@mars-stack/cli 7.0.2 → 7.0.4
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/README.md +13 -0
- package/package.json +1 -1
- package/template/AGENTS.md +20 -1
- package/template/README.md +30 -0
- package/template/docs/exec-plans/QA-dogfood-matrix.md +111 -0
- package/template/scripts/dogfood-matrix-contract.test.ts +45 -0
- package/template/src/__tests__/template-readme-contract.test.ts +21 -0
- package/template/vitest.config.ts +1 -1
package/README.md
CHANGED
|
@@ -36,6 +36,7 @@ mars create my-app
|
|
|
36
36
|
### `mars add feature <name>`
|
|
37
37
|
|
|
38
38
|
Generate a feature module at `src/features/<name>/` with:
|
|
39
|
+
|
|
39
40
|
- `server/index.ts` -- typed CRUD operations with `import 'server-only'`
|
|
40
41
|
- `types.ts` -- Zod validation schemas and TypeScript types
|
|
41
42
|
|
|
@@ -121,6 +122,18 @@ mars upgrade # upgrade to latest
|
|
|
121
122
|
mars upgrade --dry-run # preview what would change
|
|
122
123
|
```
|
|
123
124
|
|
|
125
|
+
### `mars template sync`
|
|
126
|
+
|
|
127
|
+
Copy upstream **template plumbing** (scripts, auth shell files, and other manifest-listed paths) from the CLI-bundled template into an **existing** Mars project. Requires `.mars/scaffold.json` at the project root (from `mars create`); exits with an error if missing.
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
mars template sync --dry-run # list planned changes, no writes
|
|
131
|
+
mars template sync # default: plumbing category only
|
|
132
|
+
mars template sync --only user-owned --force # overwrite user-owned paths too (backups under .mars/backups/)
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
**vs `mars upgrade`:** `mars upgrade` bumps Mars npm packages only — it does **not** re-copy template source files. Use `mars template sync` when a CLI release includes fixes to `ensure-db.mjs`, proxy, or other synced paths. See the Mars monorepo [scaffold-template-sync-upgrade](https://github.com/greaveselliott/mars/blob/main/docs/exec-plans/active/scaffold-template-sync-upgrade.md) exec plan for the safety model and path inventory.
|
|
136
|
+
|
|
124
137
|
### `mars telemetry <enable|disable>`
|
|
125
138
|
|
|
126
139
|
Opt in or out of anonymous usage analytics. Stored in `~/.marsrc`. Tracks command usage and feature selections only -- never project names, file contents, or env vars.
|
package/package.json
CHANGED
package/template/AGENTS.md
CHANGED
|
@@ -68,6 +68,7 @@ src/
|
|
|
68
68
|
## Config
|
|
69
69
|
|
|
70
70
|
`src/config/app.config.ts` is the single source of truth for:
|
|
71
|
+
|
|
71
72
|
- App identity (name, URL, support email)
|
|
72
73
|
- Feature flags (auth, admin, billing, notifications, etc.)
|
|
73
74
|
- Service providers (email, storage, database, payments, etc.)
|
|
@@ -91,18 +92,36 @@ yarn db:studio # Open Prisma Studio
|
|
|
91
92
|
|
|
92
93
|
**Email verification (local):** With console email, after register you land on `/verify` and use **“Click here to verify your email”** (no inbox needed). Set `AUTO_VERIFY_EMAIL=true` to skip that for **new** signups instead. `AUTO_VERIFY_EMAIL` applies when `yarn dev` runs or `APP_URL` points at `localhost` / `127.0.0.1`; ignored on Vercel production. Older accounts stay unverified until you use the link or Prisma Studio.
|
|
93
94
|
|
|
95
|
+
## Updating scaffold plumbing (`mars template sync`)
|
|
96
|
+
|
|
97
|
+
When you install a newer **`@mars-stack/cli`**, pull upstream template fixes into this repo with **`mars template sync`** from the project root (requires `.mars/scaffold.json` from `mars create`). If that file is missing, the CLI reports that the directory is not a Mars scaffold — you cannot sync a non-Mars project.
|
|
98
|
+
|
|
99
|
+
- **`mars template sync --dry-run`** — print the planned file operations; no writes.
|
|
100
|
+
- **Default** — sync **plumbing** paths from the bundled template manifest (scripts, shared shell, etc.).
|
|
101
|
+
- **`--force`** — also apply **user-owned** manifest entries; previous files are copied to **`.mars/backups/<timestamp>/`** before overwrite. Use when you deliberately want upstream versions of those paths.
|
|
102
|
+
- **`--only <category>`** — e.g. `plumbing` or `user-owned` (latter typically with `--force`).
|
|
103
|
+
|
|
104
|
+
Deep context: [scaffold-template-sync-upgrade](https://github.com/greaveselliott/mars/blob/main/docs/exec-plans/active/scaffold-template-sync-upgrade.md) in the Mars monorepo (path inventory and safety model). Skill for agents: [.cursor/skills/mars-upgrade-scaffold/](.cursor/skills/mars-upgrade-scaffold/).
|
|
105
|
+
|
|
106
|
+
**vs `mars upgrade`:** `mars upgrade` only bumps Mars **npm** packages and reinstalls — it does **not** re-copy template files. Use template sync when plumbing (e.g. `ensure-db.mjs`) changed in a CLI release.
|
|
107
|
+
|
|
94
108
|
## Working Discipline
|
|
95
109
|
|
|
96
110
|
1. **Commit after every step.** When executing a plan, commit after each completed task — not at the end. Version control is the progress log. Each commit message should reference the plan and step (e.g., `feat(billing): add Subscription model (billing-plan step 1.1)`).
|
|
97
111
|
2. **Document every executed plan.** All plans — whether they started in a chat, a Cursor plan file, or someone's head — must end up in `docs/exec-plans/completed/` with decisions, discoveries, and outcomes recorded. Use the `capture-conversation-context` skill.
|
|
98
112
|
3. **Feed conversations back.** Decisions, discoveries, and context that live only in chat threads are invisible to future agents. See [docs/design-docs/conversation-as-system-record.md](docs/design-docs/conversation-as-system-record.md).
|
|
99
113
|
|
|
114
|
+
## Dogfood QA
|
|
115
|
+
|
|
116
|
+
After **generator changes**, **template sync**, or before a **release**, run the manual checklist in **[docs/exec-plans/QA-dogfood-matrix.md](docs/exec-plans/QA-dogfood-matrix.md)** (happy path + edges × local / preview / prod smoke). Unchecked rows mean **not verified**. If a feature is off in `app.config.ts`, mark the row **N/A** instead of removing it.
|
|
117
|
+
|
|
100
118
|
## Pointers
|
|
101
119
|
|
|
120
|
+
- **Updating your app:** [README.md](README.md) — entry point; this section and `mars template sync` above.
|
|
102
121
|
- **Architecture details:** [docs/design-docs/](docs/design-docs/)
|
|
103
122
|
- **Core beliefs:** [docs/design-docs/core-beliefs.md](docs/design-docs/core-beliefs.md)
|
|
104
123
|
- **Conversation feedback:** [docs/design-docs/conversation-as-system-record.md](docs/design-docs/conversation-as-system-record.md)
|
|
105
|
-
- **Execution plans:** [docs/exec-plans/](docs/exec-plans/)
|
|
124
|
+
- **Execution plans:** [docs/exec-plans/](docs/exec-plans/) — includes [QA dogfood matrix](docs/exec-plans/QA-dogfood-matrix.md)
|
|
106
125
|
- **Quality scores:** [docs/QUALITY_SCORE.md](docs/QUALITY_SCORE.md)
|
|
107
126
|
- **Skills:** [.cursor/skills/](.cursor/skills/) — all skills use the `mars-` prefix (e.g., `mars-add-api-route/`, `mars-configure-email/`)
|
|
108
127
|
- **Rules:** [.cursor/rules/](.cursor/rules/) — all rules use the `mars-` prefix (e.g., `mars-security.mdc`, `mars-data-access.mdc`)
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Mars application template
|
|
2
|
+
|
|
3
|
+
This directory is the **Next.js app template** copied by `mars create` into a new project. In the Mars monorepo it is developed and tested here; published **`@mars-stack/cli`** bundles the same tree at release time.
|
|
4
|
+
|
|
5
|
+
## Updating your Mars app
|
|
6
|
+
|
|
7
|
+
After you upgrade **`@mars-stack/cli`** or want upstream fixes for scaffold **plumbing** (scripts, auth shell files, shared wiring listed in the sync manifest), run from your **project root**:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
mars template sync --dry-run # preview planned copies
|
|
11
|
+
mars template sync # apply (default: plumbing only)
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
**Requirements:** the project must be a Mars scaffold with **`.mars/scaffold.json`**. If that file is missing, the CLI exits with an error — this command does not apply to arbitrary Next.js repos.
|
|
15
|
+
|
|
16
|
+
**Flags:**
|
|
17
|
+
|
|
18
|
+
| Flag | Meaning |
|
|
19
|
+
| ------------------- | -------------------------------------------------------------------------------------------------------------- |
|
|
20
|
+
| `--dry-run` | Show what would change; no files written |
|
|
21
|
+
| `--force` | Also sync **user-owned** manifest paths; always backs up replaced files under **`.mars/backups/<timestamp>/`** |
|
|
22
|
+
| `--only <category>` | Limit to `plumbing` (default) or `user-owned` (usually with `--force`) |
|
|
23
|
+
|
|
24
|
+
**Safety:** Default sync overwrites **plumbing** files that the CLI owns (infrastructure). **User-owned** paths are skipped unless you pass **`--force`**, and overwrites are preceded by backups. Do not use `--force` on a dirty tree without reviewing `--dry-run` output.
|
|
25
|
+
|
|
26
|
+
**Not `mars upgrade`:** `mars upgrade` bumps **`@mars-stack/core`** and **`@mars-stack/ui`** in `package.json` and reinstalls — it does **not** copy template source files. Use **both** commands when you need new package versions **and** refreshed plumbing (e.g. `scripts/ensure-db.mjs`).
|
|
27
|
+
|
|
28
|
+
**Further reading (Mars monorepo):** [scaffold-template-sync-upgrade](https://github.com/greaveselliott/mars/blob/main/docs/exec-plans/active/scaffold-template-sync-upgrade.md) — full manifest, path inventory, and task history.
|
|
29
|
+
|
|
30
|
+
**Agents:** see [.cursor/skills/mars-upgrade-scaffold/](.cursor/skills/mars-upgrade-scaffold/) and [AGENTS.md](AGENTS.md).
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# Dogfood QA matrix (generated app)
|
|
2
|
+
|
|
3
|
+
Manual and automated verification that the **entire shipped surface** of this app behaves correctly end-to-end—including edge cases—in **local**, **preview**, and **production-class** environments.
|
|
4
|
+
|
|
5
|
+
**Source:** Mars monorepo [dogfood guard-rails plan](https://github.com/greaveselliott/mars/blob/main/docs/exec-plans/active/dogfood-guard-rails-generated-apps-p0.md). Update this file when you add or remove first-class features.
|
|
6
|
+
|
|
7
|
+
## How to use
|
|
8
|
+
|
|
9
|
+
1. Work **row by row**. Check the box only after the **happy path and listed edges** are exercised for that row in the given environment.
|
|
10
|
+
2. **Unchecked boxes mean “not verified”—not “passed”.** Do not infer green status from silence.
|
|
11
|
+
3. After each run, fill **Last run** with **date** (ISO `YYYY-MM-DD` is fine), **environment** (`local` / `preview` / `prod smoke`), and **commit** (short SHA or release tag you tested).
|
|
12
|
+
4. Run this matrix after **major generator or template upgrades**, before a **release**, or when changing **auth, CSRF, billing, or uploads**.
|
|
13
|
+
|
|
14
|
+
## Feature flags (`app.config.ts`)
|
|
15
|
+
|
|
16
|
+
- If a feature is **disabled** in `src/config/app.config.ts`, mark the row **N/A** in the notes column (feature not present) instead of deleting the row. If the feature is enabled but you are **skipping** verification temporarily, mark **Skip** with a short reason—still not a pass.
|
|
17
|
+
- If you **customized** Mars plumbing files, treat **user-owned** paths per `mars template sync` / upgrade docs before assuming failures are product bugs.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Matrix
|
|
22
|
+
|
|
23
|
+
### Auth
|
|
24
|
+
|
|
25
|
+
- [ ] **Verified**
|
|
26
|
+
- **Happy path + edges:** sign-in, sign-up, forgot/reset, verify email, session expiry, wrong password, locked account, already logged-in redirect to dashboard.
|
|
27
|
+
- **Local** — Date: _____________ Env: _____________ Commit: _____________
|
|
28
|
+
- **Preview** — Date: _____________ Env: _____________ Commit: _____________
|
|
29
|
+
- **Prod smoke** — Date: _____________ Env: _____________ Commit: _____________
|
|
30
|
+
- **Notes (N/A / Skip):**
|
|
31
|
+
|
|
32
|
+
### Protected shell
|
|
33
|
+
|
|
34
|
+
- [ ] **Verified**
|
|
35
|
+
- **Happy path + edges:** nav, search, notifications, command palette (⌘K), theme toggle, user menu, **logout** (cookie cleared, lands on expected page).
|
|
36
|
+
- **Local** — Date: _____________ Env: _____________ Commit: _____________
|
|
37
|
+
- **Preview** — Date: _____________ Env: _____________ Commit: _____________
|
|
38
|
+
- **Prod smoke** — Date: _____________ Env: _____________ Commit: _____________
|
|
39
|
+
- **Notes (N/A / Skip):**
|
|
40
|
+
|
|
41
|
+
### Onboarding
|
|
42
|
+
|
|
43
|
+
- [ ] **Verified**
|
|
44
|
+
- **Happy path + edges:** all steps, skip where allowed, **CSRF** on step POST, mobile stepper layout.
|
|
45
|
+
- **Local** — Date: _____________ Env: _____________ Commit: _____________
|
|
46
|
+
- **Preview** — Date: _____________ Env: _____________ Commit: _____________
|
|
47
|
+
- **Prod smoke** — Date: _____________ Env: _____________ Commit: _____________
|
|
48
|
+
- **Notes (N/A / Skip):**
|
|
49
|
+
|
|
50
|
+
### Settings
|
|
51
|
+
|
|
52
|
+
- [ ] **Verified**
|
|
53
|
+
- **Happy path + edges:** display name, password change, **session list** (copy vs multi-row behaviour), revoke one / revoke all.
|
|
54
|
+
- **Local** — Date: _____________ Env: _____________ Commit: _____________
|
|
55
|
+
- **Preview** — Date: _____________ Env: _____________ Commit: _____________
|
|
56
|
+
- **Prod smoke** — Date: _____________ Env: _____________ Commit: _____________
|
|
57
|
+
- **Notes (N/A / Skip):**
|
|
58
|
+
|
|
59
|
+
### Billing / pricing
|
|
60
|
+
|
|
61
|
+
- [ ] **Verified**
|
|
62
|
+
- **Happy path + edges:** checkout/portal where Stripe enabled; gated UI when disabled.
|
|
63
|
+
- **Local** — Date: _____________ Env: _____________ Commit: _____________
|
|
64
|
+
- **Preview** — Date: _____________ Env: _____________ Commit: _____________
|
|
65
|
+
- **Prod smoke** — Date: _____________ Env: _____________ Commit: _____________
|
|
66
|
+
- **Notes (N/A / Skip):**
|
|
67
|
+
|
|
68
|
+
### Files
|
|
69
|
+
|
|
70
|
+
- [ ] **Verified**
|
|
71
|
+
- **Happy path + edges:** upload (XHR + **CSRF**), list, download, delete (**CSRF**), size limit error.
|
|
72
|
+
- **Local** — Date: _____________ Env: _____________ Commit: _____________
|
|
73
|
+
- **Preview** — Date: _____________ Env: _____________ Commit: _____________
|
|
74
|
+
- **Prod smoke** — Date: _____________ Env: _____________ Commit: _____________
|
|
75
|
+
- **Notes (N/A / Skip):**
|
|
76
|
+
|
|
77
|
+
### AI
|
|
78
|
+
|
|
79
|
+
- [ ] **Verified**
|
|
80
|
+
- **Happy path + edges:** chat send, stream, **CSRF**, provider-none vs configured behaviour.
|
|
81
|
+
- **Local** — Date: _____________ Env: _____________ Commit: _____________
|
|
82
|
+
- **Preview** — Date: _____________ Env: _____________ Commit: _____________
|
|
83
|
+
- **Prod smoke** — Date: _____________ Env: _____________ Commit: _____________
|
|
84
|
+
- **Notes (N/A / Skip):**
|
|
85
|
+
|
|
86
|
+
### Admin
|
|
87
|
+
|
|
88
|
+
- [ ] **Verified**
|
|
89
|
+
- **Happy path + edges:** users list, forbidden for non-admin.
|
|
90
|
+
- **Local** — Date: _____________ Env: _____________ Commit: _____________
|
|
91
|
+
- **Preview** — Date: _____________ Env: _____________ Commit: _____________
|
|
92
|
+
- **Prod smoke** — Date: _____________ Env: _____________ Commit: _____________
|
|
93
|
+
- **Notes (N/A / Skip):**
|
|
94
|
+
|
|
95
|
+
### Blog, dashboard, landing, coming-soon, legal, cookie consent
|
|
96
|
+
|
|
97
|
+
- [ ] **Verified**
|
|
98
|
+
- **Happy path + edges:** load + critical interaction for blog, files page, dashboard cards, landing, coming-soon, legal pages, cookie consent as applicable.
|
|
99
|
+
- **Local** — Date: _____________ Env: _____________ Commit: _____________
|
|
100
|
+
- **Preview** — Date: _____________ Env: _____________ Commit: _____________
|
|
101
|
+
- **Prod smoke** — Date: _____________ Env: _____________ Commit: _____________
|
|
102
|
+
- **Notes (N/A / Skip):**
|
|
103
|
+
|
|
104
|
+
### Edge cases (cross-cutting)
|
|
105
|
+
|
|
106
|
+
- [ ] **Verified**
|
|
107
|
+
- **Happy path + edges:** **403 CSRF** surfaces clear message (not `SyntaxError`), **mobile ~375px**, **dark mode**, **slow network** / abort, **two tabs** same user.
|
|
108
|
+
- **Local** — Date: _____________ Env: _____________ Commit: _____________
|
|
109
|
+
- **Preview** — Date: _____________ Env: _____________ Commit: _____________
|
|
110
|
+
- **Prod smoke** — Date: _____________ Env: _____________ Commit: _____________
|
|
111
|
+
- **Notes (N/A / Skip):**
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { dirname, join } from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import { describe, expect, it } from 'vitest';
|
|
5
|
+
|
|
6
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
const matrixPath = join(__dirname, '../docs/exec-plans/QA-dogfood-matrix.md');
|
|
8
|
+
|
|
9
|
+
/** Minimum feature slices from docs/exec-plans/active/dogfood-guard-rails-generated-apps-p0.md */
|
|
10
|
+
const REQUIRED_SECTION_TITLES = [
|
|
11
|
+
'Auth',
|
|
12
|
+
'Protected shell',
|
|
13
|
+
'Onboarding',
|
|
14
|
+
'Settings',
|
|
15
|
+
'Billing / pricing',
|
|
16
|
+
'Files',
|
|
17
|
+
'AI',
|
|
18
|
+
'Admin',
|
|
19
|
+
'Blog, dashboard, landing, coming-soon, legal, cookie consent',
|
|
20
|
+
'Edge cases (cross-cutting)',
|
|
21
|
+
] as const;
|
|
22
|
+
|
|
23
|
+
describe('QA dogfood matrix contract', () => {
|
|
24
|
+
const content = readFileSync(matrixPath, 'utf8');
|
|
25
|
+
|
|
26
|
+
it('exists and documents last-run fields per environment', () => {
|
|
27
|
+
expect(content).toContain('**Local**');
|
|
28
|
+
expect(content).toContain('**Preview**');
|
|
29
|
+
expect(content).toContain('**Prod smoke**');
|
|
30
|
+
expect(content).toMatch(/Date:\s+_+.*Commit:/s);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('states that unchecked rows are not verified', () => {
|
|
34
|
+
expect(content).toMatch(/not verified|Not verified/i);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('documents N/A vs Skip for disabled or deferred features', () => {
|
|
38
|
+
expect(content).toMatch(/N\/A|Skip/);
|
|
39
|
+
expect(content).toMatch(/app\.config\.ts/);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it.each(REQUIRED_SECTION_TITLES)('includes matrix section: %s', (title) => {
|
|
43
|
+
expect(content).toContain(`### ${title}`);
|
|
44
|
+
});
|
|
45
|
+
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { dirname, join } from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import { describe, expect, it } from 'vitest';
|
|
5
|
+
|
|
6
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
const readmePath = join(__dirname, '../../README.md');
|
|
8
|
+
|
|
9
|
+
/** MARS-046: user-facing template sync docs stay discoverable in copied scaffolds */
|
|
10
|
+
describe('template README (mars template sync)', () => {
|
|
11
|
+
const content = readFileSync(readmePath, 'utf8');
|
|
12
|
+
|
|
13
|
+
it('documents dry-run, force, scaffold fingerprint, backups, and upgrade distinction', () => {
|
|
14
|
+
expect(content).toMatch(/`--dry-run`/);
|
|
15
|
+
expect(content).toMatch(/`--force`/);
|
|
16
|
+
expect(content).toMatch(/\.mars\/scaffold\.json/);
|
|
17
|
+
expect(content).toMatch(/\.mars\/backups/);
|
|
18
|
+
expect(content).toMatch(/`mars upgrade`/);
|
|
19
|
+
expect(content).toMatch(/mars template sync/);
|
|
20
|
+
});
|
|
21
|
+
});
|
|
@@ -8,7 +8,7 @@ export default defineConfig({
|
|
|
8
8
|
environment: 'jsdom',
|
|
9
9
|
globals: true,
|
|
10
10
|
setupFiles: ['./vitest.setup.ts'],
|
|
11
|
-
include: ['src/**/*.test.{ts,tsx}'],
|
|
11
|
+
include: ['src/**/*.test.{ts,tsx}', 'scripts/**/*.test.ts'],
|
|
12
12
|
passWithNoTests: true,
|
|
13
13
|
coverage: {
|
|
14
14
|
provider: 'v8',
|