create-jant 0.3.40 → 0.3.43

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 (56) hide show
  1. package/README.md +49 -62
  2. package/dist/index.js +19 -1
  3. package/package.json +4 -4
  4. package/template/.agents/skills/building-jant-site/SKILL.md +101 -0
  5. package/template/.agents/skills/jant-http-api/SKILL.md +195 -0
  6. package/template/.agents/skills/jant-site-ops/SKILL.md +88 -0
  7. package/template/AGENTS.md +65 -0
  8. package/template/README.md +86 -161
  9. package/template/examples/agent-content-automation/README.md +92 -0
  10. package/template/examples/agent-content-automation/note.json +7 -0
  11. package/template/examples/agent-content-automation/quote.json +9 -0
  12. package/template/examples/agent-content-automation/site-settings.json +5 -0
  13. package/template/package.json +1 -1
  14. package/template/wrangler.toml +1 -1
  15. package/template/docs/internal/migrate.md +0 -10
  16. package/template/docs/internal/operations.md +0 -61
  17. package/template/static-site-export/README.md +0 -70
  18. package/template/static-site-export/config.toml +0 -16
  19. package/template/static-site-export/content/41q27/index.md +0 -29
  20. package/template/static-site-export/content/_index.md +0 -4
  21. package/template/static-site-export/content/a-night-heron-field-guide-for-my-walk-folder/index.md +0 -16
  22. package/template/static-site-export/content/a-quiet-saturday-after-a-busy-week/index.md +0 -23
  23. package/template/static-site-export/content/are-na-is-the-only-bookmark-pile-i-still-revisit/index.md +0 -16
  24. package/template/static-site-export/content/bought-too-many-lemons-again/index.md +0 -15
  25. package/template/static-site-export/content/current-tea-rotation/index.md +0 -20
  26. package/template/static-site-export/content/derek-sivers-still-writes-the-kind-of-internet-i-want-more-of/index.md +0 -16
  27. package/template/static-site-export/content/desk-but-better/index.md +0 -16
  28. package/template/static-site-export/content/e0kcg/index.md +0 -12
  29. package/template/static-site-export/content/from-basho/index.md +0 -15
  30. package/template/static-site-export/content/from-epictetus/index.md +0 -15
  31. package/template/static-site-export/content/from-marcus-aurelius/index.md +0 -15
  32. package/template/static-site-export/content/from-seneca/index.md +0 -15
  33. package/template/static-site-export/content/from-thoreau/index.md +0 -15
  34. package/template/static-site-export/content/gkbvv/index.md +0 -28
  35. package/template/static-site-export/content/k5vh8/index.md +0 -29
  36. package/template/static-site-export/content/mynoise-for-rainy-afternoons/index.md +0 -16
  37. package/template/static-site-export/content/nts-archives-are-good-cleaning-music/index.md +0 -16
  38. package/template/static-site-export/content/qgfcu/index.md +0 -29
  39. package/template/static-site-export/content/rain-makes-my-neighborhood-look-better/index.md +0 -17
  40. package/template/static-site-export/content/serious-eats-on-tomato-and-egg-soup/index.md +0 -16
  41. package/template/static-site-export/content/te812/index.md +0 -29
  42. package/template/static-site-export/content/telk3/index.md +0 -29
  43. package/template/static-site-export/content/the-five-minute-reset-is-still-the-best-habit-i-have/index.md +0 -21
  44. package/template/static-site-export/content/the-hallway-light-took-12-minutes-and-3-months/index.md +0 -18
  45. package/template/static-site-export/content/the-recurse-center-manual-is-weirdly-calming/index.md +0 -16
  46. package/template/static-site-export/content/u08bn/index.md +0 -29
  47. package/template/static-site-export/content/what-i-actually-use-my-notebook-for/index.md +0 -23
  48. package/template/static-site-export/content/z4s9v/index.md +0 -29
  49. package/template/static-site-export/static/style.css +0 -338
  50. package/template/static-site-export/templates/base.html +0 -23
  51. package/template/static-site-export/templates/index.html +0 -20
  52. package/template/static-site-export/templates/macros.html +0 -58
  53. package/template/static-site-export/templates/page.html +0 -8
  54. package/template/static-site-export/templates/section.html +0 -17
  55. package/template/static-site-export/templates/taxonomy_list.html +0 -15
  56. package/template/static-site-export/templates/taxonomy_single.html +0 -13
package/README.md CHANGED
@@ -1,89 +1,76 @@
1
- # Create Jant
1
+ # create-jant
2
2
 
3
- Bookstrap a new [Jant](https://github.com/jant-me/jant) project.
3
+ Scaffold a new [Jant](https://github.com/jant-me/jant) site for Cloudflare Workers.
4
4
 
5
5
  ## Usage
6
6
 
7
7
  ```bash
8
- # Using npm
9
- npm create jant my-blog
8
+ # npm
9
+ npm create jant@latest my-site
10
10
 
11
- # Using pnpm
12
- pnpm create jant my-blog
11
+ # pnpm
12
+ pnpm create jant@latest my-site
13
13
 
14
- # Using yarn
15
- yarn create jant my-blog
14
+ # yarn
15
+ yarn create jant my-site
16
16
 
17
- # Interactive mode (prompts for project name)
18
- npm create jant
17
+ # interactive mode
18
+ npm create jant@latest
19
19
  ```
20
20
 
21
- ## What's Included
21
+ ## What It Does
22
22
 
23
- The scaffolded project includes:
23
+ The scaffold:
24
24
 
25
- - **Hono** - Fast, lightweight web framework
26
- - **Cloudflare Workers** - Serverless edge runtime
27
- - **D1** - SQLite database at the edge
28
- - **R2** - Object storage for media
29
- - **Drizzle ORM** - Type-safe database access
30
- - **Tailwind CSS v4** - Utility-first CSS framework
31
- - **BaseCoat** - UI component library
32
- - **Lingui** - Internationalization (i18n)
33
- - **better-auth** - Authentication
34
- - **Vite** - Fast build tool with HMR
25
+ - creates a Cloudflare Workers project wired for Jant
26
+ - generates a local `.dev.vars` file with a secure `AUTH_SECRET`
27
+ - installs dependencies by default
28
+ - initializes a git repository by default
29
+ - can switch the storage template to S3-compatible storage with `--s3`
35
30
 
36
- ## Getting Started
31
+ ## Options
37
32
 
38
- After creating your project:
33
+ ```bash
34
+ create-jant [project-name] [options]
35
+
36
+ --s3 Use S3-compatible storage instead of Cloudflare R2
37
+ --no-install Skip dependency installation
38
+ --no-git Skip git initialization
39
+ -y, --yes Skip prompts and use defaults
40
+ ```
41
+
42
+ ## After Scaffolding
39
43
 
40
44
  ```bash
41
45
  cd my-site
42
- pnpm install
43
- cp .dev.vars.example .dev.vars
44
- # Edit .dev.vars with your AUTH_SECRET (32+ characters)
45
- pnpm dev
46
+ npm run dev
46
47
  ```
47
48
 
48
- Visit http://localhost:3000 to see your site.
49
-
50
- Need another local port? Run `PORT=3030 pnpm dev`.
49
+ Open `http://localhost:3000`.
51
50
 
52
- ## Project Structure
51
+ Need another local port?
53
52
 
54
- ```
55
- my-site/
56
- ├── src/
57
- │ ├── index.ts # Entry point
58
- │ ├── app.tsx # Hono app factory
59
- │ ├── types.ts # TypeScript types
60
- │ ├── db/ # Database schema & migrations
61
- │ ├── services/ # Business logic
62
- │ ├── routes/ # Route handlers
63
- │ ├── theme/ # UI components & layouts
64
- │ ├── lib/ # Utilities
65
- │ ├── i18n/ # Internationalization
66
- │ └── middleware/ # Hono middleware
67
- ├── static/ # Static assets
68
- ├── vite.config.ts # Vite configuration
69
- ├── wrangler.toml # Cloudflare Workers config
70
- └── drizzle.config.ts # Drizzle ORM config
53
+ ```bash
54
+ PORT=3030 npm run dev
71
55
  ```
72
56
 
73
- ## Scripts
57
+ ## What the New Project Includes
74
58
 
75
- ```bash
76
- pnpm dev # Start dev server (http://localhost:3000)
77
- pnpm build # Build for production
78
- pnpm run deploy # Apply migrations/backfills and deploy to Cloudflare Workers
79
- pnpm typecheck # Run TypeScript checks
80
- pnpm lint # Run ESLint
81
- pnpm format # Format code with Prettier
82
- pnpm db:generate # Generate Drizzle migrations
83
- pnpm exec jant migrate --local # Apply schema migrations + data backfills (local)
84
- pnpm exec jant migrate --remote # Apply schema migrations + data backfills (production)
85
- pnpm i18n:build # Extract + compile translations
86
- ```
59
+ - Cloudflare Workers runtime
60
+ - D1 for the database
61
+ - R2 for media by default
62
+ - Drizzle ORM
63
+ - better-auth
64
+ - Tailwind CSS v4 and BaseCoat
65
+ - Lingui for localization
66
+ - Jant's CLI commands through the local `jant` binary
67
+
68
+ ## Documentation
69
+
70
+ - [Getting Started](https://github.com/jant-me/jant/blob/main/docs/getting-started.md)
71
+ - [Deploy on Cloudflare](https://github.com/jant-me/jant/blob/main/docs/deployment.md)
72
+ - [Configuration](https://github.com/jant-me/jant/blob/main/docs/configuration.md)
73
+ - [Theming](https://github.com/jant-me/jant/blob/main/docs/theming.md)
87
74
 
88
75
  ## License
89
76
 
package/dist/index.js CHANGED
@@ -9,7 +9,7 @@ import path from "path";
9
9
  import { fileURLToPath } from "url";
10
10
  var __filename = fileURLToPath(import.meta.url);
11
11
  var __dirname = path.dirname(__filename);
12
- var CORE_VERSION = "0.3.40";
12
+ var CORE_VERSION = "0.3.43";
13
13
  var WRANGLER_VERSION = "^4.76.0";
14
14
  var TEMPLATE_DIR = fs.existsSync(path.resolve(__dirname, "../template")) ? path.resolve(__dirname, "../template") : path.resolve(__dirname, "../../../sites/demo");
15
15
  function isValidProjectName(name) {
@@ -91,9 +91,15 @@ async function copyTemplate(config) {
91
91
  await fs.copy(TEMPLATE_DIR, targetDir, {
92
92
  filter: (src) => {
93
93
  const basename = path.basename(src);
94
+ const relativePath = path.relative(TEMPLATE_DIR, src);
94
95
  if (basename === "node_modules") return false;
95
96
  if (basename === ".wrangler") return false;
96
97
  if (basename === ".dev.vars") return false;
98
+ if (basename === ".claude") return false;
99
+ if (basename === "CLAUDE.md") return false;
100
+ if (relativePath === path.join("docs", "internal") || relativePath.startsWith(path.join("docs", "internal") + path.sep)) {
101
+ return false;
102
+ }
97
103
  return true;
98
104
  }
99
105
  });
@@ -157,6 +163,18 @@ S3_SECRET_ACCESS_KEY=
157
163
  devVarsContent,
158
164
  "utf-8"
159
165
  );
166
+ const agentsPath = path.join(targetDir, "AGENTS.md");
167
+ if (await fs.pathExists(agentsPath)) {
168
+ await fs.writeFile(
169
+ path.join(targetDir, "CLAUDE.md"),
170
+ "@AGENTS.md\n",
171
+ "utf-8"
172
+ );
173
+ }
174
+ const sourceSkillsDir = path.join(targetDir, ".agents", "skills");
175
+ if (await fs.pathExists(sourceSkillsDir)) {
176
+ await fs.copy(sourceSkillsDir, path.join(targetDir, ".claude", "skills"));
177
+ }
160
178
  }
161
179
  async function main() {
162
180
  console.log();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-jant",
3
- "version": "0.3.40",
3
+ "version": "0.3.43",
4
4
  "description": "Create a new Jant project",
5
5
  "type": "module",
6
6
  "bin": {
@@ -19,9 +19,9 @@
19
19
  },
20
20
  "devDependencies": {
21
21
  "@types/fs-extra": "^11.0.4",
22
- "@types/node": "^24.0.0",
22
+ "@types/node": "^25.5.0",
23
23
  "tsup": "^8.4.0",
24
- "typescript": "^5.7.3"
24
+ "typescript": "^6.0.2"
25
25
  },
26
26
  "engines": {
27
27
  "node": ">=24.0.0"
@@ -53,7 +53,7 @@
53
53
  "build": "tsup src/index.ts --format esm --clean --outDir dist",
54
54
  "dev": "tsup src/index.ts --format esm --watch",
55
55
  "typecheck": "tsc --noEmit",
56
- "copy-template": "rm -rf template && rsync -a --exclude node_modules --exclude .wrangler --exclude .dev.vars --exclude scripts ../../sites/demo/ template/ && mv template/.gitignore template/_gitignore && mv template/.github template/_github",
56
+ "copy-template": "rm -rf template && rsync -a --exclude node_modules --exclude .wrangler --exclude .dev.vars --exclude .claude --exclude CLAUDE.md --exclude docs/internal --exclude scripts ../../sites/demo/ template/ && mv template/.gitignore template/_gitignore && mv template/.github template/_github",
57
57
  "inject-version": "node -e \"const fs=require('fs');const path=require('path');const coreVersion=require('../core/package.json').version;const workspace=fs.readFileSync(path.resolve(__dirname,'../../pnpm-workspace.yaml'),'utf8');const match=workspace.match(/^[ \\t]*wrangler:[ \\t]*(.+)$/m);if(!match)throw new Error('Unable to resolve wrangler catalog version');const wranglerVersion=match[1].trim();const f='dist/index.js';const source=fs.readFileSync(f,'utf8').replace('__JANT_CORE_VERSION__',coreVersion).replace('__WRANGLER_VERSION__',wranglerVersion);fs.writeFileSync(f,source)\"",
58
58
  "test-template": "node scripts/test-template.js"
59
59
  }
@@ -0,0 +1,101 @@
1
+ ---
2
+ name: building-jant-site
3
+ description: Customize a standalone Jant site created with create-jant. Use for project structure decisions, local development, theme work, deployment setup, settings-driven customization, and deciding whether a change belongs in the site repo or in Jant core.
4
+ ---
5
+
6
+ # Building a Jant Site
7
+
8
+ Jant sites created with `create-jant` are intentionally thin. The site repo is mostly configuration and operations glue around `@jant/core`.
9
+
10
+ ## Start Here
11
+
12
+ Use this skill when you need to:
13
+
14
+ - change site configuration in `wrangler.toml`
15
+ - customize the look with theme settings or custom CSS
16
+ - decide whether a change belongs in the site repo or the Jant monorepo
17
+ - run local development or deploy to Cloudflare
18
+ - script repeatable site changes without editing core code
19
+
20
+ ## Key Constraint
21
+
22
+ Do not patch `node_modules/@jant/core`.
23
+
24
+ If the change is product behavior that should apply to all Jant sites, make it in the Jant monorepo. If the change is site-specific, keep it in:
25
+
26
+ - dashboard settings
27
+ - custom CSS
28
+ - site docs or helper scripts
29
+ - `wrangler.toml`
30
+ - the thin `index.js` entrypoint
31
+
32
+ ## Files That Matter
33
+
34
+ ```text
35
+ index.js # Server entrypoint
36
+ wrangler.toml # Cloudflare config, bindings, vars
37
+ .dev.vars # Local secrets
38
+ README.md # Human-facing project instructions
39
+ ```
40
+
41
+ ## Common Workflow
42
+
43
+ ### 1. Start local development
44
+
45
+ ```bash
46
+ npm run dev
47
+ ```
48
+
49
+ This already runs local migrations before starting Wrangler dev.
50
+
51
+ ### 2. Pick the right customization layer
52
+
53
+ - Content or editorial defaults: use the dashboard or the HTTP API
54
+ - Theme and layout changes: use Settings plus custom CSS
55
+ - Deployment and runtime config: edit `wrangler.toml`
56
+ - One-off site behavior at the server edge: wrap `createApp()` in `index.js`
57
+
58
+ ### 3. Deploy the normal way
59
+
60
+ ```bash
61
+ npm run deploy
62
+ ```
63
+
64
+ Prefer this over raw `wrangler deploy`. The Jant deploy command runs remote migrations and prepares assets before handing off to Wrangler.
65
+
66
+ ## Theming Guidance
67
+
68
+ Start with built-in theme settings. Reach for custom CSS only after the built-in color and font themes are not enough.
69
+
70
+ Useful variables include:
71
+
72
+ - `--background`
73
+ - `--foreground`
74
+ - `--primary`
75
+ - `--site-accent`
76
+ - `--site-width`
77
+ - `--card-radius`
78
+ - `--card-padding`
79
+
80
+ Useful data attributes include:
81
+
82
+ - `data-page`
83
+ - `data-post`
84
+ - `data-format`
85
+ - `data-post-body`
86
+ - `data-post-media`
87
+
88
+ Prefer variable overrides over deep selectors. They survive upstream design changes better.
89
+
90
+ ## Gotchas
91
+
92
+ 1. `index.js` should stay small. If you are about to recreate routing, rendering, or DB behavior there, you are probably changing core, not the site.
93
+ 2. `SITE_PATH_PREFIX` affects deploy behavior. Use `npm run deploy`, not raw Wrangler, so prefixed asset paths are prepared correctly.
94
+ 3. Most editable settings live behind `/api/settings` and are stored as strings.
95
+ 4. The fastest way to break a site-specific customization is to fork `@jant/core` locally instead of using settings or CSS.
96
+
97
+ ## Verify Proportionally
98
+
99
+ - Config-only changes: rerun `npm run dev` or `npm run deploy -- --dry-run` when relevant
100
+ - CSS-only changes: smoke test the affected pages in the browser
101
+ - API-driven changes: exercise the matching endpoint with a real request
@@ -0,0 +1,195 @@
1
+ ---
2
+ name: jant-http-api
3
+ description: Automate a Jant site over HTTP. Use for creating and updating posts, uploading media, managing collections, editing settings, and running public or authenticated queries against the documented Jant API.
4
+ ---
5
+
6
+ # Jant HTTP API
7
+
8
+ Use this skill when the task is better handled through the site's HTTP API than through the browser UI.
9
+
10
+ ## Auth
11
+
12
+ Use one of these:
13
+
14
+ - session cookie from a signed-in browser
15
+ - `Authorization: Bearer jnt_...` API token
16
+ - local `DEV_API_TOKEN` on localhost-style hosts
17
+
18
+ ## Prefer Local CLI First
19
+
20
+ When you already have shell access to the site directory, prefer the built-in `jant` CLI for common automation:
21
+
22
+ ```bash
23
+ npx jant posts list --limit 20
24
+ npx jant posts create --input ./post.json
25
+ npx jant media upload ./photo.webp --alt "Cover image"
26
+ npx jant media list --mimePrefix image/
27
+ npx jant collections add-post col_... pst_...
28
+ npx jant settings get
29
+ npx jant search "quiet design"
30
+ ```
31
+
32
+ The CLI uses the same site URL and token model as the HTTP API.
33
+
34
+ ## Built-in MCP
35
+
36
+ Jant also exposes a built-in MCP endpoint at `/api/mcp`.
37
+
38
+ - auth: session cookie or `Authorization: Bearer jnt_...`
39
+ - tools: posts, media, collections, settings, and search
40
+ - protocol: streamable HTTP request/response shape with `initialize`, `tools/list`, and `tools/call`
41
+
42
+ Use MCP when the caller already speaks MCP. Use the CLI or plain HTTP when you just need a direct script.
43
+
44
+ Generated sites also include worked examples in `examples/agent-content-automation/`.
45
+
46
+ Base URL examples:
47
+
48
+ - local: `http://localhost:3000`
49
+ - production: `https://your-site.example`
50
+
51
+ ## Post Automation
52
+
53
+ ### Create a note
54
+
55
+ ```bash
56
+ curl -X POST "$JANT_URL/api/posts" \
57
+ -H "Authorization: Bearer $JANT_API_TOKEN" \
58
+ -H "Content-Type: application/json" \
59
+ -d '{
60
+ "format": "note",
61
+ "title": "Hello World",
62
+ "bodyMarkdown": "A short note from the API.",
63
+ "status": "published",
64
+ "visibility": "public"
65
+ }'
66
+ ```
67
+
68
+ ### Create a quote
69
+
70
+ ```bash
71
+ curl -X POST "$JANT_URL/api/posts" \
72
+ -H "Authorization: Bearer $JANT_API_TOKEN" \
73
+ -H "Content-Type: application/json" \
74
+ -d '{
75
+ "format": "quote",
76
+ "quoteText": "What stands in the way becomes the way.",
77
+ "sourceName": "Marcus Aurelius",
78
+ "bodyMarkdown": "Still worth rereading."
79
+ }'
80
+ ```
81
+
82
+ ### Update a post
83
+
84
+ ```bash
85
+ curl -X PUT "$JANT_URL/api/posts/pst_..." \
86
+ -H "Authorization: Bearer $JANT_API_TOKEN" \
87
+ -H "Content-Type: application/json" \
88
+ -d '{
89
+ "bodyMarkdown": "Updated body copy.",
90
+ "featured": true
91
+ }'
92
+ ```
93
+
94
+ ## Important Post Rules
95
+
96
+ - Use `bodyMarkdown` for scripts unless you already have trusted TipTap JSON.
97
+ - Use `body` or `bodyMarkdown`, never both.
98
+ - Use `slug` or `path`, never both. `path` is create-only.
99
+ - Link posts require `title` and `url`.
100
+ - Quote posts require `quoteText` and must use `sourceName` / `sourceUrl`.
101
+ - Replies use `replyToId` and inherit the thread's visibility rules.
102
+ - Sending `attachments` replaces the full attachment list.
103
+ - `GET /api/posts` returns replies as well as roots.
104
+
105
+ ## Uploads
106
+
107
+ For scripted clients, prefer the local CLI:
108
+
109
+ ```bash
110
+ npx jant media upload ./photo.webp --alt "Cover image"
111
+ ```
112
+
113
+ For raw HTTP clients, use the recommended upload session flow:
114
+
115
+ 1. `POST /api/uploads/init`
116
+ 2. upload bytes to the returned transport
117
+ 3. `POST /api/uploads/:id/complete`
118
+
119
+ For simple agent scripts, the legacy one-shot endpoint can be easier:
120
+
121
+ ```bash
122
+ curl -X POST "$JANT_URL/api/upload" \
123
+ -H "Authorization: Bearer $JANT_API_TOKEN" \
124
+ -F "file=@./photo.jpg"
125
+ ```
126
+
127
+ Use the returned `med_*` ID inside a post attachment:
128
+
129
+ ```json
130
+ {
131
+ "attachments": [{ "type": "media", "mediaId": "med_..." }]
132
+ }
133
+ ```
134
+
135
+ Read text attachment markdown through:
136
+
137
+ ```bash
138
+ curl "$JANT_URL/api/attachments/med_.../content" \
139
+ -H "Authorization: Bearer $JANT_API_TOKEN"
140
+ ```
141
+
142
+ ## Collections
143
+
144
+ Create a collection:
145
+
146
+ ```bash
147
+ curl -X POST "$JANT_URL/api/collections" \
148
+ -H "Authorization: Bearer $JANT_API_TOKEN" \
149
+ -H "Content-Type: application/json" \
150
+ -d '{
151
+ "slug": "reading",
152
+ "title": "Reading",
153
+ "description": "Books and essays",
154
+ "sortOrder": "newest"
155
+ }'
156
+ ```
157
+
158
+ Attach posts by sending `collectionIds` on post create or update.
159
+
160
+ ## Settings
161
+
162
+ Read settings:
163
+
164
+ ```bash
165
+ curl "$JANT_URL/api/settings" \
166
+ -H "Authorization: Bearer $JANT_API_TOKEN"
167
+ ```
168
+
169
+ Update settings:
170
+
171
+ ```bash
172
+ curl -X PUT "$JANT_URL/api/settings" \
173
+ -H "Authorization: Bearer $JANT_API_TOKEN" \
174
+ -H "Content-Type: application/json" \
175
+ -d '{
176
+ "SITE_NAME": "My Site",
177
+ "TIME_ZONE": "Asia/Shanghai"
178
+ }'
179
+ ```
180
+
181
+ Settings values must be strings, including booleans and numbers.
182
+
183
+ ## Public Queries
184
+
185
+ - Public posts: `GET /api/public/posts`
186
+ - Single public post: `GET /api/public/posts/:slug`
187
+ - Search: `GET /api/search?q=...`
188
+ - Collections: `GET /api/collections`
189
+
190
+ ## Gotchas
191
+
192
+ 1. `latest_hidden` posts are still readable by direct URL.
193
+ 2. Quote responses use `sourceName` and `sourceUrl` instead of `title` and `url`.
194
+ 3. Clearing a post rating on update uses `"rating": 0`.
195
+ 4. Search snippets may contain `<mark>` tags. Treat them as trusted rendered snippet HTML, not plain text.
@@ -0,0 +1,88 @@
1
+ ---
2
+ name: jant-site-ops
3
+ description: Operate a standalone Jant site from the command line. Use for local development, deploys, migrations, password resets, site export/import, snapshot recovery, SQL export, and static asset preparation.
4
+ ---
5
+
6
+ # Jant Site Operations
7
+
8
+ Use this skill when the task is operational rather than purely editorial.
9
+
10
+ ## Run Commands From the Site Root
11
+
12
+ All commands below assume the current working directory is the site root created by `create-jant`.
13
+
14
+ ## Day-to-Day Commands
15
+
16
+ ```bash
17
+ npm run dev
18
+ npm run deploy
19
+ npm run export
20
+ npm run reset-password
21
+ ```
22
+
23
+ What they do:
24
+
25
+ - `npm run dev`: run local migrations, then start Wrangler dev
26
+ - `npm run deploy`: run remote migrations and deploy to Cloudflare
27
+ - `npm run export`: run the Jant export command configured by the site
28
+ - `npm run reset-password`: generate a password reset token for the local site
29
+
30
+ ## CLI Commands
31
+
32
+ ```bash
33
+ npx jant migrate --local
34
+ npx jant migrate --remote --config ./wrangler.toml
35
+ npx jant site export --output ./jant-site-export.zip
36
+ npx jant site import --path ./jant-site-export.zip --dry-run
37
+ npx jant site snapshot export --output ./jant-site-snapshot.zip
38
+ npx jant site snapshot import --path ./jant-site-snapshot.zip --replace
39
+ npx jant db export --output ./jant-export.sql
40
+ ```
41
+
42
+ ## Pick the Right Export Format
43
+
44
+ - `site export`: portable content archive for migration or static inspection
45
+ - `site snapshot export`: recovery archive that preserves Jant IDs and storage keys
46
+ - `db export`: raw SQL dump only
47
+
48
+ Do not treat those as interchangeable.
49
+
50
+ ## Deployment Guidance
51
+
52
+ Prefer:
53
+
54
+ ```bash
55
+ npm run deploy
56
+ ```
57
+
58
+ Avoid calling `wrangler deploy` directly for the normal site workflow. Jant's deploy command handles migrations and asset preparation first.
59
+
60
+ ## Media Utilities
61
+
62
+ Useful commands when working with exported sites or static archives:
63
+
64
+ ```bash
65
+ npx jant site pull-media --help
66
+ npx jant assets prepare
67
+ npx jant uploads cleanup --help
68
+ ```
69
+
70
+ Use `assets prepare` when you need the publishable asset directory assembled locally.
71
+
72
+ ## Remote Operations
73
+
74
+ Remote site export/import can use an API token:
75
+
76
+ ```bash
77
+ export JANT_API_TOKEN=jnt_your_token
78
+ npx jant site export --url https://your-site.example --output ./jant-site-export.zip
79
+ ```
80
+
81
+ For remote D1-oriented commands, pass `--remote` and your Wrangler config when needed.
82
+
83
+ ## Gotchas
84
+
85
+ 1. `site import` expects an empty target site unless you are explicitly using snapshot restore semantics.
86
+ 2. Snapshot import currently requires `--replace`.
87
+ 3. A SQL dump is not a complete backup unless you also preserve media objects.
88
+ 4. Run operations from the project root. The CLI expects local config and installed `@jant/core`.
@@ -0,0 +1,65 @@
1
+ This is a standalone Jant site created with `create-jant`.
2
+
3
+ `CLAUDE.md` is a thin compatibility shim that points here. Site skills live in `.agents/skills/`.
4
+
5
+ ## Project Shape
6
+
7
+ - `index.js` is the server entrypoint. In most projects it should stay a thin `createApp()` wrapper from `@jant/core`.
8
+ - `wrangler.toml` is the main deployment and binding config.
9
+ - `.dev.vars` holds local secrets such as `AUTH_SECRET`.
10
+ - `README.md` documents the normal site workflow for humans.
11
+
12
+ Most customization happens through:
13
+
14
+ - site settings in the dashboard
15
+ - custom CSS and theme variables
16
+ - HTTP API calls
17
+ - `jant` CLI commands for posts, collections, settings, search, export, import, migrate, and deploy
18
+ - the built-in MCP endpoint at `/api/mcp` for remote agent tooling
19
+ - examples in `examples/agent-content-automation/`
20
+
21
+ Do not edit `node_modules/@jant/core`. If you need reusable product changes, make them in the Jant monorepo instead.
22
+
23
+ ## Commands
24
+
25
+ ```bash
26
+ npm run dev
27
+ npm run deploy
28
+ npm run export
29
+ npm run reset-password
30
+
31
+ npx jant migrate --local
32
+ npx jant posts list --limit 20
33
+ npx jant media list --mimePrefix image/
34
+ npx jant collections list
35
+ npx jant settings get
36
+ npx jant search "quiet design"
37
+ npx jant site export --output ./jant-site-export.zip
38
+ npx jant site import --path ./jant-site-export.zip --dry-run
39
+ npx jant db export --output ./jant-export.sql
40
+ ```
41
+
42
+ Use `npm run deploy` for normal Cloudflare deploys. It applies remote migrations and prepares assets before calling Wrangler.
43
+
44
+ ## Skills
45
+
46
+ Load the matching skill before making substantive changes:
47
+
48
+ - `building-jant-site`: project structure, settings, theming, local development, and deployment flow
49
+ - `jant-http-api`: automating posts, uploads, collections, settings, and search over HTTP
50
+ - `jant-site-ops`: export/import, snapshot recovery, deploy, reset-password, and database operations
51
+
52
+ ## Rules
53
+
54
+ - Keep `index.js` minimal unless the site truly needs custom server behavior.
55
+ - Prefer settings, custom CSS, and documented extension points before changing runtime code.
56
+ - Prefer local `npx jant posts`, `collections`, `settings`, and `search` commands for scripted automation when you are already on the site machine.
57
+ - Use `npx jant media` for file uploads, media listing, text attachment reads, alt updates, and deletes.
58
+ - Use `/api/mcp` when an MCP client is available and you need the site to expose posts, collections, settings, or search as tools.
59
+ - Start from `examples/agent-content-automation/README.md` if the task is content automation rather than app development.
60
+ - Use `bodyMarkdown` in API scripts instead of raw TipTap JSON unless you already have trusted editor output.
61
+ - Quote posts use `quoteText`, `sourceName`, and `sourceUrl`. Do not send `title` or `url` for quote payloads.
62
+ - `PUT /api/settings` accepts strings only, even for booleans and numbers.
63
+ - `GET /api/posts` includes thread replies. Filter them yourself if you only want roots.
64
+ - `latest_hidden` posts stay public by direct URL; they are only excluded from Latest surfaces.
65
+ - Run from the site root where `@jant/core` is installed.