cici 0.3.0 → 0.4.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 (55) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-build-manifest.json +20 -20
  3. package/.next/app-path-routes-manifest.json +1 -1
  4. package/.next/build-manifest.json +2 -2
  5. package/.next/next-minimal-server.js.nft.json +1 -1
  6. package/.next/next-server.js.nft.json +1 -1
  7. package/.next/prerender-manifest.json +1 -1
  8. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  9. package/.next/server/app/api/mile/prompts.body +1 -1
  10. package/.next/server/app/atom.xml.body +1 -1
  11. package/.next/server/app/blog/[id]/page_client-reference-manifest.js +1 -1
  12. package/.next/server/app/blog/page_client-reference-manifest.js +1 -1
  13. package/.next/server/app/editor/page_client-reference-manifest.js +1 -1
  14. package/.next/server/app/login/page_client-reference-manifest.js +1 -1
  15. package/.next/server/app/memos/page_client-reference-manifest.js +1 -1
  16. package/.next/server/app/page_client-reference-manifest.js +1 -1
  17. package/.next/server/app/rss.xml.body +1 -1
  18. package/.next/server/app/sitemap.xml.body +5 -5
  19. package/.next/server/app/unavailable/page_client-reference-manifest.js +1 -1
  20. package/.next/server/app-paths-manifest.json +7 -7
  21. package/.next/server/chunks/3844.js +1 -1
  22. package/.next/server/chunks/9715.js +1 -1
  23. package/.next/server/functions-config-manifest.json +1 -1
  24. package/.next/server/pages/500.html +1 -1
  25. package/.next/server/server-reference-manifest.json +1 -1
  26. package/.next/standalone/.next/BUILD_ID +1 -1
  27. package/.next/standalone/.next/app-build-manifest.json +20 -20
  28. package/.next/standalone/.next/app-path-routes-manifest.json +1 -1
  29. package/.next/standalone/.next/build-manifest.json +2 -2
  30. package/.next/standalone/.next/prerender-manifest.json +1 -1
  31. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  32. package/.next/standalone/.next/server/app/api/mile/prompts.body +1 -1
  33. package/.next/standalone/.next/server/app/atom.xml.body +1 -1
  34. package/.next/standalone/.next/server/app/blog/[id]/page_client-reference-manifest.js +1 -1
  35. package/.next/standalone/.next/server/app/blog/page_client-reference-manifest.js +1 -1
  36. package/.next/standalone/.next/server/app/editor/page_client-reference-manifest.js +1 -1
  37. package/.next/standalone/.next/server/app/login/page_client-reference-manifest.js +1 -1
  38. package/.next/standalone/.next/server/app/memos/page_client-reference-manifest.js +1 -1
  39. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  40. package/.next/standalone/.next/server/app/rss.xml.body +1 -1
  41. package/.next/standalone/.next/server/app/sitemap.xml.body +5 -5
  42. package/.next/standalone/.next/server/app/unavailable/page_client-reference-manifest.js +1 -1
  43. package/.next/standalone/.next/server/app-paths-manifest.json +7 -7
  44. package/.next/standalone/.next/server/chunks/3844.js +1 -1
  45. package/.next/standalone/.next/server/chunks/9715.js +1 -1
  46. package/.next/standalone/.next/server/pages/500.html +1 -1
  47. package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
  48. package/.next/standalone/package.json +1 -1
  49. package/.next/trace +120 -120
  50. package/bin/cici.js +103 -33
  51. package/package.json +1 -1
  52. /package/.next/standalone/.next/static/{PDn4f_-4CIbfG8EmueowG → H78KNQuyrLX6JpnJaQChP}/_buildManifest.js +0 -0
  53. /package/.next/standalone/.next/static/{PDn4f_-4CIbfG8EmueowG → H78KNQuyrLX6JpnJaQChP}/_ssgManifest.js +0 -0
  54. /package/.next/static/{PDn4f_-4CIbfG8EmueowG → H78KNQuyrLX6JpnJaQChP}/_buildManifest.js +0 -0
  55. /package/.next/static/{PDn4f_-4CIbfG8EmueowG → H78KNQuyrLX6JpnJaQChP}/_ssgManifest.js +0 -0
package/bin/cici.js CHANGED
@@ -39,8 +39,8 @@ Commands:
39
39
  (default) Serve a --dir or --repo target (see below)
40
40
  start Boot the server from preset env (CICI_REPO/CICI_TOKEN/CICI_DIR/
41
41
  PORT/HOST) — for platform deploys where the host sets env
42
- build Stage cici's prebuilt Next output (.next/standalone, .next/static,
43
- public) into the current directory so a host (e.g. Vercel) can serve it
42
+ build Emit the Vercel Build Output API (.vercel/output) into the current
43
+ directory so a content-only repo deploys on Vercel without app source
44
44
 
45
45
  Targets (exactly one required for the default command):
46
46
  --dir <path> Local content folder (contains blog/, memos.json, …)
@@ -142,49 +142,119 @@ function runStart() {
142
142
  }
143
143
 
144
144
  /**
145
- * `cici build` — stage cici's prebuilt Next output into the CONSUMER's current
146
- * directory so a host (e.g. Vercel) can serve the content repo with cici's tooling.
145
+ * `cici build` — emit the Vercel Build Output API (`.vercel/output`) into the
146
+ * CONSUMER's current directory so a content-only repo deploys on Vercel WITHOUT
147
+ * shipping cici's app source and WITHOUT Vercel running its Next.js builder.
147
148
  *
148
- * cici publishes its full prebuilt Next output; a content repo doesn't rebuild
149
- * Next itself it just needs cici's compiled output copied alongside its content.
150
- * We copy the whole build into the cwd:
151
- * <cici>/.next <cwd>/.next (manifests + server + static + standalone)
152
- * <cici>/public <cwd>/public
153
- * The host's Next.js builder then consumes .next (routes-manifest.json, etc.).
149
+ * cici ships a self-contained Next standalone server (server.js + node_modules +
150
+ * .next/). Rather than hand Vercel a prebuilt `.next` (whose baked build-machine
151
+ * paths break Vercel's Next builder), we package that standalone as a single Node
152
+ * serverless function and drop the static assets into a static dir. Vercel serves
153
+ * the result directly from the Build Output API.
154
+ *
155
+ * Sources (inside the installed cici package = CICI_ROOT):
156
+ * <cici>/.next/standalone — self-contained server (server.js, node_modules, .next/)
157
+ * <cici>/.next/static — hashed client assets (served at /_next/static)
158
+ * <cici>/public — static public files (served at /)
159
+ *
160
+ * Produces (in <cwd>/.vercel/output, cleaned first):
161
+ * functions/index.func/ — the standalone dir + a Node handler wrapping it
162
+ * static/ — _next/static + public files
163
+ * config.json — routes: filesystem first, else the function
154
164
  */
155
165
  function runBuild() {
156
- const server = serverPath()
157
- if (!fs.existsSync(server)) {
166
+ const cwd = process.cwd()
167
+ const nextDir = path.join(CICI_ROOT, '.next')
168
+ const standalone = path.join(nextDir, 'standalone')
169
+ const standaloneServer = path.join(standalone, 'server.js')
170
+
171
+ if (!fs.existsSync(standaloneServer)) {
158
172
  fail(
159
- 'cannot build: cici has no prebuilt server (.next/standalone/server.js).\n' +
173
+ 'cannot build: cici has no prebuilt standalone server (.next/standalone/server.js).\n' +
160
174
  ' This normally ships inside the installed `cici` package. If you are running\n' +
161
175
  ' from source, build it first with `npm run build:cli`.'
162
176
  )
163
177
  }
164
178
 
165
- const cwd = process.cwd()
166
- const copies = [
167
- // Copy the FULL prebuilt .next (manifests, server chunks, static, standalone)
168
- // so the host's Next.js builder (e.g. Vercel) finds routes-manifest.json etc.
169
- // and turns it into functions — no re-build, the app is already compiled here.
170
- { from: path.join(CICI_ROOT, '.next'), to: path.join(cwd, '.next') },
171
- { from: path.join(CICI_ROOT, 'public'), to: path.join(cwd, 'public') },
172
- ]
173
-
174
- const done = []
175
- for (const { from, to } of copies) {
176
- if (!fs.existsSync(from)) continue
177
- fs.mkdirSync(path.dirname(to), { recursive: true })
178
- fs.rmSync(to, { recursive: true, force: true })
179
- fs.cpSync(from, to, { recursive: true })
180
- done.push(path.relative(cwd, to) || to)
179
+ const outDir = path.join(cwd, '.vercel', 'output')
180
+ const fnDir = path.join(outDir, 'functions', 'index.func')
181
+ const staticOut = path.join(outDir, 'static')
182
+ const ciciStatic = path.join(nextDir, 'static')
183
+ const ciciPublic = path.join(CICI_ROOT, 'public')
184
+
185
+ // Clean any prior output so stale files never leak into a deploy.
186
+ fs.rmSync(outDir, { recursive: true, force: true })
187
+
188
+ // 1. Function: the entire self-contained standalone dir.
189
+ fs.mkdirSync(fnDir, { recursive: true })
190
+ fs.cpSync(standalone, fnDir, { recursive: true })
191
+
192
+ // The runtime server reads .next/static relative to its dir ensure it's present.
193
+ if (fs.existsSync(ciciStatic)) {
194
+ fs.cpSync(ciciStatic, path.join(fnDir, '.next', 'static'), { recursive: true })
195
+ }
196
+
197
+ // 2. Handler: boot the standalone Next server as a plain Node request handler.
198
+ const handler = [
199
+ "const path = require('path')",
200
+ "process.env.NODE_ENV = 'production'",
201
+ 'process.chdir(__dirname)',
202
+ "const NextServer = require('next/dist/server/next-server').default",
203
+ 'let conf = {}',
204
+ "try { conf = require('./.next/required-server-files.json').config } catch (e) {}",
205
+ 'const app = new NextServer({ dir: __dirname, dev: false, conf, customServer: false })',
206
+ 'const handler = app.getRequestHandler()',
207
+ 'module.exports = (req, res) => handler(req, res)',
208
+ '',
209
+ ].join('\n')
210
+ fs.writeFileSync(path.join(fnDir, 'index.js'), handler)
211
+
212
+ // 3. Function config for the Vercel Node runtime.
213
+ const vcConfig = {
214
+ runtime: 'nodejs22.x',
215
+ handler: 'index.js',
216
+ launcherType: 'Nodejs',
217
+ shouldAddHelpers: false,
218
+ supportsResponseStreaming: true,
219
+ }
220
+ fs.writeFileSync(path.join(fnDir, '.vc-config.json'), JSON.stringify(vcConfig, null, 2) + '\n')
221
+
222
+ // 4. Static assets: hashed client bundles + public files.
223
+ fs.mkdirSync(staticOut, { recursive: true })
224
+ let staticCopied = false
225
+ let publicCopied = false
226
+ if (fs.existsSync(ciciStatic)) {
227
+ fs.cpSync(ciciStatic, path.join(staticOut, '_next', 'static'), { recursive: true })
228
+ staticCopied = true
229
+ }
230
+ if (fs.existsSync(ciciPublic)) {
231
+ for (const entry of fs.readdirSync(ciciPublic)) {
232
+ fs.cpSync(path.join(ciciPublic, entry), path.join(staticOut, entry), { recursive: true })
233
+ }
234
+ publicCopied = true
235
+ }
236
+
237
+ // 5. Top-level build output config: serve files first, else the function.
238
+ const config = {
239
+ version: 3,
240
+ routes: [
241
+ { handle: 'filesystem' },
242
+ { src: '/(.*)', dest: '/index' },
243
+ ],
181
244
  }
245
+ fs.writeFileSync(path.join(outDir, 'config.json'), JSON.stringify(config, null, 2) + '\n')
182
246
 
247
+ const rel = (p) => path.relative(cwd, p) || p
183
248
  process.stdout.write(
184
- `\n cici ${pkg.version} build\n` +
185
- ` staged cici's prebuilt output into ${cwd}\n` +
186
- (done.length ? done.map((d) => ` ✓ ${d}\n`).join('') : ' (nothing to copy)\n') +
187
- `\n A host can now serve this directory (server entry: .next/standalone/server.js).\n\n`
249
+ `\n cici ${pkg.version} build — Vercel Build Output API\n` +
250
+ ` emitted ${rel(outDir)}\n` +
251
+ ` ✓ ${rel(path.join(fnDir, 'index.js'))} (Node function handler)\n` +
252
+ ` ✓ ${rel(path.join(fnDir, '.vc-config.json'))} (runtime config)\n` +
253
+ ` ✓ ${rel(fnDir)}/ (standalone server + node_modules)\n` +
254
+ ` ${staticCopied ? '✓' : '·'} ${rel(path.join(staticOut, '_next', 'static'))}${staticCopied ? '' : ' (no .next/static)'}\n` +
255
+ ` ${publicCopied ? '✓' : '·'} public files → ${rel(staticOut)}${publicCopied ? '' : ' (no public/)'}\n` +
256
+ ` ✓ ${rel(path.join(outDir, 'config.json'))}\n` +
257
+ `\n Deploy on Vercel with no app source — it serves .vercel/output directly.\n\n`
188
258
  )
189
259
  }
190
260
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cici",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "private": false,
5
5
  "description": "cici — a git-backed blog CMS (pure tooling; your posts live in a separate content repo). Run `npx cici --dir <dir>` or `--repo <owner/name>` to serve/edit, or `cici build` / `cici start` to deploy.",
6
6
  "repository": {