create-minlang-app 0.1.0 → 0.2.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/bin.mjs +29 -8
- package/package.json +1 -1
- package/template/AGENTS.md +60 -0
- package/template/CLAUDE.md +3 -0
- package/template/Makefile +1 -0
- package/template/README.md +7 -3
- package/template/app/app/screens/[screen]/page.tsx +17 -0
- package/template/app/package.json +12 -6
- package/template/app/tsconfig.typecheck.json +4 -0
- package/template/github/workflows/deploy-vercel.yml +12 -53
- package/template/app/app/screens/board/page.tsx +0 -5
- package/template/app/app/screens/projects/page.tsx +0 -5
package/bin.mjs
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
// published @minlang/* runtime packages. Compile with ml1 (see the printed
|
|
5
5
|
// next steps), run with pnpm, deploy via the included Vercel workflow.
|
|
6
6
|
|
|
7
|
-
import { cpSync, mkdirSync, readdirSync, readFileSync, renameSync, statSync, writeFileSync } from "node:fs";
|
|
7
|
+
import { cpSync, existsSync, mkdirSync, readdirSync, readFileSync, renameSync, statSync, writeFileSync } from "node:fs";
|
|
8
8
|
import { dirname, join } from "node:path";
|
|
9
9
|
import { fileURLToPath } from "node:url";
|
|
10
10
|
|
|
@@ -39,20 +39,41 @@ renameSync(join(dest, "__APP_NAME__.ml"), join(dest, `${name}.ml`));
|
|
|
39
39
|
renameSync(join(dest, "gitignore"), join(dest, ".gitignore"));
|
|
40
40
|
renameSync(join(dest, "github"), join(dest, ".github"));
|
|
41
41
|
|
|
42
|
+
// .github/ only works at the repository root: warn when the scaffold is
|
|
43
|
+
// nested inside an existing git repo, where the deploy workflow would be dead.
|
|
44
|
+
const enclosingGitRoot = (start) => {
|
|
45
|
+
for (let dir = start; ; dir = dirname(dir)) {
|
|
46
|
+
if (existsSync(join(dir, ".git"))) return dir;
|
|
47
|
+
if (dirname(dir) === dir) return null;
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
const gitRoot = enclosingGitRoot(dirname(dest));
|
|
51
|
+
|
|
42
52
|
console.log(`
|
|
43
53
|
Created ${name}/ — a MinLang web app.
|
|
44
54
|
|
|
45
55
|
Next steps:
|
|
46
56
|
cd ${name}
|
|
47
|
-
# 1. install the ml1 compiler
|
|
48
|
-
#
|
|
49
|
-
#
|
|
50
|
-
# 2.
|
|
57
|
+
# 1. install the ml1 compiler:
|
|
58
|
+
# bash <(curl -fsSL https://raw.githubusercontent.com/codeshift-ai-solutions/minlang-releases/main/install/install.sh)
|
|
59
|
+
# (Windows: iwr -useb https://raw.githubusercontent.com/codeshift-ai-solutions/minlang-releases/main/install/install.ps1 | iex)
|
|
60
|
+
# 2. one-time toolchain setup:
|
|
61
|
+
corepack enable && corepack prepare pnpm@10.33.0 --activate
|
|
62
|
+
# 3. compile, install, run:
|
|
51
63
|
make compile
|
|
52
64
|
pnpm --dir app install
|
|
53
|
-
|
|
65
|
+
make dev # http://localhost:3111
|
|
54
66
|
|
|
55
67
|
Your whole app lives in ${name}.ml (it starts as a task tracker — replace it).
|
|
56
|
-
|
|
57
|
-
|
|
68
|
+
Agent instructions: ${name}/AGENTS.md
|
|
69
|
+
Language rules: https://github.com/codeshift-ai-solutions/minlang-releases/releases/latest/download/minlang-language-bundle.md
|
|
70
|
+
Deploys: push to GitHub with org secrets VERCEL_TOKEN/VERCEL_ORG_ID set;
|
|
71
|
+
the first deploy prints a VERCEL_PROJECT_ID to pin as a repo secret.
|
|
58
72
|
`);
|
|
73
|
+
|
|
74
|
+
if (gitRoot) {
|
|
75
|
+
console.warn(`warning: ${name}/ is nested inside the git repository at ${gitRoot}.
|
|
76
|
+
GitHub only runs workflows from the repository root, so ${name}/.github/ would
|
|
77
|
+
be ignored. Either create the app in its own repository (recommended) or move
|
|
78
|
+
${name}/.github/workflows/* to ${gitRoot}/.github/workflows/ and adjust paths.`);
|
|
79
|
+
}
|
package/package.json
CHANGED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Agent instructions for __APP_NAME__
|
|
2
|
+
|
|
3
|
+
This is a **MinLang** app. The entire application is `__APP_NAME__.ml` —
|
|
4
|
+
entities, constraints, actions, queries, screens, and tests in one file.
|
|
5
|
+
Everything under `app/generated/` is compiler output: committed, **never
|
|
6
|
+
hand-edited**. The `app/` directory is a thin Next.js shell over the
|
|
7
|
+
published `@minlang/*` runtime packages; it rarely needs changes.
|
|
8
|
+
|
|
9
|
+
## The one rule
|
|
10
|
+
|
|
11
|
+
To change behavior, edit `__APP_NAME__.ml`, then run `make compile`.
|
|
12
|
+
Never edit files under `app/generated/` — CI recompiles with `--check`
|
|
13
|
+
and fails the build if they drift from the `.ml` source.
|
|
14
|
+
|
|
15
|
+
## Language authority (fetch before writing MinLang)
|
|
16
|
+
|
|
17
|
+
Download the single-file language bundle and read it before producing or
|
|
18
|
+
modifying any MinLang source:
|
|
19
|
+
|
|
20
|
+
https://github.com/codeshift-ai-solutions/minlang-releases/releases/latest/download/minlang-language-bundle.md
|
|
21
|
+
|
|
22
|
+
It contains the canonical rules (Creator + Gatekeeper packets), the
|
|
23
|
+
detector list, and the end-to-end web-app authoring guide. Highlights:
|
|
24
|
+
- Forbidden everywhere: `now()`, `today()`, `random()`, `current_user`
|
|
25
|
+
(runtime inputs are injected: `created_at`, `current_time`, `actor_id`,
|
|
26
|
+
`rng_draw`, `request_id`).
|
|
27
|
+
- Generate -> validate -> fix -> revalidate until zero violations, then
|
|
28
|
+
output. `ml1 validate` is the same gate CI runs.
|
|
29
|
+
|
|
30
|
+
## Commands
|
|
31
|
+
|
|
32
|
+
| Task | Command |
|
|
33
|
+
|------|---------|
|
|
34
|
+
| One-time setup | `corepack enable && corepack prepare pnpm@10.33.0 --activate` |
|
|
35
|
+
| Validate the program | `make validate` |
|
|
36
|
+
| Compile to `app/generated/` | `make compile` |
|
|
37
|
+
| Install shell deps | `pnpm --dir app install` |
|
|
38
|
+
| Unit + generated test triads | `make test` |
|
|
39
|
+
| Dev server (http://localhost:3111) | `make dev` |
|
|
40
|
+
| Production build | `make build` |
|
|
41
|
+
| Browser tests (a11y, perf) | `make test-e2e` (installs the browser on first run) |
|
|
42
|
+
|
|
43
|
+
`make compile` requires the `ml1` compiler on PATH — install per README.
|
|
44
|
+
If `pnpm typecheck` complains about routes you deleted, remove the stale
|
|
45
|
+
Next cache: `rm -rf app/.next`.
|
|
46
|
+
|
|
47
|
+
## Workflow for every change
|
|
48
|
+
|
|
49
|
+
1. Edit `__APP_NAME__.ml`.
|
|
50
|
+
2. `make compile` (validates first; fails on any violation).
|
|
51
|
+
3. `make test`.
|
|
52
|
+
4. Commit the `.ml` file **and** `app/generated/` together.
|
|
53
|
+
|
|
54
|
+
## Shell rules (everything outside the .ml and app/generated/)
|
|
55
|
+
|
|
56
|
+
The shell is wiring and presentation only. Never put domain logic,
|
|
57
|
+
user-facing copy, or input validation in shell code — they belong in
|
|
58
|
+
`__APP_NAME__.ml`, where the validator and generated tests cover them.
|
|
59
|
+
Screens route through the single dynamic page
|
|
60
|
+
`app/app/screens/[screen]/page.tsx`; do not create per-screen folders.
|
package/template/Makefile
CHANGED
package/template/README.md
CHANGED
|
@@ -5,11 +5,15 @@ A MinLang web app. The whole application lives in `__APP_NAME__.ml`;
|
|
|
5
5
|
the thin Next.js shell consuming the published `@minlang/*` runtime.
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
+
corepack enable && corepack prepare pnpm@10.33.0 --activate
|
|
8
9
|
make compile # __APP_NAME__.ml -> app/generated/ (needs ml1 on PATH)
|
|
9
10
|
pnpm --dir app install
|
|
10
|
-
|
|
11
|
+
make dev # http://localhost:3111
|
|
11
12
|
make test # generated test triads + integration
|
|
12
13
|
```
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
https://
|
|
15
|
+
Install ml1:
|
|
16
|
+
`bash <(curl -fsSL https://raw.githubusercontent.com/codeshift-ai-solutions/minlang-releases/main/install/install.sh)`
|
|
17
|
+
|
|
18
|
+
Language rules + authoring guide (single file, for you and your coding agent):
|
|
19
|
+
https://github.com/codeshift-ai-solutions/minlang-releases/releases/latest/download/minlang-language-bundle.md
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// Thin dynamic route over the generated screens — wrapper pages never go
|
|
2
|
+
// stale when the screen set changes. Unknown keys 404.
|
|
3
|
+
// Segment config must live in the page file itself for Next to see it.
|
|
4
|
+
export const dynamic = "force-dynamic";
|
|
5
|
+
|
|
6
|
+
import type { ReactElement } from "react";
|
|
7
|
+
import { notFound } from "next/navigation";
|
|
8
|
+
import { AppScreen } from "../../../generated/app/screen";
|
|
9
|
+
import { screenSchemas } from "../../../generated/ui/screens";
|
|
10
|
+
|
|
11
|
+
export default async function Page(props: {
|
|
12
|
+
params: Promise<{ screen: string }>;
|
|
13
|
+
}): Promise<ReactElement> {
|
|
14
|
+
const { screen } = await props.params;
|
|
15
|
+
if (!screenSchemas.some((s) => s.key === screen)) notFound();
|
|
16
|
+
return AppScreen({ screenKey: screen });
|
|
17
|
+
}
|
|
@@ -2,17 +2,17 @@
|
|
|
2
2
|
"name": "__APP_NAME__-web",
|
|
3
3
|
"private": true,
|
|
4
4
|
"scripts": {
|
|
5
|
-
"dev": "next dev",
|
|
5
|
+
"dev": "next dev --port 3111",
|
|
6
6
|
"build": "next build",
|
|
7
7
|
"start": "next start --port 3111",
|
|
8
|
-
"typecheck": "tsc -p tsconfig.json",
|
|
8
|
+
"typecheck": "tsc -p tsconfig.typecheck.json",
|
|
9
9
|
"test": "vitest run",
|
|
10
10
|
"test:e2e": "next build && playwright test"
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@minlang/design-system": "^0.
|
|
14
|
-
"@minlang/runtime-web": "^0.
|
|
15
|
-
"@minlang/tailwind-preset": "^0.
|
|
13
|
+
"@minlang/design-system": "^0.2.0",
|
|
14
|
+
"@minlang/runtime-web": "^0.2.0",
|
|
15
|
+
"@minlang/tailwind-preset": "^0.2.0",
|
|
16
16
|
"next": "15.5.19",
|
|
17
17
|
"react": "19.2.7",
|
|
18
18
|
"react-dom": "19.2.7",
|
|
@@ -31,5 +31,11 @@
|
|
|
31
31
|
"typescript": "5.6.3",
|
|
32
32
|
"vitest": "3.2.6"
|
|
33
33
|
},
|
|
34
|
-
"packageManager": "pnpm@10.33.0"
|
|
34
|
+
"packageManager": "pnpm@10.33.0",
|
|
35
|
+
"pnpm": {
|
|
36
|
+
"onlyBuiltDependencies": [
|
|
37
|
+
"esbuild",
|
|
38
|
+
"sharp"
|
|
39
|
+
]
|
|
40
|
+
}
|
|
35
41
|
}
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
# Verifies the committed generated output matches the .ml source
|
|
2
|
-
#
|
|
3
|
-
#
|
|
4
|
-
#
|
|
5
|
-
#
|
|
1
|
+
# Verifies the committed generated output matches the .ml source, tests,
|
|
2
|
+
# builds, and deploys prebuilt to Vercel. All logic lives in the public
|
|
3
|
+
# reusable workflow (minlang-releases) — this file just calls it.
|
|
4
|
+
#
|
|
5
|
+
# Secrets (skips with a notice when absent):
|
|
6
|
+
# VERCEL_TOKEN + VERCEL_ORG_ID — org-level, set once for the whole org
|
|
7
|
+
# VERCEL_PROJECT_ID — per-repo; the first run links by name, prints the
|
|
8
|
+
# project id, and tells you to pin it as this secret
|
|
6
9
|
|
|
7
10
|
name: Deploy (Vercel)
|
|
8
11
|
|
|
@@ -17,51 +20,7 @@ concurrency:
|
|
|
17
20
|
|
|
18
21
|
jobs:
|
|
19
22
|
deploy:
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
steps:
|
|
25
|
-
- uses: actions/checkout@v4
|
|
26
|
-
|
|
27
|
-
- name: Generated output is current
|
|
28
|
-
uses: codeshift-ai-solutions/minlang-core/.github/actions/minlang-compile@main
|
|
29
|
-
with:
|
|
30
|
-
file: __APP_NAME__.ml
|
|
31
|
-
target: web
|
|
32
|
-
out: app
|
|
33
|
-
check: "true"
|
|
34
|
-
|
|
35
|
-
- name: Setup Node + pnpm
|
|
36
|
-
uses: actions/setup-node@v4
|
|
37
|
-
with:
|
|
38
|
-
node-version: 22
|
|
39
|
-
- run: corepack enable
|
|
40
|
-
|
|
41
|
-
- name: Install, typecheck, test
|
|
42
|
-
working-directory: app
|
|
43
|
-
run: |
|
|
44
|
-
pnpm install --frozen-lockfile
|
|
45
|
-
pnpm run typecheck
|
|
46
|
-
pnpm run test
|
|
47
|
-
|
|
48
|
-
- name: Gate on Vercel secrets
|
|
49
|
-
id: gate
|
|
50
|
-
run: |
|
|
51
|
-
if [ -z "${VERCEL_TOKEN}" ] || [ -z "${VERCEL_ORG_ID}" ]; then
|
|
52
|
-
echo "notice: VERCEL_TOKEN / VERCEL_ORG_ID not set — skipping deploy"
|
|
53
|
-
echo "enabled=false" >> "$GITHUB_OUTPUT"
|
|
54
|
-
else
|
|
55
|
-
echo "enabled=true" >> "$GITHUB_OUTPUT"
|
|
56
|
-
fi
|
|
57
|
-
|
|
58
|
-
- name: Link, build, deploy
|
|
59
|
-
if: steps.gate.outputs.enabled == 'true'
|
|
60
|
-
working-directory: app
|
|
61
|
-
run: |
|
|
62
|
-
pnpm dlx vercel@latest link --yes \
|
|
63
|
-
--project "${{ github.event.repository.name }}" --token "${VERCEL_TOKEN}"
|
|
64
|
-
pnpm dlx vercel@latest pull --yes --environment=production --token "${VERCEL_TOKEN}"
|
|
65
|
-
pnpm dlx vercel@latest build --prod --token "${VERCEL_TOKEN}"
|
|
66
|
-
url=$(pnpm dlx vercel@latest deploy --prebuilt --prod --yes --token "${VERCEL_TOKEN}")
|
|
67
|
-
echo "deployed: $url" | tee -a "$GITHUB_STEP_SUMMARY"
|
|
23
|
+
uses: codeshift-ai-solutions/minlang-releases/.github/workflows/deploy-vercel.yml@main
|
|
24
|
+
with:
|
|
25
|
+
file: __APP_NAME__.ml
|
|
26
|
+
secrets: inherit
|